From 493eab76792307d066489bc1d88798f14a5df31d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 22 Mar 2016 07:52:26 +1000 Subject: [PATCH] softpipe: add support for explicit early depth testing ARB_shader_image_load_store adds support for explicit early depth testing. However we need to make sure we don't overwrite values using the shader written values in this case. This fixes early depth testing in softpipe to conform with those requirements. Reviewed-by: Brian Paul Signed-off-by: Dave Airlie --- src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_fs_exec.c | 16 ++++++++++------ .../drivers/softpipe/sp_quad_depth_test.c | 4 ++-- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- src/gallium/drivers/softpipe/sp_quad_pipe.c | 6 ++++-- src/gallium/drivers/softpipe/sp_state.h | 3 ++- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index d5c4aaae638..d18bbe693f3 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -175,6 +175,8 @@ struct softpipe_context { } tgsi; struct tgsi_exec_machine *fs_machine; + /** whether early depth testing is enabled */ + bool early_depth; /** The primitive drawing context */ struct draw_context *draw; diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 89411777ec9..e2d527dab66 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -116,7 +116,8 @@ setup_pos_vector(const struct tgsi_interp_coef *coef, static unsigned exec_run( const struct sp_fragment_shader_variant *var, struct tgsi_exec_machine *machine, - struct quad_header *quad ) + struct quad_header *quad, + bool early_depth_test ) { /* Compute X, Y, Z, W vals for this quad */ setup_pos_vector(quad->posCoef, @@ -155,16 +156,19 @@ exec_run( const struct sp_fragment_shader_variant *var, { uint j; - for (j = 0; j < 4; j++) - quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j]; + if (!early_depth_test) { + for (j = 0; j < 4; j++) + quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j]; + } } break; case TGSI_SEMANTIC_STENCIL: { uint j; - - for (j = 0; j < 4; j++) - quad->output.stencil[j] = (unsigned)machine->Outputs[i].xyzw[1].u[j]; + if (!early_depth_test) { + for (j = 0; j < 4; j++) + quad->output.stencil[j] = (unsigned)machine->Outputs[i].xyzw[1].u[j]; + } } break; } diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 4cce9e9bc12..847a616f491 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -782,7 +782,7 @@ depth_test_quads_fallback(struct quad_stage *qs, { unsigned i, pass = 0; const struct tgsi_shader_info *fsInfo = &qs->softpipe->fs_variant->info; - boolean interp_depth = !fsInfo->writes_z; + boolean interp_depth = !fsInfo->writes_z || qs->softpipe->early_depth; boolean shader_stencil_ref = fsInfo->writes_stencil; struct depth_data data; unsigned vp_idx = quads[0]->input.viewport_index; @@ -902,7 +902,7 @@ choose_depth_test(struct quad_stage *qs, { const struct tgsi_shader_info *fsInfo = &qs->softpipe->fs_variant->info; - boolean interp_depth = !fsInfo->writes_z; + boolean interp_depth = !fsInfo->writes_z || qs->softpipe->early_depth; boolean alpha = qs->softpipe->depth_stencil->alpha.enabled; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 395bc70f2cf..8fb632d9dcf 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -80,7 +80,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad) /* run shader */ machine->flatshade_color = softpipe->rasterizer->flatshade ? TRUE : FALSE; - return softpipe->fs_variant->run( softpipe->fs_variant, machine, quad ); + return softpipe->fs_variant->run( softpipe->fs_variant, machine, quad, softpipe->early_depth ); } diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c index 7131512daee..dbe4c0eb67e 100644 --- a/src/gallium/drivers/softpipe/sp_quad_pipe.c +++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c @@ -43,15 +43,17 @@ void sp_build_quad_pipeline(struct softpipe_context *sp) { boolean early_depth_test = - sp->depth_stencil->depth.enabled && + (sp->depth_stencil->depth.enabled && sp->framebuffer.zsbuf && !sp->depth_stencil->alpha.enabled && !sp->fs_variant->info.uses_kill && !sp->fs_variant->info.writes_z && - !sp->fs_variant->info.writes_stencil; + !sp->fs_variant->info.writes_stencil) || + sp->fs_variant->info.properties[TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL]; sp->quad.first = sp->quad.blend; + sp->early_depth = early_depth_test; if (early_depth_test) { insert_stage_at_head( sp, sp->quad.shade ); insert_stage_at_head( sp, sp->quad.depth_test ); diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 16a2897f526..7a2d3715f8b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -85,7 +85,8 @@ struct sp_fragment_shader_variant unsigned (*run)(const struct sp_fragment_shader_variant *shader, struct tgsi_exec_machine *machine, - struct quad_header *quad); + struct quad_header *quad, + bool early_depth_test); /* Deletes this instance of the object */ void (*delete)(struct sp_fragment_shader_variant *shader,