summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-08-14 14:52:38 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-08-14 14:52:38 -0600
commita13de2464dd034ff117f9314df5757d068cae8e5 (patch)
treef429edad000f2e9affc8feee3fafb0ea1f113ccf
parentc7722edcfdf36e0d0bfdc51013ecb199fc7fa9f6 (diff)
Implement texture cache with multiple, direct-mapped entries.
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c13
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c81
-rw-r--r--src/mesa/pipe/tgsi/core/tgsi_exec.h14
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 096385d7a1..e767d0a470 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 f62f0abf87..de14586b67 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 b3ed124d3f..5e07e18a31 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