Finish unifying the surface and texture tile caches.

This commit is contained in:
Brian
2007-10-22 09:37:26 -06:00
parent ec3bd21c46
commit 70eb7996f2
8 changed files with 72 additions and 118 deletions

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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];
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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