summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_tile_cache.c
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2009-07-22 15:36:25 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-08-29 09:21:17 +0100
commit3adca9611479936eb0b719b276ac94889a7c6bf3 (patch)
tree92029dbbf1888243d54b1a6f0d546509f33f1d75 /src/gallium/drivers/llvmpipe/lp_tile_cache.c
parent2301314e7ccd37faae80353d35109bb029dc9335 (diff)
llvmpipe: also shortcircuit non-texture tile lookups
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_tile_cache.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
index 75cadeb228..96bfe733e1 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
@@ -49,7 +49,7 @@
* a LRU replacement policy.
*/
#define CACHE_POS(x, y) \
- (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES)
+ (((x) + (y) * 5) % NUM_ENTRIES)
@@ -57,12 +57,10 @@
* Is the tile at (x,y) in cleared state?
*/
static INLINE uint
-is_clear_flag_set(const uint *bitvec, int x, int y)
+is_clear_flag_set(const uint *bitvec, union tile_address addr)
{
int pos, bit;
- x /= TILE_SIZE;
- y /= TILE_SIZE;
- pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+ pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
bit = bitvec[pos / 32] & (1 << (pos & 31));
return bit;
@@ -73,12 +71,10 @@ is_clear_flag_set(const uint *bitvec, int x, int y)
* Mark the tile at (x,y) as not cleared.
*/
static INLINE void
-clear_clear_flag(uint *bitvec, int x, int y)
+clear_clear_flag(uint *bitvec, union tile_address addr)
{
int pos;
- x /= TILE_SIZE;
- y /= TILE_SIZE;
- pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+ pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
bitvec[pos / 32] &= ~(1 << (pos & 31));
}
@@ -349,13 +345,15 @@ lp_tile_cache_flush_clear(struct llvmpipe_tile_cache *tc)
/* push the tile to all positions marked as clear */
for (y = 0; y < h; y += TILE_SIZE) {
for (x = 0; x < w; x += TILE_SIZE) {
- if (is_clear_flag_set(tc->clear_flags, x, y)) {
+ union tile_address addr = tile_address(x, y, 0, 0, 0);
+
+ if (is_clear_flag_set(tc->clear_flags, addr)) {
pipe_put_tile_raw(pt,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
/* do this? */
- clear_clear_flag(tc->clear_flags, x, y);
+ clear_clear_flag(tc->clear_flags, addr);
numCleared++;
}
@@ -424,14 +422,14 @@ lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
* \param x, y position of tile, in pixels
*/
struct llvmpipe_cached_tile *
-lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y)
+lp_find_cached_tile(struct llvmpipe_tile_cache *tc,
+ union tile_address addr )
{
struct pipe_transfer *pt = tc->transfer;
- /* tile pos in framebuffer: */
- union tile_address addr = tile_address( x, y, 0, 0, 0 );
/* cache pos/entry: */
- const int pos = CACHE_POS(x, y);
+ const int pos = CACHE_POS(addr.bits.x,
+ addr.bits.y);
struct llvmpipe_cached_tile *tile = tc->entries + pos;
if (addr.value != tile->addr.value) {
@@ -456,7 +454,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y)
tile->addr = addr;
- if (is_clear_flag_set(tc->clear_flags, x, y)) {
+ if (is_clear_flag_set(tc->clear_flags, addr)) {
/* don't get tile from framebuffer, just clear it */
if (tc->depth_stencil) {
clear_tile(tile, pt->format, tc->clear_val);
@@ -464,7 +462,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y)
else {
clear_tile_rgba(tile, pt->format, tc->clear_color);
}
- clear_clear_flag(tc->clear_flags, x, y);
+ clear_clear_flag(tc->clear_flags, addr);
}
else {
/* get new tile data from transfer */
@@ -485,6 +483,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y)
}
}
+ tc->last_tile = tile;
return tile;
}