r300g: Use r300compiler for vertex shaders
authorNicolai Hähnle <nhaehnle@gmail.com>
Mon, 27 Jul 2009 18:23:49 +0000 (20:23 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Thu, 30 Jul 2009 21:45:18 +0000 (23:45 +0200)
16 files changed:
src/gallium/Makefile.template
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_debug.c
src/gallium/drivers/r300/r300_debug.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
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 [new file with mode: 0644]
src/gallium/drivers/r300/r300_tgsi_to_rc.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_vs.c
src/gallium/drivers/r300/r300_vs.h
src/gallium/drivers/r300/r3xx_fs.h
src/gallium/drivers/r300/r5xx_fs.h

index 98487d43bd646f4da3024fc93069da43acc5a364..2e3da436cd7a82bf9453c7ecd2f2a996dd5a60c9 100644 (file)
@@ -31,8 +31,8 @@ INCLUDES = \
 
 default: depend lib$(LIBNAME).a
 
-lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
-       $(MKLIB) -o $(LIBNAME) -static $(OBJECTS)
+lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
+       $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS)
 
 depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
        rm -f depend
index faceec9842fe6894c9234d910c01ba8ddbe1911e..93c2152edcedb5aac2ec6d92cfccfcbcfe22cbb1 100644 (file)
@@ -21,6 +21,22 @@ C_SOURCES = \
        r300_state_invariant.c \
        r300_vs.c \
        r300_surface.c \
-       r300_texture.c
+       r300_texture.c \
+       r300_tgsi_to_rc.c
+
+LIBRARY_INCLUDES = \
+       -I$(TOP)/src/mesa/drivers/dri/r300/compiler \
+       -I$(TOP)/src/mesa \
+       -I$(TOP)/include
+
+COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
+
+EXTRA_OBJECTS = \
+       $(COMPILER_ARCHIVE)
 
 include ../../Makefile.template
+
+.PHONY : $(COMPILER_ARCHIVE)
+
+$(COMPILER_ARCHIVE):
+       cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
index d891fd6265f1f9a3acbb0e2a6d4942fc04fc79a1..c1ef64e4eec9d5d00d98854c5128667ffc30e332 100644 (file)
@@ -34,6 +34,8 @@
 #include "r300_screen.h"
 #include "r300_winsys.h"
 
+struct r300_vertex_shader;
+
 struct r300_blend_state {
     uint32_t blend_control;       /* R300_RB3D_CBLEND: 0x4e04 */
     uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */
@@ -242,33 +244,6 @@ struct r300_vertex_format {
     int fs_tab[16];
 };
 
-struct r300_vertex_shader {
-    /* Parent class */
-    struct pipe_shader_state state;
-    struct tgsi_shader_info info;
-
-    /* Fallback shader, because Draw has issues */
-    struct draw_vertex_shader* draw;
-
-    /* Has this shader been translated yet? */
-    boolean translated;
-
-    /* Are there immediates in this shader?
-     * If not, we can heavily optimize recompilation. */
-    boolean uses_imms;
-
-    /* Number of used instructions */
-    int instruction_count;
-
-    /* Machine instructions */
-    struct {
-        uint32_t inst0;
-        uint32_t inst1;
-        uint32_t inst2;
-        uint32_t inst3;
-    } instructions[128]; /*< XXX magic number */
-};
-
 static struct pipe_viewport_state r300_viewport_identity = {
     .scale = {1.0, 1.0, 1.0, 1.0},
     .translate = {0.0, 0.0, 0.0, 0.0},
index c83e8526cf7938f4ec8430f15282dd05828d23b5..aae8a4fbde65f339ea52f4cd26bc77ae7817886c 100644 (file)
 
 #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;
@@ -142,57 +219,10 @@ void r5xx_fs_dump(struct r5xx_fragment_shader* fs)
                         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;
         }
     }
 }
-
-static void r300_vs_op_dump(uint32_t op)
-{
-    debug_printf(" dst: %d%s op: ",
-            (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
-    if (op & 0x80) {
-        if (op & 0x1) {
-            debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
-        } else {
-            debug_printf("   PVS_MACRO_OP_2CLK_MADD\n");
-        }
-    } else if (op & 0x40) {
-        debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]);
-    } else {
-        debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
-    }
-}
-
-void r300_vs_src_dump(uint32_t src)
-{
-    debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
-            (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
-            src & (1 << 25) ? "-" : " ",
-            r300_vs_swiz_debug[(src >> 13) & 0x7],
-            src & (1 << 26) ? "-" : " ",
-            r300_vs_swiz_debug[(src >> 16) & 0x7],
-            src & (1 << 27) ? "-" : " ",
-            r300_vs_swiz_debug[(src >> 19) & 0x7],
-            src & (1 << 28) ? "-" : " ",
-            r300_vs_swiz_debug[(src >> 22) & 0x7]);
-}
-
-void r300_vs_dump(struct r300_vertex_shader* vs)
-{
-    int i;
-
-    for (i = 0; i < vs->instruction_count; i++) {
-        debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0);
-        r300_vs_op_dump(vs->instructions[i].inst0);
-        debug_printf(" src0: 0x%08x", vs->instructions[i].inst1);
-        r300_vs_src_dump(vs->instructions[i].inst1);
-        debug_printf(" src1: 0x%08x", vs->instructions[i].inst2);
-        r300_vs_src_dump(vs->instructions[i].inst2);
-        debug_printf(" src2: 0x%08x", vs->instructions[i].inst3);
-        r300_vs_src_dump(vs->instructions[i].inst3);
-    }
-}
index 6b58c1e2501851ffa9c7c29b3fc507f12d79afe4..c551bd548e196858b8bc6021c345c8d30194577e 100644 (file)
 #include "r300_fs.h"
 #include "r300_vs.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",
-};
-
-static char* r300_vs_ve_ops[] = {
-    /* R300 vector ops */
-    "                 VE_NO_OP",
-    "           VE_DOT_PRODUCT",
-    "              VE_MULTIPLY",
-    "                   VE_ADD",
-    "          VE_MULTIPLY_ADD",
-    "       VE_DISTANCE_FACTOR",
-    "              VE_FRACTION",
-    "               VE_MAXIMUM",
-    "               VE_MINIMUM",
-    "VE_SET_GREATER_THAN_EQUAL",
-    "         VE_SET_LESS_THAN",
-    "        VE_MULTIPLYX2_ADD",
-    "        VE_MULTIPLY_CLAMP",
-    "            VE_FLT2FIX_DX",
-    "        VE_FLT2FIX_DX_RND",
-    /* R500 vector ops */
-    "      VE_PRED_SET_EQ_PUSH",
-    "      VE_PRED_SET_GT_PUSH",
-    "     VE_PRED_SET_GTE_PUSH",
-    "     VE_PRED_SET_NEQ_PUSH",
-    "         VE_COND_WRITE_EQ",
-    "         VE_COND_WRITE_GT",
-    "        VE_COND_WRITE_GTE",
-    "        VE_COND_WRITE_NEQ",
-    "      VE_SET_GREATER_THAN",
-    "             VE_SET_EQUAL",
-    "         VE_SET_NOT_EQUAL",
-    "               (reserved)",
-    "               (reserved)",
-    "               (reserved)",
-};
-
-static char* r300_vs_me_ops[] = {
-    /* R300 math ops */
-    "                 ME_NO_OP",
-    "          ME_EXP_BASE2_DX",
-    "          ME_LOG_BASE2_DX",
-    "          ME_EXP_BASEE_FF",
-    "        ME_LIGHT_COEFF_DX",
-    "         ME_POWER_FUNC_FF",
-    "              ME_RECIP_DX",
-    "              ME_RECIP_FF",
-    "         ME_RECIP_SQRT_DX",
-    "         ME_RECIP_SQRT_FF",
-    "              ME_MULTIPLY",
-    "     ME_EXP_BASE2_FULL_DX",
-    "     ME_LOG_BASE2_FULL_DX",
-    " ME_POWER_FUNC_FF_CLAMP_B",
-    "ME_POWER_FUNC_FF_CLAMP_B1",
-    "ME_POWER_FUNC_FF_CLAMP_01",
-    "                   ME_SIN",
-    "                   ME_COS",
-    /* R500 math ops */
-    "        ME_LOG_BASE2_IEEE",
-    "            ME_RECIP_IEEE",
-    "       ME_RECIP_SQRT_IEEE",
-    "           ME_PRED_SET_EQ",
-    "           ME_PRED_SET_GT",
-    "          ME_PRED_SET_GTE",
-    "          ME_PRED_SET_NEQ",
-    "          ME_PRED_SET_CLR",
-    "          ME_PRED_SET_INV",
-    "          ME_PRED_SET_POP",
-    "      ME_PRED_SET_RESTORE",
-    "               (reserved)",
-    "               (reserved)",
-    "               (reserved)",
-};
-
-/* XXX refactor to avoid clashing symbols */
-static char* r300_vs_src_debug[] = {
-    "t",
-    "i",
-    "c",
-    "a",
-};
-
-static char* r300_vs_dst_debug[] = {
-    "t",
-    "a0",
-    "o",
-    "ox",
-    "a",
-    "i",
-    "u",
-    "u",
-};
-
-static char* r300_vs_swiz_debug[] = {
-    "X",
-    "Y",
-    "Z",
-    "W",
-    "0",
-    "1",
-    "U",
-    "U",
-};
-
 void r5xx_fs_dump(struct r5xx_fragment_shader* fs);
 void r3xx_dump_fs(struct r3xx_fragment_shader* fs);
 
index ac510ffc2ed5ed3f9b8bc766cc6afeb197406044..e9ca4ac662664c547fa7aeb0f29fb3cbed4900d7 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "r300_emit.h"
 
+#include "r300_vs.h"
+
 void r300_emit_blend_state(struct r300_context* r300,
                            struct r300_blend_state* blend)
 {
@@ -380,13 +382,33 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
     END_CS;
 }
 
-void r300_emit_vertex_shader(struct r300_context* r300,
-                             struct r300_vertex_shader* vs)
+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)
 {
     int i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
-    struct r300_constant_buffer* constants =
-        &r300->shader_constants[PIPE_SHADER_VERTEX];
+    unsigned instruction_count = code->length / 4;
     CS_LOCALS(r300);
 
     if (!r300screen->caps->has_tcl) {
@@ -395,10 +417,10 @@ void r300_emit_vertex_shader(struct r300_context* r300,
         return;
     }
 
-    if (constants->count) {
-        BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4));
+    if (code->constants.Count) {
+        BEGIN_CS(14 + code->length + (code->constants.Count * 4));
     } else {
-        BEGIN_CS(11 + (vs->instruction_count * 4));
+        BEGIN_CS(11 + code->length);
     }
 
     /* R300_VAP_PVS_CODE_CNTL_0
@@ -408,30 +430,27 @@ void r300_emit_vertex_shader(struct r300_context* r300,
      * XXX these could be optimized to select better values... */
     OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
     OUT_CS(R300_PVS_FIRST_INST(0) |
-            R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) |
-            R300_PVS_LAST_INST(vs->instruction_count - 1));
-    OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1));
-    OUT_CS(vs->instruction_count - 1);
+            R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
+            R300_PVS_LAST_INST(instruction_count - 1));
+    OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1));
+    OUT_CS(instruction_count - 1);
 
     OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
-    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4);
-    for (i = 0; i < vs->instruction_count; i++) {
-        OUT_CS(vs->instructions[i].inst0);
-        OUT_CS(vs->instructions[i].inst1);
-        OUT_CS(vs->instructions[i].inst2);
-        OUT_CS(vs->instructions[i].inst3);
-    }
+    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
+    for (i = 0; i < code->length; i++)
+        OUT_CS(code->body.d[i]);
 
-    if (constants->count) {
+    if (code->constants.Count) {
         OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
                 (r300screen->caps->is_r500 ?
                  R500_PVS_CONST_START : R300_PVS_CONST_START));
-        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_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(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
+        for (i = 0; i < code->constants.Count; i++) {
+            const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
+            OUT_CS_32F(data[0]);
+            OUT_CS_32F(data[1]);
+            OUT_CS_32F(data[2]);
+            OUT_CS_32F(data[3]);
         }
     }
 
@@ -443,6 +462,12 @@ void r300_emit_vertex_shader(struct r300_context* r300,
     END_CS;
 }
 
+void r300_emit_vertex_shader(struct r300_context* r300,
+                             struct r300_vertex_shader* vs)
+{
+    r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
+}
+
 void r300_emit_viewport_state(struct r300_context* r300,
                               struct r300_viewport_state* viewport)
 {
index fda26f394810a5783b5258b0593f8f837d0941ad..fbc6487aa24e83e814fe3104c0166cd9ff175791 100644 (file)
@@ -30,6 +30,8 @@
 #include "r300_screen.h"
 #include "r300_state_inlines.h"
 
+struct r300_vertex_program_code;
+
 void r300_emit_blend_state(struct r300_context* r300,
                            struct r300_blend_state* blend);
 
@@ -68,6 +70,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
 
 void r300_emit_vertex_format_state(struct r300_context* r300);
 
+void r300_emit_vertex_program_code(struct r300_context* r300,
+                                   struct r300_vertex_program_code* code,
+                                   struct r300_constant_buffer* constants);
+
 void r300_emit_vertex_shader(struct r300_context* r300,
                              struct r300_vertex_shader* vs);
 
index 162740f594de12f8a1ffb3fa4aa7de039e6eaa03..33f1d7e79f9a9c8f89d5d0df8669e420bb9f25ba 100644 (file)
@@ -688,6 +688,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
     if (r300_screen(pipe->screen)->caps->has_tcl) {
         struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
 
+        rc_constants_destroy(&vs->code.constants);
         draw_delete_vertex_shader(r300->draw, vs->draw);
         FREE(vs->state.tokens);
         FREE(shader);
index 2477b30822b81d07ddb2f6a4acfb9eb0cdaf9f1f..5c67eb13ff802e60c793b47a31617b69152e72f2 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "r300_state_derived.h"
 
+#include "r300_vs.h"
+
 /* r300_state_derived: Various bits of state which are dependent upon
  * currently bound CSO data. */
 
index 25168ce5e950d0fe2bf8b15f2191d6422018554d..cf15333198aa0efabf88ef5b0eb535080d236acf 100644 (file)
@@ -139,7 +139,7 @@ validate:
 
     /* Vertex shader setup */
     if (caps->has_tcl) {
-        r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+        r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
     } else {
         BEGIN_CS(4);
         OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
@@ -277,7 +277,7 @@ validate:
 
     /* Vertex shader setup */
     if (caps->has_tcl) {
-        r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+        r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
     } else {
         BEGIN_CS(4);
         OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
new file mode 100644 (file)
index 0000000..f530b23
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@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 COPYRIGHT HOLDER(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_tgsi_to_rc.h"
+
+#include "radeon_compiler.h"
+#include "radeon_program.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_util.h"
+
+
+static unsigned translate_opcode(unsigned opcode)
+{
+    switch(opcode) {
+        case TGSI_OPCODE_ARL: return OPCODE_ARL;
+        case TGSI_OPCODE_MOV: return OPCODE_MOV;
+        case TGSI_OPCODE_LIT: return OPCODE_LIT;
+        case TGSI_OPCODE_RCP: return OPCODE_RCP;
+        case TGSI_OPCODE_RSQ: return OPCODE_RSQ;
+        case TGSI_OPCODE_EXP: return OPCODE_EXP;
+        case TGSI_OPCODE_LOG: return OPCODE_LOG;
+        case TGSI_OPCODE_MUL: return OPCODE_MUL;
+        case TGSI_OPCODE_ADD: return OPCODE_ADD;
+        case TGSI_OPCODE_DP3: return OPCODE_DP3;
+        case TGSI_OPCODE_DP4: return OPCODE_DP4;
+        case TGSI_OPCODE_DST: return OPCODE_DST;
+        case TGSI_OPCODE_MIN: return OPCODE_MIN;
+        case TGSI_OPCODE_MAX: return OPCODE_MAX;
+        case TGSI_OPCODE_SLT: return OPCODE_SLT;
+        case TGSI_OPCODE_SGE: return OPCODE_SGE;
+        case TGSI_OPCODE_MAD: return OPCODE_MAD;
+        case TGSI_OPCODE_SUB: return OPCODE_SUB;
+        case TGSI_OPCODE_LRP: return OPCODE_LRP;
+     /* case TGSI_OPCODE_CND: return OPCODE_CND; */
+     /* case TGSI_OPCODE_CND0: return OPCODE_CND0; */
+        case TGSI_OPCODE_DP2A: return OPCODE_DP2A;
+                                        /* gap */
+        case TGSI_OPCODE_FRC: return OPCODE_FRC;
+     /* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */
+        case TGSI_OPCODE_FLR: return OPCODE_FLR;
+     /* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */
+        case TGSI_OPCODE_EX2: return OPCODE_EX2;
+        case TGSI_OPCODE_LG2: return OPCODE_LG2;
+        case TGSI_OPCODE_POW: return OPCODE_POW;
+        case TGSI_OPCODE_XPD: return OPCODE_XPD;
+                                        /* gap */
+        case TGSI_OPCODE_ABS: return OPCODE_ABS;
+        case TGSI_OPCODE_RCC: return OPCODE_RCC;
+        case TGSI_OPCODE_DPH: return OPCODE_DPH;
+        case TGSI_OPCODE_COS: return OPCODE_COS;
+        case TGSI_OPCODE_DDX: return OPCODE_DDX;
+        case TGSI_OPCODE_DDY: return OPCODE_DDY;
+     /* case TGSI_OPCODE_KILP: return OPCODE_KILP; */
+        case TGSI_OPCODE_PK2H: return OPCODE_PK2H;
+        case TGSI_OPCODE_PK2US: return OPCODE_PK2US;
+        case TGSI_OPCODE_PK4B: return OPCODE_PK4B;
+        case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB;
+        case TGSI_OPCODE_RFL: return OPCODE_RFL;
+        case TGSI_OPCODE_SEQ: return OPCODE_SEQ;
+        case TGSI_OPCODE_SFL: return OPCODE_SFL;
+        case TGSI_OPCODE_SGT: return OPCODE_SGT;
+        case TGSI_OPCODE_SIN: return OPCODE_SIN;
+        case TGSI_OPCODE_SLE: return OPCODE_SLE;
+        case TGSI_OPCODE_SNE: return OPCODE_SNE;
+        case TGSI_OPCODE_STR: return OPCODE_STR;
+        case TGSI_OPCODE_TEX: return OPCODE_TEX;
+        case TGSI_OPCODE_TXD: return OPCODE_TXD;
+        case TGSI_OPCODE_TXP: return OPCODE_TXP;
+        case TGSI_OPCODE_UP2H: return OPCODE_UP2H;
+        case TGSI_OPCODE_UP2US: return OPCODE_UP2US;
+        case TGSI_OPCODE_UP4B: return OPCODE_UP4B;
+        case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB;
+        case TGSI_OPCODE_X2D: return OPCODE_X2D;
+        case TGSI_OPCODE_ARA: return OPCODE_ARA;
+        case TGSI_OPCODE_ARR: return OPCODE_ARR;
+        case TGSI_OPCODE_BRA: return OPCODE_BRA;
+        case TGSI_OPCODE_CAL: return OPCODE_CAL;
+        case TGSI_OPCODE_RET: return OPCODE_RET;
+        case TGSI_OPCODE_SSG: return OPCODE_SSG;
+        case TGSI_OPCODE_CMP: return OPCODE_CMP;
+        case TGSI_OPCODE_SCS: return OPCODE_SCS;
+        case TGSI_OPCODE_TXB: return OPCODE_TXB;
+     /* case TGSI_OPCODE_NRM: return OPCODE_NRM; */
+     /* case TGSI_OPCODE_DIV: return OPCODE_DIV; */
+        case TGSI_OPCODE_DP2: return OPCODE_DP2;
+        case TGSI_OPCODE_TXL: return OPCODE_TXL;
+        case TGSI_OPCODE_BRK: return OPCODE_BRK;
+        case TGSI_OPCODE_IF: return OPCODE_IF;
+     /* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */
+     /* case TGSI_OPCODE_REP: return OPCODE_REP; */
+        case TGSI_OPCODE_ELSE: return OPCODE_ELSE;
+        case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF;
+        case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP;
+     /* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */
+        case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA;
+        case TGSI_OPCODE_POPA: return OPCODE_POPA;
+     /* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */
+     /* case TGSI_OPCODE_I2F: return OPCODE_I2F; */
+        case TGSI_OPCODE_NOT: return OPCODE_NOT;
+        case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC;
+     /* case TGSI_OPCODE_SHL: return OPCODE_SHL; */
+     /* case TGSI_OPCODE_SHR: return OPCODE_SHR; */
+        case TGSI_OPCODE_AND: return OPCODE_AND;
+        case TGSI_OPCODE_OR: return OPCODE_OR;
+     /* case TGSI_OPCODE_MOD: return OPCODE_MOD; */
+        case TGSI_OPCODE_XOR: return OPCODE_XOR;
+     /* case TGSI_OPCODE_SAD: return OPCODE_SAD; */
+     /* case TGSI_OPCODE_TXF: return OPCODE_TXF; */
+     /* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */
+        case TGSI_OPCODE_CONT: return OPCODE_CONT;
+     /* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */
+     /* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */
+     /* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */
+        case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB;
+     /* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */
+        case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB;
+        case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1;
+        case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2;
+        case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3;
+        case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4;
+        case TGSI_OPCODE_NOP: return OPCODE_NOP;
+                                        /* gap */
+        case TGSI_OPCODE_NRM4: return OPCODE_NRM4;
+     /* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */
+     /* case TGSI_OPCODE_IFC: return OPCODE_IFC; */
+     /* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */
+        case TGSI_OPCODE_KIL: return OPCODE_KIL;
+        case TGSI_OPCODE_END: return OPCODE_END;
+        case TGSI_OPCODE_SWZ: return OPCODE_SWZ;
+    }
+
+    fprintf(stderr, "Unknown opcode: %i\n", opcode);
+    abort();
+}
+
+static unsigned translate_saturate(unsigned saturate)
+{
+    switch(saturate) {
+        case TGSI_SAT_NONE: return SATURATE_OFF;
+        case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE;
+        case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE;
+    }
+
+    fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
+    abort();
+}
+
+static unsigned translate_register_file(unsigned file)
+{
+    switch(file) {
+        case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT;
+        case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT;
+        case TGSI_FILE_INPUT: return PROGRAM_INPUT;
+        case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT;
+        case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY;
+        case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS;
+    }
+
+    fprintf(stderr, "Unhandled register file: %i\n", file);
+    abort();
+}
+
+static int translate_register_index(
+    struct tgsi_to_rc * ttr,
+    unsigned file,
+    int index)
+{
+    if (file == TGSI_FILE_IMMEDIATE)
+        return ttr->immediate_offset + index;
+
+    return index;
+}
+
+static void transform_dstreg(
+    struct tgsi_to_rc * ttr,
+    struct prog_dst_register * dst,
+    struct tgsi_full_dst_register * src)
+{
+    dst->File = translate_register_file(src->DstRegister.File);
+    dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index);
+    dst->WriteMask = src->DstRegister.WriteMask;
+    dst->RelAddr = src->DstRegister.Indirect;
+}
+
+static void transform_srcreg(
+    struct tgsi_to_rc * ttr,
+    struct prog_src_register * dst,
+    struct tgsi_full_src_register * src)
+{
+    dst->File = translate_register_file(src->SrcRegister.File);
+    dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index);
+    dst->RelAddr = src->SrcRegister.Indirect;
+    dst->Swizzle = tgsi_util_get_full_src_register_extswizzle(src, 0);
+    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 1) << 3;
+    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 2) << 6;
+    dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 3) << 9;
+    dst->Abs = src->SrcRegisterExtMod.Absolute;
+    dst->Negate =
+        src->SrcRegisterExtSwz.NegateX |
+        (src->SrcRegisterExtSwz.NegateY << 1) |
+        (src->SrcRegisterExtSwz.NegateZ << 2) |
+        (src->SrcRegisterExtSwz.NegateW << 3);
+    dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;
+}
+
+static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src)
+{
+    if (src->Instruction.Opcode == TGSI_OPCODE_END)
+        return;
+
+    struct rc_instruction * dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev);
+    int i;
+
+    dst->I.Opcode = translate_opcode(src->Instruction.Opcode);
+    dst->I.SaturateMode = translate_saturate(src->Instruction.Saturate);
+
+    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]);
+
+    /* TODO: Textures */
+}
+
+static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
+{
+    struct rc_constant constant;
+    int i;
+
+    constant.Type = RC_CONSTANT_IMMEDIATE;
+    constant.Size = 4;
+    for(i = 0; i < 4; ++i)
+        constant.u.Immediate[i] = imm->u[i].Float;
+    rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+}
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens)
+{
+    struct tgsi_parse_context parser;
+    int i;
+
+    /* Allocate constants placeholders.
+     *
+     * Note: What if declared constants are not contiguous? */
+    for(i = 0; i <= ttr->info->file_max[TGSI_FILE_CONSTANT]; ++i) {
+        struct rc_constant constant;
+        memset(&constant, 0, sizeof(constant));
+        constant.Type = RC_CONSTANT_EXTERNAL;
+        constant.Size = 4;
+        constant.u.External = i;
+        rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+    }
+
+    ttr->immediate_offset = ttr->compiler->Program.Constants.Count;
+
+    tgsi_parse_init(&parser, tokens);
+
+    while (!tgsi_parse_end_of_tokens(&parser)) {
+        tgsi_parse_token(&parser);
+
+        switch (parser.FullToken.Token.Type) {
+            case TGSI_TOKEN_TYPE_DECLARATION:
+                break;
+            case TGSI_TOKEN_TYPE_IMMEDIATE:
+                handle_immediate(ttr, &parser.FullToken.FullImmediate);
+                break;
+            case TGSI_TOKEN_TYPE_INSTRUCTION:
+                transform_instruction(ttr, &parser.FullToken.FullInstruction);
+                break;
+        }
+    }
+
+    tgsi_parse_free(&parser);
+
+    rc_calculate_inputs_outputs(ttr->compiler);
+}
+
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
new file mode 100644 (file)
index 0000000..93e90ec
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@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 COPYRIGHT HOLDER(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_TGSI_TO_RC_H
+#define R300_TGSI_TO_RC_H
+
+struct radeon_compiler;
+
+struct tgsi_full_declaration;
+struct tgsi_shader_info;
+struct tgsi_token;
+
+struct tgsi_to_rc {
+    struct radeon_compiler * compiler;
+    const struct tgsi_shader_info * info;
+
+    int immediate_offset;
+};
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens);
+
+#endif /* R300_TGSI_TO_RC_H */
index 741a1b69895c6cffc560679114a58900baa9a5a7..02dd7be7c494897010b2b7e8eda702ec38122047 100644 (file)
 
 #include "r300_vs.h"
 
-static void r300_vs_declare(struct r300_vs_asm* assembler,
-                            struct tgsi_full_declaration* decl)
-{
-    switch (decl->Declaration.File) {
-        case TGSI_FILE_INPUT:
-            break;
-        case TGSI_FILE_OUTPUT:
-            switch (decl->Semantic.SemanticName) {
-                case TGSI_SEMANTIC_POSITION:
-                    assembler->tab[decl->DeclarationRange.First] = 0;
-                    break;
-                case TGSI_SEMANTIC_COLOR:
-                    assembler->tab[decl->DeclarationRange.First] =
-                        (assembler->point_size ? 1 : 0) +
-                        assembler->out_colors;
-                    break;
-                case TGSI_SEMANTIC_FOG:
-                case TGSI_SEMANTIC_GENERIC:
-                    /* XXX multiple? */
-                    assembler->tab[decl->DeclarationRange.First] =
-                        (assembler->point_size ? 1 : 0) +
-                        assembler->out_colors +
-                        assembler->out_texcoords;
-                    break;
-                case TGSI_SEMANTIC_PSIZE:
-                    assembler->tab[decl->DeclarationRange.First] = 1;
-                    break;
-                default:
-                    debug_printf("r300: vs: Bad semantic declaration %d\n",
-                        decl->Semantic.SemanticName);
-                    break;
-            }
-            break;
-        case TGSI_FILE_CONSTANT:
-            break;
-        case TGSI_FILE_TEMPORARY:
-            assembler->temp_count++;
-            break;
-        default:
-            debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File);
-            break;
-    }
-}
+#include "r300_context.h"
+#include "r300_tgsi_to_rc.h"
 
-static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
-                                        struct tgsi_src_register* src)
-{
-    switch (src->File) {
-        case TGSI_FILE_NULL:
-        case TGSI_FILE_INPUT:
-            /* Probably a zero or one swizzle */
-            return R300_PVS_SRC_REG_INPUT;
-        case TGSI_FILE_TEMPORARY:
-            return R300_PVS_SRC_REG_TEMPORARY;
-        case TGSI_FILE_CONSTANT:
-        case TGSI_FILE_IMMEDIATE:
-            return R300_PVS_SRC_REG_CONSTANT;
-        default:
-            debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
-            break;
-    }
-    return 0;
-}
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_parse.h"
 
-static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler,
-                                   struct tgsi_src_register* src)
-{
-    switch (src->File) {
-        case TGSI_FILE_NULL:
-        case TGSI_FILE_INPUT:
-        case TGSI_FILE_TEMPORARY:
-        case TGSI_FILE_CONSTANT:
-            return src->Index;
-        case TGSI_FILE_IMMEDIATE:
-            return src->Index + assembler->imm_offset;
-        default:
-            debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
-            break;
-    }
-    return 0;
-}
+#include "radeon_compiler.h"
 
-static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,
-                                        struct tgsi_dst_register* dst)
-{
-    switch (dst->File) {
-        case TGSI_FILE_TEMPORARY:
-            return R300_PVS_DST_REG_TEMPORARY;
-        case TGSI_FILE_OUTPUT:
-            return R300_PVS_DST_REG_OUT;
-        default:
-            debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);
-            break;
-    }
-    return 0;
-}
 
-static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
-                                   struct tgsi_dst_register* dst)
-{
-    switch (dst->File) {
-        case TGSI_FILE_TEMPORARY:
-            return dst->Index;
-        case TGSI_FILE_OUTPUT:
-            return assembler->tab[dst->Index];
-        default:
-            debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);
-            break;
-    }
-    return 0;
-}
-
-static uint32_t r300_vs_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_DP3:
-        case TGSI_OPCODE_DP4:
-            return R300_VE_DOT_PRODUCT;
-        case TGSI_OPCODE_MUL:
-            return R300_VE_MULTIPLY;
-        case TGSI_OPCODE_ADD:
-        case TGSI_OPCODE_MOV:
-        case TGSI_OPCODE_SUB:
-        case TGSI_OPCODE_SWZ:
-            return R300_VE_ADD;
-        case TGSI_OPCODE_MAX:
-            return R300_VE_MAXIMUM;
-        case TGSI_OPCODE_SLT:
-            return R300_VE_SET_LESS_THAN;
-        case TGSI_OPCODE_RSQ:
-            return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;
-        case TGSI_OPCODE_MAD:
-            return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;
-        default:
-            break;
-    }
-    return 0;
-}
-
-static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
-{
-    if (reg->SrcRegister.Extended) {
-        return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
-            reg->SrcRegisterExtSwz.ExtSwizzleX |
-            (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) |
-            (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) |
-            (reg->SrcRegisterExtSwz.ExtSwizzleW << 9);
-    } else {
-        return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
-            reg->SrcRegister.SwizzleX |
-            (reg->SrcRegister.SwizzleY << 3) |
-            (reg->SrcRegister.SwizzleZ << 6) |
-            (reg->SrcRegister.SwizzleW << 9);
-    }
-}
-
-/* XXX icky icky icky icky */
-static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
-{
-    if (reg->SrcRegister.Extended) {
-        return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
-            reg->SrcRegisterExtSwz.ExtSwizzleX |
-            (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
-            (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
-            (reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
-    } else {
-        return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
-            reg->SrcRegister.SwizzleX |
-            (reg->SrcRegister.SwizzleX << 3) |
-            (reg->SrcRegister.SwizzleX << 6) |
-            (reg->SrcRegister.SwizzleX << 9);
-    }
-}
-
-/* XXX scalar stupidity */
-static void r300_vs_emit_inst(struct r300_vertex_shader* vs,
-                              struct r300_vs_asm* assembler,
-                              struct tgsi_full_src_register* src,
-                              struct tgsi_full_dst_register* dst,
-                              unsigned op,
-                              unsigned count,
-                              boolean is_scalar)
-{
-    int i = vs->instruction_count;
-    vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |
-        R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |
-        R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) |
-        R300_PVS_DST_WE(dst->DstRegister.WriteMask);
-    switch (count) {
-        case 3:
-            vs->instructions[i].inst3 =
-                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
-                            &src[2].SrcRegister)) |
-                R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
-                            &src[2].SrcRegister)) |
-                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));
-            /* Fall through */
-        case 2:
-            vs->instructions[i].inst2 =
-                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
-                            &src[1].SrcRegister)) |
-                R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
-                            &src[1].SrcRegister)) |
-                R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));
-            /* Fall through */
-        case 1:
-            vs->instructions[i].inst1 =
-                R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
-                            &src[0].SrcRegister)) |
-                R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
-                            &src[0].SrcRegister)) |
-                /* XXX the icky, it burns */
-                R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0])
-                        : r300_vs_swiz(&src[0]));
-            break;
-    }
-    vs->instruction_count++;
-}
-
-static void r300_vs_instruction(struct r300_vertex_shader* vs,
-                                struct r300_vs_asm* assembler,
-                                struct tgsi_full_instruction* inst)
-{
-    switch (inst->Instruction.Opcode) {
-        case TGSI_OPCODE_RSQ:
-            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode,
-                    1, TRUE);
-            break;
-        case TGSI_OPCODE_SUB:
-            inst->FullSrcRegisters[1].SrcRegister.Negate =
-                !inst->FullSrcRegisters[1].SrcRegister.Negate;
-            /* Fall through */
-        case TGSI_OPCODE_ADD:
-        case TGSI_OPCODE_MUL:
-        case TGSI_OPCODE_MAX:
-        case TGSI_OPCODE_SLT:
-            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode,
-                    2, FALSE);
-            break;
-        case TGSI_OPCODE_DP3:
-            /* Set alpha swizzle to zero for src0 and src1 */
-            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_ZERO;
-            if (!inst->FullSrcRegisters[1].SrcRegister.Extended) {
-                inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE;
-                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX =
-                    inst->FullSrcRegisters[1].SrcRegister.SwizzleX;
-                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY =
-                    inst->FullSrcRegisters[1].SrcRegister.SwizzleY;
-                inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ =
-                    inst->FullSrcRegisters[1].SrcRegister.SwizzleZ;
-            }
-            inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW =
-                TGSI_EXTSWIZZLE_ZERO;
-            /* Fall through */
-        case TGSI_OPCODE_DP4:
-            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode,
-                    2, FALSE);
-            break;
-        case TGSI_OPCODE_MOV:
-        case TGSI_OPCODE_SWZ:
-            inst->FullSrcRegisters[1] = r300_constant_zero;
-            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode,
-                    2, FALSE);
-            break;
-        case TGSI_OPCODE_MAD:
-            r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode,
-                    3, FALSE);
-            break;
-        case TGSI_OPCODE_END:
-            break;
-        default:
-            debug_printf("r300: vs: Bad opcode %d\n",
-                    inst->Instruction.Opcode);
-            break;
-    }
-}
-
-static void r300_vs_init(struct r300_vertex_shader* vs,
-                         struct r300_vs_asm* assembler)
+static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
 {
+    struct r300_vertex_shader * vs = c->UserData;
     struct tgsi_shader_info* info = &vs->info;
+    boolean pointsize = false;
+    int out_colors = 0;
+    int colors = 0;
+    int out_generic = 0;
+    int generic = 0;
     int i;
 
+    /* Fill in the input mapping */
+    for (i = 0; i < info->num_inputs; i++)
+        c->code->inputs[i] = i;
+
+    /* Fill in the output mapping */
     for (i = 0; i < info->num_outputs; i++) {
         switch (info->output_semantic_name[i]) {
             case TGSI_SEMANTIC_PSIZE:
-                assembler->point_size = TRUE;
+                pointsize = true;
                 break;
             case TGSI_SEMANTIC_COLOR:
-                assembler->out_colors++;
+                out_colors++;
                 break;
             case TGSI_SEMANTIC_FOG:
             case TGSI_SEMANTIC_GENERIC:
-                assembler->out_texcoords++;
+                out_generic++;
                 break;
         }
     }
 
-    vs->instruction_count = 0;
-}
-
-void r300_translate_vertex_shader(struct r300_context* r300,
-                                  struct r300_vertex_shader* vs)
-{
     struct tgsi_parse_context parser;
-    int i;
-    struct r300_constant_buffer* consts =
-        &r300->shader_constants[PIPE_SHADER_VERTEX];
-
-    struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm);
-    if (assembler == NULL) {
-        return;
-    }
-
-    /* Init assembler. */
-    r300_vs_init(vs, assembler);
-
-    /* Setup starting offset for immediates. */
-    assembler->imm_offset = consts->user_count;
 
     tgsi_parse_init(&parser, vs->state.tokens);
 
     while (!tgsi_parse_end_of_tokens(&parser)) {
         tgsi_parse_token(&parser);
 
-        /* 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_vs_declare(assembler, &parser.FullToken.FullDeclaration);
+        if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION)
+            continue;
+
+        struct tgsi_full_declaration * decl = &parser.FullToken.FullDeclaration;
+
+        if (decl->Declaration.File != TGSI_FILE_OUTPUT)
+            continue;
+
+        switch (decl->Semantic.SemanticName) {
+            case TGSI_SEMANTIC_POSITION:
+                c->code->outputs[decl->DeclarationRange.First] = 0;
                 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++;
+            case TGSI_SEMANTIC_PSIZE:
+                c->code->outputs[decl->DeclarationRange.First] = 1;
+                break;
+            case TGSI_SEMANTIC_COLOR:
+                c->code->outputs[decl->DeclarationRange.First] = 1 +
+                    (pointsize ? 1 : 0) +
+                    colors++;
+                break;
+            case TGSI_SEMANTIC_FOG:
+            case TGSI_SEMANTIC_GENERIC:
+                c->code->outputs[decl->DeclarationRange.First] = 1 +
+                    (pointsize ? 1 : 0) +
+                    out_colors +
+                    generic++;
                 break;
-            case TGSI_TOKEN_TYPE_INSTRUCTION:
-                r300_vs_instruction(vs, assembler,
-                        &parser.FullToken.FullInstruction);
+            default:
+                debug_printf("r300: vs: Bad semantic declaration %d\n",
+                    decl->Semantic.SemanticName);
                 break;
         }
     }
 
-    debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n",
-            assembler->tex_count, assembler->color_count,
-            assembler->tex_count + assembler->color_count);
+    tgsi_parse_free(&parser);
+}
 
-    consts->count = consts->user_count + assembler->imm_count;
-    vs->uses_imms = assembler->imm_count;
-    debug_printf("r300: vs: %d total constants, "
-            "%d from user and %d from immediates\n", consts->count,
-            consts->user_count, assembler->imm_count);
 
-    debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0],
-            assembler->tab[1], assembler->tab[2], assembler->tab[3]);
+void r300_translate_vertex_shader(struct r300_context* r300,
+                                  struct r300_vertex_shader* vs)
+{
+    struct r300_vertex_program_compiler compiler;
+    struct tgsi_to_rc ttr;
 
-    tgsi_dump(vs->state.tokens, 0);
-    /* XXX finish r300 vertex shader dumper */
-    r300_vs_dump(vs);
+    printf("translate_vertex_shader\n");
 
-    tgsi_parse_free(&parser);
-    FREE(assembler);
+    /* Setup the compiler */
+    rc_init(&compiler.Base);
+
+    compiler.Base.Debug = 1;
+    compiler.code = &vs->code;
+    compiler.UserData = vs;
+
+    if (compiler.Base.Debug) {
+        debug_printf("r300: Initial vertex program\n");
+        tgsi_dump(vs->state.tokens, 0);
+    }
+
+    /* Translate TGSI to our internal representation */
+    ttr.compiler = &compiler.Base;
+    ttr.info = &vs->info;
+
+    r300_tgsi_to_rc(&ttr, vs->state.tokens);
+
+    compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs);
+    compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
+
+    /* Invoke the compiler */
+    r3xx_compile_vertex_program(&compiler);
+    if (compiler.Base.Error) {
+        /* Todo: Fail gracefully */
+        fprintf(stderr, "r300 VP: Compiler error\n");
+        abort();
+    }
 
     /* And, finally... */
+    rc_destroy(&compiler.Base);
     vs->translated = TRUE;
 }
+
+
+/* XXX get these to r300_reg */
+#define R300_PVS_DST_OPCODE(x)   ((x) << 0)
+#   define R300_VE_DOT_PRODUCT            1
+#   define R300_VE_MULTIPLY               2
+#   define R300_VE_ADD                    3
+#   define R300_VE_MAXIMUM                7
+#   define R300_VE_SET_LESS_THAN          10
+#define R300_PVS_DST_MATH_INST     (1 << 6)
+#   define R300_ME_RECIP_DX               6
+#define R300_PVS_DST_MACRO_INST    (1 << 7)
+#   define R300_PVS_MACRO_OP_2CLK_MADD    0
+#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
+#   define R300_PVS_DST_REG_TEMPORARY     0
+#   define R300_PVS_DST_REG_A0            1
+#   define R300_PVS_DST_REG_OUT           2
+#   define R300_PVS_DST_REG_OUT_REPL_X    3
+#   define R300_PVS_DST_REG_ALT_TEMPORARY 4
+#   define R300_PVS_DST_REG_INPUT         5
+#define R300_PVS_DST_OFFSET(x)   ((x) << 13)
+#define R300_PVS_DST_WE(x)       ((x) << 20)
+#define R300_PVS_DST_WE_XYZW     (0xf << 20)
+
+#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
+#   define R300_PVS_SRC_REG_TEMPORARY     0
+#   define R300_PVS_SRC_REG_INPUT         1
+#   define R300_PVS_SRC_REG_CONSTANT      2
+#   define R300_PVS_SRC_REG_ALT_TEMPORARY 3
+#define R300_PVS_SRC_OFFSET(x)   ((x) << 5)
+#define R300_PVS_SRC_SWIZZLE(x)  ((x) << 13)
+#   define R300_PVS_SRC_SELECT_X          0
+#   define R300_PVS_SRC_SELECT_Y          1
+#   define R300_PVS_SRC_SELECT_Z          2
+#   define R300_PVS_SRC_SELECT_W          3
+#   define R300_PVS_SRC_SELECT_FORCE_0    4
+#   define R300_PVS_SRC_SELECT_FORCE_1    5
+#   define R300_PVS_SRC_SWIZZLE_XYZW \
+    ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
+     (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
+#   define R300_PVS_SRC_SWIZZLE_ZERO \
+    ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
+     (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
+      (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
+#   define R300_PVS_SRC_SWIZZLE_ONE \
+    ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
+     (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
+      (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
+#define R300_PVS_MODIFIER_X        (1 << 25)
+#define R300_PVS_MODIFIER_Y        (1 << 26)
+#define R300_PVS_MODIFIER_Z        (1 << 27)
+#define R300_PVS_MODIFIER_W        (1 << 28)
+#define R300_PVS_NEGATE_XYZW \
+    (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
+     R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+
+struct r300_vertex_program_code r300_passthrough_vertex_shader = {
+    .length = 8, /* two instructions */
+
+    /* MOV out[0], in[0] */
+    .body.d[0] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
+    .body.d[1] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
+    .body.d[2] = R300_PVS_SRC_SWIZZLE_ZERO,
+    .body.d[3] = 0x0,
+
+    /* MOV out[1], in[1] */
+    .body.d[4] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
+    .body.d[5] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
+    .body.d[6] = R300_PVS_SRC_SWIZZLE_ZERO,
+    .body.d[7] = 0x0,
+
+    .inputs[0] = 0,
+    .inputs[1] = 1,
+    .outputs[0] = 0,
+    .outputs[1] = 1,
+
+    .InputsRead = 3,
+    .OutputsWritten = 3
+};
+
index 165d717812218b82cf43e7bbb2829de68d8dc93e..2a4ce315e3213c06f85244d9ddffd8e381e95538 100644 (file)
 #ifndef R300_VS_H
 #define R300_VS_H
 
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_dump.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h"
 
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
+#include "radeon_code.h"
 
-/* XXX get these to r300_reg */
-#define R300_PVS_DST_OPCODE(x)   ((x) << 0)
-#   define R300_VE_DOT_PRODUCT            1
-#   define R300_VE_MULTIPLY               2
-#   define R300_VE_ADD                    3
-#   define R300_VE_MAXIMUM                7
-#   define R300_VE_SET_LESS_THAN          10
-#define R300_PVS_DST_MATH_INST     (1 << 6)
-#   define R300_ME_RECIP_DX               6
-#define R300_PVS_DST_MACRO_INST    (1 << 7)
-#   define R300_PVS_MACRO_OP_2CLK_MADD    0
-#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
-#   define R300_PVS_DST_REG_TEMPORARY     0
-#   define R300_PVS_DST_REG_A0            1
-#   define R300_PVS_DST_REG_OUT           2
-#   define R300_PVS_DST_REG_OUT_REPL_X    3
-#   define R300_PVS_DST_REG_ALT_TEMPORARY 4
-#   define R300_PVS_DST_REG_INPUT         5
-#define R300_PVS_DST_OFFSET(x)   ((x) << 13)
-#define R300_PVS_DST_WE(x)       ((x) << 20)
-#define R300_PVS_DST_WE_XYZW     (0xf << 20)
+struct r300_context;
 
-#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
-#   define R300_PVS_SRC_REG_TEMPORARY     0
-#   define R300_PVS_SRC_REG_INPUT         1
-#   define R300_PVS_SRC_REG_CONSTANT      2
-#   define R300_PVS_SRC_REG_ALT_TEMPORARY 3
-#define R300_PVS_SRC_OFFSET(x)   ((x) << 5)
-#define R300_PVS_SRC_SWIZZLE(x)  ((x) << 13)
-#   define R300_PVS_SRC_SELECT_X          0
-#   define R300_PVS_SRC_SELECT_Y          1
-#   define R300_PVS_SRC_SELECT_Z          2
-#   define R300_PVS_SRC_SELECT_W          3
-#   define R300_PVS_SRC_SELECT_FORCE_0    4
-#   define R300_PVS_SRC_SELECT_FORCE_1    5
-#   define R300_PVS_SRC_SWIZZLE_XYZW \
-    ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
-     (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
-#   define R300_PVS_SRC_SWIZZLE_ZERO \
-    ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
-     (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
-      (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
-#   define R300_PVS_SRC_SWIZZLE_ONE \
-    ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
-     (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
-      (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
-#define R300_PVS_MODIFIER_X        (1 << 25)
-#define R300_PVS_MODIFIER_Y        (1 << 26)
-#define R300_PVS_MODIFIER_Z        (1 << 27)
-#define R300_PVS_MODIFIER_W        (1 << 28)
-#define R300_PVS_NEGATE_XYZW \
-    (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
-     R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+struct r300_vertex_shader {
+    /* Parent class */
+    struct pipe_shader_state state;
+    struct tgsi_shader_info info;
 
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_vs_asm {
-    /* Pipe context. */
-    struct r300_context* r300;
-    /* Number of colors. */
-    unsigned color_count;
-    /* Number of texcoords. */
-    unsigned tex_count;
-    /* 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;
-    /* Number of colors to write. */
-    unsigned out_colors;
-    /* Number of texcoords to write. */
-    unsigned out_texcoords;
-    /* Whether to emit point size. */
-    boolean point_size;
-    /* Tab of declared outputs to OVM outputs. */
-    unsigned tab[16];
-};
+    /* Fallback shader, because Draw has issues */
+    struct draw_vertex_shader* draw;
 
-static struct r300_vertex_shader r300_passthrough_vertex_shader = {
-        /* XXX translate these back into normal instructions */
-    .instruction_count = 2,
-    .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
-        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
-        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
-    .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
-        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
-    .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
-    .instructions[0].inst3 = 0x0,
-    .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
-        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
-        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
-    .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
-        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
-    .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
-    .instructions[1].inst3 = 0x0,
-};
+    /* Has this shader been translated yet? */
+    boolean translated;
 
-static struct r300_vertex_shader r300_texture_vertex_shader = {
-        /* XXX translate these back into normal instructions */
-    .instruction_count = 2,
-    .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
-        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
-        R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
-    .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
-        R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
-    .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
-    .instructions[0].inst3 = 0x0,
-    .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
-        R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
-        R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
-    .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
-        R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
-    .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
-    .instructions[1].inst3 = 0x0,
+    /* Machine code (if translated) */
+    struct r300_vertex_program_code code;
 };
 
+
+extern struct r300_vertex_program_code r300_passthrough_vertex_shader;
+
 void r300_translate_vertex_shader(struct r300_context* r300,
                                   struct r300_vertex_shader* vs);
 
index 3da39ec25269c07c75d86f840827fd8d2c5ba2a1..592898d8998da51caf79ba9342447d083d8bbe20 100644 (file)
@@ -66,6 +66,8 @@ static struct r3xx_fragment_shader r3xx_texture_fragment_shader = {
         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);
 
index 629e587be4d0b57f7062592468b910845890bd29..7e62c3352b2c2c22c8009f18b567247cbf9beb32 100644 (file)
@@ -122,6 +122,8 @@ static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {
         R500_ALU_RGBA_A_SWIZ_0,
 };
 
+struct r300_fs_asm;
+
 void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
                       struct r300_fs_asm* assembler);