diff options
-rw-r--r-- | src/mesa/pipe/softpipe/sp_quad_fs.c | 13 | ||||
-rw-r--r-- | src/mesa/pipe/softpipe/sp_tex_sample.c | 81 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_exec.h | 14 |
3 files changed, 67 insertions, 41 deletions
diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 096385d7a10..e767d0a470e 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -318,16 +318,21 @@ static void shade_begin(struct quad_stage *qs) { struct quad_shade_stage *qss = quad_shade_stage(qs); struct softpipe_context *softpipe = qs->softpipe; - GLuint i; + GLuint i, entry; + 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 */ - qss->samplers[i].cache_x = - qss->samplers[i].cache_y = -1; - qss->samplers[i].cache_level = -1; + 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; + } } if (qs->next) diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index f62f0abf874..de14586b672 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -529,31 +529,27 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, } + /** - * Load the texture cache with a new texture tile. + * 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 void -cache_tex_tile(struct tgsi_sampler *sampler, - unsigned face, unsigned level, unsigned zslice, int cx, int cy) +static unsigned +compute_cache_pos(unsigned face, unsigned level, unsigned zslice, + int tx, int ty) { - struct pipe_context *pipe = (struct pipe_context *) sampler->pipe; - struct pipe_surface *ps - = pipe->get_tex_surface(pipe, sampler->texture, face, level, zslice); - assert(ps->width == sampler->texture->level[level].width); - assert(ps->height == sampler->texture->level[level].height); - sampler->cache_level = level; - sampler->cache_x = cx; - sampler->cache_y = cy; - ps->get_tile(ps, - cx * SAMPLER_CACHE_SIZE, - cy * SAMPLER_CACHE_SIZE, - SAMPLER_CACHE_SIZE, SAMPLER_CACHE_SIZE, - (float *) sampler->cache); + unsigned entry = tx + ty * 2 + zslice *4 + level + face; + return entry % TEX_CACHE_NUM_ENTRIES; } /** - * Get a texel from a texture. + * Get a texel from a texture, using the texture tile cache. + * * \param face the cube face in 0..5 * \param level the mipmap level * \param zslize which slice of a 3D texture @@ -565,17 +561,36 @@ cache_tex_tile(struct tgsi_sampler *sampler, static void get_texel(struct tgsi_sampler *sampler, unsigned face, unsigned level, unsigned zslice, int x, int y, - float rgba[NUM_CHANNELS][QUAD_SIZE], GLuint j) + float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - int cx = x / SAMPLER_CACHE_SIZE; - int cy = y / SAMPLER_CACHE_SIZE; + 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); - if (cx != sampler->cache_x || cy != sampler->cache_y || - level != sampler->cache_level) { - cache_tex_tile(sampler, face, level, zslice, cx, cy); - /* printf("cache miss (%d, %d)\n", x, y); - */ + + 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); } else { /* @@ -583,13 +598,13 @@ get_texel(struct tgsi_sampler *sampler, */ } - /* get texel from cache */ - cx = x % SAMPLER_CACHE_SIZE; - cy = y % SAMPLER_CACHE_SIZE; - rgba[0][j] = sampler->cache[cy][cx][0]; - rgba[1][j] = sampler->cache[cy][cx][1]; - rgba[2][j] = sampler->cache[cy][cx][2]; - rgba[3][j] = sampler->cache[cy][cx][3]; + /* get the texel from cache entry */ + tx = x % TEX_CACHE_TILE_SIZE; + ty = y % TEX_CACHE_TILE_SIZE; + 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]; } diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.h b/src/mesa/pipe/tgsi/core/tgsi_exec.h index b3ed124d3f9..5e07e18a31e 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_exec.h +++ b/src/mesa/pipe/tgsi/core/tgsi_exec.h @@ -21,13 +21,21 @@ struct tgsi_exec_vector union tgsi_exec_channel xyzw[4]; }; -#define SAMPLER_CACHE_SIZE 8 #define NUM_CHANNELS 4 /* R,G,B,A */ #ifndef QUAD_SIZE #define QUAD_SIZE 4 /* 4 pixel/quad */ #endif +#define TEX_CACHE_TILE_SIZE 8 +#define TEX_CACHE_NUM_ENTRIES 8 + +struct tgsi_texture_cache_entry +{ + int x, y, face, level, zslice; + GLfloat data[TEX_CACHE_TILE_SIZE][TEX_CACHE_TILE_SIZE][4]; +}; + struct tgsi_sampler { const struct pipe_sampler_state *state; @@ -40,9 +48,7 @@ struct tgsi_sampler GLfloat lodbias, GLfloat rgba[NUM_CHANNELS][QUAD_SIZE]); void *pipe; /*XXX temporary*/ - - GLint cache_x, cache_y, cache_level; - GLfloat cache[SAMPLER_CACHE_SIZE][SAMPLER_CACHE_SIZE][4]; + struct tgsi_texture_cache_entry cache[TEX_CACHE_NUM_ENTRIES]; }; struct tgsi_exec_labels |