Convert Z/stencil ops to use cached tiles like colors.

Also, quite a bit of re-org of the tile caches and surface mapping/unmapping.
Leave surfaces mapped between primitives now.
This commit is contained in:
Brian 2007-10-20 15:18:02 -06:00
parent 832e73bc09
commit 7e83963998
16 changed files with 394 additions and 125 deletions

View File

@ -69,5 +69,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
/* XXX skip this fill if we're using tile cache */
pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue);
#if 0
sp_clear_tile_cache(sps, clearValue);
#endif
}

View File

@ -39,6 +39,7 @@
#include "sp_region.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_tex_layout.h"
#include "sp_winsys.h"
@ -113,6 +114,9 @@ softpipe_max_texture_size(struct pipe_context *pipe, unsigned textureType,
}
/**
* Map any drawing surfaces which aren't already mapped
*/
void
softpipe_map_surfaces(struct softpipe_context *sp)
{
@ -120,68 +124,88 @@ softpipe_map_surfaces(struct softpipe_context *sp)
unsigned i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
if (sps->surface.region)
pipe->region_map(pipe, sps->surface.region);
struct pipe_surface *ps = sp->framebuffer.cbufs[i];
if (ps->region && !ps->region->map) {
pipe->region_map(pipe, ps->region);
}
}
if (sp->framebuffer.zbuf) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
if (sps->surface.region)
pipe->region_map(pipe, sps->surface.region);
struct pipe_surface *ps = sp->framebuffer.zbuf;
if (ps->region && !ps->region->map) {
pipe->region_map(pipe, ps->region);
}
}
if (sp->framebuffer.sbuf) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.sbuf);
if (sps->surface.region)
pipe->region_map(pipe, sps->surface.region);
struct pipe_surface *ps = sp->framebuffer.sbuf;
if (ps->region && !ps->region->map) {
pipe->region_map(pipe, ps->region);
}
}
}
void
softpipe_map_texture_surfaces(struct softpipe_context *sp)
{
struct pipe_context *pipe = &sp->pipe;
uint i;
/* textures */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
struct pipe_mipmap_tree *mt = sp->texture[i];
if (mt) {
pipe->region_map(pipe, mt->region);
}
}
/* XXX depth & stencil bufs */
}
/**
* Unmap any mapped drawing surfaces
*/
void
softpipe_unmap_surfaces(struct softpipe_context *sp)
{
struct pipe_context *pipe = &sp->pipe;
unsigned i;
uint i;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
sp_flush_tile_cache(sp->cbuf_cache[i]);
sp_flush_tile_cache(sp->zbuf_cache);
sp_flush_tile_cache(sp->sbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
if (sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
struct pipe_surface *ps = sp->framebuffer.cbufs[i];
if (ps->region)
pipe->region_unmap(pipe, ps->region);
}
if (sp->framebuffer.zbuf) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
if (sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
struct pipe_surface *ps = sp->framebuffer.zbuf;
if (ps->region)
pipe->region_unmap(pipe, ps->region);
}
if (sp->framebuffer.sbuf) {
struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.sbuf);
if (sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
if (sp->framebuffer.sbuf && sp->framebuffer.sbuf != sp->framebuffer.zbuf) {
struct pipe_surface *ps = sp->framebuffer.sbuf;
if (ps->region)
pipe->region_unmap(pipe, ps->region);
}
}
/* textures */
void
softpipe_unmap_texture_surfaces(struct softpipe_context *sp)
{
struct pipe_context *pipe = &sp->pipe;
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
struct pipe_mipmap_tree *mt = sp->texture[i];
if (mt) {
pipe->region_unmap(pipe, mt->region);
}
}
/* XXX depth & stencil bufs */
}
@ -248,6 +272,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
struct softpipe_winsys *softpipe_winsys )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
#if defined(__i386__) || defined(__386__)
softpipe->use_sse = getenv("GALLIUM_SSE") != NULL;
@ -355,5 +380,10 @@ 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();
return &softpipe->pipe;
}

View File

@ -44,6 +44,7 @@ struct softpipe_surface;
struct softpipe_winsys;
struct draw_context;
struct draw_stage;
struct softpipe_tile_cache;
#define SP_NEW_VIEWPORT 0x1
@ -155,6 +156,13 @@ struct softpipe_context {
struct pipe_surface *cbuf; /**< current color buffer (one of cbufs) */
struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
struct softpipe_tile_cache *zbuf_cache;
/** Stencil buffer cache, for stencil separate from Z */
struct softpipe_tile_cache *sbuf_cache_sep;
/** This either points to zbuf_cache or sbuf_cache_sep */
struct softpipe_tile_cache *sbuf_cache;
int use_sse : 1;
};

View File

@ -113,7 +113,7 @@ softpipe_draw_elements(struct pipe_context *pipe,
softpipe_update_derived( sp );
softpipe_map_surfaces(sp);
softpipe_map_texture_surfaces(sp);
softpipe_map_constant_buffers(sp);
/*
@ -184,7 +184,8 @@ softpipe_draw_elements(struct pipe_context *pipe,
}
softpipe_unmap_surfaces(sp);
/* Note: leave drawing surfaces mapped */
softpipe_unmap_texture_surfaces(sp);
softpipe_unmap_constant_buffers(sp);
return TRUE;

View File

@ -54,10 +54,14 @@ softpipe_flush( struct pipe_context *pipe,
* - flush the render cache
*/
for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.cbufs[i]);
if (sps)
sp_flush_tile_cache(sps);
}
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
if (softpipe->cbuf_cache[i])
sp_flush_tile_cache(softpipe->cbuf_cache[i]);
if (softpipe->zbuf_cache)
sp_flush_tile_cache(softpipe->zbuf_cache);
if (softpipe->sbuf_cache)
sp_flush_tile_cache(softpipe->sbuf_cache);
}

View File

@ -101,14 +101,13 @@ static void
logicop_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
float dest[4][QUAD_SIZE];
ubyte src[4][4], dst[4][4], res[4][4];
uint *src4 = (uint *) src;
uint *dst4 = (uint *) dst;
uint *res4 = (uint *) res;
struct softpipe_cached_tile *
tile = sp_get_cached_tile(sps, quad->x0, quad->y0);
tile = sp_get_cached_tile(softpipe->cbuf_cache[0], quad->x0, quad->y0);
uint i, j;
/* get/swizzle dest colors */
@ -220,12 +219,11 @@ static void
blend_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
struct softpipe_cached_tile *
tile = sp_get_cached_tile(sps, quad->x0, quad->y0);
tile = sp_get_cached_tile(softpipe->cbuf_cache[0], quad->x0, quad->y0);
uint i, j;
if (softpipe->blend->logicop_enable) {

View File

@ -47,10 +47,9 @@ static void
colormask_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
float dest[4][QUAD_SIZE];
struct softpipe_cached_tile *
tile = sp_get_cached_tile(sps, quad->x0, quad->y0);
tile = sp_get_cached_tile(softpipe->cbuf_cache[0], quad->x0, quad->y0);
uint i, j;
/* get/swizzle dest colors */

View File

@ -39,55 +39,86 @@
* Do depth testing for a quad.
* Not static since it's used by the stencil code.
*/
/*
* To increase efficiency, we should probably have multiple versions
* of this function that are specifically for Z16, Z32 and FP Z buffers.
* Try to effectively do that with codegen...
*/
void
sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf);
const uint format = sps->surface.format;
unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
unsigned zmask = 0;
unsigned j;
float scale;
#if 0
struct cached_tile *tile = sp_get_cached_tile(softpipe, quad->x0, quad->y0);
#endif
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe->zbuf_cache, quad->x0, quad->y0);
assert(sps); /* shouldn't get here if there's no zbuffer */
/*
* To increase efficiency, we should probably have multiple versions
* of this function that are specifically for Z16, Z32 and FP Z buffers.
* Try to effectively do that with codegen...
*/
if (sps->surface.format == PIPE_FORMAT_U_Z16)
scale = 65535.0;
else if (sps->surface.format == PIPE_FORMAT_S8_Z24)
scale = (float) ((1 << 24) - 1);
else
assert(0); /* XXX fix this someday */
/*
* Convert quad's float depth values to int depth values.
* Convert quad's float depth values to int depth values (qzzzz).
* If the Z buffer stores integer values, we _have_ to do the depth
* compares with integers (not floats). Otherwise, the float->int->float
* conversion of Z values (which isn't an identity function) will cause
* Z-fighting errors.
*
* Also, get the zbuffer values (bzzzz) from the cached tile.
*/
for (j = 0; j < QUAD_SIZE; j++) {
qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale);
}
switch (format) {
case PIPE_FORMAT_U_Z16:
{
float scale = 65535.0;
#if 0
for (j = 0; j < 4; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
bzzzz[j] = tile->depth[y][x];
for (j = 0; j < QUAD_SIZE; j++) {
qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale);
}
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
bzzzz[j] = tile->data.depth16[y][x];
}
}
break;
case PIPE_FORMAT_U_Z32:
{
double scale = (double) (uint) ~0UL;
for (j = 0; j < QUAD_SIZE; j++) {
qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale);
}
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
bzzzz[j] = tile->data.depth32[y][x];
}
}
break;
case PIPE_FORMAT_S8_Z24:
{
float scale = (float) ((1 << 24) - 1);
for (j = 0; j < QUAD_SIZE; j++) {
qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale);
}
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
}
}
break;
default:
assert(0);
}
#else
/* get zquad from zbuffer */
sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz);
#endif
switch (softpipe->depth_stencil->depth.func) {
case PIPE_FUNC_NEVER:
@ -151,16 +182,34 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
}
#if 1
/* write updated zquad to zbuffer */
sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz);
#else
for (j = 0; j < 4; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->depth[y][x] = bzzzz[j];
/* put updated Z values back into cached tile */
switch (format) {
case PIPE_FORMAT_U_Z16:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->data.depth16[y][x] = bzzzz[j];
}
break;
case PIPE_FORMAT_U_Z32:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->data.depth32[y][x] = bzzzz[j];
}
break;
case PIPE_FORMAT_S8_Z24:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
uint s8z24 = tile->data.depth32[y][x];
s8z24 = (s8z24 & 0xff000000) | bzzzz[j];
tile->data.depth32[y][x] = s8z24;
}
break;
default:
assert(0);
}
#endif
}
}

View File

@ -42,9 +42,8 @@ static void
output_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf);
struct softpipe_cached_tile *tile
= sp_get_cached_tile(sps, quad->x0, quad->y0);
= sp_get_cached_tile(softpipe->cbuf_cache[0], quad->x0, quad->y0);
/* in-tile pos: */
const int itx = quad->x0 % TILE_SIZE;
const int ity = quad->y0 % TILE_SIZE;

View File

@ -7,6 +7,7 @@
#include "sp_context.h"
#include "sp_headers.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_quad.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
@ -200,10 +201,13 @@ static void
stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
struct softpipe_surface *s_surf = softpipe_surface(softpipe->framebuffer.sbuf);
struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.sbuf);
unsigned func, zFailOp, zPassOp, failOp;
ubyte ref, wrtMask, valMask;
ubyte stencilVals[QUAD_SIZE];
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe->sbuf_cache, quad->x0, quad->y0);
uint j;
/* choose front or back face function, operator, etc */
/* XXX we could do these initializations once per primitive */
@ -226,8 +230,27 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
valMask = softpipe->depth_stencil->stencil.value_mask[0];
}
assert(s_surf); /* shouldn't get here if there's no stencil buffer */
s_surf->read_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals);
assert(sps); /* shouldn't get here if there's no stencil buffer */
/* get stencil values from cached tile */
switch (sps->surface.format) {
case PIPE_FORMAT_S8_Z24:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
stencilVals[j] = tile->data.depth32[y][x] >> 24;
}
break;
case PIPE_FORMAT_U_S8:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
stencilVals[j] = tile->data.stencil8[y][x];
}
break;
default:
assert(0);
}
/* do the stencil test first */
{
@ -242,7 +265,6 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
if (quad->mask) {
/* now the pixels that passed the stencil test are depth tested */
if (softpipe->depth_stencil->depth.enabled) {
const unsigned origMask = quad->mask;
@ -267,7 +289,27 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
s_surf->write_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals);
/* put new stencil values into cached tile */
switch (sps->surface.format) {
case PIPE_FORMAT_S8_Z24:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
uint s8z24 = tile->data.depth32[y][x];
s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff);
tile->data.depth32[y][x] = s8z24;
}
break;
case PIPE_FORMAT_U_S8:
for (j = 0; j < QUAD_SIZE; j++) {
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
tile->data.stencil8[y][x] = stencilVals[j];
}
break;
default:
assert(0);
}
if (quad->mask)
qs->next->run(qs->next, quad);

View File

@ -141,4 +141,10 @@ softpipe_map_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_surfaces(struct softpipe_context *sp);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
#endif

View File

@ -30,20 +30,100 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
/*
/**
* XXX this might get moved someday
* Set the framebuffer surface info: color buffers, zbuffer, stencil buffer.
* Here, we map the surfaces and update the tile cache to point to the new
* surfaces.
*/
void
softpipe_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct softpipe_context *sp = softpipe_context(pipe);
struct softpipe_surface *sps;
uint i;
softpipe->framebuffer = *fb; /* struct copy */
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
/* check if changing cbuf */
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
/* flush old */
sp_flush_tile_cache(sp->cbuf_cache[i]);
/* unmap old */
sps = softpipe_surface(sp->framebuffer.cbufs[i]);
if (sps && sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
/* map new */
sps = softpipe_surface(fb->cbufs[i]);
if (sps)
pipe->region_map(pipe, sps->surface.region);
/* assign new */
sp->framebuffer.cbufs[i] = fb->cbufs[i];
softpipe->dirty |= SP_NEW_FRAMEBUFFER;
/* update cache */
sp_tile_cache_set_surface(sp->cbuf_cache[i], sps);
}
}
sp->framebuffer.num_cbufs = fb->num_cbufs;
/* zbuf changing? */
if (sp->framebuffer.zbuf != fb->zbuf) {
/* flush old */
sp_flush_tile_cache(sp->zbuf_cache);
/* unmap old */
sps = softpipe_surface(sp->framebuffer.zbuf);
if (sps && sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) {
/* combined z/stencil */
sp->framebuffer.sbuf = NULL;
}
/* map new */
sps = softpipe_surface(fb->zbuf);
if (sps)
pipe->region_map(pipe, sps->surface.region);
/* assign new */
sp->framebuffer.zbuf = fb->zbuf;
/* update cache */
sp_tile_cache_set_surface(sp->zbuf_cache, sps);
}
/* XXX combined depth/stencil here */
/* sbuf changing? */
if (sp->framebuffer.sbuf != fb->sbuf) {
/* flush old */
sp_flush_tile_cache(sp->sbuf_cache_sep);
/* unmap old */
sps = softpipe_surface(sp->framebuffer.sbuf);
if (sps && sps->surface.region)
pipe->region_unmap(pipe, sps->surface.region);
/* map new */
sps = softpipe_surface(fb->sbuf);
if (sps && fb->sbuf != fb->zbuf)
pipe->region_map(pipe, sps->surface.region);
/* assign new */
sp->framebuffer.sbuf = fb->sbuf;
/* update cache */
if (fb->sbuf != fb->zbuf) {
/* separate stencil buf */
sp->sbuf_cache = sp->sbuf_cache_sep;
sp_tile_cache_set_surface(sp->sbuf_cache, sps);
}
else {
/* combined depth/stencil */
sp->sbuf_cache = sp->zbuf_cache;
sp_tile_cache_set_surface(sp->sbuf_cache, sps);
}
}
sp->dirty |= SP_NEW_FRAMEBUFFER;
}

View File

@ -61,6 +61,10 @@
#else
#define CLIP_TILE \
do { \
if (x >= ps->width) \
return; \
if (y >= ps->height) \
return; \
if (x + w > ps->width) \
w = ps->width - x; \
if (y + h > ps->height) \
@ -907,13 +911,16 @@ put_tile_raw32(struct pipe_surface *ps,
unsigned i;
unsigned w0 = w;
assert(w < 1000);
assert(ps->region->map);
assert(ps->format == PIPE_FORMAT_S8_Z24 ||
ps->format == PIPE_FORMAT_U_Z32);
assert(w < 1000);
CLIP_TILE;
for (i = 0; i < h; i++) {
assert(w < 1000);
memcpy(dst, pSrc, w * sizeof(uint));
dst += ps->region->pitch;
pSrc += w0;
@ -980,8 +987,6 @@ put_tile_raw16(struct pipe_surface *ps,
void
softpipe_init_surface_funcs(struct softpipe_surface *sps)
{
sps->tc = sp_create_tile_cache();
assert(sps->surface.format);
switch (sps->surface.format) {

View File

@ -46,8 +46,6 @@ struct softpipe_tile_cache;
struct softpipe_surface {
struct pipe_surface surface;
struct softpipe_tile_cache *tc;
/**
* Functions for read/writing surface data
*/

View File

@ -48,6 +48,7 @@
struct softpipe_tile_cache
{
struct softpipe_surface *surface; /**< the surface we're caching */
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
};
@ -115,45 +116,64 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
}
void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct softpipe_surface *sps)
{
tc->surface = sps;
}
void
sp_flush_tile_cache(struct softpipe_surface *sps)
sp_flush_tile_cache(struct softpipe_tile_cache *tc)
{
struct softpipe_tile_cache *tc = sps->tc;
/*
struct softpipe_surface *zsurf = softpipe_surface(softpipe->zbuf);
*/
struct pipe_surface *ps = &tc->surface->surface;
boolean is_depth_stencil;
int inuse = 0, pos;
if (!ps || !ps->region || !ps->region->map)
return;
is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 ||
ps->format == PIPE_FORMAT_U_Z16 ||
ps->format == PIPE_FORMAT_U_Z32 ||
ps->format == PIPE_FORMAT_U_S8);
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
if (tile->x >= 0) {
sps->surface.put_tile(&sps->surface,
tile->x,
tile->y,
TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
/*
sps->surface.put_tile(&zsurf->surface,
tile->x,
tile->y,
TILE_SIZE, TILE_SIZE,
(float *) tile->depth);
*/
if (is_depth_stencil) {
ps->put_tile_raw(ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32);
}
else {
ps->put_tile(ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
tile->x = tile->y = -1; /* mark as empty */
inuse++;
}
}
/*printf("flushed tiles in use: %d\n", inuse);*/
/*
printf("flushed tiles in use: %d\n", inuse);
*/
}
struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_surface *sps, int x, int y)
sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y)
{
struct softpipe_tile_cache *tc = sps->tc;
struct pipe_surface *ps = &tc->surface->surface;
boolean is_depth_stencil
= (ps->format == PIPE_FORMAT_S8_Z24 ||
ps->format == PIPE_FORMAT_U_Z16 ||
ps->format == PIPE_FORMAT_U_Z32 ||
ps->format == PIPE_FORMAT_U_S8);
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
@ -176,13 +196,22 @@ sp_get_cached_tile(struct softpipe_surface *sps, int x, int y)
if (tile->x != -1) {
/* put dirty tile back in framebuffer */
sps->surface.put_tile(&sps->surface, tile->x, tile->y,
TILE_SIZE, TILE_SIZE, (float *) tile->data.color);
if (is_depth_stencil) {
ps->put_tile_raw(ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32);
}
else {
ps->put_tile(ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
if (is_clear_flag_set(tc->clear_flags, x, y)) {
printf("clear tile\n");
if (0/*is_clear_flag_set(tc->clear_flags, x, y)*/) {
/* don't get tile from framebuffer, just clear it */
#if 0
printf("clear tile\n");
uint i, j;
for (i = 0; i < TILE_SIZE; i++) {
for (j = 0; j < TILE_SIZE; j++) {
@ -192,14 +221,24 @@ sp_get_cached_tile(struct softpipe_surface *sps, int x, int y)
tile->data.color[i][j][3] = 0.5;
}
}
#else
(void) is_clear_flag_set;
#endif
memset(tile->data.color, 0, sizeof(tile->data.color));
clear_clear_flag(tc->clear_flags, x, y);
}
else {
/* get new tile from framebuffer */
sps->surface.get_tile(&sps->surface, tile_x, tile_y,
TILE_SIZE, TILE_SIZE, (float *) tile->data.color);
if (is_depth_stencil) {
ps->get_tile_raw(ps,
tile_x, tile_y, TILE_SIZE, TILE_SIZE,
tile->data.depth32);
}
else {
ps->get_tile(ps,
tile_x, tile_y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
tile->x = tile_x;
@ -211,8 +250,8 @@ sp_get_cached_tile(struct softpipe_surface *sps, int x, int y)
void
sp_clear_tile_cache(struct softpipe_surface *sps, unsigned clearval)
sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval)
{
(void) clearval; /* XXX use this */
memset(sps->tc->clear_flags, 255, sizeof(sps->tc->clear_flags));
memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
}

View File

@ -36,6 +36,9 @@ struct softpipe_context;
struct softpipe_tile_cache;
/**
* Cache tile size (width and height). This needs to be a power of two.
*/
#define TILE_SIZE 64
@ -45,7 +48,9 @@ struct softpipe_cached_tile
int x, y; /** pos of tile in window coords */
union {
float color[TILE_SIZE][TILE_SIZE][4];
uint depth[TILE_SIZE][TILE_SIZE];
uint depth32[TILE_SIZE][TILE_SIZE];
ushort depth16[TILE_SIZE][TILE_SIZE];
ubyte stencil8[TILE_SIZE][TILE_SIZE];
} data;
};
@ -57,13 +62,17 @@ extern void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc);
extern void
sp_flush_tile_cache(struct softpipe_surface *sps);
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct softpipe_surface *sps);
extern void
sp_clear_tile_cache(struct softpipe_surface *sps, unsigned clearval);
sp_flush_tile_cache(struct softpipe_tile_cache *tc);
extern void
sp_clear_tile_cache(struct softpipe_tile_cache *tc, unsigned clearval);
extern struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_surface *sps, int x, int y);
sp_get_cached_tile(struct softpipe_tile_cache *tc, int x, int y);
#endif /* SP_TILE_CACHE_H */