From: Keith Whitwell Date: Wed, 29 Jul 2009 06:40:50 +0000 (+0100) Subject: softpipe: split texture and surface tile caches X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=80c78472ad43f4288c9ef5076074ba9d31a39885;p=mesa.git softpipe: split texture and surface tile caches These do similar jobs but with largely disjoint code. Will want to evolve them separately going forward. --- diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index a6ed7ea6a2a..3da9be6957e 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -30,6 +30,7 @@ C_SOURCES = \ sp_state_vertex.c \ sp_texture.c \ sp_tex_sample.c \ + sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index dcc25732baf..30c099813e1 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -37,6 +37,7 @@ softpipe = env.ConvenienceLibrary( 'sp_state_vertex.c', 'sp_surface.c', 'sp_tex_sample.c', + 'sp_tex_tile_cache.c', 'sp_texture.c', 'sp_tile_cache.c', ]) diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e35c6b3aec7..396d4c6557a 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -97,7 +97,7 @@ static void softpipe_destroy( struct pipe_context *pipe ) sp_destroy_tile_cache(softpipe->zsbuf_cache); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - sp_destroy_tile_cache(softpipe->tex_cache[i]); + sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); for (i = 0; i < Elements(softpipe->constants); i++) { if (softpipe->constants[i].buffer) { @@ -220,7 +220,7 @@ softpipe_create( struct pipe_screen *screen ) softpipe->zsbuf_cache = sp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache( screen ); + softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index fa3306c020a..683c3aef9b6 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -43,6 +43,7 @@ struct softpipe_vbuf_render; struct draw_context; struct draw_stage; struct softpipe_tile_cache; +struct softpipe_tex_tile_cache; struct sp_fragment_shader; struct sp_vertex_shader; @@ -141,7 +142,7 @@ struct softpipe_context { struct softpipe_tile_cache *zsbuf_cache; unsigned tex_timestamp; - struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; unsigned use_sse : 1; unsigned dump_fs : 1; diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 679ad0cd3d4..e38b767cf2c 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -37,6 +37,7 @@ #include "sp_surface.h" #include "sp_state.h" #include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "sp_winsys.h" @@ -52,7 +53,7 @@ softpipe_flush( struct pipe_context *pipe, if (flags & PIPE_FLUSH_TEXTURE_CACHE) { for (i = 0; i < softpipe->num_textures; i++) { - sp_flush_tile_cache(softpipe->tex_cache[i]); + sp_flush_tex_tile_cache(softpipe->tex_cache[i]); } } diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 3ed1de7e178..88a6e4fbdfa 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -212,7 +212,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe ) } for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - sp_tile_cache_validate_texture( softpipe->tex_cache[i] ); + sp_tex_tile_cache_validate_texture( softpipe->tex_cache[i] ); } } diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index aa2f3f2ccd6..a725925264a 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -37,7 +37,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" -#include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "draw/draw_context.h" @@ -97,7 +97,7 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&softpipe->texture[i], tex); - sp_tile_cache_set_texture(softpipe->tex_cache[i], tex); + sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); } softpipe->num_textures = num; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 4651d781a95..8bed573e8c1 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -38,7 +38,7 @@ #include "sp_surface.h" #include "sp_texture.h" #include "sp_tex_sample.h" -#include "sp_tile_cache.h" +#include "sp_tex_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -659,7 +659,7 @@ choose_mipmap_levels(const struct pipe_texture *texture, * \param rgba the quad to put the texel/color into * \param j which element of the rgba quad to write to * - * XXX maybe move this into sp_tile_cache.c and merge with the + * XXX maybe move this into sp_tex_tile_cache.c and merge with the * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ static void @@ -669,9 +669,9 @@ get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler, { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_cached_tile *tile + const struct softpipe_tex_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, 0, face, level)); + tex_tile_address(x, y, 0, face, level)); y %= TILE_SIZE; x %= TILE_SIZE; @@ -688,9 +688,9 @@ get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler, { const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler); - const struct softpipe_cached_tile *tile + const struct softpipe_tex_cached_tile *tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, 0, face, level)); + tex_tile_address(x, y, 0, face, level)); y %= TILE_SIZE; x %= TILE_SIZE; @@ -736,10 +736,10 @@ get_texel(const struct tgsi_sampler *tgsi_sampler, else { const unsigned tx = x % TILE_SIZE; const unsigned ty = y % TILE_SIZE; - const struct softpipe_cached_tile *tile; + const struct softpipe_tex_cached_tile *tile; tile = sp_get_cached_tile_tex(samp->cache, - tile_address(x, y, z, face, level)); + 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]; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 0650c7830b9..1756d3a4ee3 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -48,7 +48,7 @@ struct sp_shader_sampler const struct pipe_texture *texture; const struct pipe_sampler_state *sampler; - struct softpipe_tile_cache *cache; + struct softpipe_tex_tile_cache *cache; }; diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c new file mode 100644 index 00000000000..c2dd68c7a2a --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -0,0 +1,274 @@ +/************************************************************************** + * + * 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 "sp_context.h" +#include "sp_surface.h" +#include "sp_texture.h" +#include "sp_tex_tile_cache.h" + + + +struct softpipe_tex_tile_cache * +sp_create_tex_tile_cache( struct pipe_screen *screen ) +{ + struct softpipe_tex_tile_cache *tc; + uint pos; + + tc = CALLOC_STRUCT( softpipe_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 +sp_destroy_tex_tile_cache(struct softpipe_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 +sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc) +{ + if (tc->tex_trans && !tc->tex_trans_map) + tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); +} + + +void +sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc) +{ + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } +} + +void +sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc) +{ + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + if (spt->timestamp != tc->timestamp) { + /* texture was modified, invalidate all cached tiles */ + uint i; + _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].addr.bits.invalid = 1; + } + + tc->timestamp = spt->timestamp; + } + } +} + +/** + * Specify the texture to cache. + */ +void +sp_tex_tile_cache_set_texture(struct softpipe_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 +sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc) +{ + int pos; + + 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; + } + +} + + +/** + * 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 sp_get_cached_tile() but for textures. + * Tiles are read-only and indexed with more params. + */ +const struct softpipe_tex_cached_tile * +sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + struct pipe_screen *screen = tc->screen; + struct softpipe_tex_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; +} + + + diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h new file mode 100644 index 00000000000..c6003f35508 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -0,0 +1,161 @@ +/************************************************************************** + * + * 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 SP_TEX_TILE_CACHE_H +#define SP_TEX_TILE_CACHE_H + + +#include "pipe/p_compiler.h" + + +struct softpipe_context; +struct softpipe_tex_tile_cache; + + +/** + * Cache tile size (width and height). This needs to be a power of two. + */ +#define 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 / TILE_SIZE */ + unsigned y:6; /* 4096 / TILE_SIZE */ + unsigned z:12; /* 4096 -- z not tiled */ + unsigned face:3; + unsigned level:4; + unsigned invalid:1; + } bits; + unsigned value; +}; + + +struct softpipe_tex_cached_tile +{ + union tex_tile_address addr; + union { + float color[TILE_SIZE][TILE_SIZE][4]; + } data; +}; + +#define NUM_ENTRIES 50 + + +/** XXX move these */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + + +struct softpipe_tex_tile_cache +{ + struct pipe_screen *screen; + struct pipe_transfer *transfer; + void *transfer_map; + + struct pipe_texture *texture; /**< if caching a texture */ + unsigned timestamp; + + struct softpipe_tex_cached_tile entries[NUM_ENTRIES]; + + struct pipe_transfer *tex_trans; + void *tex_trans_map; + int tex_face, tex_level, tex_z; + + struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ +}; + + +extern struct softpipe_tex_tile_cache * +sp_create_tex_tile_cache( struct pipe_screen *screen ); + +extern void +sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc); + + +extern void +sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc); + +extern void +sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc); + +extern void +sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, + struct pipe_texture *texture); + +void +sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc); + +extern void +sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc); + + + +extern const struct softpipe_tex_cached_tile * +sp_find_cached_tile_tex(struct softpipe_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 / TILE_SIZE; + addr.bits.y = y / 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 softpipe_tex_cached_tile * +sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc, + union tex_tile_address addr ) +{ + if (tc->last_tile->addr.value == addr.value) + return tc->last_tile; + + return sp_find_cached_tile_tex( tc, addr ); +} + + + + + +#endif /* SP_TEX_TILE_CACHE_H */ + diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 77d02fa3e7a..2d82badcec3 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -26,7 +26,7 @@ **************************************************************************/ /** - * Texture tile caching. + * Render target tile caching. * * Author: * Brian Paul @@ -37,7 +37,6 @@ #include "util/u_tile.h" #include "sp_context.h" #include "sp_surface.h" -#include "sp_texture.h" #include "sp_tile_cache.h" @@ -111,10 +110,6 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc) 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 ); } @@ -127,8 +122,6 @@ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { - assert(!tc->texture); - if (tc->transfer) { struct pipe_screen *screen = tc->transfer->texture->screen; @@ -180,9 +173,6 @@ sp_tile_cache_map_transfers(struct softpipe_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); } @@ -193,68 +183,8 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) 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 -sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc) -{ - if (tc->texture) { - struct softpipe_texture *spt = softpipe_texture(tc->texture); - if (spt->timestamp != tc->timestamp) { - /* texture was modified, invalidate all cached tiles */ - uint i; - _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp); - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->timestamp = spt->timestamp; - } - } -} - -/** - * Specify the texture to cache. - */ -void -sp_tile_cache_set_texture(struct softpipe_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. */ @@ -345,7 +275,7 @@ sp_tile_cache_flush_clear(struct softpipe_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) { - union tile_address addr = tile_address(x, y, 0, 0, 0); + union tile_address addr = tile_address(x, y); if (is_clear_flag_set(tc->clear_flags, addr)) { pipe_put_tile_raw(pt, @@ -403,13 +333,6 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) sp_tile_cache_flush_clear(tc); #endif } - 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); @@ -488,97 +411,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, } -/** - * 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 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 sp_get_cached_tile() but for textures. - * Tiles are read-only and indexed with more params. - */ -const struct softpipe_cached_tile * -sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ) -{ - struct pipe_screen *screen = tc->screen; - struct softpipe_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; -} /** diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index ac2aae58758..3b0be274d5e 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -51,10 +51,8 @@ union tile_address { struct { unsigned x:6; /* 4096 / TILE_SIZE */ unsigned y:6; /* 4096 / TILE_SIZE */ - unsigned z:12; /* 4096 -- z not tiled */ - unsigned face:3; - unsigned level:4; unsigned invalid:1; + unsigned pad:19; } bits; unsigned value; }; @@ -88,19 +86,12 @@ struct softpipe_tile_cache struct pipe_transfer *transfer; void *transfer_map; - struct pipe_texture *texture; /**< if caching a texture */ - unsigned timestamp; - struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; float clear_color[4]; /**< for color bufs */ uint clear_val; /**< for z+stencil, or packed color clear value */ boolean depth_stencil; /**< Is the surface a depth/stencil format? */ - struct pipe_transfer *tex_trans; - void *tex_trans_map; - int tex_face, tex_level, tex_z; - struct softpipe_cached_tile tile; /**< scratch tile for clears */ struct softpipe_cached_tile *last_tile; /**< most recently retrieved tile */ @@ -126,13 +117,6 @@ sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc); extern void sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc); -extern void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_texture *texture); - -void -sp_tile_cache_validate_texture(struct softpipe_tile_cache *tc); - extern void sp_flush_tile_cache(struct softpipe_tile_cache *tc); @@ -144,47 +128,27 @@ extern struct softpipe_cached_tile * sp_find_cached_tile(struct softpipe_tile_cache *tc, union tile_address addr ); -extern const struct softpipe_cached_tile * -sp_find_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ); static INLINE const union tile_address tile_address( unsigned x, - unsigned y, - unsigned z, - unsigned face, - unsigned level ) + unsigned y ) { union tile_address addr; addr.value = 0; addr.bits.x = x / TILE_SIZE; addr.bits.y = y / 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 softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, - union tile_address addr ) -{ - if (tc->last_tile->addr.value == addr.value) - return tc->last_tile; - - return sp_find_cached_tile_tex( tc, addr ); -} - - static INLINE struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y ) { - union tile_address addr = tile_address( x, y, 0, 0, 0 ); + union tile_address addr = tile_address( x, y ); if (tc->last_tile->addr.value == addr.value) return tc->last_tile;