softpipe: add support for explicit early depth testing
authorDave Airlie <airlied@redhat.com>
Mon, 21 Mar 2016 21:52:26 +0000 (07:52 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 30 Mar 2016 23:13:54 +0000 (09:13 +1000)
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 <brianp@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_fs_exec.c
src/gallium/drivers/softpipe/sp_quad_depth_test.c
src/gallium/drivers/softpipe/sp_quad_fs.c
src/gallium/drivers/softpipe/sp_quad_pipe.c
src/gallium/drivers/softpipe/sp_state.h

index d5c4aaae6381546e09f7199acbc720b2edda7699..d18bbe693f3ba38f7b5a92777e68e737fb805c86 100644 (file)
@@ -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;
index 89411777ec978e6398fea4dcc826bf2d5a7b733e..e2d527dab6640a5ec2b89ae8cc2a86c4100929b1 100644 (file)
@@ -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;
          }
index 4cce9e9bc127e5b957951f1ef898ee8e89021f97..847a616f4911e28a0d6b8b10da31ef4149283f06 100644 (file)
@@ -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;
 
index 395bc70f2cfc90f33d3f49d9a6025cb9a067836b..8fb632d9dcf1f7832408d2ee8167774ddb1f2908 100644 (file)
@@ -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 );
 }
 
 
index 7131512daeee012cb00f56f5d167dee1875efb0e..dbe4c0eb67e44a457f6e95e47fa921e5a195b385 100644 (file)
@@ -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 );
index 16a2897f52663074428f0f0233f3d6ce78b84512..7a2d3715f8bb8ccfd6582409137d42ce4425ecad 100644 (file)
@@ -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,