summaryrefslogtreecommitdiff
path: root/src/mesa/pipe
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-10-22 09:37:26 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-10-22 09:37:26 -0600
commit70eb7996f265f3634dabda078f13d1be3533cc65 (patch)
tree30148a72c347274cafa3386accb22aae4c1f9c7a /src/mesa/pipe
parentec3bd21c465f27d0a8e313e00338109d21019fc0 (diff)
Finish unifying the surface and texture tile caches.
Diffstat (limited to 'src/mesa/pipe')
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c20
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c20
-rw-r--r--src/mesa/pipe/softpipe/sp_state_sampler.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c98
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c31
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.h5
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.h10
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 10c53a257b..bf61019f62 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 ea05f80d59..3e77bd6b85 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 c850f08c57..674e02d0f4 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 4084e9163f..c00e815f2d 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 64cb94d944..385b8042c3 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 d88bce4619..1e287c91a4 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 9879b1821c..a1cc387a12 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 20647e72e2..978c2d574e 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