r300-gallium: organize fragment/vertex shaders
authorJoakim Sindholt <opensource@zhasha.com>
Thu, 25 Jun 2009 23:08:13 +0000 (01:08 +0200)
committerJoakim Sindholt <opensource@zhasha.com>
Thu, 25 Jun 2009 23:13:06 +0000 (01:13 +0200)
Appart from separating r3xx/r5xx fragment shaders, a more consistent
naming scheme has been applied. From now on:
r300 = all chips
r3xx = R300/R400 only
r5xx = R500 only
This way r300_fragment_shader is the master struct, and the structs
r3xx_fragment_shader and r5xx_fragment_shader inherits it.

24 files changed:
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r300/SConscript
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_fs.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_fs.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_fs_inlines.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_shader_inlines.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_shader.c [deleted file]
src/gallium/drivers/r300/r300_state_shader.h [deleted file]
src/gallium/drivers/r300/r300_state_tcl.c [deleted file]
src/gallium/drivers/r300/r300_state_tcl.h [deleted file]
src/gallium/drivers/r300/r300_surface.c
src/gallium/drivers/r300/r300_surface.h
src/gallium/drivers/r300/r300_vs.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_vs.h [new file with mode: 0644]
src/gallium/drivers/r300/r3xx_fs.c [new file with mode: 0644]
src/gallium/drivers/r300/r3xx_fs.h [new file with mode: 0644]
src/gallium/drivers/r300/r5xx_fs.c [new file with mode: 0644]
src/gallium/drivers/r300/r5xx_fs.h [new file with mode: 0644]

index e44f9b9dfc5327150bf116ec162c0561872dc3ec..faceec9842fe6894c9234d910c01ba8ddbe1911e 100644 (file)
@@ -4,20 +4,22 @@ include $(TOP)/configs/current
 LIBNAME = r300
 
 C_SOURCES = \
+       r3xx_fs.c \
+       r5xx_fs.c \
        r300_chipset.c \
        r300_clear.c \
        r300_context.c \
        r300_debug.c \
        r300_emit.c \
        r300_flush.c \
+       r300_fs.c \
        r300_query.c \
        r300_render.c \
        r300_screen.c \
        r300_state.c \
        r300_state_derived.c \
        r300_state_invariant.c \
-       r300_state_shader.c \
-       r300_state_tcl.c \
+       r300_vs.c \
        r300_surface.c \
        r300_texture.c
 
index 182ed2d459a8cb1de2ce683868e478160ead2db7..493d7b28bc3b4e60080e441a413c006531e0896e 100644 (file)
@@ -5,20 +5,22 @@ env = env.Clone()
 r300 = env.ConvenienceLibrary(
     target = 'r300',
     source = [
+        'r3xx_fs.c',
+        'r5xx_fs.c',
         'r300_chipset.c',
         'r300_clear.c',
         'r300_context.c',
         'r300_debug.c',
         'r300_emit.c',
         'r300_flush.c',
+        'r300_fs.c',
         'r300_query.c',
         'r300_render.c',
         'r300_screen.c',
         'r300_state.c',
         'r300_state_derived.c',
         'r300_state_invariant.c',
-        'r300_state_shader.c',
-        'r300_state_tcl.c',
+        'r300_vs.c',
         'r300_surface.c',
         'r300_texture.c',
     ])
index 27bc7fd1a930d80e0f1e0435896c68f845d0877c..ae7857498fc7a256f3470967d1aa9489becdf4ab 100644 (file)
@@ -149,7 +149,7 @@ struct r300_constant_buffer {
     unsigned count;
 };
 
-struct r3xx_fragment_shader {
+struct r300_fragment_shader {
     /* Parent class */
     struct pipe_shader_state state;
     struct tgsi_shader_info info;
@@ -165,9 +165,9 @@ struct r3xx_fragment_shader {
     boolean uses_imms;
 };
 
-struct r300_fragment_shader {
+struct r3xx_fragment_shader {
     /* Parent class */
-    struct r3xx_fragment_shader shader;
+    struct r300_fragment_shader shader;
 
     /* Number of ALU instructions */
     int alu_instruction_count;
@@ -190,9 +190,9 @@ struct r300_fragment_shader {
     } instructions[64]; /* XXX magic num */
 };
 
-struct r500_fragment_shader {
+struct r5xx_fragment_shader {
     /* Parent class */
-    struct r3xx_fragment_shader shader;
+    struct r300_fragment_shader shader;
 
     /* Number of used instructions */
     int instruction_count;
@@ -300,7 +300,7 @@ struct r300_context {
     /* Depth, stencil, and alpha state. */
     struct r300_dsa_state* dsa_state;
     /* Fragment shader. */
-    struct r3xx_fragment_shader* fs;
+    struct r300_fragment_shader* fs;
     /* Framebuffer state. We currently don't need our own version of this. */
     struct pipe_framebuffer_state framebuffer_state;
     /* Rasterizer state. */
index 678cd2b81210dbae439b4332c794a8080af5f706..c83e8526cf7938f4ec8430f15282dd05828d23b5 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "r300_debug.h"
 
-static void r300_dump_fs(struct r300_fragment_shader* fs)
+void r3xx_dump_fs(struct r3xx_fragment_shader* fs)
 {
     int i;
 
@@ -30,7 +30,7 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)
     }
 }
 
-void r500_fs_dump(struct r500_fragment_shader* fs)
+void r5xx_fs_dump(struct r5xx_fragment_shader* fs)
 {
     int i;
     uint32_t inst;
@@ -58,8 +58,8 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
                 inst & R500_INST_NOP ? "NOP" : "",
                 inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");
         debug_printf("wmask: %s omask: %s\n",
-                r500_fs_mask[(inst >> 11) & 0xf],
-                r500_fs_mask[(inst >> 15) & 0xf]);
+                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:
@@ -85,36 +85,36 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
                 debug_printf("    3: RGB_INST   0x%08x:", inst);
                 debug_printf("rgb_A_src:%d %s/%s/%s %d "
                         "rgb_B_src:%d %s/%s/%s %d\n",
-                        inst & 0x3, r500_fs_swiz[(inst >> 2) & 0x7],
-                        r500_fs_swiz[(inst >> 5) & 0x7],
-                        r500_fs_swiz[(inst >> 8) & 0x7],
+                        inst & 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,
-                        r500_fs_swiz[(inst >> 15) & 0x7],
-                        r500_fs_swiz[(inst >> 18) & 0x7],
-                        r500_fs_swiz[(inst >> 21) & 0x7],
+                        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",
-                        r500_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
+                        r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
                         inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
-                        r500_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
-                        (inst >> 19) & 0x3, r500_fs_swiz[(inst >> 21) & 0x7],
+                        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",
-                        r500_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
+                        r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
                         inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
-                        r500_fs_swiz[(inst >> 14) & 0x7],
-                        r500_fs_swiz[(inst >> 17) & 0x7],
-                        r500_fs_swiz[(inst >> 20) & 0x7],
+                        r5xx_fs_swiz[(inst >> 14) & 0x7],
+                        r5xx_fs_swiz[(inst >> 17) & 0x7],
+                        r5xx_fs_swiz[(inst >> 20) & 0x7],
                         (inst >> 23) & 0x3, (inst >> 25) & 0x3,
-                        r500_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
+                        r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
                 break;
             case R500_INST_TYPE_FC:
                 /* XXX don't even bother yet */
@@ -124,7 +124,7 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
                 debug_printf("    1: TEX_INST   0x%08x: id: %d "
                         "op:%s, %s, %s %s\n",
                         inst, (inst >> 16) & 0xf,
-                        r500_fs_tex[(inst >> 22) & 0x7],
+                        r5xx_fs_tex[(inst >> 22) & 0x7],
                         (inst & (1 << 25)) ? "ACQ" : "",
                         (inst & (1 << 26)) ? "IGNUNC" : "",
                         (inst & (1 << 27)) ? "UNSCALED" : "SCALED");
@@ -133,15 +133,15 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
                 debug_printf("    2: TEX_ADDR   0x%08x: "
                         "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",
                         inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "",
-                        r500_fs_swiz[(inst >> 8) & 0x3],
-                        r500_fs_swiz[(inst >> 10) & 0x3],
-                        r500_fs_swiz[(inst >> 12) & 0x3],
-                        r500_fs_swiz[(inst >> 14) & 0x3],
+                        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)" : "",
-                        r500_fs_swiz[(inst >> 24) & 0x3],
-                        r500_fs_swiz[(inst >> 26) & 0x3],
-                        r500_fs_swiz[(inst >> 28) & 0x3],
-                        r500_fs_swiz[(inst >> 30) & 0x3]);
+                        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);
index c86410ec0a964cb2bc69f90e9b20cedeb1ae4e67..6b58c1e2501851ffa9c7c29b3fc507f12d79afe4 100644 (file)
 #define R300_DEBUG_H
 
 #include "r300_reg.h"
-#include "r300_state_shader.h"
-#include "r300_state_tcl.h"
+#include "r300_fs.h"
+#include "r300_vs.h"
 
-static char* r500_fs_swiz[] = {
+static char* r5xx_fs_swiz[] = {
     " R",
     " G",
     " B",
@@ -38,7 +38,7 @@ static char* r500_fs_swiz[] = {
     " U",
 };
 
-static char* r500_fs_op_rgb[] = {
+static char* r5xx_fs_op_rgb[] = {
     "MAD",
     "DP3",
     "DP4",
@@ -54,7 +54,7 @@ static char* r500_fs_op_rgb[] = {
     "MDV",
 };
 
-static char* r500_fs_op_alpha[] = {
+static char* r5xx_fs_op_alpha[] = {
     "MAD",
     " DP",
     "MIN",
@@ -73,7 +73,7 @@ static char* r500_fs_op_alpha[] = {
     "MDV",
 };
 
-static char* r500_fs_mask[] = {
+static char* r5xx_fs_mask[] = {
     "NONE",
     "R   ",
     " G  ",
@@ -92,7 +92,7 @@ static char* r500_fs_mask[] = {
     "RGBA",
 };
 
-static char* r500_fs_tex[] = {
+static char* r5xx_fs_tex[] = {
     "    NOP",
     "     LD",
     "TEXKILL",
@@ -203,7 +203,8 @@ static char* r300_vs_swiz_debug[] = {
     "U",
 };
 
-void r500_fs_dump(struct r500_fragment_shader* fs);
+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);
 
index 93cf6909a33a824dd07774a6892525074f230422..1d297e859304fbac00bfc4a776f1af04536d94b2 100644 (file)
@@ -110,7 +110,7 @@ void r300_emit_dsa_state(struct r300_context* r300,
 }
 
 void r300_emit_fragment_shader(struct r300_context* r300,
-                               struct r300_fragment_shader* fs)
+                               struct r3xx_fragment_shader* fs)
 {
     int i;
     CS_LOCALS(r300);
@@ -142,7 +142,7 @@ void r300_emit_fragment_shader(struct r300_context* r300,
 }
 
 void r500_emit_fragment_shader(struct r300_context* r300,
-                               struct r500_fragment_shader* fs)
+                               struct r5xx_fragment_shader* fs)
 {
     int i;
     struct r300_constant_buffer* constants =
@@ -570,10 +570,10 @@ validate:
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
         if (r300screen->caps->is_r500) {
             r500_emit_fragment_shader(r300,
-                (struct r500_fragment_shader*)r300->fs);
+                (struct r5xx_fragment_shader*)r300->fs);
         } else {
             r300_emit_fragment_shader(r300,
-                (struct r300_fragment_shader*)r300->fs);
+                (struct r3xx_fragment_shader*)r300->fs);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
     }
index 946f625bd89df5da5ce011f7eb31e1788fdd56e9..196b6c58d3c0d92fc9477a03f9d745871d1bb8a1 100644 (file)
@@ -43,10 +43,10 @@ void r300_emit_dsa_state(struct r300_context* r300,
                          struct r300_dsa_state* dsa);
 
 void r300_emit_fragment_shader(struct r300_context* r300,
-                               struct r300_fragment_shader* fs);
+                               struct r3xx_fragment_shader* fs);
 
 void r500_emit_fragment_shader(struct r300_context* r300,
-                               struct r500_fragment_shader* fs);
+                               struct r5xx_fragment_shader* fs);
 
 void r300_emit_fb_state(struct r300_context* r300,
                         struct pipe_framebuffer_state* fb);
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
new file mode 100644 (file)
index 0000000..4b30430
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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. */
+
+#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];
+
+    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;
+    }
+
+    tgsi_parse_init(&parser, fs->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_fs_declare(assembler, &parser.FullToken.FullDeclaration);
+                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.ImmediateFloat32[i]
+                        .Float;
+                }
+                assembler->imm_count++;
+                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);
+                }
+                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);
+    }
+
+    tgsi_dump(fs->state.tokens, 0);
+    /* XXX finish r300 dumper too */
+    if (is_r500) {
+        r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
+    }
+
+    tgsi_parse_free(&parser);
+    FREE(assembler);
+}
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
new file mode 100644 (file)
index 0000000..18deb7a
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_H
+#define R300_FS_H
+
+#include "tgsi/tgsi_dump.h"
+
+#include "r300_context.h"
+#include "r3xx_fs.h"
+#include "r5xx_fs.h"
+
+void r300_translate_fragment_shader(struct r300_context* r300,
+                                    struct r300_fragment_shader* fs);
+
+    #endif /* R300_FS_H */
diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h
new file mode 100644 (file)
index 0000000..be4be94
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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 */
diff --git a/src/gallium/drivers/r300/r300_shader_inlines.h b/src/gallium/drivers/r300/r300_shader_inlines.h
new file mode 100644 (file)
index 0000000..a04f45b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009 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_SHADER_INLINES_H
+#define R300_SHADER_INLINES_H
+
+/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
+ * not using enough of it. */
+static const struct tgsi_full_src_register r300_constant_zero = {
+    .SrcRegister.Extended = TRUE,
+    .SrcRegister.File = TGSI_FILE_NULL,
+    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
+    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
+    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
+    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
+};
+
+static const struct tgsi_full_src_register r300_constant_one = {
+    .SrcRegister.Extended = TRUE,
+    .SrcRegister.File = TGSI_FILE_NULL,
+    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE,
+    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE,
+    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE,
+    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE,
+};
+
+#endif /* R300_SHADER_INLINES_H */
index 01e2b511534af1b20c2f10408afd22a4f55b0d1f..d70ef6ba28f3a6719093351abc8d363fa5c78cba 100644 (file)
@@ -29,7 +29,7 @@
 #include "r300_context.h"
 #include "r300_reg.h"
 #include "r300_state_inlines.h"
-#include "r300_state_shader.h"
+#include "r300_fs.h"
 
 /* r300_state: Functions used to intialize state context by translating
  * Gallium state objects into semi-native r300 state objects. */
@@ -283,14 +283,12 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
                                   const struct pipe_shader_state* shader)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r3xx_fragment_shader* fs = NULL;
+    struct r300_fragment_shader* fs = NULL;
 
     if (r300_screen(r300->context.screen)->caps->is_r500) {
-        fs =
-            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader);
+        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);
     } else {
-        fs =
-            (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
+        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);
     }
 
     /* Copy state directly into shader. */
@@ -306,7 +304,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
 static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
+    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
 
     if (fs == NULL) {
         r300->fs = NULL;
@@ -324,7 +322,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
 /* Delete fragment shader state. */
 static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
 {
-    struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
+    struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
     FREE(fs->state.tokens);
     FREE(shader);
 }
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
deleted file mode 100644 (file)
index cc7f6a7..0000000
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright 2008 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_state_shader.h"
-
-static 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));
-}
-
-static INLINE unsigned r500_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 r500_rgba_swiz(struct tgsi_full_src_register* reg)
-{
-    if (reg->SrcRegister.Extended) {
-        return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
-            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
-            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
-            (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
-    } else {
-        return reg->SrcRegister.SwizzleX |
-            (reg->SrcRegister.SwizzleY << 3) |
-            (reg->SrcRegister.SwizzleZ << 6) |
-            (reg->SrcRegister.SwizzleW << 9);
-    }
-}
-
-static uint32_t r500_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 r500_rgb_swiz(struct tgsi_full_src_register* reg)
-{
-    /* Only the first 9 bits... */
-    return (r500_rgba_swiz(reg) & 0x1ff) |
-        (reg->SrcRegister.Negate ? (1 << 9) : 0) |
-        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg)
-{
-    /* Only the last 3 bits... */
-    return (r500_rgba_swiz(reg) >> 9) |
-        (reg->SrcRegister.Negate ? (1 << 9) : 0) |
-        (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r300_rgb_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_MOV:
-            return R300_ALU_OUTC_CMP;
-        default:
-            return 0;
-    }
-}
-
-static INLINE uint32_t r300_alpha_op(unsigned op)
-{
-    switch (op) {
-        case TGSI_OPCODE_MOV:
-            return R300_ALU_OUTA_CMP;
-        default:
-            return 0;
-    }
-}
-
-static INLINE uint32_t r500_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 r500_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 r500_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;
-    }
-}
-
-static INLINE void r300_emit_maths(struct r300_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;
-
-    fs->instructions[i].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_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_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
-        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
-        r300_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;
-
-    fs->alu_instruction_count++;
-}
-
-/* Setup an ALU operation. */
-static INLINE void r500_emit_maths(struct r500_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(r500_rgb_swiz(&src[2])) |
-                R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
-                R500_SWIZ_ALPHA_C(r500_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(r500_rgb_swiz(&src[1]));
-            fs->instructions[i].inst4 |=
-                R500_ALPHA_SEL_B_SRC1 |
-                R500_SWIZ_ALPHA_B(r500_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(r500_rgb_swiz(&src[0]));
-            fs->instructions[i].inst4 |=
-                R500_ALPHA_SEL_A_SRC0 |
-                R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0]));
-            break;
-    }
-
-    fs->instructions[i].inst4 |= r500_alpha_op(op);
-    fs->instructions[i].inst5 |= r500_rgba_op(op);
-
-    fs->instruction_count++;
-}
-
-static INLINE void r500_emit_tex(struct r500_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 |
-        r500_tex_op(op);
-    fs->instructions[i].inst2 =
-        R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
-        R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) |
-        R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
-        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
-        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
-
-    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] = r500_constant_zero;
-        r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
-    } else {
-        fs->instruction_count++;
-    }
-}
-
-static void r300_fs_instruction(struct r300_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] = r500_constant_zero;
-            r300_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;
-    }
-}
-
-static void r500_fs_instruction(struct r500_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:
-            r500_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:
-            r500_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];
-            r500_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] = r500_constant_one;
-            r500_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] = r500_constant_zero;
-            r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
-            break;
-        case TGSI_OPCODE_MAD:
-            r500_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] = r500_constant_zero;
-            r500_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;
-            r500_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];
-            r500_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;
-            r500_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] = r500_constant_zero;
-            r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
-                    &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
-            inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
-            r500_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:
-            r500_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;
-    }
-}
-
-static void r300_fs_finalize(struct r3xx_fragment_shader* fs,
-                             struct r300_fs_asm* assembler)
-{
-    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
-}
-
-static void r500_fs_finalize(struct r500_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 r300_translate_fragment_shader(struct r300_context* r300,
-                                    struct r3xx_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];
-
-    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 r500_fragment_shader*)fs)->instruction_count = 0;
-    }
-
-    tgsi_parse_init(&parser, fs->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_fs_declare(assembler, &parser.FullToken.FullDeclaration);
-                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.ImmediateFloat32[i]
-                        .Float;
-                }
-                assembler->imm_count++;
-                break;
-            case TGSI_TOKEN_TYPE_INSTRUCTION:
-                if (is_r500) {
-                    r500_fs_instruction((struct r500_fragment_shader*)fs,
-                            assembler, &parser.FullToken.FullInstruction);
-                } else {
-                    r300_fs_instruction((struct r300_fragment_shader*)fs,
-                            assembler, &parser.FullToken.FullInstruction);
-                }
-                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);
-    r300_fs_finalize(fs, assembler);
-    if (is_r500) {
-        r500_fs_finalize((struct r500_fragment_shader*)fs, assembler);
-    }
-
-    tgsi_dump(fs->state.tokens);
-    /* XXX finish r300 dumper too */
-    if (is_r500) {
-        r500_fs_dump((struct r500_fragment_shader*)fs);
-    }
-
-    tgsi_parse_free(&parser);
-    FREE(assembler);
-}
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
deleted file mode 100644 (file)
index b608740..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2008 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_STATE_SHADER_H
-#define R300_STATE_SHADER_H
-
-#include "tgsi/tgsi_parse.h"
-
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.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)
-
-/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
- * not using enough of it. */
-static const struct tgsi_full_src_register r500_constant_zero = {
-    .SrcRegister.Extended = TRUE,
-    .SrcRegister.File = TGSI_FILE_NULL,
-    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
-};
-
-static const struct tgsi_full_src_register r500_constant_one = {
-    .SrcRegister.Extended = TRUE,
-    .SrcRegister.File = TGSI_FILE_NULL,
-    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ONE,
-    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ONE,
-    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ONE,
-    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ONE,
-};
-
-/* 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;
-};
-
-void r300_translate_fragment_shader(struct r300_context* r300,
-                           struct r3xx_fragment_shader* fs);
-
-static struct r300_fragment_shader r300_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 r500_fragment_shader r500_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 r300_fragment_shader r300_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,
-};
-
-static struct r500_fragment_shader r500_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,
-};
-
-#endif /* R300_STATE_SHADER_H */
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
deleted file mode 100644 (file)
index 8cf8250..0000000
+++ /dev/null
@@ -1,412 +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_state_tcl.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;
-    }
-}
-
-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;
-}
-
-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;
-}
-
-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)
-{
-    struct tgsi_shader_info* info = &vs->info;
-    int i;
-
-    for (i = 0; i < info->num_outputs; i++) {
-        switch (info->output_semantic_name[i]) {
-            case TGSI_SEMANTIC_PSIZE:
-                assembler->point_size = TRUE;
-                break;
-            case TGSI_SEMANTIC_COLOR:
-                assembler->out_colors++;
-                break;
-            case TGSI_SEMANTIC_FOG:
-            case TGSI_SEMANTIC_GENERIC:
-                assembler->out_texcoords++;
-                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);
-                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.ImmediateFloat32[i]
-                        .Float;
-                }
-                assembler->imm_count++;
-                break;
-            case TGSI_TOKEN_TYPE_INSTRUCTION:
-                r300_vs_instruction(vs, assembler,
-                        &parser.FullToken.FullInstruction);
-                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);
-
-    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]);
-
-    tgsi_dump(vs->state.tokens);
-    /* XXX finish r300 vertex shader dumper */
-    r300_vs_dump(vs);
-
-    tgsi_parse_free(&parser);
-    FREE(assembler);
-}
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
deleted file mode 100644 (file)
index 2c8b586..0000000
+++ /dev/null
@@ -1,164 +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_STATE_TCL_H
-#define R300_STATE_TCL_H
-
-#include "tgsi/tgsi_parse.h"
-
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.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)
-
-#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)
-
-static const struct tgsi_full_src_register r300_constant_zero = {
-    .SrcRegister.Extended = TRUE,
-    .SrcRegister.File = TGSI_FILE_NULL,
-    .SrcRegisterExtSwz.ExtSwizzleX = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleY = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleZ = TGSI_EXTSWIZZLE_ZERO,
-    .SrcRegisterExtSwz.ExtSwizzleW = TGSI_EXTSWIZZLE_ZERO,
-};
-
-/* 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];
-};
-
-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,
-};
-
-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,
-};
-
-void r300_translate_vertex_shader(struct r300_context* r300,
-                                  struct r300_vertex_shader* vs);
-
-#endif /* R300_STATE_TCL_H */
index c9e2dff14ed7fef81e59fe3cca8281b8cb9be625..75b5096919049ac0f1ad422e8362da9e92f71754 100644 (file)
@@ -151,11 +151,11 @@ validate:
 
     /* Fragment shader setup */
     if (caps->is_r500) {
-        r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader);
-        r300_emit_rs_block_state(r300, &r500_rs_block_clear_state);
+        r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
+        r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
     } else {
-        r300_emit_fragment_shader(r300, &r300_passthrough_fragment_shader);
-        r300_emit_rs_block_state(r300, &r300_rs_block_clear_state);
+        r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
+        r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
     }
 
     BEGIN_CS(26);
@@ -291,11 +291,11 @@ validate:
 
     /* Fragment shader setup */
     if (caps->is_r500) {
-        r500_emit_fragment_shader(r300, &r500_texture_fragment_shader);
-        r300_emit_rs_block_state(r300, &r500_rs_block_copy_state);
+        r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
+        r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
     } else {
-        r300_emit_fragment_shader(r300, &r300_texture_fragment_shader);
-        r300_emit_rs_block_state(r300, &r300_rs_block_copy_state);
+        r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
+        r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
     }
 
     BEGIN_CS(30);
index 9a4c39f58bdbf5a1fe80a1eab7c1b8c10180efc4..d01f0b143f51a378b9820a45ed7d638a66ceefec 100644 (file)
@@ -31,8 +31,8 @@
 #include "r300_context.h"
 #include "r300_cs.h"
 #include "r300_emit.h"
-#include "r300_state_shader.h"
-#include "r300_state_tcl.h"
+#include "r300_fs.h"
+#include "r300_vs.h"
 #include "r300_state_inlines.h"
 
 static struct r300_blend_state blend_clear_state = {
@@ -72,7 +72,7 @@ static struct r300_rs_state rs_clear_state = {
     .color_control = R300_SHADE_MODEL_FLAT,
 };
 
-static struct r300_rs_block r300_rs_block_clear_state = {
+static struct r300_rs_block r3xx_rs_block_clear_state = {
     .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
         R500_RS_SEL_T(R300_RS_SEL_K0) |
         R500_RS_SEL_R(R300_RS_SEL_K0) |
@@ -82,7 +82,7 @@ static struct r300_rs_block r300_rs_block_clear_state = {
     .inst_count = 0,
 };
 
-static struct r300_rs_block r500_rs_block_clear_state = {
+static struct r300_rs_block r5xx_rs_block_clear_state = {
     .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) |
         R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
         R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
@@ -94,7 +94,7 @@ static struct r300_rs_block r500_rs_block_clear_state = {
 
 /* The following state is used for surface_copy only. */
 
-static struct r300_rs_block r300_rs_block_copy_state = {
+static struct r300_rs_block r3xx_rs_block_copy_state = {
     .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
         R500_RS_SEL_T(R300_RS_SEL_K0) |
         R500_RS_SEL_R(R300_RS_SEL_K0) |
@@ -104,7 +104,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {
     .inst_count = R300_RS_TX_OFFSET(0),
 };
 
-static struct r300_rs_block r500_rs_block_copy_state = {
+static struct r300_rs_block r5xx_rs_block_copy_state = {
     .ip[0] = R500_RS_SEL_S(0) |
         R500_RS_SEL_T(1) |
         R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
new file mode 100644 (file)
index 0000000..f87435f
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * 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_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;
+    }
+}
+
+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;
+}
+
+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;
+}
+
+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)
+{
+    struct tgsi_shader_info* info = &vs->info;
+    int i;
+
+    for (i = 0; i < info->num_outputs; i++) {
+        switch (info->output_semantic_name[i]) {
+            case TGSI_SEMANTIC_PSIZE:
+                assembler->point_size = TRUE;
+                break;
+            case TGSI_SEMANTIC_COLOR:
+                assembler->out_colors++;
+                break;
+            case TGSI_SEMANTIC_FOG:
+            case TGSI_SEMANTIC_GENERIC:
+                assembler->out_texcoords++;
+                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);
+                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.ImmediateFloat32[i]
+                        .Float;
+                }
+                assembler->imm_count++;
+                break;
+            case TGSI_TOKEN_TYPE_INSTRUCTION:
+                r300_vs_instruction(vs, assembler,
+                        &parser.FullToken.FullInstruction);
+                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);
+
+    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]);
+
+    tgsi_dump(vs->state.tokens, 0);
+    /* XXX finish r300 vertex shader dumper */
+    r300_vs_dump(vs);
+
+    tgsi_parse_free(&parser);
+    FREE(assembler);
+}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
new file mode 100644 (file)
index 0000000..165d717
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * 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_VS_H
+#define R300_VS_H
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "r300_context.h"
+#include "r300_debug.h"
+#include "r300_reg.h"
+#include "r300_screen.h"
+#include "r300_shader_inlines.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)
+
+#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)
+
+/* 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];
+};
+
+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,
+};
+
+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,
+};
+
+void r300_translate_vertex_shader(struct r300_context* r300,
+                                  struct r300_vertex_shader* vs);
+
+#endif /* R300_VS_H */
diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c
new file mode 100644 (file)
index 0000000..6e05d76
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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. */
+
+#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;
+    }
+}
+
+static INLINE uint32_t r3xx_alpha_op(unsigned op)
+{
+    switch (op) {
+        case TGSI_OPCODE_MOV:
+            return R300_ALU_OUTA_CMP;
+        default:
+            return 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;
+
+    fs->instructions[i].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) |
+        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_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;
+
+    fs->alu_instruction_count++;
+}
+
+void r3xx_fs_finalize(struct r300_fragment_shader* fs,
+                      struct r300_fs_asm* assembler)
+{
+    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
+}
+
+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;
+    }
+}
diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h
new file mode 100644 (file)
index 0000000..3da39ec
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 R3XX_FS_H
+#define R3XX_FS_H
+
+#include "r300_fs_inlines.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,
+};
+
+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);
+
+#endif /* R3XX_FS_H */
diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c
new file mode 100644 (file)
index 0000000..99d8262
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * 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. */
+
+#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)) |
+        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;
+    }
+}
diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h
new file mode 100644 (file)
index 0000000..629e587
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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 R5XX_FS_H
+#define R5XX_FS_H
+
+#include "r300_fs_inlines.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,
+};
+
+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);
+
+#endif /* R5XX_FS_H */