1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci/* Author:
29bf215546Sopenharmony_ci *    Keith Whitwell <keithw@vmware.com>
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "pipe/p_defines.h"
34bf215546Sopenharmony_ci#include "pipe/p_screen.h"
35bf215546Sopenharmony_ci#include "draw/draw_context.h"
36bf215546Sopenharmony_ci#include "sp_flush.h"
37bf215546Sopenharmony_ci#include "sp_context.h"
38bf215546Sopenharmony_ci#include "sp_state.h"
39bf215546Sopenharmony_ci#include "sp_tile_cache.h"
40bf215546Sopenharmony_ci#include "sp_tex_tile_cache.h"
41bf215546Sopenharmony_ci#include "util/u_debug_image.h"
42bf215546Sopenharmony_ci#include "util/u_memory.h"
43bf215546Sopenharmony_ci#include "util/u_string.h"
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_civoid
47bf215546Sopenharmony_cisoftpipe_flush( struct pipe_context *pipe,
48bf215546Sopenharmony_ci                unsigned flags,
49bf215546Sopenharmony_ci                struct pipe_fence_handle **fence )
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci   struct softpipe_context *softpipe = softpipe_context(pipe);
52bf215546Sopenharmony_ci   uint i;
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   draw_flush(softpipe->draw);
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   if (flags & SP_FLUSH_TEXTURE_CACHE) {
57bf215546Sopenharmony_ci      unsigned sh;
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci      for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
60bf215546Sopenharmony_ci         for (i = 0; i < softpipe->num_sampler_views[sh]; i++) {
61bf215546Sopenharmony_ci            sp_flush_tex_tile_cache(softpipe->tex_cache[sh][i]);
62bf215546Sopenharmony_ci         }
63bf215546Sopenharmony_ci      }
64bf215546Sopenharmony_ci   }
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   /* If this is a swapbuffers, just flush color buffers.
67bf215546Sopenharmony_ci    *
68bf215546Sopenharmony_ci    * The zbuffer changes are not discarded, but held in the cache
69bf215546Sopenharmony_ci    * in the hope that a later clear will wipe them out.
70bf215546Sopenharmony_ci    */
71bf215546Sopenharmony_ci   for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
72bf215546Sopenharmony_ci      if (softpipe->cbuf_cache[i])
73bf215546Sopenharmony_ci         sp_flush_tile_cache(softpipe->cbuf_cache[i]);
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   if (softpipe->zsbuf_cache)
76bf215546Sopenharmony_ci      sp_flush_tile_cache(softpipe->zsbuf_cache);
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   softpipe->dirty_render_cache = FALSE;
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci   /* Enable to dump BMPs of the color/depth buffers each frame */
81bf215546Sopenharmony_ci#if 0
82bf215546Sopenharmony_ci   if (flags & PIPE_FLUSH_END_OF_FRAME) {
83bf215546Sopenharmony_ci      static unsigned frame_no = 1;
84bf215546Sopenharmony_ci      static char filename[256];
85bf215546Sopenharmony_ci      snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no);
86bf215546Sopenharmony_ci      debug_dump_surface_bmp(pipe, filename, softpipe->framebuffer.cbufs[0]);
87bf215546Sopenharmony_ci      snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no);
88bf215546Sopenharmony_ci      debug_dump_surface_bmp(pipe, filename, softpipe->framebuffer.zsbuf);
89bf215546Sopenharmony_ci      ++frame_no;
90bf215546Sopenharmony_ci   }
91bf215546Sopenharmony_ci#endif
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   if (fence)
94bf215546Sopenharmony_ci      *fence = (void*)(intptr_t)1;
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_civoid
98bf215546Sopenharmony_cisoftpipe_flush_wrapped(struct pipe_context *pipe,
99bf215546Sopenharmony_ci                       struct pipe_fence_handle **fence,
100bf215546Sopenharmony_ci                       unsigned flags)
101bf215546Sopenharmony_ci{
102bf215546Sopenharmony_ci   softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence);
103bf215546Sopenharmony_ci}
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci/**
107bf215546Sopenharmony_ci * Flush context if necessary.
108bf215546Sopenharmony_ci *
109bf215546Sopenharmony_ci * Returns FALSE if it would have block, but do_not_block was set, TRUE
110bf215546Sopenharmony_ci * otherwise.
111bf215546Sopenharmony_ci *
112bf215546Sopenharmony_ci * TODO: move this logic to an auxiliary library?
113bf215546Sopenharmony_ci */
114bf215546Sopenharmony_ciboolean
115bf215546Sopenharmony_cisoftpipe_flush_resource(struct pipe_context *pipe,
116bf215546Sopenharmony_ci                        struct pipe_resource *texture,
117bf215546Sopenharmony_ci                        unsigned level,
118bf215546Sopenharmony_ci                        int layer,
119bf215546Sopenharmony_ci                        unsigned flush_flags,
120bf215546Sopenharmony_ci                        boolean read_only,
121bf215546Sopenharmony_ci                        boolean cpu_access,
122bf215546Sopenharmony_ci                        boolean do_not_block)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   unsigned referenced;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   referenced = softpipe_is_resource_referenced(pipe, texture, level, layer);
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   if ((referenced & SP_REFERENCED_FOR_WRITE) ||
129bf215546Sopenharmony_ci       ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) {
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci      /*
132bf215546Sopenharmony_ci       * TODO: The semantics of these flush flags are too obtuse. They should
133bf215546Sopenharmony_ci       * disappear and the pipe driver should just ensure that all visible
134bf215546Sopenharmony_ci       * side-effects happen when they need to happen.
135bf215546Sopenharmony_ci       */
136bf215546Sopenharmony_ci      if (referenced & SP_REFERENCED_FOR_READ)
137bf215546Sopenharmony_ci         flush_flags |= SP_FLUSH_TEXTURE_CACHE;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci      if (cpu_access) {
140bf215546Sopenharmony_ci         /*
141bf215546Sopenharmony_ci          * Flush and wait.
142bf215546Sopenharmony_ci          */
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci         struct pipe_fence_handle *fence = NULL;
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci         if (do_not_block)
147bf215546Sopenharmony_ci            return FALSE;
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci         softpipe_flush(pipe, flush_flags, &fence);
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci         if (fence) {
152bf215546Sopenharmony_ci            /*
153bf215546Sopenharmony_ci             * This is for illustrative purposes only, as softpipe does not
154bf215546Sopenharmony_ci             * have fences.
155bf215546Sopenharmony_ci             */
156bf215546Sopenharmony_ci            pipe->screen->fence_finish(pipe->screen, NULL, fence,
157bf215546Sopenharmony_ci                                       PIPE_TIMEOUT_INFINITE);
158bf215546Sopenharmony_ci            pipe->screen->fence_reference(pipe->screen, &fence, NULL);
159bf215546Sopenharmony_ci         }
160bf215546Sopenharmony_ci      } else {
161bf215546Sopenharmony_ci         /*
162bf215546Sopenharmony_ci          * Just flush.
163bf215546Sopenharmony_ci          */
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci         softpipe_flush(pipe, flush_flags, NULL);
166bf215546Sopenharmony_ci      }
167bf215546Sopenharmony_ci   }
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci   return TRUE;
170bf215546Sopenharmony_ci}
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_civoid softpipe_texture_barrier(struct pipe_context *pipe, unsigned flags)
173bf215546Sopenharmony_ci{
174bf215546Sopenharmony_ci   struct softpipe_context *softpipe = softpipe_context(pipe);
175bf215546Sopenharmony_ci   uint i, sh;
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
178bf215546Sopenharmony_ci      for (i = 0; i < softpipe->num_sampler_views[sh]; i++) {
179bf215546Sopenharmony_ci         sp_flush_tex_tile_cache(softpipe->tex_cache[sh][i]);
180bf215546Sopenharmony_ci      }
181bf215546Sopenharmony_ci   }
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci   for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
184bf215546Sopenharmony_ci      if (softpipe->cbuf_cache[i])
185bf215546Sopenharmony_ci         sp_flush_tile_cache(softpipe->cbuf_cache[i]);
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci   if (softpipe->zsbuf_cache)
188bf215546Sopenharmony_ci      sp_flush_tile_cache(softpipe->zsbuf_cache);
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci   softpipe->dirty_render_cache = FALSE;
191bf215546Sopenharmony_ci}
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_civoid softpipe_memory_barrier(struct pipe_context *pipe, unsigned flags)
194bf215546Sopenharmony_ci{
195bf215546Sopenharmony_ci   if (!(flags & ~PIPE_BARRIER_UPDATE))
196bf215546Sopenharmony_ci      return;
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci   softpipe_texture_barrier(pipe, 0);
199bf215546Sopenharmony_ci}
200