Finish unifying the surface and texture tile caches.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user