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:
parent
832e73bc09
commit
7e83963998
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue