summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2007-11-18 18:20:20 +0000
committerMichal Krol <[email protected]>2007-11-18 18:20:20 +0000
commit7f718f047676e88b660618784f256a96f7e8ed58 (patch)
tree0e7c6676b64df5394eb0d09073a934cc4bbaa408 /src/mesa
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.
Diffstat (limited to 'src/mesa')
-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 2cbd9e5b515..59628531cc8 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 be4da0ec64a..d5e68c189de 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 a411969bc02..872766101d5 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 429497e9b26..5a0df6de9d3 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 534541122b3..f1e0281764f 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 00000000000..7e0b37519cd
--- /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;
+}