r300-gallium: r500-fs: Add shader dumper and more tex work.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 11 Mar 2009 21:26:25 +0000 (14:26 -0700)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 11 Mar 2009 22:23:09 +0000 (15:23 -0700)
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r300/r300_debug.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_debug.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_state_shader.c
src/gallium/drivers/r300/r300_state_shader.h

index 4c400bff580cd274e8721431c3b38a281120d3fa..0e4e11553252758d4f693c34a56cc2993afe4d27 100644 (file)
@@ -7,6 +7,7 @@ C_SOURCES = \
        r300_chipset.c \
        r300_clear.c \
        r300_context.c \
+       r300_debug.c \
        r300_emit.c \
        r300_flush.c \
        r300_query.c \
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
new file mode 100644 (file)
index 0000000..4c6d2a2
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+#include "r300_debug.h"
+
+static char* r500_fs_swiz[] = {
+    " R",
+    " G",
+    " B",
+    " A",
+    " 0",
+    ".5",
+    " 1",
+    " U",
+};
+
+static char* r500_fs_op_rgb[] = {
+    "MAD",
+    "DP3",
+    "DP4",
+    "D2A",
+    "MIN",
+    "MAX",
+    "---",
+    "CND",
+    "CMP",
+    "FRC",
+    "SOP",
+    "MDH",
+    "MDV",
+};
+
+static char* r500_fs_op_alpha[] = {
+    "MAD",
+    " DP",
+    "MIN",
+    "MAX",
+    "---",
+    "CND",
+    "CMP",
+    "FRC",
+    "EX2",
+    "LN2",
+    "RCP",
+    "RSQ",
+    "SIN",
+    "COS",
+    "MDH",
+    "MDV",
+};
+
+static char* r500_fs_mask[] = {
+    "NONE",
+    "R   ",
+    " G  ",
+    "RG  ",
+    "  B ",
+    "R B ",
+    " GB ",
+    "RGB ",
+    "   A",
+    "R  A",
+    " G A",
+    "RG A",
+    "  BA",
+    "R BA",
+    " GBA",
+    "RGBA",
+};
+
+static char* r500_fs_tex[] = {
+    "    NOP",
+    "     LD",
+    "TEXKILL",
+    "   PROJ",
+    "LODBIAS",
+    "    LOD",
+    "   DXDY",
+};
+
+void r500_fs_dump(struct r500_fragment_shader* fs)
+{
+    int i;
+    uint32_t inst;
+
+    for (i = 0; i < fs->instruction_count; i++) {
+        inst = fs->instructions[i].inst0;
+        debug_printf("%d:  0: CMN_INST   0x%08x:", i, inst);
+        switch (inst & 0x3) {
+            case R500_INST_TYPE_ALU:
+                debug_printf("ALU ");
+                break;
+            case R500_INST_TYPE_OUT:
+                debug_printf("OUT ");
+                break;
+            case R500_INST_TYPE_FC:
+                debug_printf("FC  ");
+                break;
+            case R500_INST_TYPE_TEX:
+                debug_printf("TEX ");
+                break;
+        }
+        debug_printf("%s %s %s %s ",
+                inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "",
+                inst & R500_INST_LAST ? "LAST" : "",
+                inst & R500_INST_NOP ? "NOP" : "",
+                inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");
+        debug_printf("wmask: %s omask: %s\n",
+                r500_fs_mask[(inst >> 11) & 0xf],
+                r500_fs_mask[(inst >> 15) & 0xf]);
+        switch (inst & 0x3) {
+            case R500_INST_TYPE_ALU:
+            case R500_INST_TYPE_OUT:
+                inst = fs->instructions[i].inst1;
+                debug_printf("    1: RGB_ADDR   0x%08x:", inst);
+                debug_printf("Addr0: %d%c, Addr1: %d%c, "
+                        "Addr2: %d%c, srcp:%d\n",
+                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
+                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
+                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
+                        (inst >> 30));
+
+                inst = fs->instructions[i].inst2;
+                debug_printf("    2: ALPHA_ADDR 0x%08x:", inst);
+                debug_printf("Addr0: %d%c, Addr1: %d%c, "
+                        "Addr2: %d%c, srcp:%d\n",
+                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
+                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
+                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
+                        (inst >> 30));
+
+                inst = fs->instructions[i].inst3;
+                debug_printf("    3: RGB_INST   0x%08x:", inst);
+                debug_printf("rgb_A_src:%d %s/%s/%s %d "
+                        "rgb_B_src:%d %s/%s/%s %d\n",
+                        inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7],
+                        r500_fs_swiz[(inst >> 5) & 0x7],
+                        r500_fs_swiz[(inst >> 8) & 0x7],
+                        (inst >> 11) & 0x3, (inst >> 13) & 0x3,
+                        r500_fs_swiz[(inst >> 15) & 0x7],
+                        r500_fs_swiz[(inst >> 18) & 0x7],
+                        r500_fs_swiz[(inst >> 21) & 0x7],
+                        (inst >> 24) & 0x3);
+
+                inst = fs->instructions[i].inst4;
+                debug_printf("    4: ALPHA_INST 0x%08x:", inst);
+                debug_printf("%s dest:%d%s alp_A_src:%d %s %d "
+                        "alp_B_src:%d %s %d w:%d\n",
+                        r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
+                        inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
+                        r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
+                        (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7],
+                        (inst >> 24) & 0x3, (inst >> 31) & 0x1);
+
+                inst = fs->instructions[i].inst5;
+                debug_printf("    5: RGBA_INST  0x%08x:", inst);
+                debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d "
+                        "alp_C_src:%d %s %d\n",
+                        r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
+                        inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
+                        r500_fs_swiz[(inst >> 14) & 0x7],
+                        r500_fs_swiz[(inst >> 17) & 0x7],
+                        r500_fs_swiz[(inst >> 20) & 0x7],
+                        (inst >> 23) & 0x3, (inst >> 25) & 0x3,
+                        r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
+                break;
+            case R500_INST_TYPE_FC:
+                /* XXX don't even bother yet */
+                break;
+            case R500_INST_TYPE_TEX:
+                inst = fs->instructions[i].inst1;
+                debug_printf("    1: TEX_INST  0x%08x: id: %d "
+                        "op:%s, %s, %s %s\n",
+                        inst, (inst >> 16) & 0xf,
+                        r500_fs_tex[(inst >> 22) & 0x7],
+                        (inst & (1 << 25)) ? "ACQ" : "",
+                        (inst & (1 << 26)) ? "IGNUNC" : "",
+                        (inst & (1 << 27)) ? "UNSCALED" : "SCALED");
+
+                inst = fs->instructions[i].inst2;
+                debug_printf("    2: TEX_ADDR  0x%08x: "
+                        "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",
+                        inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "",
+                        r500_fs_swiz[(inst >> 8) & 0x7],
+                        r500_fs_swiz[(inst >> 10) & 0x7],
+                        r500_fs_swiz[(inst >> 12) & 0x7],
+                        r500_fs_swiz[(inst >> 14) & 0x7],
+                        (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "",
+                        r500_fs_swiz[(inst >> 24) & 0x7],
+                        r500_fs_swiz[(inst >> 26) & 0x7],
+                        r500_fs_swiz[(inst >> 28) & 0x7],
+                        r500_fs_swiz[(inst >> 30) & 0x7]);
+                
+                inst = fs->instructions[i].inst3;
+                debug_printf("    3: TEX_DXDY  0x%08x\n", inst);
+                break;
+        }
+    }
+}
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
new file mode 100644 (file)
index 0000000..de5d701
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on 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
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+#ifndef R300_DEBUG_H
+#define R300_DEBUG_H
+
+#include "r300_reg.h"
+#include "r300_state_shader.h"
+
+void r500_fs_dump(struct r500_fragment_shader* fs);
+
+#endif /* R300_DEBUG_H */
index 07705adaf40ca3806e51e8c1650c218578930cfc..7629bfb1f433ced04bd46e215dce3c6ee8b6adc7 100644 (file)
@@ -60,6 +60,9 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
             break;
         case TGSI_FILE_OUTPUT:
             break;
+        case TGSI_FILE_TEMPORARY:
+            assembler->temp_count++;
+            break;
         default:
             debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
             break;
@@ -68,6 +71,41 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
     assembler->temp_offset = assembler->color_count + assembler->tex_count;
 }
 
+static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler,
+                                   struct tgsi_src_register* src)
+{
+    switch (src->File) {
+        case TGSI_FILE_INPUT:
+            /* XXX may be wrong */
+            return src->Index;
+            break;
+        case TGSI_FILE_TEMPORARY:
+            return src->Index + assembler->temp_offset;
+            break;
+        default:
+            debug_printf("r300: fs: Unimplemented src %d\n", src->File);
+            break;
+    }
+    return 0;
+}
+
+static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
+                                   struct tgsi_dst_register* dst)
+{
+    switch (dst->File) {
+        case TGSI_FILE_OUTPUT:
+            return 0;
+            break;
+        case TGSI_FILE_TEMPORARY:
+            return dst->Index + assembler->temp_offset;
+            break;
+        default:
+            debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
+            break;
+    }
+    return 0;
+}
+
 static INLINE unsigned r500_fix_swiz(unsigned s)
 {
     /* For historical reasons, the swizzle values x, y, z, w, and 0 are
@@ -80,25 +118,31 @@ static INLINE unsigned r500_fix_swiz(unsigned s)
     }
 }
 
-static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg)
+static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg)
 {
     if (reg->SrcRegister.Extended) {
         return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
             (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
-            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6);
+            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
+            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
     } else {
-        return reg->SrcRegister.SwizzleX | (reg->SrcRegister.SwizzleY << 3) |
-            (reg->SrcRegister.SwizzleZ << 6);
+        return reg->SrcRegister.SwizzleX |
+            (reg->SrcRegister.SwizzleY << 3) |
+            (reg->SrcRegister.SwizzleZ << 6) |
+            (reg->SrcRegister.SwizzleW << 9);
     }
 }
 
+static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg)
+{
+    /* Only the first 9 bits... */
+    return r500_rgba_swiz(reg) & 0x1ff;
+}
+
 static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg)
 {
-    if (reg->SrcRegister.Extended) {
-        return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW);
-    } else {
-        return reg->SrcRegister.SwizzleW;
-    }
+    /* Only the last 3 bits... */
+    return r500_rgba_swiz(reg) >> 9;
 }
 
 static INLINE void r500_emit_mov(struct r500_fragment_shader* fs,
@@ -107,16 +151,15 @@ static INLINE void r500_emit_mov(struct r500_fragment_shader* fs,
                                  struct tgsi_full_dst_register* dst)
 {
     int i = fs->instruction_count;
+
     fs->instructions[i].inst0 = R500_INST_TYPE_OUT |
         R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
         R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
         R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
     fs->instructions[i].inst1 =
-        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
-        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST;
+        R500_RGB_ADDR0(r300_fs_src(assembler, &src->SrcRegister));
     fs->instructions[i].inst2 =
-        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
-        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST;
+        R500_ALPHA_ADDR0(r300_fs_src(assembler, &src->SrcRegister));
     fs->instructions[i].inst3 = R500_ALU_RGB_SEL_A_SRC0 |
         R500_SWIZ_RGB_A(r500_rgb_swiz(src)) |
         R500_ALU_RGB_SEL_B_SRC0 |
@@ -132,6 +175,27 @@ static INLINE void r500_emit_mov(struct r500_fragment_shader* fs,
     fs->instruction_count++;
 }
 
+static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
+                                 struct r300_fs_asm* assembler,
+                                 uint32_t op,
+                                 struct tgsi_full_src_register* src,
+                                 struct tgsi_full_dst_register* dst)
+{
+    int i = fs->instruction_count;
+
+    fs->instructions[i].inst0 = R500_INST_TYPE_TEX |
+        R500_INST_TEX_SEM_WAIT;
+    fs->instructions[i].inst1 = R500_TEX_ID(0) |
+        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED |
+        R500_TEX_INST_PROJ;
+    fs->instructions[i].inst2 =
+        R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
+        R500_SWIZ_TEX_STRQ(r500_rgba_swiz(src)) |
+        R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
+        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
+        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
+}
+
 static void r500_fs_instruction(struct r500_fragment_shader* fs,
                                 struct r300_fs_asm* assembler,
                                 struct tgsi_full_instruction* inst)
@@ -145,6 +209,10 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
             r500_emit_mov(fs, assembler, &inst->FullSrcRegisters[0],
                     &inst->FullDstRegisters[0]);
             break;
+        case TGSI_OPCODE_TXP:
+            r500_emit_tex(fs, assembler, 0, &inst->FullSrcRegisters[0],
+                    &inst->FullDstRegisters[0]);
+            break;
         case TGSI_OPCODE_END:
             break;
         default:
@@ -205,6 +273,7 @@ void r500_translate_fragment_shader(struct r300_context* r300,
     fs->shader.stack_size = assembler->temp_offset;
 
     tgsi_dump(fs->shader.state.tokens);
+    r500_fs_dump(fs);
 
     //r500_copy_passthrough_shader(fs);
 
index 410926a26a502ac0a40bc200dd13347f83b49e5f..a74dce47641358c3a2cb1eddbc50b1ee9a55cfd0 100644 (file)
@@ -26,6 +26,7 @@
 #include "tgsi/tgsi_parse.h"
 
 #include "r300_context.h"
+#include "r300_debug.h"
 #include "r300_reg.h"
 #include "r300_screen.h"
 
@@ -63,6 +64,8 @@ struct r300_fs_asm {
      * distinguishing markings, so inputs start at 0 and the first usable
      * temporary register is after all inputs. */
     unsigned temp_offset;
+    /* Number of requested temporary registers. */
+    unsigned temp_count;
 };
 
 void r300_translate_fragment_shader(struct r300_context* r300,