From 0318f3e53eed88f0feea6e7a4fd8a8d9becc9774 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 9 Aug 2009 17:22:01 +0100 Subject: llvmpipe: Split the texture cache from the color/depth/stencil cache. --- src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_context.c | 5 +- src/gallium/drivers/llvmpipe/lp_context.h | 3 +- src/gallium/drivers/llvmpipe/lp_flush.c | 3 +- src/gallium/drivers/llvmpipe/lp_state_derived.c | 3 +- src/gallium/drivers/llvmpipe/lp_state_sampler.c | 4 +- src/gallium/drivers/llvmpipe/lp_tex_cache.c | 332 ++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_tex_cache.h | 154 +++++++++++ src/gallium/drivers/llvmpipe/lp_tex_sample.c | 20 +- src/gallium/drivers/llvmpipe/lp_tex_sample.h | 5 +- src/gallium/drivers/llvmpipe/lp_texture.c | 2 +- src/gallium/drivers/llvmpipe/lp_tile_cache.c | 127 --------- src/gallium/drivers/llvmpipe/lp_tile_cache.h | 22 -- 13 files changed, 513 insertions(+), 168 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_tex_cache.c create mode 100644 src/gallium/drivers/llvmpipe/lp_tex_cache.h (limited to 'src') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 0a8e6e8fad..8565c7e011 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -47,6 +47,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_surface.c', 'lp_state_vertex.c', 'lp_surface.c', + 'lp_tex_cache.c', 'lp_tex_sample.c', 'lp_texture.c', 'lp_tile_cache.c', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 7f2c2b6acd..a30db444d4 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -42,6 +42,7 @@ #include "lp_state.h" #include "lp_surface.h" #include "lp_tile_cache.h" +#include "lp_tex_cache.h" #include "lp_texture.h" #include "lp_winsys.h" #include "lp_query.h" @@ -97,7 +98,7 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) lp_destroy_tile_cache(llvmpipe->zsbuf_cache); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - lp_destroy_tile_cache(llvmpipe->tex_cache[i]); + lp_destroy_tex_tile_cache(llvmpipe->tex_cache[i]); for (i = 0; i < Elements(llvmpipe->constants); i++) { if (llvmpipe->constants[i].buffer) { @@ -220,7 +221,7 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe->zsbuf_cache = lp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - llvmpipe->tex_cache[i] = lp_create_tile_cache( screen ); + llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 036585808d..7b5da6ee91 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -43,6 +43,7 @@ struct llvmpipe_vbuf_render; struct draw_context; struct draw_stage; struct llvmpipe_tile_cache; +struct llvmpipe_tex_tile_cache; struct lp_fragment_shader; struct lp_vertex_shader; @@ -141,7 +142,7 @@ struct llvmpipe_context { struct llvmpipe_tile_cache *zsbuf_cache; unsigned tex_timestamp; - struct llvmpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; unsigned use_sse : 1; unsigned dump_fs : 1; diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 866d4fb099..f3b43cfce9 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -37,6 +37,7 @@ #include "lp_surface.h" #include "lp_state.h" #include "lp_tile_cache.h" +#include "lp_tex_cache.h" #include "lp_winsys.h" @@ -52,7 +53,7 @@ llvmpipe_flush( struct pipe_context *pipe, if (flags & PIPE_FLUSH_TEXTURE_CACHE) { for (i = 0; i < llvmpipe->num_textures; i++) { - lp_flush_tile_cache(llvmpipe->tex_cache[i]); + lp_flush_tex_tile_cache(llvmpipe->tex_cache[i]); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index a2bf27cc67..79861b2d13 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -33,6 +33,7 @@ #include "draw/draw_private.h" #include "lp_context.h" #include "lp_screen.h" +#include "lp_tex_cache.h" #include "lp_state.h" @@ -211,7 +212,7 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe ) } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - lp_tile_cache_validate_texture( llvmpipe->tex_cache[i] ); + lp_tex_tile_cache_validate_texture( llvmpipe->tex_cache[i] ); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 02ae2c17e1..4fef541b1e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -37,7 +37,7 @@ #include "lp_context.h" #include "lp_state.h" #include "lp_texture.h" -#include "lp_tile_cache.h" +#include "lp_tex_cache.h" #include "draw/draw_context.h" @@ -97,7 +97,7 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&llvmpipe->texture[i], tex); - lp_tile_cache_set_texture(llvmpipe->tex_cache[i], tex); + lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex); } llvmpipe->num_textures = num; diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c new file mode 100644 index 0000000000..984f71688b --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.c @@ -0,0 +1,332 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Texture tile caching. + * + * Author: + * Brian Paul + */ + +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "util/u_tile.h" +#include "lp_context.h" +#include "lp_surface.h" +#include "lp_texture.h" +#include "lp_tex_cache.h" + + + +/** + * Return the position in the cache for the tile that contains win pos (x,y). + * We currently use a direct mapped cache so this is like a hack key. + * At some point we should investige something more sophisticated, like + * a LRU replacement policy. + */ +#define CACHE_POS(x, y) \ + (((x) + (y) * 5) % NUM_ENTRIES) + + + +/** + * Is the tile at (x,y) in cleared state? + */ +static INLINE uint +is_clear_flag_set(const uint *bitvec, union tex_tile_address addr) +{ + int pos, bit; + pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x; + assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32); + bit = bitvec[pos / 32] & (1 << (pos & 31)); + return bit; +} + + +/** + * Mark the tile at (x,y) as not cleared. + */ +static INLINE void +clear_clear_flag(uint *bitvec, union tex_tile_address addr) +{ + int pos; + pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x; + assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32); + bitvec[pos / 32] &= ~(1 << (pos & 31)); +} + + +struct llvmpipe_tex_tile_cache * +lp_create_tex_tile_cache( struct pipe_screen *screen ) +{ + struct llvmpipe_tex_tile_cache *tc; + uint pos; + + tc = CALLOC_STRUCT( llvmpipe_tex_tile_cache ); + if (tc) { + tc->screen = screen; + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].addr.bits.invalid = 1; + } + tc->last_tile = &tc->entries[0]; /* any tile */ + } + return tc; +} + + +void +lp_destroy_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc) +{ + struct pipe_screen *screen; + uint pos; + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + /*assert(tc->entries[pos].x < 0);*/ + } + if (tc->transfer) { + screen = tc->transfer->texture->screen; + screen->tex_transfer_destroy(tc->transfer); + } + if (tc->tex_trans) { + screen = tc->tex_trans->texture->screen; + screen->tex_transfer_destroy(tc->tex_trans); + } + + FREE( tc ); +} + + +void +lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_tile_cache *tc) +{ + if (tc->transfer && !tc->transfer_map) + tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); + + if (tc->tex_trans && !tc->tex_trans_map) + tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); +} + + +void +lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc) +{ + if (tc->transfer_map) { + tc->screen->transfer_unmap(tc->screen, tc->transfer); + tc->transfer_map = NULL; + } + + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } +} + +void +lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc) +{ + if (tc->texture) { + struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture); + if (lpt->timestamp != tc->timestamp) { + /* texture was modified, invalidate all cached tiles */ + uint i; + _debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp); + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; + } + + tc->timestamp = lpt->timestamp; + } + } +} + +/** + * Specify the texture to cache. + */ +void +lp_tex_tile_cache_set_texture(struct llvmpipe_tex_tile_cache *tc, + struct pipe_texture *texture) +{ + uint i; + + assert(!tc->transfer); + + if (tc->texture != texture) { + pipe_texture_reference(&tc->texture, texture); + + if (tc->tex_trans) { + struct pipe_screen *screen = tc->tex_trans->texture->screen; + + if (tc->tex_trans_map) { + screen->transfer_unmap(screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + /* mark as entries as invalid/empty */ + /* XXX we should try to avoid this when the teximage hasn't changed */ + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; + } + + tc->tex_face = -1; /* any invalid value here */ + } +} + + +/** + * Flush the tile cache: write all dirty tiles back to the transfer. + * any tiles "flagged" as cleared will be "really" cleared. + */ +void +lp_flush_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc) +{ + struct pipe_transfer *pt = tc->transfer; + int inuse = 0, pos; + + if (pt) { + /* caching a drawing transfer */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct llvmpipe_cached_tex_tile *tile = tc->entries + pos; + if (!tile->addr.bits.invalid) { + pipe_put_tile_rgba(pt, + tile->addr.bits.x * TEX_TILE_SIZE, + tile->addr.bits.y * TEX_TILE_SIZE, + TEX_TILE_SIZE, TEX_TILE_SIZE, + (float *) tile->color); + tile->addr.bits.invalid = 1; /* mark as empty */ + inuse++; + } + } + } + else if (tc->texture) { + /* caching a texture, mark all entries as empty */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].addr.bits.invalid = 1; + } + tc->tex_face = -1; + } + +#if 0 + debug_printf("flushed tiles in use: %d\n", inuse); +#endif +} + + +/** + * Given the texture face, level, zslice, x and y values, compute + * the cache entry position/index where we'd hope to find the + * cached texture tile. + * This is basically a direct-map cache. + * XXX There's probably lots of ways in which we can improve this. + */ +static INLINE uint +tex_cache_pos( union tex_tile_address addr ) +{ + uint entry = (addr.bits.x + + addr.bits.y * 9 + + addr.bits.z * 3 + + addr.bits.face + + addr.bits.level * 7); + + return entry % NUM_ENTRIES; +} + +/** + * Similar to lp_get_cached_tile() but for textures. + * Tiles are read-only and indexed with more params. + */ +const struct llvmpipe_cached_tex_tile * +lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + struct pipe_screen *screen = tc->screen; + struct llvmpipe_cached_tex_tile *tile; + + tile = tc->entries + tex_cache_pos( addr ); + + if (addr.value != tile->addr.value) { + + /* cache miss. Most misses are because we've invaldiated the + * texture cache previously -- most commonly on binding a new + * texture. Currently we effectively flush the cache on texture + * bind. + */ +#if 0 + _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" + " tile %u: x=%d y=%d z=%d face=%d level=%d\n", + pos, x/TEX_TILE_SIZE, y/TEX_TILE_SIZE, z, face, level, + pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); +#endif + + /* check if we need to get a new transfer */ + if (!tc->tex_trans || + tc->tex_face != addr.bits.face || + tc->tex_level != addr.bits.level || + tc->tex_z != addr.bits.z) { + /* get new transfer (view into texture) */ + + if (tc->tex_trans) { + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + tc->tex_trans = + screen->get_tex_transfer(screen, tc->texture, + addr.bits.face, + addr.bits.level, + addr.bits.z, + PIPE_TRANSFER_READ, 0, 0, + tc->texture->width[addr.bits.level], + tc->texture->height[addr.bits.level]); + + tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); + + tc->tex_face = addr.bits.face; + tc->tex_level = addr.bits.level; + tc->tex_z = addr.bits.z; + } + + /* get tile from the transfer (view into texture) */ + pipe_get_tile_rgba(tc->tex_trans, + addr.bits.x * TEX_TILE_SIZE, + addr.bits.y * TEX_TILE_SIZE, + TEX_TILE_SIZE, TEX_TILE_SIZE, + (float *) tile->color); + tile->addr = addr; + } + + tc->last_tile = tile; + return tile; +} diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.h b/src/gallium/drivers/llvmpipe/lp_tex_cache.h new file mode 100644 index 0000000000..f521b2ae0b --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.h @@ -0,0 +1,154 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef LP_TEX_CACHE_H +#define LP_TEX_CACHE_H + + +#include "pipe/p_compiler.h" + + +struct llvmpipe_context; +struct llvmpipe_tex_tile_cache; + + +/** + * Cache tile size (width and height). This needs to be a power of two. + */ +#define TEX_TILE_SIZE 64 + + +/* If we need to support > 4096, just expand this to be a 64 bit + * union, or consider tiling in Z as well. + */ +union tex_tile_address { + struct { + unsigned x:6; /* 4096 / TEX_TILE_SIZE */ + unsigned y:6; /* 4096 / TEX_TILE_SIZE */ + unsigned z:12; /* 4096 -- z not tiled */ + unsigned face:3; + unsigned level:4; + unsigned invalid:1; + } bits; + unsigned value; +}; + + +struct llvmpipe_cached_tex_tile +{ + union tex_tile_address addr; + float color[TEX_TILE_SIZE][TEX_TILE_SIZE][4]; +}; + +#define NUM_ENTRIES 50 + + +/** XXX move these */ +#define MAX_TEX_WIDTH 2048 +#define MAX_TEX_HEIGHT 2048 + + +struct llvmpipe_tex_tile_cache +{ + struct pipe_screen *screen; + struct pipe_surface *surface; /**< the surface we're caching */ + struct pipe_transfer *transfer; + void *transfer_map; + + struct pipe_texture *texture; /**< if caching a texture */ + unsigned timestamp; + + struct llvmpipe_cached_tex_tile entries[NUM_ENTRIES]; + + struct pipe_transfer *tex_trans; + void *tex_trans_map; + int tex_face, tex_level, tex_z; + + struct llvmpipe_cached_tex_tile *last_tile; /**< most recently retrieved tile */ +}; + + +extern struct llvmpipe_tex_tile_cache * +lp_create_tex_tile_cache( struct pipe_screen *screen ); + +extern void +lp_destroy_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc); + +extern void +lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_tile_cache *tc); + +extern void +lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc); + +extern void +lp_tex_tile_cache_set_texture(struct llvmpipe_tex_tile_cache *tc, + struct pipe_texture *texture); + +void +lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc); + +extern void +lp_flush_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc); + +extern const struct llvmpipe_cached_tex_tile * +lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, + union tex_tile_address addr ); + +static INLINE const union tex_tile_address +tex_tile_address( unsigned x, + unsigned y, + unsigned z, + unsigned face, + unsigned level ) +{ + union tex_tile_address addr; + + addr.value = 0; + addr.bits.x = x / TEX_TILE_SIZE; + addr.bits.y = y / TEX_TILE_SIZE; + addr.bits.z = z; + addr.bits.face = face; + addr.bits.level = level; + + return addr; +} + +/* Quickly retrieve tile if it matches last lookup. + */ +static INLINE const struct llvmpipe_cached_tex_tile * +lp_get_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + if (tc->last_tile->addr.value == addr.value) + return tc->last_tile; + + return lp_find_cached_tex_tile( tc, addr ); +} + + +#endif /* LP_TEX_CACHE_H */ + diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index d24845cac9..ff2dbce66b 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -38,7 +38,7 @@ #include "lp_surface.h" #include "lp_texture.h" #include "lp_tex_sample.h" -#include "lp_tile_cache.h" +#include "lp_tex_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -680,17 +680,17 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, rgba[3][j] = sampler->border_color[3]; } else { - const unsigned tx = x % TILE_SIZE; - const unsigned ty = y % TILE_SIZE; - const struct llvmpipe_cached_tile *tile; + const unsigned tx = x % TEX_TILE_SIZE; + const unsigned ty = y % TEX_TILE_SIZE; + const struct llvmpipe_cached_tex_tile *tile; - tile = lp_get_cached_tile_tex(samp->cache, - tile_address(x, y, z, face, level)); + tile = lp_get_cached_tex_tile(samp->cache, + tex_tile_address(x, y, z, face, level)); - rgba[0][j] = tile->data.color[ty][tx][0]; - rgba[1][j] = tile->data.color[ty][tx][1]; - rgba[2][j] = tile->data.color[ty][tx][2]; - rgba[3][j] = tile->data.color[ty][tx][3]; + rgba[0][j] = tile->color[ty][tx][0]; + rgba[1][j] = tile->color[ty][tx][1]; + rgba[2][j] = tile->color[ty][tx][2]; + rgba[3][j] = tile->color[ty][tx][3]; if (0) { debug_printf("Get texel %f %f %f %f from %s\n", diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h index 08f1451331..727d56056f 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h @@ -32,6 +32,9 @@ #include "tgsi/tgsi_exec.h" +struct llvmpipe_tex_tile_cache; + + /** * Subclass of tgsi_sampler */ @@ -42,7 +45,7 @@ struct lp_shader_sampler const struct pipe_texture *texture; const struct pipe_sampler_state *sampler; - struct llvmpipe_tile_cache *cache; + struct llvmpipe_tex_tile_cache *cache; }; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 542e313445..0fad1fcfdf 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -40,7 +40,7 @@ #include "lp_context.h" #include "lp_state.h" #include "lp_texture.h" -#include "lp_tile_cache.h" +#include "lp_tex_cache.h" #include "lp_screen.h" #include "lp_winsys.h" diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c index 96bfe733e1..01ba843806 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c @@ -200,60 +200,6 @@ lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc) } } -void -lp_tile_cache_validate_texture(struct llvmpipe_tile_cache *tc) -{ - if (tc->texture) { - struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture); - if (lpt->timestamp != tc->timestamp) { - /* texture was modified, invalidate all cached tiles */ - uint i; - _debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp); - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->timestamp = lpt->timestamp; - } - } -} - -/** - * Specify the texture to cache. - */ -void -lp_tile_cache_set_texture(struct llvmpipe_tile_cache *tc, - struct pipe_texture *texture) -{ - uint i; - - assert(!tc->transfer); - - if (tc->texture != texture) { - pipe_texture_reference(&tc->texture, texture); - - if (tc->tex_trans) { - struct pipe_screen *screen = tc->tex_trans->texture->screen; - - if (tc->tex_trans_map) { - screen->transfer_unmap(screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - /* mark as entries as invalid/empty */ - /* XXX we should try to avoid this when the teximage hasn't changed */ - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->tex_face = -1; /* any invalid value here */ - } -} - /** * Set pixels in a tile to the given clear color/value, float. @@ -507,79 +453,6 @@ tex_cache_pos( union tile_address addr ) return entry % NUM_ENTRIES; } -/** - * Similar to lp_get_cached_tile() but for textures. - * Tiles are read-only and indexed with more params. - */ -const struct llvmpipe_cached_tile * -lp_find_cached_tile_tex(struct llvmpipe_tile_cache *tc, - union tile_address addr ) -{ - struct pipe_screen *screen = tc->screen; - struct llvmpipe_cached_tile *tile; - - tile = tc->entries + tex_cache_pos( addr ); - - if (addr.value != tile->addr.value) { - - /* cache miss. Most misses are because we've invaldiated the - * texture cache previously -- most commonly on binding a new - * texture. Currently we effectively flush the cache on texture - * bind. - */ -#if 0 - _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" - " tile %u: x=%d y=%d z=%d face=%d level=%d\n", - pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level, - pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); -#endif - - /* check if we need to get a new transfer */ - if (!tc->tex_trans || - tc->tex_face != addr.bits.face || - tc->tex_level != addr.bits.level || - tc->tex_z != addr.bits.z) { - /* get new transfer (view into texture) */ - - if (tc->tex_trans) { - if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - tc->tex_trans = - screen->get_tex_transfer(screen, tc->texture, - addr.bits.face, - addr.bits.level, - addr.bits.z, - PIPE_TRANSFER_READ, 0, 0, - tc->texture->width[addr.bits.level], - tc->texture->height[addr.bits.level]); - - tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); - - tc->tex_face = addr.bits.face; - tc->tex_level = addr.bits.level; - tc->tex_z = addr.bits.z; - } - - /* get tile from the transfer (view into texture) */ - pipe_get_tile_rgba(tc->tex_trans, - addr.bits.x * TILE_SIZE, - addr.bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); - tile->addr = addr; - } - - tc->last_tile = tile; - return tile; -} - /** * When a whole surface is being cleared to a value we can avoid diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h index 1cc5a17bb5..19676392dc 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h @@ -126,13 +126,6 @@ lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc); extern void lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc); -extern void -lp_tile_cache_set_texture(struct llvmpipe_tile_cache *tc, - struct pipe_texture *texture); - -void -lp_tile_cache_validate_texture(struct llvmpipe_tile_cache *tc); - extern void lp_flush_tile_cache(struct llvmpipe_tile_cache *tc); @@ -144,10 +137,6 @@ extern struct llvmpipe_cached_tile * lp_find_cached_tile(struct llvmpipe_tile_cache *tc, union tile_address addr ); -extern const struct llvmpipe_cached_tile * -lp_find_cached_tile_tex(struct llvmpipe_tile_cache *tc, - union tile_address addr ); - static INLINE const union tile_address tile_address( unsigned x, unsigned y, @@ -169,17 +158,6 @@ tile_address( unsigned x, /* Quickly retrieve tile if it matches last lookup. */ -static INLINE const struct llvmpipe_cached_tile * -lp_get_cached_tile_tex(struct llvmpipe_tile_cache *tc, - union tile_address addr ) -{ - if (tc->last_tile->addr.value == addr.value) - return tc->last_tile; - - return lp_find_cached_tile_tex( tc, addr ); -} - - static INLINE struct llvmpipe_cached_tile * lp_get_cached_tile(struct llvmpipe_tile_cache *tc, int x, int y ) -- cgit v1.2.3