r300g: Use radeon compiler for fragment programs
authorNicolai Hähnle <nhaehnle@gmail.com>
Thu, 30 Jul 2009 21:45:34 +0000 (23:45 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Thu, 30 Jul 2009 21:55:12 +0000 (23:55 +0200)
This is entirely untested on R500, and needs more testing on R300.

17 files changed:
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_debug.c [deleted file]
src/gallium/drivers/r300/r300_debug.h [deleted file]
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
src/gallium/drivers/r300/r300_fs.c
src/gallium/drivers/r300/r300_fs.h
src/gallium/drivers/r300/r300_fs_inlines.h [deleted file]
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_surface.c
src/gallium/drivers/r300/r300_tgsi_to_rc.c
src/gallium/drivers/r300/r3xx_fs.c
src/gallium/drivers/r300/r3xx_fs.h
src/gallium/drivers/r300/r5xx_fs.c
src/gallium/drivers/r300/r5xx_fs.h

index 93c2152..d7a2c8c 100644 (file)
@@ -9,7 +9,6 @@ C_SOURCES = \
        r300_chipset.c \
        r300_clear.c \
        r300_context.c \
-       r300_debug.c \
        r300_emit.c \
        r300_flush.c \
        r300_fs.c \
index c1ef64e..6984225 100644 (file)
@@ -34,6 +34,7 @@
 #include "r300_screen.h"
 #include "r300_winsys.h"
 
+struct r300_fragment_shader;
 struct r300_vertex_shader;
 
 struct r300_blend_state {
@@ -151,65 +152,6 @@ struct r300_constant_buffer {
     unsigned count;
 };
 
-struct r300_fragment_shader {
-    /* Parent class */
-    struct pipe_shader_state state;
-    struct tgsi_shader_info info;
-
-    /* Has this shader been translated yet? */
-    boolean translated;
-
-    /* Pixel stack size */
-    int stack_size;
-
-    /* Are there immediates in this shader?
-     * If not, we can heavily optimize recompilation. */
-    boolean uses_imms;
-};
-
-struct r3xx_fragment_shader {
-    /* Parent class */
-    struct r300_fragment_shader shader;
-
-    /* Number of ALU instructions */
-    int alu_instruction_count;
-
-    /* Number of texture instructions */
-    int tex_instruction_count;
-
-    /* Number of texture indirections */
-    int indirections;
-
-    /* Indirection node offsets */
-    int alu_offset[4];
-
-    /* Machine instructions */
-    struct {
-        uint32_t alu_rgb_inst;
-        uint32_t alu_rgb_addr;
-        uint32_t alu_alpha_inst;
-        uint32_t alu_alpha_addr;
-    } instructions[64]; /* XXX magic num */
-};
-
-struct r5xx_fragment_shader {
-    /* Parent class */
-    struct r300_fragment_shader shader;
-
-    /* Number of used instructions */
-    int instruction_count;
-
-    /* Machine instructions */
-    struct {
-        uint32_t inst0;
-        uint32_t inst1;
-        uint32_t inst2;
-        uint32_t inst3;
-        uint32_t inst4;
-        uint32_t inst5;
-    } instructions[256]; /*< XXX magic number */
-};
-
 struct r300_texture {
     /* Parent class */
     struct pipe_texture tex;
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
deleted file mode 100644 (file)
index aae8a4f..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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* r5xx_fs_swiz[] = {
-    " R",
-    " G",
-    " B",
-    " A",
-    " 0",
-    ".5",
-    " 1",
-    " U",
-};
-
-static char* r5xx_fs_op_rgb[] = {
-    "MAD",
-    "DP3",
-    "DP4",
-    "D2A",
-    "MIN",
-    "MAX",
-    "---",
-    "CND",
-    "CMP",
-    "FRC",
-    "SOP",
-    "MDH",
-    "MDV",
-};
-
-static char* r5xx_fs_op_alpha[] = {
-    "MAD",
-    " DP",
-    "MIN",
-    "MAX",
-    "---",
-    "CND",
-    "CMP",
-    "FRC",
-    "EX2",
-    "LN2",
-    "RCP",
-    "RSQ",
-    "SIN",
-    "COS",
-    "MDH",
-    "MDV",
-};
-
-static char* r5xx_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* r5xx_fs_tex[] = {
-    "    NOP",
-    "     LD",
-    "TEXKILL",
-    "   PROJ",
-    "LODBIAS",
-    "    LOD",
-    "   DXDY",
-};
-
-
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs)
-{
-    int i;
-
-    for (i = 0; i < fs->alu_instruction_count; i++) {
-    }
-}
-
-void r5xx_fs_dump(struct r5xx_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",
-                r5xx_fs_mask[(inst >> 11) & 0xf],
-                r5xx_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, r5xx_fs_swiz[(inst >> 2) & 0x7],
-                        r5xx_fs_swiz[(inst >> 5) & 0x7],
-                        r5xx_fs_swiz[(inst >> 8) & 0x7],
-                        (inst >> 11) & 0x3, (inst >> 13) & 0x3,
-                        r5xx_fs_swiz[(inst >> 15) & 0x7],
-                        r5xx_fs_swiz[(inst >> 18) & 0x7],
-                        r5xx_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",
-                        r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
-                        inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
-                        r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
-                        (inst >> 19) & 0x3, r5xx_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",
-                        r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
-                        inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
-                        r5xx_fs_swiz[(inst >> 14) & 0x7],
-                        r5xx_fs_swiz[(inst >> 17) & 0x7],
-                        r5xx_fs_swiz[(inst >> 20) & 0x7],
-                        (inst >> 23) & 0x3, (inst >> 25) & 0x3,
-                        r5xx_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,
-                        r5xx_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)" : "",
-                        r5xx_fs_swiz[(inst >> 8) & 0x3],
-                        r5xx_fs_swiz[(inst >> 10) & 0x3],
-                        r5xx_fs_swiz[(inst >> 12) & 0x3],
-                        r5xx_fs_swiz[(inst >> 14) & 0x3],
-                        (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "",
-                        r5xx_fs_swiz[(inst >> 24) & 0x3],
-                        r5xx_fs_swiz[(inst >> 26) & 0x3],
-                        r5xx_fs_swiz[(inst >> 28) & 0x3],
-                        r5xx_fs_swiz[(inst >> 30) & 0x3]);
-
-                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
deleted file mode 100644 (file)
index c551bd5..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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_fs.h"
-#include "r300_vs.h"
-
-void r5xx_fs_dump(struct r5xx_fragment_shader* fs);
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs);
-
-void r300_vs_dump(struct r300_vertex_shader* vs);
-
-#endif /* R300_DEBUG_H */
index e9ca4ac..e0c38a0 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "r300_emit.h"
 
+#include "r300_fs.h"
 #include "r300_vs.h"
 
 void r300_emit_blend_state(struct r300_context* r300,
@@ -111,73 +112,158 @@ void r300_emit_dsa_state(struct r300_context* r300,
     END_CS;
 }
 
-void r300_emit_fragment_shader(struct r300_context* r300,
-                               struct r3xx_fragment_shader* fs)
+static const float * get_shader_constant(
+    struct r300_context * r300,
+    struct rc_constant * constant,
+    struct r300_constant_buffer * externals)
+{
+    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+    switch(constant->Type) {
+        case RC_CONSTANT_EXTERNAL:
+            return externals->constants[constant->u.External];
+
+        case RC_CONSTANT_IMMEDIATE:
+            return constant->u.Immediate;
+
+        default:
+            debug_printf("r300: Implementation error: Unhandled constant type %i\n",
+                constant->Type);
+            return zero;
+    }
+}
+
+/* Convert a normal single-precision float into the 7.16 format
+ * used by the R300 fragment shader.
+ */
+static uint32_t pack_float24(float f)
+{
+    union {
+        float fl;
+        uint32_t u;
+    } u;
+    float mantissa;
+    int exponent;
+    uint32_t float24 = 0;
+
+    if (f == 0.0)
+        return 0;
+
+    u.fl = f;
+
+    mantissa = frexpf(f, &exponent);
+
+    /* Handle -ve */
+    if (mantissa < 0) {
+        float24 |= (1 << 23);
+        mantissa = mantissa * -1.0;
+    }
+    /* Handle exponent, bias of 63 */
+    exponent += 62;
+    float24 |= (exponent << 16);
+    /* Kill 7 LSB of mantissa */
+    float24 |= (u.u & 0x7FFFFF) >> 7;
+
+    return float24;
+}
+
+void r300_emit_fragment_program_code(struct r300_context* r300,
+                                     struct rX00_fragment_program_code* generic_code,
+                                     struct r300_constant_buffer* externals)
 {
+    struct r300_fragment_program_code * code = &generic_code->code.r300;
+    struct rc_constant_list * constants = &generic_code->constants;
     int i;
     CS_LOCALS(r300);
 
-    BEGIN_CS(22);
-
-    OUT_CS_REG(R300_US_CONFIG, fs->indirections);
-    OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size);
-    /* XXX figure out exactly how big the sizes are on this reg */
-    OUT_CS_REG(R300_US_CODE_OFFSET, 0x40);
-    /* XXX figure these ones out a bit better kthnx */
-    OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
-    OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
-    OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
-    OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT);
-
-    for (i = 0; i < fs->alu_instruction_count; i++) {
-        OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i),
-            fs->instructions[i].alu_rgb_inst);
-        OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i),
-            fs->instructions[i].alu_rgb_addr);
-        OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i),
-            fs->instructions[i].alu_alpha_inst);
-        OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i),
-            fs->instructions[i].alu_alpha_addr);
+    BEGIN_CS(15 +
+             code->alu.length * 4 +
+             (code->tex.length ? (1 + code->tex.length) : 0) +
+             (constants->Count ? (1 + constants->Count * 4) : 0));
+
+    OUT_CS_REG(R300_US_CONFIG, code->config);
+    OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
+    OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset);
+
+    OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4);
+    for(i = 0; i < 4; ++i)
+        OUT_CS(code->code_addr[i]);
+
+    OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++)
+        OUT_CS(code->alu.inst[i].rgb_inst);
+
+    OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++)
+        OUT_CS(code->alu.inst[i].rgb_addr);
+
+    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++)
+        OUT_CS(code->alu.inst[i].alpha_inst);
+
+    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
+    for (i = 0; i < code->alu.length; i++)
+        OUT_CS(code->alu.inst[i].alpha_addr);
+
+    if (code->tex.length) {
+        OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length);
+        for(i = 0; i < code->tex.length; ++i)
+            OUT_CS(code->tex.inst[i]);
+    }
+
+    if (constants->Count) {
+        OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4);
+        for(i = 0; i < constants->Count; ++i) {
+            const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+            OUT_CS(pack_float24(data[0]));
+            OUT_CS(pack_float24(data[1]));
+            OUT_CS(pack_float24(data[2]));
+            OUT_CS(pack_float24(data[3]));
+        }
     }
 
     END_CS;
 }
 
-void r500_emit_fragment_shader(struct r300_context* r300,
-                               struct r5xx_fragment_shader* fs)
+void r500_emit_fragment_program_code(struct r300_context* r300,
+                                     struct rX00_fragment_program_code* generic_code,
+                                     struct r300_constant_buffer* externals)
 {
+    struct r500_fragment_program_code * code = &generic_code->code.r500;
+    struct rc_constant_list * constants = &generic_code->constants;
     int i;
-    struct r300_constant_buffer* constants =
-        &r300->shader_constants[PIPE_SHADER_FRAGMENT];
     CS_LOCALS(r300);
 
-    BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) +
-            (constants->count * 4));
-    OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
-    OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size);
-    OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) |
-            R500_US_CODE_END_ADDR(fs->instruction_count));
+    BEGIN_CS(13 +
+             ((code->inst_end + 1) * 6) +
+             (constants->Count ? (3 + (constants->Count * 4)) : 0));
+    OUT_CS_REG(R500_US_CONFIG, 0);
+    OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
+    OUT_CS_REG(R500_US_CODE_RANGE,
+               R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
+    OUT_CS_REG(R500_US_CODE_OFFSET, 0);
+    OUT_CS_REG(R500_US_CODE_ADDR,
+               R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end));
 
     OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR);
-    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6);
-    for (i = 0; i < fs->instruction_count; i++) {
-        OUT_CS(fs->instructions[i].inst0);
-        OUT_CS(fs->instructions[i].inst1);
-        OUT_CS(fs->instructions[i].inst2);
-        OUT_CS(fs->instructions[i].inst3);
-        OUT_CS(fs->instructions[i].inst4);
-        OUT_CS(fs->instructions[i].inst5);
-    }
-
-    if (constants->count) {
-        OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
-                R500_GA_US_VECTOR_INDEX_TYPE_CONST);
-        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4);
-        for (i = 0; i < constants->count; i++) {
-            OUT_CS_32F(constants->constants[i][0]);
-            OUT_CS_32F(constants->constants[i][1]);
-            OUT_CS_32F(constants->constants[i][2]);
-            OUT_CS_32F(constants->constants[i][3]);
+    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6);
+    for (i = 0; i <= code->inst_end; i++) {
+        OUT_CS(code->inst[i].inst0);
+        OUT_CS(code->inst[i].inst1);
+        OUT_CS(code->inst[i].inst2);
+        OUT_CS(code->inst[i].inst3);
+        OUT_CS(code->inst[i].inst4);
+        OUT_CS(code->inst[i].inst5);
+    }
+
+    if (constants->Count) {
+        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
+        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
+        for (i = 0; i < constants->Count; i++) {
+            const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+            OUT_CS_32F(data[0]);
+            OUT_CS_32F(data[1]);
+            OUT_CS_32F(data[2]);
+            OUT_CS_32F(data[3]);
         }
     }
 
@@ -382,26 +468,6 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
     END_CS;
 }
 
-static const float * get_shader_constant(
-    struct r300_context * r300,
-    struct rc_constant * constant,
-    struct r300_constant_buffer * externals)
-{
-    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
-    switch(constant->Type) {
-        case RC_CONSTANT_EXTERNAL:
-            return externals->constants[constant->u.External];
-
-        case RC_CONSTANT_IMMEDIATE:
-            return constant->u.Immediate;
-
-        default:
-            debug_printf("r300: Implementation error: Unhandled constant type %i\n",
-                constant->Type);
-            return zero;
-    }
-}
-
 void r300_emit_vertex_program_code(struct r300_context* r300,
                                    struct r300_vertex_program_code* code,
                                    struct r300_constant_buffer* constants)
@@ -589,11 +655,9 @@ validate:
 
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
         if (r300screen->caps->is_r500) {
-            r500_emit_fragment_shader(r300,
-                (struct r5xx_fragment_shader*)r300->fs);
+            r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
         } else {
-            r300_emit_fragment_shader(r300,
-                (struct r3xx_fragment_shader*)r300->fs);
+            r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
     }
index fbc6487..350691d 100644 (file)
@@ -30,6 +30,7 @@
 #include "r300_screen.h"
 #include "r300_state_inlines.h"
 
+struct rX00_fragment_program_code;
 struct r300_vertex_program_code;
 
 void r300_emit_blend_state(struct r300_context* r300,
@@ -44,11 +45,13 @@ void r300_emit_clip_state(struct r300_context* r300,
 void r300_emit_dsa_state(struct r300_context* r300,
                          struct r300_dsa_state* dsa);
 
-void r300_emit_fragment_shader(struct r300_context* r300,
-                               struct r3xx_fragment_shader* fs);
+void r300_emit_fragment_program_code(struct r300_context* r300,
+                                     struct rX00_fragment_program_code* generic_code,
+                                     struct r300_constant_buffer* externals);
 
-void r500_emit_fragment_shader(struct r300_context* r300,
-                               struct r5xx_fragment_shader* fs);
+void r500_emit_fragment_program_code(struct r300_context* r300,
+                                     struct rX00_fragment_program_code* generic_code,
+                                     struct r300_constant_buffer* externals);
 
 void r300_emit_fb_state(struct r300_context* r300,
                         struct pipe_framebuffer_state* fb);
index ca8ef99..2cddb97 100644 (file)
 
 #include "r300_fs.h"
 
-void r300_translate_fragment_shader(struct r300_context* r300,
-                                    struct r300_fragment_shader* fs)
-{
-    struct tgsi_parse_context parser;
-    int i;
-    boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
-    struct r300_constant_buffer* consts =
-        &r300->shader_constants[PIPE_SHADER_FRAGMENT];
+#include "r300_tgsi_to_rc.h"
 
-    struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
-    if (assembler == NULL) {
-        return;
-    }
-    /* 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) {
-        ((struct r5xx_fragment_shader*)fs)->instruction_count = 0;
-    }
+#include "radeon_compiler.h"
 
-    tgsi_parse_init(&parser, fs->state.tokens);
+static void find_output_registers(struct r300_fragment_program_compiler * compiler,
+                                  struct r300_fragment_shader * fs)
+{
+    unsigned i;
 
-    while (!tgsi_parse_end_of_tokens(&parser)) {
-        tgsi_parse_token(&parser);
+    /* Mark the outputs as not present initially */
+    compiler->OutputColor = fs->info.num_outputs;
+    compiler->OutputDepth = fs->info.num_outputs;
 
-        /* This is seriously the lamest way to create fragment programs ever.
-         * I blame TGSI. */
-        switch (parser.FullToken.Token.Type) {
-            case TGSI_TOKEN_TYPE_DECLARATION:
-                /* Allocated registers sitting at the beginning
-                 * of the program. */
-                r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
+    /* Now see where they really are. */
+    for(i = 0; i < fs->info.num_outputs; ++i) {
+        switch(fs->info.output_semantic_name[i]) {
+            case TGSI_SEMANTIC_COLOR:
+                compiler->OutputColor = i;
+                break;
+            case TGSI_SEMANTIC_POSITION:
+                compiler->OutputDepth = i;
                 break;
-            case TGSI_TOKEN_TYPE_IMMEDIATE:
-                debug_printf("r300: Emitting immediate to constant buffer, "
-                        "position %d\n",
-                        assembler->imm_offset + assembler->imm_count);
-                /* I am not amused by the length of these. */
-                for (i = 0; i < 4; i++) {
-                    consts->constants[assembler->imm_offset +
-                        assembler->imm_count][i] =
-                        parser.FullToken.FullImmediate.u[i].Float;
-                }
-                assembler->imm_count++;
+        }
+    }
+}
+
+static void allocate_hardware_inputs(
+    struct r300_fragment_program_compiler * c,
+    void (*allocate)(void * data, unsigned input, unsigned hwreg),
+    void * mydata)
+{
+    struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info;
+    int total_colors = 0;
+    int colors = 0;
+    int total_generic = 0;
+    int generic = 0;
+    int i;
+
+    for (i = 0; i < info->num_inputs; i++) {
+        switch (info->input_semantic_name[i]) {
+            case TGSI_SEMANTIC_COLOR:
+                total_colors++;
                 break;
-            case TGSI_TOKEN_TYPE_INSTRUCTION:
-                if (is_r500) {
-                    r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
-                            assembler, &parser.FullToken.FullInstruction);
-                } else {
-                    r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
-                            assembler, &parser.FullToken.FullInstruction);
-                }
+            case TGSI_SEMANTIC_FOG:
+            case TGSI_SEMANTIC_GENERIC:
+                total_generic++;
                 break;
         }
     }
 
-    debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
-            assembler->tex_count, assembler->color_count,
-            assembler->tex_count + assembler->color_count);
-
-    consts->count = consts->user_count + assembler->imm_count;
-    fs->uses_imms = assembler->imm_count;
-    debug_printf("r300: fs: %d total constants, "
-            "%d from user and %d from immediates\n", consts->count,
-            consts->user_count, assembler->imm_count);
-    r3xx_fs_finalize(fs, assembler);
-    if (is_r500) {
-        r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
+    for(i = 0; i < info->num_inputs; i++) {
+        switch (info->input_semantic_name[i]) {
+            case TGSI_SEMANTIC_COLOR:
+                allocate(mydata, i, colors);
+                colors++;
+                break;
+            case TGSI_SEMANTIC_FOG:
+            case TGSI_SEMANTIC_GENERIC:
+                allocate(mydata, i, total_colors + generic);
+                generic++;
+                break;
+        }
     }
+}
+
+void r300_translate_fragment_shader(struct r300_context* r300,
+                                    struct r300_fragment_shader* fs)
+{
+    struct r300_fragment_program_compiler compiler;
+    struct tgsi_to_rc ttr;
 
-    tgsi_dump(fs->state.tokens, 0);
-    /* XXX finish r300 dumper too */
-    if (is_r500) {
-        r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
+    memset(&compiler, 0, sizeof(compiler));
+    rc_init(&compiler.Base);
+    compiler.Base.Debug = 1;
+
+    compiler.code = &fs->code;
+    compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
+    compiler.AllocateHwInputs = &allocate_hardware_inputs;
+    compiler.UserData = fs;
+
+    /* TODO: Program compilation depends on texture compare modes,
+     * which are sampler state. Therefore, programs need to be recompiled
+     * depending on this state as in the classic Mesa driver.
+     *
+     * This is not yet handled correctly.
+     */
+
+    find_output_registers(&compiler, fs);
+
+    if (compiler.Base.Debug) {
+        debug_printf("r300: Initial vertex program\n");
+        tgsi_dump(fs->state.tokens, 0);
     }
 
-    tgsi_parse_free(&parser);
-    FREE(assembler);
+    /* Translate TGSI to our internal representation */
+    ttr.compiler = &compiler.Base;
+    ttr.info = &fs->info;
+
+    r300_tgsi_to_rc(&ttr, fs->state.tokens);
+
+    /* Invoke the compiler */
+    r3xx_compile_fragment_program(&compiler);
+    if (compiler.Base.Error) {
+        /* Todo: Fail gracefully */
+        fprintf(stderr, "r300 FP: Compiler error\n");
+        abort();
+    }
 
     /* And, finally... */
+    rc_destroy(&compiler.Base);
     fs->translated = TRUE;
 }
index 18deb7a..9fab789 100644 (file)
 #include "r3xx_fs.h"
 #include "r5xx_fs.h"
 
+#include "radeon_code.h"
+
+struct r300_fragment_shader {
+    /* Parent class */
+    struct pipe_shader_state state;
+    struct tgsi_shader_info info;
+
+    /* Has this shader been translated yet? */
+    boolean translated;
+
+    /* Compiled code */
+    struct rX00_fragment_program_code code;
+};
+
+
 void r300_translate_fragment_shader(struct r300_context* r300,
                                     struct r300_fragment_shader* fs);
 
diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h
deleted file mode 100644 (file)
index be4be94..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- *                Joakim Sindholt <opensource@zhasha.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_FS_INLINES_H
-#define R300_FS_INLINES_H
-
-#include "tgsi/tgsi_parse.h"
-
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
-
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_fs_asm {
-    /* Pipe context. */
-    struct r300_context* r300;
-    /* Number of colors. */
-    unsigned color_count;
-    /* Number of texcoords. */
-    unsigned tex_count;
-    /* Offset for temporary registers. Inputs and temporaries have no
-     * 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;
-    /* Offset for immediate constants. Neither R300 nor R500 can do four
-     * inline constants per source, so instead we copy immediates into the
-     * constant buffer. */
-    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;
-};
-
-static INLINE void r300_fs_declare(struct r300_fs_asm* assembler,
-                            struct tgsi_full_declaration* decl)
-{
-    switch (decl->Declaration.File) {
-        case TGSI_FILE_INPUT:
-            switch (decl->Semantic.SemanticName) {
-                case TGSI_SEMANTIC_COLOR:
-                    assembler->color_count++;
-                    break;
-                case TGSI_SEMANTIC_FOG:
-                case TGSI_SEMANTIC_GENERIC:
-                    assembler->tex_count++;
-                    break;
-                default:
-                    debug_printf("r300: fs: Bad semantic declaration %d\n",
-                        decl->Semantic.SemanticName);
-                    break;
-            }
-            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:
-            assembler->temp_count++;
-            break;
-        default:
-            debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
-            break;
-    }
-
-    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_NULL:
-            return 0;
-        case TGSI_FILE_INPUT:
-            /* XXX may be wrong */
-            return src->Index;
-            break;
-        case TGSI_FILE_TEMPORARY:
-            return src->Index + assembler->temp_offset;
-            break;
-        case TGSI_FILE_IMMEDIATE:
-            return (src->Index + assembler->imm_offset) | (1 << 8);
-            break;
-        case TGSI_FILE_CONSTANT:
-            /* XXX magic */
-            return src->Index | (1 << 8);
-            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_NULL:
-            /* This happens during KIL instructions. */
-            return 0;
-            break;
-        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 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));
-}
-
-#endif /* R300_FS_INLINES_H */
index 33f1d7e..bb4b4be 100644 (file)
@@ -32,6 +32,7 @@
 #include "r300_reg.h"
 #include "r300_state_inlines.h"
 #include "r300_fs.h"
+#include "r300_vs.h"
 
 /* r300_state: Functions used to intialize state context by translating
  * Gallium state objects into semi-native r300 state objects. */
@@ -155,20 +156,6 @@ static void
     }
 
     r300->dirty_state |= R300_NEW_CONSTANTS;
-#if 0
-    /* If the number of constants have changed, invalidate the shader. */
-    if (r300->shader_constants[shader].user_count != i) {
-        if (shader == PIPE_SHADER_FRAGMENT && r300->fs &&
-                r300->fs->uses_imms) {
-            r300->fs->translated = FALSE;
-            r300_translate_fragment_shader(r300, r300->fs);
-        } else if (shader == PIPE_SHADER_VERTEX && r300->vs &&
-                r300->vs->uses_imms) {
-            r300->vs->translated = FALSE;
-            r300_translate_vertex_shader(r300, r300->vs);
-        }
-    }
-#endif
 }
 
 /* Create a new depth, stencil, and alpha state based on the CSO dsa state.
@@ -285,14 +272,9 @@ static void
 static void* r300_create_fs_state(struct pipe_context* pipe,
                                   const struct pipe_shader_state* shader)
 {
-    struct r300_context* r300 = r300_context(pipe);
     struct r300_fragment_shader* fs = NULL;
 
-    if (r300_screen(r300->context.screen)->caps->is_r500) {
-        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);
-    } else {
-        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);
-    }
+    fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
 
     /* Copy state directly into shader. */
     fs->state = *shader;
@@ -325,6 +307,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
 static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
 {
     struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
+    rc_constants_destroy(&fs->code.constants);
     FREE(fs->state.tokens);
     FREE(shader);
 }
index 5c67eb1..ea670f4 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "r300_state_derived.h"
 
+#include "r300_fs.h"
 #include "r300_vs.h"
 
 /* r300_state_derived: Various bits of state which are dependent upon
index cf15333..7dbfb64 100644 (file)
@@ -152,10 +152,10 @@ validate:
 
     /* Fragment shader setup */
     if (caps->is_r500) {
-        r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
+        r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0);
         r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
     } else {
-        r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
+        r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0);
         r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
     }
 
@@ -290,10 +290,10 @@ validate:
 
     /* Fragment shader setup */
     if (caps->is_r500) {
-        r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
+        r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0);
         r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
     } else {
-        r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
+        r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0);
         r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
     }
 
index f530b23..3adbb71 100644 (file)
@@ -224,6 +224,39 @@ static void transform_srcreg(
     dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;
 }
 
+static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src)
+{
+    switch(src.Texture) {
+        case TGSI_TEXTURE_1D:
+            dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+            break;
+        case TGSI_TEXTURE_2D:
+            dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+            break;
+        case TGSI_TEXTURE_3D:
+            dst->I.TexSrcTarget = TEXTURE_3D_INDEX;
+            break;
+        case TGSI_TEXTURE_CUBE:
+            dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX;
+            break;
+        case TGSI_TEXTURE_RECT:
+            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+            break;
+        case TGSI_TEXTURE_SHADOW1D:
+            dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+            dst->I.TexShadow = 1;
+            break;
+        case TGSI_TEXTURE_SHADOW2D:
+            dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+            dst->I.TexShadow = 1;
+            break;
+        case TGSI_TEXTURE_SHADOWRECT:
+            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+            dst->I.TexShadow = 1;
+            break;
+    }
+}
+
 static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src)
 {
     if (src->Instruction.Opcode == TGSI_OPCODE_END)
@@ -238,10 +271,15 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst
     if (src->Instruction.NumDstRegs)
         transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]);
 
-    for(i = 0; i < src->Instruction.NumSrcRegs; ++i)
-        transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]);
+    for(i = 0; i < src->Instruction.NumSrcRegs; ++i) {
+        if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER)
+            dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index;
+        else
+            transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]);
+    }
 
-    /* TODO: Textures */
+    /* Texturing. */
+    transform_texture(dst, src->InstructionExtTexture);
 }
 
 static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
index 6e05d76..c1c1194 100644 (file)
 
 #include "r3xx_fs.h"
 
-static INLINE uint32_t r3xx_rgb_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_MOV:
-            return R300_ALU_OUTC_CMP;
-        default:
-            return 0;
-    }
-}
+#include "r300_reg.h"
 
-static INLINE uint32_t r3xx_alpha_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_MOV:
-            return R300_ALU_OUTA_CMP;
-        default:
-            return 0;
-    }
-}
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = {
+    .code.r300.alu.length = 1,
+    .code.r300.tex.length = 0,
 
-static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs,
-                                   struct r300_fs_asm* assembler,
-                                   struct tgsi_full_src_register* src,
-                                   struct tgsi_full_dst_register* dst,
-                                   unsigned op,
-                                   unsigned count)
-{
-    int i = fs->alu_instruction_count;
+    .code.r300.config = 0,
+    .code.r300.pixsize = 0,
+    .code.r300.code_offset = 0,
+    .code.r300.code_addr[3] = R300_RGBA_OUT,
 
-    fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
         R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
         R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
-        r3xx_rgb_op(op);
-    fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
-        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
-    fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+        R300_ALU_OUTC_CMP,
+    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
         R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
         R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
-        r3xx_alpha_op(op);
-    fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
-        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
+        R300_ALU_OUTA_CMP,
+    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
 
-    fs->alu_instruction_count++;
-}
+struct rX00_fragment_program_code r3xx_texture_fragment_shader = {
+    .code.r300.alu.length = 1,
+    .code.r300.tex.length = 1,
 
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
-                      struct r300_fs_asm* assembler)
-{
-    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
-}
+    .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX,
+    .code.r300.pixsize = 0,
+    .code.r300.code_offset = 0,
+    .code.r300.code_addr[3] = R300_RGBA_OUT,
 
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
-                         struct r300_fs_asm* assembler,
-                         struct tgsi_full_instruction* inst)
-{
-    switch (inst->Instruction.Opcode) {
-        case TGSI_OPCODE_MOV:
-            /* src0 -> src1 and src2 forced to zero */
-            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
-            inst->FullSrcRegisters[2] = r300_constant_zero;
-            r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-        case TGSI_OPCODE_END:
-            break;
-        default:
-            debug_printf("r300: fs: Bad opcode %d\n",
-                    inst->Instruction.Opcode);
-            break;
-    }
-}
+    .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT,
+
+    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
+        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
+        R300_ALU_OUTC_CMP,
+    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
+        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
+        R300_ALU_OUTA_CMP,
+    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
index 592898d..51cd245 100644 (file)
 #ifndef R3XX_FS_H
 #define R3XX_FS_H
 
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
 
-static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = {
-    .alu_instruction_count = 1,
-    .tex_instruction_count = 0,
-    .indirections = 0,
-    .shader.stack_size = 1,
-
-    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
-        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
-        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
-        R300_ALU_OUTC_CMP,
-    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
-        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
-    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
-        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
-        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
-        R300_ALU_OUTA_CMP,
-    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
-        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-static struct r3xx_fragment_shader r3xx_texture_fragment_shader = {
-    .alu_instruction_count = 1,
-    .tex_instruction_count = 0,
-    .indirections = 0,
-    .shader.stack_size = 1,
-
-    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
-        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
-        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
-        R300_ALU_OUTC_CMP,
-    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
-        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
-    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
-        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
-        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
-        R300_ALU_OUTA_CMP,
-    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
-        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-struct r300_fs_asm;
-
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
-                      struct r300_fs_asm* assembler);
-
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
-                         struct r300_fs_asm* assembler,
-                         struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r3xx_texture_fragment_shader;
 
 #endif /* R3XX_FS_H */
index 99d8262..f072dea 100644 (file)
 
 #include "r5xx_fs.h"
 
-static INLINE unsigned r5xx_fix_swiz(unsigned s)
-{
-    /* For historical reasons, the swizzle values x, y, z, w, and 0 are
-     * equivalent to the actual machine code, but 1 is not. Thus, we just
-     * adjust it a bit... */
-    if (s == TGSI_EXTSWIZZLE_ONE) {
-        return R500_SWIZZLE_ONE;
-    } else {
-        return s;
-    }
-}
-
-static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg)
-{
-    if (reg->SrcRegister.Extended) {
-        return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
-            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
-            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
-            (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
-    } else {
-        return reg->SrcRegister.SwizzleX |
-            (reg->SrcRegister.SwizzleY << 3) |
-            (reg->SrcRegister.SwizzleZ << 6) |
-            (reg->SrcRegister.SwizzleW << 9);
-    }
-}
-
-static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg)
-{
-    return reg->SrcRegister.SwizzleX |
-        (reg->SrcRegister.SwizzleY << 2) |
-        (reg->SrcRegister.SwizzleZ << 4) |
-        (reg->SrcRegister.SwizzleW << 6);
-}
-
-static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg)
-{
-    /* Only the first 9 bits... */
-    return (r5xx_rgba_swiz(reg) & 0x1ff) |
-        (reg->SrcRegister.Negate ? (1 << 9) : 0) |
-        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg)
-{
-    /* Only the last 3 bits... */
-    return (r5xx_rgba_swiz(reg) >> 9) |
-        (reg->SrcRegister.Negate ? (1 << 9) : 0) |
-        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_rgba_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_COS:
-        case TGSI_OPCODE_EX2:
-        case TGSI_OPCODE_LG2:
-        case TGSI_OPCODE_RCP:
-        case TGSI_OPCODE_RSQ:
-        case TGSI_OPCODE_SIN:
-            return R500_ALU_RGBA_OP_SOP;
-        case TGSI_OPCODE_DDX:
-            return R500_ALU_RGBA_OP_MDH;
-        case TGSI_OPCODE_DDY:
-            return R500_ALU_RGBA_OP_MDV;
-        case TGSI_OPCODE_FRC:
-            return R500_ALU_RGBA_OP_FRC;
-        case TGSI_OPCODE_DP3:
-            return R500_ALU_RGBA_OP_DP3;
-        case TGSI_OPCODE_DP4:
-        case TGSI_OPCODE_DPH:
-            return R500_ALU_RGBA_OP_DP4;
-        case TGSI_OPCODE_ABS:
-        case TGSI_OPCODE_CMP:
-        case TGSI_OPCODE_MOV:
-        case TGSI_OPCODE_SWZ:
-            return R500_ALU_RGBA_OP_CMP;
-        case TGSI_OPCODE_ADD:
-        case TGSI_OPCODE_MAD:
-        case TGSI_OPCODE_MUL:
-        case TGSI_OPCODE_SUB:
-            return R500_ALU_RGBA_OP_MAD;
-        default:
-            return 0;
-    }
-}
-
-static INLINE uint32_t r5xx_alpha_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_COS:
-            return R500_ALPHA_OP_COS;
-        case TGSI_OPCODE_EX2:
-            return R500_ALPHA_OP_EX2;
-        case TGSI_OPCODE_LG2:
-            return R500_ALPHA_OP_LN2;
-        case TGSI_OPCODE_RCP:
-            return R500_ALPHA_OP_RCP;
-        case TGSI_OPCODE_RSQ:
-            return R500_ALPHA_OP_RSQ;
-        case TGSI_OPCODE_FRC:
-            return R500_ALPHA_OP_FRC;
-        case TGSI_OPCODE_SIN:
-            return R500_ALPHA_OP_SIN;
-        case TGSI_OPCODE_DDX:
-            return R500_ALPHA_OP_MDH;
-        case TGSI_OPCODE_DDY:
-            return R500_ALPHA_OP_MDV;
-        case TGSI_OPCODE_DP3:
-        case TGSI_OPCODE_DP4:
-        case TGSI_OPCODE_DPH:
-            return R500_ALPHA_OP_DP;
-        case TGSI_OPCODE_ABS:
-        case TGSI_OPCODE_CMP:
-        case TGSI_OPCODE_MOV:
-        case TGSI_OPCODE_SWZ:
-            return R500_ALPHA_OP_CMP;
-        case TGSI_OPCODE_ADD:
-        case TGSI_OPCODE_MAD:
-        case TGSI_OPCODE_MUL:
-        case TGSI_OPCODE_SUB:
-            return R500_ALPHA_OP_MAD;
-        default:
-            return 0;
-    }
-}
-
-static INLINE uint32_t r5xx_tex_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_KIL:
-            return R500_TEX_INST_TEXKILL;
-        case TGSI_OPCODE_TEX:
-            return R500_TEX_INST_LD;
-        case TGSI_OPCODE_TXB:
-            return R500_TEX_INST_LODBIAS;
-        case TGSI_OPCODE_TXP:
-            return R500_TEX_INST_PROJ;
-        default:
-            return 0;
-    }
-}
-
-/* Setup an ALU operation. */
-static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs,
-                                   struct r300_fs_asm* assembler,
-                                   struct tgsi_full_src_register* src,
-                                   struct tgsi_full_dst_register* dst,
-                                   unsigned op,
-                                   unsigned count)
-{
-    int i = fs->instruction_count;
-
-    if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
-        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);
-    }
-
-    fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
-
-    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));
-
-    switch (count) {
-        case 3:
-            fs->instructions[i].inst1 =
-                R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
-            fs->instructions[i].inst2 =
-                R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
-            fs->instructions[i].inst5 |=
-                R500_ALU_RGBA_SEL_C_SRC2 |
-                R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) |
-                R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
-                R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2]));
-        case 2:
-            fs->instructions[i].inst1 |=
-                R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
-            fs->instructions[i].inst2 |=
-                R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
-            fs->instructions[i].inst3 =
-                R500_ALU_RGB_SEL_B_SRC1 |
-                R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1]));
-            fs->instructions[i].inst4 |=
-                R500_ALPHA_SEL_B_SRC1 |
-                R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1]));
-        case 1:
-        case 0:
-        default:
-            fs->instructions[i].inst1 |=
-                R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
-            fs->instructions[i].inst2 |=
-                R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
-            fs->instructions[i].inst3 |=
-                R500_ALU_RGB_SEL_A_SRC0 |
-                R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0]));
-            fs->instructions[i].inst4 |=
-                R500_ALPHA_SEL_A_SRC0 |
-                R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0]));
-            break;
-    }
-
-    fs->instructions[i].inst4 |= r5xx_alpha_op(op);
-    fs->instructions[i].inst5 |= r5xx_rgba_op(op);
-
-    fs->instruction_count++;
-}
-
-static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs,
-                                 struct r300_fs_asm* assembler,
-                                 struct tgsi_full_src_register* src,
-                                 struct tgsi_full_dst_register* dst,
-                                 uint32_t op)
-{
-    int i = fs->instruction_count;
-
-    fs->instructions[i].inst0 = R500_INST_TYPE_TEX |
-        R500_TEX_WMASK(dst->DstRegister.WriteMask) |
-        R500_INST_TEX_SEM_WAIT;
-    fs->instructions[i].inst1 = R500_TEX_ID(0) |
-        R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED |
-        r5xx_tex_op(op);
-    fs->instructions[i].inst2 =
-        R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
-        R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) |
-        R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
+#include "r300_reg.h"
+
+/* XXX this all should find its way back to r300_reg */
+/* Swizzle tools */
+#define R500_SWIZZLE_ZERO 4
+#define R500_SWIZZLE_HALF 5
+#define R500_SWIZZLE_ONE 6
+#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
+#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
+#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
+#define R500_SWIZ_MOD_NEG 1
+#define R500_SWIZ_MOD_ABS 2
+#define R500_SWIZ_MOD_NEG_ABS 3
+/* Swizzles for inst2 */
+#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
+#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
+/* Swizzles for inst3 */
+#define R500_SWIZ_RGB_A(x) ((x) << 2)
+#define R500_SWIZ_RGB_B(x) ((x) << 15)
+/* Swizzles for inst4 */
+#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
+/* Swizzle for inst5 */
+#define R500_SWIZ_RGBA_C(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
+/* Writemasks */
+#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)
+
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = {
+    .code.r500.max_temp_idx = 0,
+    .code.r500.inst_end = 0,
+
+    .code.r500.inst[0].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,
+    .code.r500.inst[0].inst1 =
+        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+    .code.r500.inst[0].inst2 =
+        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+    .code.r500.inst[0].inst3 =
+        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+    .code.r500.inst[0].inst4 =
+        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+    .code.r500.inst[0].inst5 =
+        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+        R500_ALU_RGBA_A_SWIZ_0,
+};
+
+struct rX00_fragment_program_code r5xx_texture_fragment_shader = {
+    .code.r500.max_temp_idx = 0,
+    .code.r500.inst_end = 1,
+
+    .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX |
+        R500_INST_TEX_SEM_WAIT |
+        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
+        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+    .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
+        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
+    .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) |
+        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
+        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
+        R500_TEX_DST_ADDR(0) |
         R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
-        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
-
-    if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
-        fs->instructions[i].inst2 |=
-            R500_TEX_DST_ADDR(assembler->temp_count +
-                    assembler->temp_offset);
-
-        fs->instruction_count++;
-
-        /* Setup and emit a MOV. */
-        src[0].SrcRegister.Index = assembler->temp_count;
-        src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-
-        src[1] = src[0];
-        src[2] = r300_constant_zero;
-        r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
-    } else {
-        fs->instruction_count++;
-    }
-}
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
-                      struct r300_fs_asm* assembler)
-{
-    /* XXX should this just go with OPCODE_END? */
-    fs->instructions[fs->instruction_count - 1].inst0 |=
-        R500_INST_LAST;
-}
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
-                         struct r300_fs_asm* assembler,
-                         struct tgsi_full_instruction* inst)
-{
-    /* Switch between opcodes. When possible, prefer using the official
-     * AMD/ATI names for opcodes, please, as it facilitates using the
-     * documentation. */
-    switch (inst->Instruction.Opcode) {
-        /* XXX trig needs extra prep */
-        case TGSI_OPCODE_COS:
-        case TGSI_OPCODE_SIN:
-        /* The simple scalar ops. */
-        case TGSI_OPCODE_EX2:
-        case TGSI_OPCODE_LG2:
-        case TGSI_OPCODE_RCP:
-        case TGSI_OPCODE_RSQ:
-            /* Copy red swizzle to alpha for src0 */
-            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
-                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
-                inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
-            /* Fall through */
-        case TGSI_OPCODE_DDX:
-        case TGSI_OPCODE_DDY:
-        case TGSI_OPCODE_FRC:
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
-            break;
-
-        /* The dot products. */
-        case TGSI_OPCODE_DPH:
-            /* Set alpha swizzle to one for src0 */
-            if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
-                inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
-                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
-                    inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
-                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
-                    inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
-                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
-                    inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
-            }
-            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
-                TGSI_EXTSWIZZLE_ONE;
-            /* Fall through */
-        case TGSI_OPCODE_DP3:
-        case TGSI_OPCODE_DP4:
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);
-            break;
-
-        /* Simple three-source operations. */
-        case TGSI_OPCODE_CMP:
-            /* Swap src0 and src2 */
-            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];
-            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];
-            inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3];
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-
-        /* The MAD variants. */
-        case TGSI_OPCODE_SUB:
-            /* Just like ADD, but flip the negation on src1 first */
-            inst->FullSrcRegisters[1].SrcRegister.Negate =
-                !inst->FullSrcRegisters[1].SrcRegister.Negate;
-            /* Fall through */
-        case TGSI_OPCODE_ADD:
-            /* Force src0 to one, move all registers over */
-            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];
-            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
-            inst->FullSrcRegisters[0] = r300_constant_one;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-        case TGSI_OPCODE_MUL:
-            /* Force our src2 to zero */
-            inst->FullSrcRegisters[2] = r300_constant_zero;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-        case TGSI_OPCODE_MAD:
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-
-        /* The MOV variants. */
-        case TGSI_OPCODE_ABS:
-            /* Set absolute value modifiers. */
-            inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE;
-            /* Fall through */
-        case TGSI_OPCODE_MOV:
-        case TGSI_OPCODE_SWZ:
-            /* src0 -> src1 and src2 forced to zero */
-            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
-            inst->FullSrcRegisters[2] = r300_constant_zero;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-
-        /* The compound and hybrid insts. */
-        case TGSI_OPCODE_LRP:
-            /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */
-            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1];
-            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2];
-            inst->FullSrcRegisters[0].SrcRegister.Negate =
-                !(inst->FullSrcRegisters[0].SrcRegister.Negate);
-            inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
-            inst->FullDstRegisters[0].DstRegister.Index =
-                assembler->temp_count;
-            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
-            inst->FullSrcRegisters[2].SrcRegister.Index =
-                assembler->temp_count;
-            inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
-            inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-            inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-            inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
-            inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
-            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3];
-            inst->FullSrcRegisters[0].SrcRegister.Negate =
-                !(inst->FullSrcRegisters[0].SrcRegister.Negate);
-            inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
-            break;
-        case TGSI_OPCODE_POW:
-            /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */
-            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
-                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
-                inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
-            inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
-            inst->FullDstRegisters[0].DstRegister.Index =
-                assembler->temp_count;
-            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
-            inst->FullSrcRegisters[0].SrcRegister.Index =
-                assembler->temp_count;
-            inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
-            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
-            inst->FullSrcRegisters[2] = r300_constant_zero;
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
-            inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
-            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
-            break;
-
-        /* The texture instruction set. */
-        case TGSI_OPCODE_KIL:
-        case TGSI_OPCODE_TEX:
-        case TGSI_OPCODE_TXB:
-        case TGSI_OPCODE_TXP:
-            r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode);
-            break;
-
-        /* This is the end. My only friend, the end. */
-        case TGSI_OPCODE_END:
-            break;
-        default:
-            debug_printf("r300: fs: Bad opcode %d\n",
-                    inst->Instruction.Opcode);
-            break;
-    }
-
-    /* Clamp, if saturation flags are set. */
-    if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
-        fs->instructions[fs->instruction_count - 1].inst0 |=
-            R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
-    }
-}
+        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
+    .code.r500.inst[0].inst3 = 0x0,
+    .code.r500.inst[0].inst4 = 0x0,
+    .code.r500.inst[0].inst5 = 0x0,
+
+    .code.r500.inst[1].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,
+    .code.r500.inst[1].inst1 =
+        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+    .code.r500.inst[1].inst2 =
+        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+    .code.r500.inst[1].inst3 =
+        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+    .code.r500.inst[1].inst4 =
+        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+    .code.r500.inst[1].inst5 =
+        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+        R500_ALU_RGBA_A_SWIZ_0,
+};
index 7e62c33..a4addde 100644 (file)
 #ifndef R5XX_FS_H
 #define R5XX_FS_H
 
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
 
-/* XXX this all should find its way back to r300_reg */
-/* Swizzle tools */
-#define R500_SWIZZLE_ZERO 4
-#define R500_SWIZZLE_HALF 5
-#define R500_SWIZZLE_ONE 6
-#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
-#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
-#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
-#define R500_SWIZ_MOD_NEG 1
-#define R500_SWIZ_MOD_ABS 2
-#define R500_SWIZ_MOD_NEG_ABS 3
-/* Swizzles for inst2 */
-#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
-#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
-/* Swizzles for inst3 */
-#define R500_SWIZ_RGB_A(x) ((x) << 2)
-#define R500_SWIZ_RGB_B(x) ((x) << 15)
-/* Swizzles for inst4 */
-#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
-/* Swizzle for inst5 */
-#define R500_SWIZ_RGBA_C(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
-/* Writemasks */
-#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)
-
-static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = {
-    .shader.stack_size = 0,
-    .instruction_count = 1,
-    .instructions[0].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,
-    .instructions[0].inst1 =
-        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
-        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
-    .instructions[0].inst2 =
-        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
-        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
-    .instructions[0].inst3 =
-        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
-        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
-        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
-        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
-    .instructions[0].inst4 =
-        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
-    .instructions[0].inst5 =
-        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
-        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
-        R500_ALU_RGBA_A_SWIZ_0,
-};
-
-static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {
-    .shader.stack_size = 1,
-    .instruction_count = 2,
-    .instructions[0].inst0 = R500_INST_TYPE_TEX |
-        R500_INST_TEX_SEM_WAIT |
-        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
-        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
-    .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
-        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
-    .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) |
-        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
-        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
-        R500_TEX_DST_ADDR(0) |
-        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
-        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
-    .instructions[0].inst3 = 0x0,
-    .instructions[0].inst4 = 0x0,
-    .instructions[0].inst5 = 0x0,
-    .instructions[1].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,
-    .instructions[1].inst1 =
-        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
-        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
-    .instructions[1].inst2 =
-        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
-        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
-    .instructions[1].inst3 =
-        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
-        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
-        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
-        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
-    .instructions[1].inst4 =
-        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
-    .instructions[1].inst5 =
-        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
-        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
-        R500_ALU_RGBA_A_SWIZ_0,
-};
-
-struct r300_fs_asm;
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
-                      struct r300_fs_asm* assembler);
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
-                         struct r300_fs_asm* assembler,
-                         struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r5xx_texture_fragment_shader;
 
 #endif /* R5XX_FS_H */