summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-10-20 15:18:02 -0600
committerBrian <[email protected]>2007-10-20 15:18:02 -0600
commit7e8396399824108d62dc3e02b2af0422e98aab8e (patch)
tree89f1ca9279bdc87e2f1b9125322331898a020466
parent832e73bc098fa8fd680d70cb495f495b33769630 (diff)
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.
-rw-r--r--src/mesa/pipe/softpipe/sp_clear.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c82
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h8
-rw-r--r--src/mesa/pipe/softpipe/sp_draw_arrays.c5
-rw-r--r--src/mesa/pipe/softpipe/sp_flush.c14
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_blend.c6
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_colormask.c3
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_depth_test.c127
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_output.c3
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_stencil.c52
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h6
-rw-r--r--src/mesa/pipe/softpipe/sp_state_surface.c88
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c9
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c97
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.h17
16 files changed, 395 insertions, 126 deletions
diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c
index 46370b4ed9a..4f04f8243fa 100644
--- a/src/mesa/pipe/softpipe/sp_clear.c
+++ b/src/mesa/pipe/softpipe/sp_clear.c
@@ -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
}
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index 44cc6851053..87eaf6fb544 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -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;
}
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index 4f429e81397..ea05f80d59a 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -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;
};
diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c
index 405659fb464..64a4fbe333e 100644
--- a/src/mesa/pipe/softpipe/sp_draw_arrays.c
+++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c
@@ -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;
diff --git a/src/mesa/pipe/softpipe/sp_flush.c b/src/mesa/pipe/softpipe/sp_flush.c
index d4eada82287..f2186dbb653 100644
--- a/src/mesa/pipe/softpipe/sp_flush.c
+++ b/src/mesa/pipe/softpipe/sp_flush.c
@@ -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);
}
diff --git a/src/mesa/pipe/softpipe/sp_quad_blend.c b/src/mesa/pipe/softpipe/sp_quad_blend.c
index 43294e4cd4d..5787b89588d 100644
--- a/src/mesa/pipe/softpipe/sp_quad_blend.c
+++ b/src/mesa/pipe/softpipe/sp_quad_blend.c
@@ -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) {
diff --git a/src/mesa/pipe/softpipe/sp_quad_colormask.c b/src/mesa/pipe/softpipe/sp_quad_colormask.c
index aa69f53580e..3c0196dd5dc 100644
--- a/src/mesa/pipe/softpipe/sp_quad_colormask.c
+++ b/src/mesa/pipe/softpipe/sp_quad_colormask.c
@@ -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 */
diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
index efd08b981cf..29231322b83 100644
--- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c
+++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c
@@ -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);
- }
-
-#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];
+ switch (format) {
+ case PIPE_FORMAT_U_Z16:
+ {
+ float scale = 65535.0;
+
+ 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
}
}
diff --git a/src/mesa/pipe/softpipe/sp_quad_output.c b/src/mesa/pipe/softpipe/sp_quad_output.c
index 01ee06a69c1..e86f42be461 100644
--- a/src/mesa/pipe/softpipe/sp_quad_output.c
+++ b/src/mesa/pipe/softpipe/sp_quad_output.c
@@ -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;
diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c
index bf72bb23cd0..4a3823d6468 100644
--- a/src/mesa/pipe/softpipe/sp_quad_stencil.c
+++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c
@@ -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);
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index f9061e86e53..c194f0ea0db 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -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
diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c
index a534ffb2c2e..cd1e75c563a 100644
--- a/src/mesa/pipe/softpipe/sp_state_surface.c
+++ b/src/mesa/pipe/softpipe/sp_state_surface.c
@@ -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;
+
+ 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];
+
+ /* 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;
- softpipe->framebuffer = *fb; /* struct copy */
+ /* 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);
+ }
+ }
- softpipe->dirty |= SP_NEW_FRAMEBUFFER;
+ sp->dirty |= SP_NEW_FRAMEBUFFER;
}
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index 8aad5f6c13e..fb8c8d08265 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -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) {
diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h
index 431303553fb..522f7612ab9 100644
--- a/src/mesa/pipe/softpipe/sp_surface.h
+++ b/src/mesa/pipe/softpipe/sp_surface.h
@@ -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
*/
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c
index 2ecdfc89e42..74bd4a3d11c 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.c
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.c
@@ -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));
}
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h
index 4248361f99d..80bcac6904d 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.h
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.h
@@ -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 */