summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe/sp_quad_depth_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_quad_depth_test.c')
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c259
1 files changed, 72 insertions, 187 deletions
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 4815a0d49f..17cd5b8207 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +19,7 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -26,7 +27,7 @@
**************************************************************************/
/**
- * \brief Quad depth testing
+ * \brief Quad depth / stencil testing
*/
#include "pipe/p_defines.h"
@@ -96,7 +97,9 @@ get_depth_stencil_values( struct depth_data *data,
}
}
-/* If the shader has not been run, interpolate the depth values
+
+/**
+ * If the shader has not been run, interpolate the depth values
* ourselves.
*/
static void
@@ -115,6 +118,9 @@ interpolate_quad_depth( struct quad_header *quad )
}
+/**
+ * Compute the depth_data::qzzzz[] values from the float fragment Z values.
+ */
static void
convert_quad_depth( struct depth_data *data,
const struct quad_header *quad )
@@ -173,6 +179,9 @@ convert_quad_depth( struct depth_data *data,
+/**
+ * Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer.
+ */
static void
write_depth_stencil_values( struct depth_data *data,
struct quad_header *quad )
@@ -225,7 +234,6 @@ write_depth_stencil_values( struct depth_data *data,
-
/** Only 8-bit stencil supported */
#define STENCIL_MAX 0xff
@@ -408,12 +416,11 @@ apply_stencil_op(struct depth_data *data,
-/*
+/**
* 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...
*/
-
static boolean
depth_test_quad(struct quad_stage *qs,
struct depth_data *data,
@@ -523,7 +530,6 @@ depth_stencil_test_quad(struct quad_stage *qs,
wrtMask = softpipe->depth_stencil->stencil[face].writemask;
valMask = softpipe->depth_stencil->stencil[face].valuemask;
-
/* do the stencil test first */
{
unsigned passMask, failMask;
@@ -563,7 +569,7 @@ depth_stencil_test_quad(struct quad_stage *qs,
#define ALPHATEST( FUNC, COMP ) \
- static int \
+ static int \
alpha_test_quads_##FUNC( struct quad_stage *qs, \
struct quad_header *quads[], \
unsigned nr ) \
@@ -629,6 +635,7 @@ alpha_test_quads(struct quad_stage *qs,
}
}
+
static unsigned mask_count[16] =
{
0, /* 0x0 */
@@ -665,6 +672,9 @@ get_depth_bits(struct quad_stage *qs)
+/**
+ * General depth/stencil test function. Used when there's no fast-path.
+ */
static void
depth_test_quads_fallback(struct quad_stage *qs,
struct quad_header *quads[],
@@ -712,7 +722,6 @@ depth_test_quads_fallback(struct quad_stage *qs,
write_depth_stencil_values(&data, quads[i]);
}
-
quads[pass++] = quads[i];
}
@@ -730,169 +739,36 @@ depth_test_quads_fallback(struct quad_stage *qs,
/**
- * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and
- * Z buffer writes enabled.
- *
- * NOTE: there's no guarantee that the quads are sequentially side by
- * side. The fragment shader may have culled some quads, etc. Sliver
- * triangles may generate non-sequential quads.
- */
-static void
-depth_interp_z16_less_write(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- unsigned i, pass = 0;
- const unsigned ix = quads[0]->input.x0;
- const unsigned iy = quads[0]->input.y0;
- const float fx = (float) ix;
- const float fy = (float) iy;
- const float dzdx = quads[0]->posCoef->dadx[2];
- const float dzdy = quads[0]->posCoef->dady[2];
- const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
- struct softpipe_cached_tile *tile;
- ushort (*depth16)[TILE_SIZE];
- ushort init_idepth[4], idepth[4], depth_step;
- const float scale = 65535.0;
-
- /* compute scaled depth of the four pixels in first quad */
- init_idepth[0] = (ushort)((z0) * scale);
- init_idepth[1] = (ushort)((z0 + dzdx) * scale);
- init_idepth[2] = (ushort)((z0 + dzdy) * scale);
- init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
-
- depth_step = (ushort)(dzdx * scale);
-
- tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
-
- for (i = 0; i < nr; i++) {
- const unsigned outmask = quads[i]->inout.mask;
- const int dx = quads[i]->input.x0 - ix;
- unsigned mask = 0;
-
- /* compute depth for this quad */
- idepth[0] = init_idepth[0] + dx * depth_step;
- idepth[1] = init_idepth[1] + dx * depth_step;
- idepth[2] = init_idepth[2] + dx * depth_step;
- idepth[3] = init_idepth[3] + dx * depth_step;
-
- depth16 = (ushort (*)[TILE_SIZE])
- &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
-
- if ((outmask & 1) && idepth[0] < depth16[0][0]) {
- depth16[0][0] = idepth[0];
- mask |= (1 << 0);
- }
-
- if ((outmask & 2) && idepth[1] < depth16[0][1]) {
- depth16[0][1] = idepth[1];
- mask |= (1 << 1);
- }
-
- if ((outmask & 4) && idepth[2] < depth16[1][0]) {
- depth16[1][0] = idepth[2];
- mask |= (1 << 2);
- }
-
- if ((outmask & 8) && idepth[3] < depth16[1][1]) {
- depth16[1][1] = idepth[3];
- mask |= (1 << 3);
- }
-
- quads[i]->inout.mask = mask;
- if (quads[i]->inout.mask)
- quads[pass++] = quads[i];
- }
-
- if (pass)
- qs->next->run(qs->next, quads, pass);
-
-}
-
-
-/**
- * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and
- * Z buffer writes enabled.
- *
- * NOTE: there's no guarantee that the quads are sequentially side by
- * side. The fragment shader may have culled some quads, etc. Sliver
- * triangles may generate non-sequential quads.
+ * Special-case Z testing for 16-bit Zbuffer and Z buffer writes enabled.
*/
-static void
-depth_interp_z16_lequal_write(struct quad_stage *qs,
- struct quad_header *quads[],
- unsigned nr)
-{
- unsigned i, pass = 0;
- const unsigned ix = quads[0]->input.x0;
- const unsigned iy = quads[0]->input.y0;
- const float fx = (float) ix;
- const float fy = (float) iy;
- const float dzdx = quads[0]->posCoef->dadx[2];
- const float dzdy = quads[0]->posCoef->dady[2];
- const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
- struct softpipe_cached_tile *tile;
- ushort (*depth16)[TILE_SIZE];
- ushort init_idepth[4], idepth[4], depth_step;
- const float scale = 65535.0;
-
- /* compute scaled depth of the four pixels in first quad */
- init_idepth[0] = (ushort)((z0) * scale);
- init_idepth[1] = (ushort)((z0 + dzdx) * scale);
- init_idepth[2] = (ushort)((z0 + dzdy) * scale);
- init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
-
- depth_step = (ushort)(dzdx * scale);
- tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
-
- for (i = 0; i < nr; i++) {
- const unsigned outmask = quads[i]->inout.mask;
- const int dx = quads[i]->input.x0 - ix;
- unsigned mask = 0;
-
- /* compute depth for this quad */
- idepth[0] = init_idepth[0] + dx * depth_step;
- idepth[1] = init_idepth[1] + dx * depth_step;
- idepth[2] = init_idepth[2] + dx * depth_step;
- idepth[3] = init_idepth[3] + dx * depth_step;
-
- depth16 = (ushort (*)[TILE_SIZE])
- &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
-
- if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
- depth16[0][0] = idepth[0];
- mask |= (1 << 0);
- }
-
- if ((outmask & 2) && idepth[1] <= depth16[0][1]) {
- depth16[0][1] = idepth[1];
- mask |= (1 << 1);
- }
-
- if ((outmask & 4) && idepth[2] <= depth16[1][0]) {
- depth16[1][0] = idepth[2];
- mask |= (1 << 2);
- }
-
- if ((outmask & 8) && idepth[3] <= depth16[1][1]) {
- depth16[1][1] = idepth[3];
- mask |= (1 << 3);
- }
+#define NAME depth_interp_z16_less_write
+#define OPERATOR <
+#include "sp_quad_depth_test_tmp.h"
- depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
+#define NAME depth_interp_z16_equal_write
+#define OPERATOR ==
+#include "sp_quad_depth_test_tmp.h"
- quads[i]->inout.mask = mask;
- if (quads[i]->inout.mask)
- quads[pass++] = quads[i];
- }
+#define NAME depth_interp_z16_lequal_write
+#define OPERATOR <=
+#include "sp_quad_depth_test_tmp.h"
- if (pass)
- qs->next->run(qs->next, quads, pass);
+#define NAME depth_interp_z16_greater_write
+#define OPERATOR >
+#include "sp_quad_depth_test_tmp.h"
-}
+#define NAME depth_interp_z16_notequal_write
+#define OPERATOR !=
+#include "sp_quad_depth_test_tmp.h"
+#define NAME depth_interp_z16_gequal_write
+#define OPERATOR >=
+#include "sp_quad_depth_test_tmp.h"
+#define NAME depth_interp_z16_always_write
+#define ALWAYS 1
+#include "sp_quad_depth_test_tmp.h"
@@ -926,6 +802,10 @@ choose_depth_test(struct quad_stage *qs,
boolean occlusion = qs->softpipe->active_query_count;
+ /* default */
+ qs->run = depth_test_quads_fallback;
+
+ /* look for special cases */
if (!alpha &&
!depth &&
!stencil) {
@@ -938,57 +818,62 @@ choose_depth_test(struct quad_stage *qs,
!occlusion &&
!stencil)
{
- switch (depthfunc) {
- case PIPE_FUNC_LESS:
- switch (qs->softpipe->framebuffer.zsbuf->format) {
- case PIPE_FORMAT_Z16_UNORM:
+ if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
+ switch (depthfunc) {
+ case PIPE_FUNC_NEVER:
+ qs->run = depth_test_quads_fallback;
+ break;
+ case PIPE_FUNC_LESS:
qs->run = depth_interp_z16_less_write;
break;
- default:
- qs->run = depth_test_quads_fallback;
+ case PIPE_FUNC_EQUAL:
+ qs->run = depth_interp_z16_equal_write;
break;
- }
- break;
- case PIPE_FUNC_LEQUAL:
- switch (qs->softpipe->framebuffer.zsbuf->format) {
- case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FUNC_LEQUAL:
qs->run = depth_interp_z16_lequal_write;
break;
+ case PIPE_FUNC_GREATER:
+ qs->run = depth_interp_z16_greater_write;
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ qs->run = depth_interp_z16_notequal_write;
+ break;
+ case PIPE_FUNC_GEQUAL:
+ qs->run = depth_interp_z16_gequal_write;
+ break;
+ case PIPE_FUNC_ALWAYS:
+ qs->run = depth_interp_z16_always_write;
+ break;
default:
qs->run = depth_test_quads_fallback;
break;
}
- break;
- default:
- qs->run = depth_test_quads_fallback;
}
}
- else {
- qs->run = depth_test_quads_fallback;
- }
-
+ /* next quad/fragment stage */
qs->run( qs, quads, nr );
}
-
-
-static void depth_test_begin(struct quad_stage *qs)
+static void
+depth_test_begin(struct quad_stage *qs)
{
qs->run = choose_depth_test;
qs->next->begin(qs->next);
}
-static void depth_test_destroy(struct quad_stage *qs)
+static void
+depth_test_destroy(struct quad_stage *qs)
{
FREE( qs );
}
-struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe )
+struct quad_stage *
+sp_quad_depth_test_stage(struct softpipe_context *softpipe)
{
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);