146c3cf18315345effd15a69987294c1195843e2aBrian/**************************************************************************
246c3cf18315345effd15a69987294c1195843e2aBrian *
346c3cf18315345effd15a69987294c1195843e2aBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
446c3cf18315345effd15a69987294c1195843e2aBrian * All Rights Reserved.
546c3cf18315345effd15a69987294c1195843e2aBrian *
646c3cf18315345effd15a69987294c1195843e2aBrian * Permission is hereby granted, free of charge, to any person obtaining a
746c3cf18315345effd15a69987294c1195843e2aBrian * copy of this software and associated documentation files (the
846c3cf18315345effd15a69987294c1195843e2aBrian * "Software"), to deal in the Software without restriction, including
946c3cf18315345effd15a69987294c1195843e2aBrian * without limitation the rights to use, copy, modify, merge, publish,
1046c3cf18315345effd15a69987294c1195843e2aBrian * distribute, sub license, and/or sell copies of the Software, and to
1146c3cf18315345effd15a69987294c1195843e2aBrian * permit persons to whom the Software is furnished to do so, subject to
1246c3cf18315345effd15a69987294c1195843e2aBrian * the following conditions:
1346c3cf18315345effd15a69987294c1195843e2aBrian *
1446c3cf18315345effd15a69987294c1195843e2aBrian * The above copyright notice and this permission notice (including the
1546c3cf18315345effd15a69987294c1195843e2aBrian * next paragraph) shall be included in all copies or substantial portions
1646c3cf18315345effd15a69987294c1195843e2aBrian * of the Software.
1746c3cf18315345effd15a69987294c1195843e2aBrian *
1846c3cf18315345effd15a69987294c1195843e2aBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1946c3cf18315345effd15a69987294c1195843e2aBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2046c3cf18315345effd15a69987294c1195843e2aBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2146c3cf18315345effd15a69987294c1195843e2aBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2246c3cf18315345effd15a69987294c1195843e2aBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2346c3cf18315345effd15a69987294c1195843e2aBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2446c3cf18315345effd15a69987294c1195843e2aBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2546c3cf18315345effd15a69987294c1195843e2aBrian *
2646c3cf18315345effd15a69987294c1195843e2aBrian **************************************************************************/
2746c3cf18315345effd15a69987294c1195843e2aBrian
2846c3cf18315345effd15a69987294c1195843e2aBrian/**
2980c78472ad43f4288c9ef5076074ba9d31a39885Keith Whitwell * Render target tile caching.
3046c3cf18315345effd15a69987294c1195843e2aBrian *
3146c3cf18315345effd15a69987294c1195843e2aBrian * Author:
3246c3cf18315345effd15a69987294c1195843e2aBrian *    Brian Paul
3346c3cf18315345effd15a69987294c1195843e2aBrian */
3446c3cf18315345effd15a69987294c1195843e2aBrian
3528486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
36cceeab39ea541b1be1521114316d660a77769c2aMichal Krol#include "util/u_format.h"
374f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
384f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_tile.h"
3946c3cf18315345effd15a69987294c1195843e2aBrian#include "sp_tile_cache.h"
4046c3cf18315345effd15a69987294c1195843e2aBrian
41029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulstatic struct softpipe_cached_tile *
42029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulsp_alloc_tile(struct softpipe_tile_cache *tc);
4346c3cf18315345effd15a69987294c1195843e2aBrian
4446c3cf18315345effd15a69987294c1195843e2aBrian
4546c3cf18315345effd15a69987294c1195843e2aBrian/**
4646c3cf18315345effd15a69987294c1195843e2aBrian * Return the position in the cache for the tile that contains win pos (x,y).
4746c3cf18315345effd15a69987294c1195843e2aBrian * We currently use a direct mapped cache so this is like a hack key.
4846c3cf18315345effd15a69987294c1195843e2aBrian * At some point we should investige something more sophisticated, like
4946c3cf18315345effd15a69987294c1195843e2aBrian * a LRU replacement policy.
5046c3cf18315345effd15a69987294c1195843e2aBrian */
5146c3cf18315345effd15a69987294c1195843e2aBrian#define CACHE_POS(x, y) \
5219097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell   (((x) + (y) * 5) % NUM_ENTRIES)
5346c3cf18315345effd15a69987294c1195843e2aBrian
5446c3cf18315345effd15a69987294c1195843e2aBrian
5546c3cf18315345effd15a69987294c1195843e2aBrian
56127a493fe2a2f7fd8515b278185322dfacdad357Brian/**
57127a493fe2a2f7fd8515b278185322dfacdad357Brian * Is the tile at (x,y) in cleared state?
58127a493fe2a2f7fd8515b278185322dfacdad357Brian */
5957df347bb8a119e1d00fe808e30a0623e0ae8563Brianstatic INLINE uint
6019097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwellis_clear_flag_set(const uint *bitvec, union tile_address addr)
6146c3cf18315345effd15a69987294c1195843e2aBrian{
6246c3cf18315345effd15a69987294c1195843e2aBrian   int pos, bit;
6319097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell   pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
6476a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
6546c3cf18315345effd15a69987294c1195843e2aBrian   bit = bitvec[pos / 32] & (1 << (pos & 31));
6646c3cf18315345effd15a69987294c1195843e2aBrian   return bit;
6746c3cf18315345effd15a69987294c1195843e2aBrian}
6846c3cf18315345effd15a69987294c1195843e2aBrian
6946c3cf18315345effd15a69987294c1195843e2aBrian
70127a493fe2a2f7fd8515b278185322dfacdad357Brian/**
71127a493fe2a2f7fd8515b278185322dfacdad357Brian * Mark the tile at (x,y) as not cleared.
72127a493fe2a2f7fd8515b278185322dfacdad357Brian */
7357df347bb8a119e1d00fe808e30a0623e0ae8563Brianstatic INLINE void
7419097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwellclear_clear_flag(uint *bitvec, union tile_address addr)
7546c3cf18315345effd15a69987294c1195843e2aBrian{
7646c3cf18315345effd15a69987294c1195843e2aBrian   int pos;
7719097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell   pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
7876a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian   assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
7946c3cf18315345effd15a69987294c1195843e2aBrian   bitvec[pos / 32] &= ~(1 << (pos & 31));
8046c3cf18315345effd15a69987294c1195843e2aBrian}
8146c3cf18315345effd15a69987294c1195843e2aBrian
8246c3cf18315345effd15a69987294c1195843e2aBrian
8346c3cf18315345effd15a69987294c1195843e2aBrianstruct softpipe_tile_cache *
84b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwellsp_create_tile_cache( struct pipe_context *pipe )
8546c3cf18315345effd15a69987294c1195843e2aBrian{
8646c3cf18315345effd15a69987294c1195843e2aBrian   struct softpipe_tile_cache *tc;
8746c3cf18315345effd15a69987294c1195843e2aBrian   uint pos;
88e41707becaffd604fedc885719e5b061a4a5b363Brian Paul   int maxLevels, maxTexSize;
89e41707becaffd604fedc885719e5b061a4a5b363Brian Paul
90e41707becaffd604fedc885719e5b061a4a5b363Brian Paul   /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
91b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell   maxLevels = pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
92e41707becaffd604fedc885719e5b061a4a5b363Brian Paul   maxTexSize = 1 << (maxLevels - 1);
93e41707becaffd604fedc885719e5b061a4a5b363Brian Paul   assert(MAX_WIDTH >= maxTexSize);
9446c3cf18315345effd15a69987294c1195843e2aBrian
95af4f75c8fe1c53b8def966f480e7fda8021f1b63Brian Paul   assert(sizeof(union tile_address) == 4);
96af4f75c8fe1c53b8def966f480e7fda8021f1b63Brian Paul
97af4f75c8fe1c53b8def966f480e7fda8021f1b63Brian Paul   assert((TILE_SIZE << TILE_ADDR_BITS) >= MAX_WIDTH);
98af4f75c8fe1c53b8def966f480e7fda8021f1b63Brian Paul
99ee295fccdd0c94cb6b8af4dfb30283e39f548223Michal Krol   tc = CALLOC_STRUCT( softpipe_tile_cache );
10046c3cf18315345effd15a69987294c1195843e2aBrian   if (tc) {
101b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      tc->pipe = pipe;
10246c3cf18315345effd15a69987294c1195843e2aBrian      for (pos = 0; pos < NUM_ENTRIES; pos++) {
103029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         tc->tile_addrs[pos].bits.invalid = 1;
104029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      }
105029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->last_tile_addr.bits.invalid = 1;
106029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
107029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      /* this allocation allows us to guarantee that allocation
108029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul       * failures are never fatal later
109029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul       */
110029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile = MALLOC_STRUCT( softpipe_cached_tile );
111029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      if (!tc->tile)
112029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      {
113029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         FREE(tc);
114029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         return NULL;
11546c3cf18315345effd15a69987294c1195843e2aBrian      }
116564df9dc5f6335eb8dc68f3c69cf054d2142663cBrian Paul
117768481ed40cb7530fdbadbf4d6dc00b74209adf1Brian Paul      /* XXX this code prevents valgrind warnings about use of uninitialized
118768481ed40cb7530fdbadbf4d6dc00b74209adf1Brian Paul       * memory in programs that don't clear the surface before rendering.
119768481ed40cb7530fdbadbf4d6dc00b74209adf1Brian Paul       * However, it breaks clearing in other situations (such as in
120768481ed40cb7530fdbadbf4d6dc00b74209adf1Brian Paul       * progs/tests/drawbuffers, see bug 24402).
121768481ed40cb7530fdbadbf4d6dc00b74209adf1Brian Paul       */
12289f244931f444056a1ccf544e608b533fa993fa2José Fonseca#if 0
123564df9dc5f6335eb8dc68f3c69cf054d2142663cBrian Paul      /* set flags to indicate all the tiles are cleared */
124564df9dc5f6335eb8dc68f3c69cf054d2142663cBrian Paul      memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
125564df9dc5f6335eb8dc68f3c69cf054d2142663cBrian Paul#endif
12646c3cf18315345effd15a69987294c1195843e2aBrian   }
12746c3cf18315345effd15a69987294c1195843e2aBrian   return tc;
12846c3cf18315345effd15a69987294c1195843e2aBrian}
12946c3cf18315345effd15a69987294c1195843e2aBrian
13046c3cf18315345effd15a69987294c1195843e2aBrian
13146c3cf18315345effd15a69987294c1195843e2aBrianvoid
13246c3cf18315345effd15a69987294c1195843e2aBriansp_destroy_tile_cache(struct softpipe_tile_cache *tc)
13346c3cf18315345effd15a69987294c1195843e2aBrian{
1348122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol   if (tc) {
1358122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      uint pos;
1366656864135411d379c06e071c5a5e73b4e4baea5Brian
1378122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      for (pos = 0; pos < NUM_ENTRIES; pos++) {
1388122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol         /*assert(tc->entries[pos].x < 0);*/
139029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         FREE( tc->entries[pos] );
1408122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      }
141029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      FREE( tc->tile );
142029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
1438122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      if (tc->transfer) {
1448122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol         tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
1458122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      }
1466656864135411d379c06e071c5a5e73b4e4baea5Brian
1478122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol      FREE( tc );
1488122baf8badfa9fe7a80bfc904ad7b6ddcdecb0cMichal Krol   }
14946c3cf18315345effd15a69987294c1195843e2aBrian}
15046c3cf18315345effd15a69987294c1195843e2aBrian
15146c3cf18315345effd15a69987294c1195843e2aBrian
152127a493fe2a2f7fd8515b278185322dfacdad357Brian/**
153127a493fe2a2f7fd8515b278185322dfacdad357Brian * Specify the surface to cache.
154127a493fe2a2f7fd8515b278185322dfacdad357Brian */
1557e8396399824108d62dc3e02b2af0422e98aab8eBrianvoid
15657df347bb8a119e1d00fe808e30a0623e0ae8563Briansp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
157f6a73c3f2815c4c84563c186bba6c8e67bb42ae9Brian                          struct pipe_surface *ps)
1587e8396399824108d62dc3e02b2af0422e98aab8eBrian{
159b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell   struct pipe_context *pipe = tc->pipe;
1605af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer
161b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell   if (tc->transfer) {
1622142bf5e17d699396772b90ee5b2592289334f28Michel Dänzer      if (ps == tc->surface)
1634617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer         return;
164b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer
1654617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      if (tc->transfer_map) {
166b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell         pipe->transfer_unmap(pipe, tc->transfer);
1674617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer         tc->transfer_map = NULL;
1684617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      }
1694617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer
170287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, tc->transfer);
17171e3aa14fb09616a9b06cd6fd01fcabf3853cacdBrian Paul      tc->transfer = NULL;
172872caf6089e325cf3a0cee877f5119cac560edacBrian   }
173b859cdf6f191b4d8b56537c8dc30082a7e2d94b3Michel Dänzer
1742142bf5e17d699396772b90ee5b2592289334f28Michel Dänzer   tc->surface = ps;
1752142bf5e17d699396772b90ee5b2592289334f28Michel Dänzer
1765af34758e3bba55cb8c227ae1256818e8f112727Michel Dänzer   if (ps) {
1774c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      tc->transfer = pipe_get_transfer(pipe, ps->texture,
1784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                       ps->u.tex.level, ps->u.tex.first_layer,
1794c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                       PIPE_TRANSFER_READ_WRITE |
1804c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                       PIPE_TRANSFER_UNSYNCHRONIZED,
1814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                       0, 0, ps->width, ps->height);
182a51d0e419a285c5445061a38fdaf3aca02ad2c3cBrian
18389999204eca233b879ed055aaf2c6a299c263b16Brian Paul      tc->depth_stencil = util_format_is_depth_or_stencil(ps->format);
184127a493fe2a2f7fd8515b278185322dfacdad357Brian   }
1857e8396399824108d62dc3e02b2af0422e98aab8eBrian}
1867e8396399824108d62dc3e02b2af0422e98aab8eBrian
1877e8396399824108d62dc3e02b2af0422e98aab8eBrian
188127a493fe2a2f7fd8515b278185322dfacdad357Brian/**
1894617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer * Return the transfer being cached.
190127a493fe2a2f7fd8515b278185322dfacdad357Brian */
191f6a73c3f2815c4c84563c186bba6c8e67bb42ae9Brianstruct pipe_surface *
19257df347bb8a119e1d00fe808e30a0623e0ae8563Briansp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
19376a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian{
19476a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian   return tc->surface;
19576a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian}
19676a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian
19776a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian
198c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzervoid
1994617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzersp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
200c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer{
2014617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   if (tc->transfer && !tc->transfer_map)
202b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      tc->transfer_map = tc->pipe->transfer_map(tc->pipe, tc->transfer);
203c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer}
204c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer
205c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer
206c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzervoid
2074617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzersp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
208c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer{
2094617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer   if (tc->transfer_map) {
210b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      tc->pipe->transfer_unmap(tc->pipe, tc->transfer);
2114617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      tc->transfer_map = NULL;
212c76efb96b405e43e3261d1dc9e8812fdb2cfbac8Michel Dänzer   }
213b3204c2aff3f3d442ada04f241f352155a3af205Brian}
2147e8396399824108d62dc3e02b2af0422e98aab8eBrian
21546c3cf18315345effd15a69987294c1195843e2aBrian
216127a493fe2a2f7fd8515b278185322dfacdad357Brian/**
217127a493fe2a2f7fd8515b278185322dfacdad357Brian * Set pixels in a tile to the given clear color/value, float.
218127a493fe2a2f7fd8515b278185322dfacdad357Brian */
219127a493fe2a2f7fd8515b278185322dfacdad357Brianstatic void
220127a493fe2a2f7fd8515b278185322dfacdad357Brianclear_tile_rgba(struct softpipe_cached_tile *tile,
221127a493fe2a2f7fd8515b278185322dfacdad357Brian                enum pipe_format format,
222396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                const union pipe_color_union *clear_value)
22357df347bb8a119e1d00fe808e30a0623e0ae8563Brian{
224396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie   if (clear_value->f[0] == 0.0 &&
225396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie       clear_value->f[1] == 0.0 &&
226396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie       clear_value->f[2] == 0.0 &&
227396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie       clear_value->f[3] == 0.0) {
228127a493fe2a2f7fd8515b278185322dfacdad357Brian      memset(tile->data.color, 0, sizeof(tile->data.color));
229127a493fe2a2f7fd8515b278185322dfacdad357Brian   }
230127a493fe2a2f7fd8515b278185322dfacdad357Brian   else {
231127a493fe2a2f7fd8515b278185322dfacdad357Brian      uint i, j;
232396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie
233396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie      if (util_format_is_pure_uint(format)) {
234396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         for (i = 0; i < TILE_SIZE; i++) {
235396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            for (j = 0; j < TILE_SIZE; j++) {
236396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colorui128[i][j][0] = clear_value->ui[0];
237396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colorui128[i][j][1] = clear_value->ui[1];
238396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colorui128[i][j][2] = clear_value->ui[2];
239396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colorui128[i][j][3] = clear_value->ui[3];
240396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            }
241396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         }
242396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie      } else if (util_format_is_pure_sint(format)) {
243396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         for (i = 0; i < TILE_SIZE; i++) {
244396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            for (j = 0; j < TILE_SIZE; j++) {
245396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colori128[i][j][0] = clear_value->i[0];
246396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colori128[i][j][1] = clear_value->i[1];
247396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colori128[i][j][2] = clear_value->i[2];
248396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.colori128[i][j][3] = clear_value->i[3];
249396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            }
250396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         }
251396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie      } else {
252396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         for (i = 0; i < TILE_SIZE; i++) {
253396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            for (j = 0; j < TILE_SIZE; j++) {
254396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.color[i][j][0] = clear_value->f[0];
255396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.color[i][j][1] = clear_value->f[1];
256396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.color[i][j][2] = clear_value->f[2];
257396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               tile->data.color[i][j][3] = clear_value->f[3];
258396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            }
259127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
260127a493fe2a2f7fd8515b278185322dfacdad357Brian      }
261127a493fe2a2f7fd8515b278185322dfacdad357Brian   }
26257df347bb8a119e1d00fe808e30a0623e0ae8563Brian}
26357df347bb8a119e1d00fe808e30a0623e0ae8563Brian
26457df347bb8a119e1d00fe808e30a0623e0ae8563Brian
26557df347bb8a119e1d00fe808e30a0623e0ae8563Brian/**
266127a493fe2a2f7fd8515b278185322dfacdad357Brian * Set a tile to a solid value/color.
26757df347bb8a119e1d00fe808e30a0623e0ae8563Brian */
26857df347bb8a119e1d00fe808e30a0623e0ae8563Brianstatic void
26954fc80ab31f89520d3119196bfa9c6332b35fe2fBrianclear_tile(struct softpipe_cached_tile *tile,
27054fc80ab31f89520d3119196bfa9c6332b35fe2fBrian           enum pipe_format format,
271e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand           uint64_t clear_value)
27257df347bb8a119e1d00fe808e30a0623e0ae8563Brian{
27357df347bb8a119e1d00fe808e30a0623e0ae8563Brian   uint i, j;
27457df347bb8a119e1d00fe808e30a0623e0ae8563Brian
275b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   switch (util_format_get_blocksize(format)) {
27641b1aa51096e844c0b06f950b1891dc7e5256db7Brian   case 1:
277c84abe36a93312cfa061ce1bd005e43eb9f6a6dfKeith Whitwell      memset(tile->data.any, clear_value, TILE_SIZE * TILE_SIZE);
27857df347bb8a119e1d00fe808e30a0623e0ae8563Brian      break;
27941b1aa51096e844c0b06f950b1891dc7e5256db7Brian   case 2:
280127a493fe2a2f7fd8515b278185322dfacdad357Brian      if (clear_value == 0) {
281127a493fe2a2f7fd8515b278185322dfacdad357Brian         memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE);
28257df347bb8a119e1d00fe808e30a0623e0ae8563Brian      }
283127a493fe2a2f7fd8515b278185322dfacdad357Brian      else {
28457df347bb8a119e1d00fe808e30a0623e0ae8563Brian         for (i = 0; i < TILE_SIZE; i++) {
28557df347bb8a119e1d00fe808e30a0623e0ae8563Brian            for (j = 0; j < TILE_SIZE; j++) {
286271f9dac79a9247de9a57f4d248e404bf1652a13José Fonseca               tile->data.depth16[i][j] = (ushort) clear_value;
28757df347bb8a119e1d00fe808e30a0623e0ae8563Brian            }
28857df347bb8a119e1d00fe808e30a0623e0ae8563Brian         }
28957df347bb8a119e1d00fe808e30a0623e0ae8563Brian      }
29057df347bb8a119e1d00fe808e30a0623e0ae8563Brian      break;
29141b1aa51096e844c0b06f950b1891dc7e5256db7Brian   case 4:
292127a493fe2a2f7fd8515b278185322dfacdad357Brian      if (clear_value == 0) {
293127a493fe2a2f7fd8515b278185322dfacdad357Brian         memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE);
29457df347bb8a119e1d00fe808e30a0623e0ae8563Brian      }
29557df347bb8a119e1d00fe808e30a0623e0ae8563Brian      else {
29657df347bb8a119e1d00fe808e30a0623e0ae8563Brian         for (i = 0; i < TILE_SIZE; i++) {
29757df347bb8a119e1d00fe808e30a0623e0ae8563Brian            for (j = 0; j < TILE_SIZE; j++) {
298e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand               tile->data.depth32[i][j] = clear_value;
299e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand            }
300e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand         }
301e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand      }
302e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand      break;
303e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand   case 8:
304e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand      if (clear_value == 0) {
305e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand         memset(tile->data.any, 0, 8 * TILE_SIZE * TILE_SIZE);
306e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand      }
307e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand      else {
308e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand         for (i = 0; i < TILE_SIZE; i++) {
309e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand            for (j = 0; j < TILE_SIZE; j++) {
310e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand               tile->data.depth64[i][j] = clear_value;
31157df347bb8a119e1d00fe808e30a0623e0ae8563Brian            }
31257df347bb8a119e1d00fe808e30a0623e0ae8563Brian         }
31357df347bb8a119e1d00fe808e30a0623e0ae8563Brian      }
31441b1aa51096e844c0b06f950b1891dc7e5256db7Brian      break;
31541b1aa51096e844c0b06f950b1891dc7e5256db7Brian   default:
31641b1aa51096e844c0b06f950b1891dc7e5256db7Brian      assert(0);
31757df347bb8a119e1d00fe808e30a0623e0ae8563Brian   }
31857df347bb8a119e1d00fe808e30a0623e0ae8563Brian}
31957df347bb8a119e1d00fe808e30a0623e0ae8563Brian
32057df347bb8a119e1d00fe808e30a0623e0ae8563Brian
32157df347bb8a119e1d00fe808e30a0623e0ae8563Brian/**
322872caf6089e325cf3a0cee877f5119cac560edacBrian * Actually clear the tiles which were flagged as being in a clear state.
32357df347bb8a119e1d00fe808e30a0623e0ae8563Brian */
324872caf6089e325cf3a0cee877f5119cac560edacBrianstatic void
325aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwellsp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
32657df347bb8a119e1d00fe808e30a0623e0ae8563Brian{
327479d929530ce40a39d9310576b97cb46fab214deMichel Dänzer   struct pipe_transfer *pt = tc->transfer;
328287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   const uint w = tc->transfer->box.width;
329287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   const uint h = tc->transfer->box.height;
33057df347bb8a119e1d00fe808e30a0623e0ae8563Brian   uint x, y;
33157df347bb8a119e1d00fe808e30a0623e0ae8563Brian   uint numCleared = 0;
33257df347bb8a119e1d00fe808e30a0623e0ae8563Brian
333287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(pt->resource);
334029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   if (!tc->tile)
335029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile = sp_alloc_tile(tc);
336029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
337de1201a0ba05068ccdc731f0a79395ce58b9121aBrian   /* clear the scratch tile to the clear value */
3383b2ca688a7016fe504768ecb72f2e42c7b2905acMichal Krol   if (tc->depth_stencil) {
339029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      clear_tile(tc->tile, pt->resource->format, tc->clear_val);
3403b2ca688a7016fe504768ecb72f2e42c7b2905acMichal Krol   } else {
341396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie      clear_tile_rgba(tc->tile, pt->resource->format, &tc->clear_color);
3423b2ca688a7016fe504768ecb72f2e42c7b2905acMichal Krol   }
34357df347bb8a119e1d00fe808e30a0623e0ae8563Brian
34457df347bb8a119e1d00fe808e30a0623e0ae8563Brian   /* push the tile to all positions marked as clear */
34557df347bb8a119e1d00fe808e30a0623e0ae8563Brian   for (y = 0; y < h; y += TILE_SIZE) {
34657df347bb8a119e1d00fe808e30a0623e0ae8563Brian      for (x = 0; x < w; x += TILE_SIZE) {
34780c78472ad43f4288c9ef5076074ba9d31a39885Keith Whitwell         union tile_address addr = tile_address(x, y);
34819097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell
34919097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell         if (is_clear_flag_set(tc->clear_flags, addr)) {
3503b2ca688a7016fe504768ecb72f2e42c7b2905acMichal Krol            /* write the scratch tile to the surface */
351ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul            if (tc->depth_stencil) {
352ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul               pipe_put_tile_raw(tc->pipe,
353ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul                                 pt,
354ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul                                 x, y, TILE_SIZE, TILE_SIZE,
355029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                                 tc->tile->data.any, 0/*STRIDE*/);
356ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul            }
357ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul            else {
358396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               if (util_format_is_pure_uint(tc->surface->format)) {
359396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                  pipe_put_tile_ui_format(tc->pipe, pt,
360396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                          x, y, TILE_SIZE, TILE_SIZE,
361396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                          pt->resource->format,
362396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                          (unsigned *) tc->tile->data.colorui128);
363396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               } else if (util_format_is_pure_sint(tc->surface->format)) {
364396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                  pipe_put_tile_i_format(tc->pipe, pt,
365396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         x, y, TILE_SIZE, TILE_SIZE,
366396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         pt->resource->format,
367396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         (int *) tc->tile->data.colori128);
368396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               } else {
369396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                  pipe_put_tile_rgba(tc->pipe, pt,
370396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                     x, y, TILE_SIZE, TILE_SIZE,
371396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                     (float *) tc->tile->data.color);
372396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               }
373ef2d10cd45c0aba00aedbd7f412af0eb24385b77Brian Paul            }
37457df347bb8a119e1d00fe808e30a0623e0ae8563Brian            numCleared++;
37557df347bb8a119e1d00fe808e30a0623e0ae8563Brian         }
37657df347bb8a119e1d00fe808e30a0623e0ae8563Brian      }
37757df347bb8a119e1d00fe808e30a0623e0ae8563Brian   }
378e1762fb870f86afc4f6bd000b4a1c059d161f10dBrian Paul
379e1762fb870f86afc4f6bd000b4a1c059d161f10dBrian Paul   /* reset all clear flags to zero */
380e1762fb870f86afc4f6bd000b4a1c059d161f10dBrian Paul   memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
381e1762fb870f86afc4f6bd000b4a1c059d161f10dBrian Paul
38257df347bb8a119e1d00fe808e30a0623e0ae8563Brian#if 0
3839791d7f64c5a58b9c1bf32d00c71e0e031f54f70José Fonseca   debug_printf("num cleared: %u\n", numCleared);
38457df347bb8a119e1d00fe808e30a0623e0ae8563Brian#endif
38546c3cf18315345effd15a69987294c1195843e2aBrian}
38646c3cf18315345effd15a69987294c1195843e2aBrian
387029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulstatic void
388029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulsp_flush_tile(struct softpipe_tile_cache* tc, unsigned pos)
389029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul{
390029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   if (!tc->tile_addrs[pos].bits.invalid) {
391029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      if (tc->depth_stencil) {
392029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         pipe_put_tile_raw(tc->pipe, tc->transfer,
393029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                           tc->tile_addrs[pos].bits.x * TILE_SIZE,
394029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                           tc->tile_addrs[pos].bits.y * TILE_SIZE,
395029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                           TILE_SIZE, TILE_SIZE,
396029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                           tc->entries[pos]->data.depth32, 0/*STRIDE*/);
397029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      }
398029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      else {
399396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         if (util_format_is_pure_uint(tc->surface->format)) {
400396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            pipe_put_tile_ui_format(tc->pipe, tc->transfer,
401396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                    tc->tile_addrs[pos].bits.x * TILE_SIZE,
402396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                    tc->tile_addrs[pos].bits.y * TILE_SIZE,
403396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                    TILE_SIZE, TILE_SIZE,
404396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                    tc->surface->format,
405396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                    (unsigned *) tc->entries[pos]->data.colorui128);
406396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         } else if (util_format_is_pure_sint(tc->surface->format)) {
407396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            pipe_put_tile_i_format(tc->pipe, tc->transfer,
4084c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                   tc->tile_addrs[pos].bits.x * TILE_SIZE,
4094c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                   tc->tile_addrs[pos].bits.y * TILE_SIZE,
4104c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                   TILE_SIZE, TILE_SIZE,
4114c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                   tc->surface->format,
412396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                   (int *) tc->entries[pos]->data.colori128);
413396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         } else {
414396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            pipe_put_tile_rgba_format(tc->pipe, tc->transfer,
415396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->tile_addrs[pos].bits.x * TILE_SIZE,
416396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->tile_addrs[pos].bits.y * TILE_SIZE,
417396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      TILE_SIZE, TILE_SIZE,
418396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->surface->format,
419396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      (float *) tc->entries[pos]->data.color);
420396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie         }
421029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      }
422029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile_addrs[pos].bits.invalid = 1;  /* mark as empty */
423029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   }
424029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul}
42546c3cf18315345effd15a69987294c1195843e2aBrian
426872caf6089e325cf3a0cee877f5119cac560edacBrian/**
4274617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer * Flush the tile cache: write all dirty tiles back to the transfer.
428872caf6089e325cf3a0cee877f5119cac560edacBrian * any tiles "flagged" as cleared will be "really" cleared.
429872caf6089e325cf3a0cee877f5119cac560edacBrian */
430872caf6089e325cf3a0cee877f5119cac560edacBrianvoid
431aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwellsp_flush_tile_cache(struct softpipe_tile_cache *tc)
432872caf6089e325cf3a0cee877f5119cac560edacBrian{
433479d929530ce40a39d9310576b97cb46fab214deMichel Dänzer   struct pipe_transfer *pt = tc->transfer;
434872caf6089e325cf3a0cee877f5119cac560edacBrian   int inuse = 0, pos;
435872caf6089e325cf3a0cee877f5119cac560edacBrian
436479d929530ce40a39d9310576b97cb46fab214deMichel Dänzer   if (pt) {
4374617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      /* caching a drawing transfer */
438d5640a2dbdc4454d0405f2cd5b18fc49b1ca7694Brian      for (pos = 0; pos < NUM_ENTRIES; pos++) {
439029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         struct softpipe_cached_tile *tile = tc->entries[pos];
440029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         if (!tile)
441029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         {
442029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            assert(tc->tile_addrs[pos].bits.invalid);
443029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            continue;
444127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
445029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
446029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         sp_flush_tile(tc, pos);
447029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         ++inuse;
448872caf6089e325cf3a0cee877f5119cac560edacBrian      }
449872caf6089e325cf3a0cee877f5119cac560edacBrian
450aa5db684382bd8662a83ca09ed000e4a5a1013f9Keith Whitwell      sp_tile_cache_flush_clear(tc);
451029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
452029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
453029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->last_tile_addr.bits.invalid = 1;
454d5640a2dbdc4454d0405f2cd5b18fc49b1ca7694Brian   }
455872caf6089e325cf3a0cee877f5119cac560edacBrian
456872caf6089e325cf3a0cee877f5119cac560edacBrian#if 0
4579791d7f64c5a58b9c1bf32d00c71e0e031f54f70José Fonseca   debug_printf("flushed tiles in use: %d\n", inuse);
458872caf6089e325cf3a0cee877f5119cac560edacBrian#endif
459872caf6089e325cf3a0cee877f5119cac560edacBrian}
460872caf6089e325cf3a0cee877f5119cac560edacBrian
461029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulstatic struct softpipe_cached_tile *
462029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paulsp_alloc_tile(struct softpipe_tile_cache *tc)
463029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul{
464029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   struct softpipe_cached_tile * tile = MALLOC_STRUCT(softpipe_cached_tile);
465029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   if (!tile)
466029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   {
467029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      /* in this case, steal an existing tile */
468029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      if (!tc->tile)
469029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      {
470029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         unsigned pos;
471029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         for (pos = 0; pos < NUM_ENTRIES; ++pos) {
472029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            if (!tc->entries[pos])
473029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul               continue;
474029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
475029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            sp_flush_tile(tc, pos);
476029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            tc->tile = tc->entries[pos];
477029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            tc->entries[pos] = NULL;
478029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            break;
479029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         }
480029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
481029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         /* this should never happen */
482029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul         if (!tc->tile)
483029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul            abort();
484029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      }
485029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
486029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tile = tc->tile;
487029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile = NULL;
488029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
489029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->last_tile_addr.bits.invalid = 1;
490029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   }
491029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   return tile;
492029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul}
493872caf6089e325cf3a0cee877f5119cac560edacBrian
494872caf6089e325cf3a0cee877f5119cac560edacBrian/**
495872caf6089e325cf3a0cee877f5119cac560edacBrian * Get a tile from the cache.
496872caf6089e325cf3a0cee877f5119cac560edacBrian * \param x, y  position of tile, in pixels
497872caf6089e325cf3a0cee877f5119cac560edacBrian */
49846c3cf18315345effd15a69987294c1195843e2aBrianstruct softpipe_cached_tile *
49919097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwellsp_find_cached_tile(struct softpipe_tile_cache *tc,
50019097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell                    union tile_address addr )
50146c3cf18315345effd15a69987294c1195843e2aBrian{
502479d929530ce40a39d9310576b97cb46fab214deMichel Dänzer   struct pipe_transfer *pt = tc->transfer;
50346c3cf18315345effd15a69987294c1195843e2aBrian   /* cache pos/entry: */
50419097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell   const int pos = CACHE_POS(addr.bits.x,
50519097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell                             addr.bits.y);
506029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   struct softpipe_cached_tile *tile = tc->entries[pos];
507029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul
508029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   if (!tile) {
509029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tile = sp_alloc_tile(tc);
510029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->entries[pos] = tile;
511029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   }
51246c3cf18315345effd15a69987294c1195843e2aBrian
513029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   if (addr.value != tc->tile_addrs[pos].value) {
51446c3cf18315345effd15a69987294c1195843e2aBrian
515287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      assert(pt->resource);
516029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      if (tc->tile_addrs[pos].bits.invalid == 0) {
51746c3cf18315345effd15a69987294c1195843e2aBrian         /* put dirty tile back in framebuffer */
518127a493fe2a2f7fd8515b278185322dfacdad357Brian         if (tc->depth_stencil) {
519d35ecca5ee231c072687578642e0c22c6c0590b1Keith Whitwell            pipe_put_tile_raw(tc->pipe, pt,
520029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                              tc->tile_addrs[pos].bits.x * TILE_SIZE,
521029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                              tc->tile_addrs[pos].bits.y * TILE_SIZE,
522f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell                              TILE_SIZE, TILE_SIZE,
523c36cdc61561fee21108f0a68ca661f0d8c7f5d94Brian                              tile->data.depth32, 0/*STRIDE*/);
524127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
525127a493fe2a2f7fd8515b278185322dfacdad357Brian         else {
526396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            if (util_format_is_pure_uint(tc->surface->format)) {
527396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_put_tile_ui_format(tc->pipe, pt,
528396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->tile_addrs[pos].bits.x * TILE_SIZE,
529396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->tile_addrs[pos].bits.y * TILE_SIZE,
530396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      TILE_SIZE, TILE_SIZE,
531396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      tc->surface->format,
532396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      (unsigned *) tile->data.colorui128);
533396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            } else if (util_format_is_pure_sint(tc->surface->format)) {
534396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_put_tile_i_format(tc->pipe, pt,
5354c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                      tc->tile_addrs[pos].bits.x * TILE_SIZE,
5364c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                      tc->tile_addrs[pos].bits.y * TILE_SIZE,
5374c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                      TILE_SIZE, TILE_SIZE,
5384c9ad084c1f54d83b4f27ce2b4cec23b6c7371c8Brian Paul                                      tc->surface->format,
539396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                      (int *) tile->data.colori128);
540396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            } else {
541396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_put_tile_rgba_format(tc->pipe, pt,
542396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.x * TILE_SIZE,
543396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.y * TILE_SIZE,
544396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         TILE_SIZE, TILE_SIZE,
545396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->surface->format,
546396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         (float *) tile->data.color);
547396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            }
548127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
54946c3cf18315345effd15a69987294c1195843e2aBrian      }
55046c3cf18315345effd15a69987294c1195843e2aBrian
551029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile_addrs[pos] = addr;
55257df347bb8a119e1d00fe808e30a0623e0ae8563Brian
55319097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell      if (is_clear_flag_set(tc->clear_flags, addr)) {
5547e8396399824108d62dc3e02b2af0422e98aab8eBrian         /* don't get tile from framebuffer, just clear it */
555127a493fe2a2f7fd8515b278185322dfacdad357Brian         if (tc->depth_stencil) {
556287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell            clear_tile(tile, pt->resource->format, tc->clear_val);
557127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
558127a493fe2a2f7fd8515b278185322dfacdad357Brian         else {
559396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            clear_tile_rgba(tile, pt->resource->format, &tc->clear_color);
560127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
56119097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell         clear_clear_flag(tc->clear_flags, addr);
56246c3cf18315345effd15a69987294c1195843e2aBrian      }
56346c3cf18315345effd15a69987294c1195843e2aBrian      else {
5644617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer         /* get new tile data from transfer */
565127a493fe2a2f7fd8515b278185322dfacdad357Brian         if (tc->depth_stencil) {
566d35ecca5ee231c072687578642e0c22c6c0590b1Keith Whitwell            pipe_get_tile_raw(tc->pipe, pt,
567029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                              tc->tile_addrs[pos].bits.x * TILE_SIZE,
568029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul                              tc->tile_addrs[pos].bits.y * TILE_SIZE,
569f911c3b9897b90132c8621a72bfeb824eb3b01e5Keith Whitwell                              TILE_SIZE, TILE_SIZE,
570c36cdc61561fee21108f0a68ca661f0d8c7f5d94Brian                              tile->data.depth32, 0/*STRIDE*/);
571127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
572127a493fe2a2f7fd8515b278185322dfacdad357Brian         else {
573396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            if (util_format_is_pure_uint(tc->surface->format)) {
574396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_get_tile_ui_format(tc->pipe, pt,
575396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.x * TILE_SIZE,
576396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.y * TILE_SIZE,
577396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         TILE_SIZE, TILE_SIZE,
578396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->surface->format,
579396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         (unsigned *) tile->data.colorui128);
580396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            } else if (util_format_is_pure_sint(tc->surface->format)) {
581396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_get_tile_i_format(tc->pipe, pt,
582396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.x * TILE_SIZE,
583396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.y * TILE_SIZE,
584396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         TILE_SIZE, TILE_SIZE,
585396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->surface->format,
586396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         (int *) tile->data.colori128);
587396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            } else {
588396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie               pipe_get_tile_rgba_format(tc->pipe, pt,
589396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.x * TILE_SIZE,
590396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->tile_addrs[pos].bits.y * TILE_SIZE,
591396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         TILE_SIZE, TILE_SIZE,
592396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         tc->surface->format,
593396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                                         (float *) tile->data.color);
594396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie            }
595127a493fe2a2f7fd8515b278185322dfacdad357Brian         }
59646c3cf18315345effd15a69987294c1195843e2aBrian      }
59746c3cf18315345effd15a69987294c1195843e2aBrian   }
59846c3cf18315345effd15a69987294c1195843e2aBrian
59919097907ef042b97bbbda39b34bf3212f4cf154aKeith Whitwell   tc->last_tile = tile;
600029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   tc->last_tile_addr = addr;
60146c3cf18315345effd15a69987294c1195843e2aBrian   return tile;
60246c3cf18315345effd15a69987294c1195843e2aBrian}
60346c3cf18315345effd15a69987294c1195843e2aBrian
60446c3cf18315345effd15a69987294c1195843e2aBrian
605b3204c2aff3f3d442ada04f241f352155a3af205Brian
606b3204c2aff3f3d442ada04f241f352155a3af205Brian
607b3204c2aff3f3d442ada04f241f352155a3af205Brian
60876a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian/**
60976a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian * When a whole surface is being cleared to a value we can avoid
61076a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian * fetching tiles above.
61176a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian * Save the color and set a 'clearflag' for each tile of the screen.
61276a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian */
61346c3cf18315345effd15a69987294c1195843e2aBrianvoid
614396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airliesp_tile_cache_clear(struct softpipe_tile_cache *tc,
615396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie                    const union pipe_color_union *color,
616e763b6e78825f11aa3e9e2368ba8fc47313a7848Morgan Armand                    uint64_t clearValue)
61746c3cf18315345effd15a69987294c1195843e2aBrian{
6181cf3c77e086d3f8b01921aae9b7309aa62b3d15eBrian   uint pos;
619127a493fe2a2f7fd8515b278185322dfacdad357Brian
620396ac41fc285f0d7c8545f2b32ba373693a7a326Dave Airlie   tc->clear_color = *color;
621127a493fe2a2f7fd8515b278185322dfacdad357Brian
622f4d744af24e07103f0f297b485f3dbca1fb7bc3bBrian Paul   tc->clear_val = clearValue;
62376a4fd098f44ae4f226d4747b9fdaf9db5d40270Brian
624872caf6089e325cf3a0cee877f5119cac560edacBrian   /* set flags to indicate all the tiles are cleared */
6257e8396399824108d62dc3e02b2af0422e98aab8eBrian   memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
6261cf3c77e086d3f8b01921aae9b7309aa62b3d15eBrian
6271cf3c77e086d3f8b01921aae9b7309aa62b3d15eBrian   for (pos = 0; pos < NUM_ENTRIES; pos++) {
628029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul      tc->tile_addrs[pos].bits.invalid = 1;
6291cf3c77e086d3f8b01921aae9b7309aa62b3d15eBrian   }
630029c099b54b24a4ecbe63f5fbe2df6c91da79b63Brian Paul   tc->last_tile_addr.bits.invalid = 1;
63146c3cf18315345effd15a69987294c1195843e2aBrian}
632