summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Krol <michal@tungstengraphics.com>2007-11-18 18:20:20 +0000
committerMichal Krol <michal@tungstengraphics.com>2007-11-18 18:20:20 +0000
commit7f718f047676e88b660618784f256a96f7e8ed58 (patch)
tree0e7c6676b64df5394eb0d09073a934cc4bbaa408
parentca7f68a7cf25a51f382bba8c42d8c6ab7db57b5d (diff)
Implement early depth test.
Early depth test is enabled when depth test is enabled and alpha test is disabled and fragment shader does not write depth. The early-z is implemented by moving the depth test stage just before the fragment shader stage and prepending it with an earlyz stage, introduced with this commit. The earlyz stage prepares the quad->outputs.depth for the following depth test stage by interpolating Z position, just as the fragment shader would do.
-rw-r--r--src/mesa/pipe/softpipe/Makefile1
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h1
-rw-r--r--src/mesa/pipe/softpipe/sp_quad.c70
-rw-r--r--src/mesa/pipe/softpipe/sp_quad.h1
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_earlyz.c100
6 files changed, 150 insertions, 25 deletions
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile
index 2cbd9e5b51..59628531cc 100644
--- a/src/mesa/pipe/softpipe/Makefile
+++ b/src/mesa/pipe/softpipe/Makefile
@@ -18,6 +18,7 @@ DRIVER_SOURCES = \
sp_quad_colormask.c \
sp_quad_coverage.c \
sp_quad_depth_test.c \
+ sp_quad_earlyz.c \
sp_quad_fs.c \
sp_quad_occlusion.c \
sp_quad_output.c \
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index be4da0ec64..d5e68c189d 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -161,6 +161,7 @@ static void softpipe_destroy( struct pipe_context *pipe )
draw_destroy( softpipe->draw );
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
+ softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
softpipe->quad.shade->destroy( softpipe->quad.shade );
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
@@ -369,6 +370,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
/* setup quad rendering stages */
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
+ softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index a411969bc0..872766101d 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -134,6 +134,7 @@ struct softpipe_context {
/** Software quad rendering pipeline */
struct {
struct quad_stage *polygon_stipple;
+ struct quad_stage *earlyz;
struct quad_stage *shade;
struct quad_stage *alpha_test;
struct quad_stage *stencil_test;
diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c
index 429497e9b2..5a0df6de9d 100644
--- a/src/mesa/pipe/softpipe/sp_quad.c
+++ b/src/mesa/pipe/softpipe/sp_quad.c
@@ -28,24 +28,52 @@
#include "sp_context.h"
+#include "sp_state.h"
+#include "pipe/tgsi/exec/tgsi_token.h"
+static void
+sp_push_quad_first(
+ struct softpipe_context *sp,
+ struct quad_stage *quad )
+{
+ quad->next = sp->quad.first;
+ sp->quad.first = quad;
+}
+
+static void
+sp_build_depth_stencil(
+ struct softpipe_context *sp )
+{
+ if (sp->depth_stencil->stencil.front_enabled ||
+ sp->depth_stencil->stencil.back_enabled) {
+ sp_push_quad_first( sp, sp->quad.stencil_test );
+ }
+ else if (sp->depth_stencil->depth.enabled &&
+ sp->framebuffer.zbuf) {
+ sp_push_quad_first( sp, sp->quad.depth_test );
+ }
+}
void
sp_build_quad_pipeline(struct softpipe_context *sp)
{
+ boolean early_depth_test =
+ sp->depth_stencil->depth.enabled &&
+ sp->framebuffer.zbuf &&
+ !sp->alpha_test->enabled &&
+ sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION;
+
/* build up the pipeline in reverse order... */
sp->quad.first = sp->quad.output;
if (sp->blend->colormask != 0xf) {
- sp->quad.colormask->next = sp->quad.first;
- sp->quad.first = sp->quad.colormask;
+ sp_push_quad_first( sp, sp->quad.colormask );
}
if (sp->blend->blend_enable ||
sp->blend->logicop_enable) {
- sp->quad.blend->next = sp->quad.first;
- sp->quad.first = sp->quad.blend;
+ sp_push_quad_first( sp, sp->quad.blend );
}
if (sp->framebuffer.num_cbufs == 1) {
@@ -54,46 +82,38 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
}
else {
/* insert bufloop stage */
- sp->quad.bufloop->next = sp->quad.first;
- sp->quad.first = sp->quad.bufloop;
+ sp_push_quad_first( sp, sp->quad.bufloop );
}
if (sp->depth_stencil->depth.occlusion_count) {
- sp->quad.occlusion->next = sp->quad.first;
- sp->quad.first = sp->quad.occlusion;
+ sp_push_quad_first( sp, sp->quad.occlusion );
}
if (sp->rasterizer->poly_smooth ||
sp->rasterizer->line_smooth ||
sp->rasterizer->point_smooth) {
- sp->quad.coverage->next = sp->quad.first;
- sp->quad.first = sp->quad.coverage;
+ sp_push_quad_first( sp, sp->quad.coverage );
}
- if ( sp->depth_stencil->stencil.front_enabled
- || sp->depth_stencil->stencil.back_enabled) {
- sp->quad.stencil_test->next = sp->quad.first;
- sp->quad.first = sp->quad.stencil_test;
- }
- else if (sp->depth_stencil->depth.enabled &&
- sp->framebuffer.zbuf) {
- sp->quad.depth_test->next = sp->quad.first;
- sp->quad.first = sp->quad.depth_test;
+ if (!early_depth_test) {
+ sp_build_depth_stencil( sp );
}
if (sp->alpha_test->enabled) {
- sp->quad.alpha_test->next = sp->quad.first;
- sp->quad.first = sp->quad.alpha_test;
+ sp_push_quad_first( sp, sp->quad.alpha_test );
}
/* XXX always enable shader? */
if (1) {
- sp->quad.shade->next = sp->quad.first;
- sp->quad.first = sp->quad.shade;
+ sp_push_quad_first( sp, sp->quad.shade );
+ }
+
+ if (early_depth_test) {
+ sp_build_depth_stencil( sp );
+ sp_push_quad_first( sp, sp->quad.earlyz );
}
if (sp->rasterizer->poly_stipple_enable) {
- sp->quad.polygon_stipple->next = sp->quad.first;
- sp->quad.first = sp->quad.polygon_stipple;
+ sp_push_quad_first( sp, sp->quad.polygon_stipple );
}
}
diff --git a/src/mesa/pipe/softpipe/sp_quad.h b/src/mesa/pipe/softpipe/sp_quad.h
index 534541122b..f1e0281764 100644
--- a/src/mesa/pipe/softpipe/sp_quad.h
+++ b/src/mesa/pipe/softpipe/sp_quad.h
@@ -51,6 +51,7 @@ struct quad_stage {
struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
diff --git a/src/mesa/pipe/softpipe/sp_quad_earlyz.c b/src/mesa/pipe/softpipe/sp_quad_earlyz.c
new file mode 100644
index 0000000000..7e0b37519c
--- /dev/null
+++ b/src/mesa/pipe/softpipe/sp_quad_earlyz.c
@@ -0,0 +1,100 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * 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
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * \brief Quad early-z testing
+ */
+
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "sp_context.h"
+#include "sp_headers.h"
+#include "sp_surface.h"
+#include "sp_quad.h"
+#include "sp_tile_cache.h"
+
+static void
+earlyz_quad(
+ struct quad_stage *qs,
+ struct quad_header *quad )
+{
+ uint i;
+ const float fx = (float) quad->x0;
+ const float fy = (float) quad->y0;
+ float xy[4][2];
+
+ xy[0][0] = fx;
+ xy[1][0] = fx + 1.0f;
+ xy[2][0] = fx;
+ xy[3][0] = fx + 1.0f;
+
+ xy[0][1] = fy;
+ xy[1][1] = fy;
+ xy[2][1] = fy + 1.0f;
+ xy[3][1] = fy + 1.0f;
+
+ for (i = 0; i < QUAD_SIZE; i++) {
+ quad->outputs.depth[i] =
+ quad->coef[0].a0[2] +
+ quad->coef[0].dadx[2] * xy[i][0] +
+ quad->coef[0].dady[2] * xy[i][1];
+ }
+
+ if (qs->next) {
+ qs->next->run( qs->next, quad );
+ }
+}
+
+static void
+earlyz_begin(
+ struct quad_stage *qs )
+{
+ if (qs->next) {
+ qs->next->begin( qs->next );
+ }
+}
+
+static void
+earlyz_destroy(
+ struct quad_stage *qs )
+{
+ FREE( qs );
+}
+
+struct quad_stage *
+sp_quad_earlyz_stage(
+ struct softpipe_context *softpipe )
+{
+ struct quad_stage *stage = CALLOC_STRUCT( quad_stage );
+
+ stage->softpipe = softpipe;
+ stage->begin = earlyz_begin;
+ stage->run = earlyz_quad;
+ stage->destroy = earlyz_destroy;
+
+ return stage;
+}