gallium: disable early Z test if fragment shader contains KIL instruction.
authorBrian <brian.paul@tungstengraphics.com>
Sat, 23 Feb 2008 23:17:17 +0000 (16:17 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Sat, 23 Feb 2008 23:17:17 +0000 (16:17 -0700)
Use tgsi_scan_shader() to determine if the fragment shader uses KIL or
writes fragment.z

src/gallium/drivers/softpipe/sp_quad.c
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_fs.c

index 15b5594547dec9b21080001e39155b4d940d5a8b..142dbcc77106c97cffed3772287ff892362aeaaa 100644 (file)
@@ -56,11 +56,12 @@ sp_build_depth_stencil(
 void
 sp_build_quad_pipeline(struct softpipe_context *sp)
 {
-   boolean  early_depth_test =
+   boolean early_depth_test =
                sp->depth_stencil->depth.enabled &&
                sp->framebuffer.zsbuf &&
                !sp->depth_stencil->alpha.enabled &&
-               sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION;
+               !sp->fs->uses_kill &&
+               !sp->fs->writes_z;
 
    /* build up the pipeline in reverse order... */
 
index 6ff31e601ff26f87e992d79d3970900c2c02b012..5aaa9e346bcfb5d94d9752e5b6f728faf0e373cd 100644 (file)
@@ -63,6 +63,9 @@ struct tgsi_exec_machine;
 struct sp_fragment_shader {
    struct pipe_shader_state   shader;
 
+   boolean uses_kill;
+   boolean writes_z;
+
    void (*prepare)( const struct sp_fragment_shader *shader,
                    struct tgsi_exec_machine *machine,
                    struct tgsi_sampler *samplers);
index b0238f817376ecafcc13a5d70bb85f35d5f76fe2..b184ac61bb9957f0b775063ce893e5b03a05fe1a 100644 (file)
@@ -36,6 +36,7 @@
 #include "pipe/p_shader_tokens.h"
 #include "draw/draw_context.h"
 #include "tgsi/util/tgsi_dump.h"
+#include "tgsi/util/tgsi_scan.h"
 
 
 void *
@@ -44,21 +45,24 @@ softpipe_create_fs_state(struct pipe_context *pipe,
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
    struct sp_fragment_shader *state;
+   struct tgsi_shader_info info;
+
+   tgsi_scan_shader(templ->tokens, &info);
 
    if (softpipe->dump_fs) 
       tgsi_dump(templ->tokens, 0);
 
    state = softpipe_create_fs_llvm( softpipe, templ );
-   if (state)
-      return state;
-   
-   state = softpipe_create_fs_sse( softpipe, templ );
-   if (state)
-      return state;
-
-   state = softpipe_create_fs_exec( softpipe, templ );
-
+   if (!state) {
+      state = softpipe_create_fs_sse( softpipe, templ );
+      if (!state) {
+         state = softpipe_create_fs_exec( softpipe, templ );
+      }
+   }
    assert(state);
+   state->uses_kill = (info.opcode_count[TGSI_OPCODE_KIL] ||
+                       info.opcode_count[TGSI_OPCODE_KILP]);
+   state->writes_z = info.writes_z;
    return state;
 }