r300-gallium: r500-fs: Enable depth writes, kinda.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Sun, 17 May 2009 17:30:59 +0000 (10:30 -0700)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Sun, 17 May 2009 17:30:59 +0000 (10:30 -0700)
Should work, but doesn't. Hm.

src/gallium/drivers/r300/r300_state_shader.c
src/gallium/drivers/r300/r300_state_shader.h

index 1b02239ee763201036b54b0447499524353b6d02..7257638dbeda62af4b1f1de4e526ccbf56c45c7a 100644 (file)
@@ -59,6 +59,12 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
             }
             break;
         case TGSI_FILE_OUTPUT:
+            /* Depth write. Mark the position of the output so we can
+             * identify it later. */
+            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
+                assembler->depth_output = decl->DeclarationRange.First;
+            }
+            break;
         case TGSI_FILE_CONSTANT:
             break;
         case TGSI_FILE_TEMPORARY:
@@ -120,6 +126,14 @@ static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
     return 0;
 }
 
+static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
+                                      struct tgsi_dst_register* dst)
+{
+    return (assembler->writes_depth &&
+            (dst->File == TGSI_FILE_OUTPUT) &&
+            (dst->Index == assembler->depth_output));
+}
+
 static INLINE unsigned r500_fix_swiz(unsigned s)
 {
     /* For historical reasons, the swizzle values x, y, z, w, and 0 are
@@ -302,16 +316,21 @@ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
     int i = fs->instruction_count;
 
     if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
-        fs->instructions[i].inst0 = R500_INST_TYPE_OUT |
-        R500_ALU_OMASK(dst->DstRegister.WriteMask);
+        fs->instructions[i].inst0 = R500_INST_TYPE_OUT;
+        if (r300_fs_is_depr(assembler, dst)) {
+            fs->instructions[i].inst4 = R500_W_OMASK;
+        } else {
+            fs->instructions[i].inst0 |=
+                R500_ALU_OMASK(dst->DstRegister.WriteMask);
+        }
     } else {
         fs->instructions[i].inst0 = R500_INST_TYPE_ALU |
-        R500_ALU_WMASK(dst->DstRegister.WriteMask);
+            R500_ALU_WMASK(dst->DstRegister.WriteMask);
     }
 
     fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
 
-    fs->instructions[i].inst4 =
+    fs->instructions[i].inst4 |=
         R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
     fs->instructions[i].inst5 =
         R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
@@ -581,6 +600,8 @@ void r300_translate_fragment_shader(struct r300_context* r300,
     }
     /* Setup starting offset for immediates. */
     assembler->imm_offset = consts->user_count;
+    /* Enable depth writes, if needed. */
+    assembler->writes_depth = fs->info.writes_z;
 
     /* Make sure we start at the beginning of the shader. */
     if (is_r500) {
index 185fdd90f0cd93a1c59c0a78b975ade035f2d998..f4fb31d86c95c0a88ebf5093db5693ee0ca8d87a 100644 (file)
@@ -57,6 +57,7 @@
 #define R500_TEX_WMASK(x) ((x) << 11)
 #define R500_ALU_WMASK(x) ((x) << 11)
 #define R500_ALU_OMASK(x) ((x) << 15)
+#define R500_W_OMASK (1 << 31)
 
 /* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
  * not using enough of it. */
@@ -99,6 +100,11 @@ struct r300_fs_asm {
     unsigned imm_offset;
     /* Number of immediate constants. */
     unsigned imm_count;
+    /* Are depth writes enabled? */
+    boolean writes_depth;
+    /* Depth write offset. This is the TGSI output that corresponds to
+     * depth writes. */
+    unsigned depth_output;
 };
 
 void r300_translate_fragment_shader(struct r300_context* r300,