From 70eb7996f265f3634dabda078f13d1be3533cc65 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 22 Oct 2007 09:37:26 -0600 Subject: [PATCH] Finish unifying the surface and texture tile caches. --- src/mesa/pipe/softpipe/sp_context.c | 20 +++-- src/mesa/pipe/softpipe/sp_context.h | 2 + src/mesa/pipe/softpipe/sp_quad_fs.c | 20 ++--- src/mesa/pipe/softpipe/sp_state_sampler.c | 4 + src/mesa/pipe/softpipe/sp_tex_sample.c | 98 ++++------------------- src/mesa/pipe/softpipe/sp_tile_cache.c | 31 ++++--- src/mesa/pipe/softpipe/sp_tile_cache.h | 5 +- src/mesa/pipe/tgsi/exec/tgsi_exec.h | 10 +-- 8 files changed, 72 insertions(+), 118 deletions(-) diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 10c53a257bd..bf61019f624 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -343,6 +343,20 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zbuf_cache = sp_create_tile_cache(); + softpipe->sbuf_cache_sep = sp_create_tile_cache(); + softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */ + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + /* setup quad rendering stages */ softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); softpipe->quad.shade = sp_quad_shade_stage(softpipe); @@ -380,11 +394,5 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, sp_init_region_functions(softpipe); sp_init_surface_functions(softpipe); - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zbuf_cache = sp_create_tile_cache(); - softpipe->sbuf_cache_sep = sp_create_tile_cache(); - softpipe->sbuf_cache = softpipe->sbuf_cache_sep; /* initial value */ - return &softpipe->pipe; } diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index ea05f80d59a..3e77bd6b856 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -163,6 +163,8 @@ struct softpipe_context { /** This either points to zbuf_cache or sbuf_cache_sep */ struct softpipe_tile_cache *sbuf_cache; + struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + int use_sse : 1; }; diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index c850f08c575..674e02d0f43 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -153,19 +153,10 @@ static void shade_begin(struct quad_stage *qs) struct softpipe_context *softpipe = qs->softpipe; unsigned i, entry; + /* set TGSI sampler state that varies */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { qss->samplers[i].state = softpipe->sampler[i]; qss->samplers[i].texture = softpipe->texture[i]; - qss->samplers[i].get_samples = sp_get_samples; - qss->samplers[i].pipe = &softpipe->pipe; - /* init cache info here */ - for (entry = 0; entry < TEX_CACHE_NUM_ENTRIES; entry++) { - qss->samplers[i].cache[entry].x = -1; - qss->samplers[i].cache[entry].y = -1; - qss->samplers[i].cache[entry].level = -1; - qss->samplers[i].cache[entry].face = -1; - qss->samplers[i].cache[entry].zslice = -1; - } } /* XXX only do this if the fragment shader changes... */ @@ -196,6 +187,7 @@ static void shade_begin(struct quad_stage *qs) struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) { struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; /* allocate storage for program inputs/outputs, aligned to 16 bytes */ qss->inputs = malloc(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); @@ -207,5 +199,13 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) qss->stage.begin = shade_begin; qss->stage.run = shade_quad; + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + return &qss->stage; } diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 4084e9163f3..c00e815f2d4 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -31,6 +31,8 @@ #include "sp_context.h" #include "sp_state.h" +#include "sp_tile_cache.h" + void * softpipe_create_sampler_state(struct pipe_context *pipe, @@ -72,5 +74,7 @@ softpipe_set_texture_state(struct pipe_context *pipe, assert(unit < PIPE_MAX_SAMPLERS); softpipe->texture[unit] = texture; /* ptr, not struct */ + sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); + softpipe->dirty |= SP_NEW_TEXTURE; } diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 64cb94d9441..385b8042c32 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -36,6 +36,7 @@ #include "sp_context.h" #include "sp_surface.h" #include "sp_tex_sample.h" +#include "sp_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" @@ -522,28 +523,6 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, } - -/** - * 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 - * texture caching.... - */ -static unsigned -compute_cache_pos(unsigned face, unsigned level, unsigned zslice, - int tx, int ty) -{ -#if 01 - unsigned entry = tx + ty * 2 + zslice * 4 + face + level; - return entry % TEX_CACHE_NUM_ENTRIES; -#else - return 0; -#endif -} - - /** * Get a texel from a texture, using the texture tile cache. * @@ -551,74 +530,27 @@ compute_cache_pos(unsigned face, unsigned level, unsigned zslice, * \param level the mipmap level * \param x the x coord of texel within 2D image * \param y the y coord of texel within 2D image - * \param zslice which slice of a 3D texture + * \param z which slice of a 3D 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 + * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... */ static void get_texel(struct tgsi_sampler *sampler, - unsigned face, unsigned level, int x, int y, unsigned zslice, + unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - int tx = x / TEX_CACHE_TILE_SIZE; - int ty = y / TEX_CACHE_TILE_SIZE; - unsigned entry = compute_cache_pos(face, level, zslice, tx, ty); - - if (tx != sampler->cache[entry].x || - ty != sampler->cache[entry].y || - face != sampler->cache[entry].face || - level != sampler->cache[entry].level || - zslice != sampler->cache[entry].zslice) { - /* entry is not what's expected */ - struct pipe_context *pipe = (struct pipe_context *) sampler->pipe; - struct pipe_surface *ps - = pipe->get_tex_surface(pipe, sampler->texture, face, level, zslice); - - /* - printf("cache miss (%d, %d) face %u\n", tx, ty, face); - */ - - assert(ps->width == sampler->texture->level[level].width); - assert(ps->height == sampler->texture->level[level].height); - sampler->cache[entry].x = tx; - sampler->cache[entry].y = ty; - sampler->cache[entry].level = level; - sampler->cache[entry].face = face; - sampler->cache[entry].zslice = zslice; - ps->get_tile(ps, - tx * TEX_CACHE_TILE_SIZE, - ty * TEX_CACHE_TILE_SIZE, - TEX_CACHE_TILE_SIZE, TEX_CACHE_TILE_SIZE, - (float *) sampler->cache[entry].data); - - pipe_surface_reference(&ps, NULL); - } - else { - /* - printf("cache hit (%d, %d)\n", x, y); - */ - } - - /* get the texel from cache entry */ - tx = x % TEX_CACHE_TILE_SIZE; - ty = y % TEX_CACHE_TILE_SIZE; - if (sampler->texture->format == PIPE_FORMAT_U_Z16 || - sampler->texture->format == PIPE_FORMAT_U_Z32 || - sampler->texture->format == PIPE_FORMAT_S8_Z24) { - /* get_tile() returned one float per texel */ - float *src = (float *) sampler->cache[entry].data; - rgba[0][j] = - rgba[1][j] = - rgba[2][j] = - rgba[3][j] = src[ty * TEX_CACHE_TILE_SIZE + tx]; - } - else { - /* get_tile() returned four floats per texel */ - rgba[0][j] = sampler->cache[entry].data[ty][tx][0]; - rgba[1][j] = sampler->cache[entry].data[ty][tx][1]; - rgba[2][j] = sampler->cache[entry].data[ty][tx][2]; - rgba[3][j] = sampler->cache[entry].data[ty][tx][3]; - } + const int tx = x % TILE_SIZE; + const int ty = y % TILE_SIZE; + const struct softpipe_cached_tile *tile + = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, + 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]; } diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index d88bce46190..1e287c91a41 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -129,7 +129,15 @@ void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_mipmap_tree *texture) { + uint i; + tc->texture = texture; + + /* 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].x = -1; + } } @@ -263,10 +271,10 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y) * This is basically a direct-map cache. * XXX There's probably lots of ways in which we can improve this. */ -static uint +static INLINE uint tex_cache_pos(int x, int y, int z, int face, int level) { - uint entry = x + y * 2 + z * 4 + face + level; + uint entry = x + y * 5 + z * 4 + face + level; return entry % NUM_ENTRIES; } @@ -275,19 +283,17 @@ tex_cache_pos(int x, int y, int z, int face, int level) * Similar to sp_get_cached_tile() but for textures. * Tiles are read-only and indexed with more params. */ -struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, +const struct softpipe_cached_tile * +sp_get_cached_tile_tex(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, int x, int y, int z, int face, int level) { - struct pipe_context *pipe; /* XXX need this */ - /* tile pos in framebuffer: */ const int tile_x = x & ~(TILE_SIZE - 1); const int tile_y = y & ~(TILE_SIZE - 1); - /* cache pos/entry: */ - const int pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, - z, face, level); + const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z, + face, level); struct softpipe_cached_tile *tile = tc->entries + pos; if (tile_x != tile->x || @@ -295,6 +301,7 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, z != tile->z || face != tile->face || level != tile->level) { + /* XXX this call is a bit heavier than we'd like: */ struct pipe_surface *ps = pipe->get_tex_surface(pipe, tc->texture, face, level, z); @@ -303,6 +310,12 @@ sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, (float *) tile->data.color); pipe_surface_reference(&ps, NULL); + + tile->x = tile_x; + tile->y = tile_y; + tile->z = z; + tile->face = face; + tile->level = level; } return tile; diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index 9879b1821ce..a1cc387a12d 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -79,8 +79,9 @@ sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval); extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y); -extern struct softpipe_cached_tile * -sp_get_cached_tile_tex(struct softpipe_tile_cache *tc, int x, int y, int z, +extern const struct softpipe_cached_tile * +sp_get_cached_tile_tex(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, int x, int y, int z, int face, int level); diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h index 20647e72e23..978c2d574e2 100644 --- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h +++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h @@ -29,14 +29,8 @@ struct tgsi_interp_coef float dady[NUM_CHANNELS]; }; -#define TEX_CACHE_TILE_SIZE 8 -#define TEX_CACHE_NUM_ENTRIES 8 -struct tgsi_texture_cache_entry -{ - int x, y, face, level, zslice; - float data[TEX_CACHE_TILE_SIZE][TEX_CACHE_TILE_SIZE][4]; -}; +struct softpipe_tile_cache; /**< Opaque to TGSI */ struct tgsi_sampler { @@ -50,7 +44,7 @@ struct tgsi_sampler float lodbias, float rgba[NUM_CHANNELS][QUAD_SIZE]); void *pipe; /*XXX temporary*/ - struct tgsi_texture_cache_entry cache[TEX_CACHE_NUM_ENTRIES]; + struct softpipe_tile_cache *cache; }; struct tgsi_exec_labels -- 2.30.2