diff options
| author | Nicolai Hähnle <nhaehnle@gmail.com> | 2009-07-30 23:45:34 +0200 | 
|---|---|---|
| committer | Nicolai Hähnle <nhaehnle@gmail.com> | 2009-07-30 23:55:12 +0200 | 
| commit | d0c398a8e2985b855f923aec3470cef8734a622a (patch) | |
| tree | c35bc03f01da577f0cb139e6d433287e0f00ffe6 /src | |
| parent | fbc88a7334c9567b623572b60267c747a9baa0fb (diff) | |
r300g: Use radeon compiler for fragment programs
This is entirely untested on R500, and needs more testing on R300.
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/Makefile | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 60 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_debug.c | 228 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_debug.h | 35 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 208 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.h | 11 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_fs.c | 158 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_fs.h | 15 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_fs_inlines.h | 158 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 23 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_surface.c | 8 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_tgsi_to_rc.c | 44 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r3xx_fs.c | 100 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r3xx_fs.h | 52 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r5xx_fs.c | 528 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r5xx_fs.h | 108 | 
17 files changed, 438 insertions, 1300 deletions
| diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 93c2152edc..d7a2c8c462 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -9,7 +9,6 @@ C_SOURCES = \  	r300_chipset.c \  	r300_clear.c \  	r300_context.c \ -	r300_debug.c \  	r300_emit.c \  	r300_flush.c \  	r300_fs.c \ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index c1ef64e4ee..6984225967 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -34,6 +34,7 @@  #include "r300_screen.h"  #include "r300_winsys.h" +struct r300_fragment_shader;  struct r300_vertex_shader;  struct r300_blend_state { @@ -151,65 +152,6 @@ struct r300_constant_buffer {      unsigned count;  }; -struct r300_fragment_shader { -    /* Parent class */ -    struct pipe_shader_state state; -    struct tgsi_shader_info info; - -    /* Has this shader been translated yet? */ -    boolean translated; - -    /* Pixel stack size */ -    int stack_size; - -    /* Are there immediates in this shader? -     * If not, we can heavily optimize recompilation. */ -    boolean uses_imms; -}; - -struct r3xx_fragment_shader { -    /* Parent class */ -    struct r300_fragment_shader shader; - -    /* Number of ALU instructions */ -    int alu_instruction_count; - -    /* Number of texture instructions */ -    int tex_instruction_count; - -    /* Number of texture indirections */ -    int indirections; - -    /* Indirection node offsets */ -    int alu_offset[4]; - -    /* Machine instructions */ -    struct { -        uint32_t alu_rgb_inst; -        uint32_t alu_rgb_addr; -        uint32_t alu_alpha_inst; -        uint32_t alu_alpha_addr; -    } instructions[64]; /* XXX magic num */ -}; - -struct r5xx_fragment_shader { -    /* Parent class */ -    struct r300_fragment_shader shader; - -    /* Number of used instructions */ -    int instruction_count; - -    /* Machine instructions */ -    struct { -        uint32_t inst0; -        uint32_t inst1; -        uint32_t inst2; -        uint32_t inst3; -        uint32_t inst4; -        uint32_t inst5; -    } instructions[256]; /*< XXX magic number */ -}; -  struct r300_texture {      /* Parent class */      struct pipe_texture tex; diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c deleted file mode 100644 index aae8a4fbde..0000000000 --- a/src/gallium/drivers/r300/r300_debug.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include "r300_debug.h" - - -static char* r5xx_fs_swiz[] = { -    " R", -    " G", -    " B", -    " A", -    " 0", -    ".5", -    " 1", -    " U", -}; - -static char* r5xx_fs_op_rgb[] = { -    "MAD", -    "DP3", -    "DP4", -    "D2A", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "SOP", -    "MDH", -    "MDV", -}; - -static char* r5xx_fs_op_alpha[] = { -    "MAD", -    " DP", -    "MIN", -    "MAX", -    "---", -    "CND", -    "CMP", -    "FRC", -    "EX2", -    "LN2", -    "RCP", -    "RSQ", -    "SIN", -    "COS", -    "MDH", -    "MDV", -}; - -static char* r5xx_fs_mask[] = { -    "NONE", -    "R   ", -    " G  ", -    "RG  ", -    "  B ", -    "R B ", -    " GB ", -    "RGB ", -    "   A", -    "R  A", -    " G A", -    "RG A", -    "  BA", -    "R BA", -    " GBA", -    "RGBA", -}; - -static char* r5xx_fs_tex[] = { -    "    NOP", -    "     LD", -    "TEXKILL", -    "   PROJ", -    "LODBIAS", -    "    LOD", -    "   DXDY", -}; - - -void r3xx_dump_fs(struct r3xx_fragment_shader* fs) -{ -    int i; - -    for (i = 0; i < fs->alu_instruction_count; i++) { -    } -} - -void r5xx_fs_dump(struct r5xx_fragment_shader* fs) -{ -    int i; -    uint32_t inst; - -    for (i = 0; i < fs->instruction_count; i++) { -        inst = fs->instructions[i].inst0; -        debug_printf("%d:  0: CMN_INST   0x%08x:", i, inst); -        switch (inst & 0x3) { -            case R500_INST_TYPE_ALU: -                debug_printf("ALU "); -                break; -            case R500_INST_TYPE_OUT: -                debug_printf("OUT "); -                break; -            case R500_INST_TYPE_FC: -                debug_printf("FC  "); -                break; -            case R500_INST_TYPE_TEX: -                debug_printf("TEX "); -                break; -        } -        debug_printf("%s %s %s %s ", -                inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", -                inst & R500_INST_LAST ? "LAST" : "", -                inst & R500_INST_NOP ? "NOP" : "", -                inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : ""); -        debug_printf("wmask: %s omask: %s\n", -                r5xx_fs_mask[(inst >> 11) & 0xf], -                r5xx_fs_mask[(inst >> 15) & 0xf]); -        switch (inst & 0x3) { -            case R500_INST_TYPE_ALU: -            case R500_INST_TYPE_OUT: -                inst = fs->instructions[i].inst1; -                debug_printf("    1: RGB_ADDR   0x%08x:", inst); -                debug_printf("Addr0: %d%c, Addr1: %d%c, " -                        "Addr2: %d%c, srcp:%d\n", -                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', -                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', -                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', -                        (inst >> 30)); - -                inst = fs->instructions[i].inst2; -                debug_printf("    2: ALPHA_ADDR 0x%08x:", inst); -                debug_printf("Addr0: %d%c, Addr1: %d%c, " -                        "Addr2: %d%c, srcp:%d\n", -                        inst & 0xff, (inst & (1 << 8)) ? 'c' : 't', -                        (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't', -                        (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't', -                        (inst >> 30)); - -                inst = fs->instructions[i].inst3; -                debug_printf("    3: RGB_INST   0x%08x:", inst); -                debug_printf("rgb_A_src:%d %s/%s/%s %d " -                        "rgb_B_src:%d %s/%s/%s %d\n", -                        inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7], -                        r5xx_fs_swiz[(inst >> 5) & 0x7], -                        r5xx_fs_swiz[(inst >> 8) & 0x7], -                        (inst >> 11) & 0x3, (inst >> 13) & 0x3, -                        r5xx_fs_swiz[(inst >> 15) & 0x7], -                        r5xx_fs_swiz[(inst >> 18) & 0x7], -                        r5xx_fs_swiz[(inst >> 21) & 0x7], -                        (inst >> 24) & 0x3); - -                inst = fs->instructions[i].inst4; -                debug_printf("    4: ALPHA_INST 0x%08x:", inst); -                debug_printf("%s dest:%d%s alp_A_src:%d %s %d " -                        "alp_B_src:%d %s %d w:%d\n", -                        r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f, -                        inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3, -                        (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7], -                        (inst >> 24) & 0x3, (inst >> 31) & 0x1); - -                inst = fs->instructions[i].inst5; -                debug_printf("    5: RGBA_INST  0x%08x:", inst); -                debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d " -                        "alp_C_src:%d %s %d\n", -                        r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f, -                        inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3, -                        r5xx_fs_swiz[(inst >> 14) & 0x7], -                        r5xx_fs_swiz[(inst >> 17) & 0x7], -                        r5xx_fs_swiz[(inst >> 20) & 0x7], -                        (inst >> 23) & 0x3, (inst >> 25) & 0x3, -                        r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3); -                break; -            case R500_INST_TYPE_FC: -                /* XXX don't even bother yet */ -                break; -            case R500_INST_TYPE_TEX: -                inst = fs->instructions[i].inst1; -                debug_printf("    1: TEX_INST   0x%08x: id: %d " -                        "op:%s, %s, %s %s\n", -                        inst, (inst >> 16) & 0xf, -                        r5xx_fs_tex[(inst >> 22) & 0x7], -                        (inst & (1 << 25)) ? "ACQ" : "", -                        (inst & (1 << 26)) ? "IGNUNC" : "", -                        (inst & (1 << 27)) ? "UNSCALED" : "SCALED"); - -                inst = fs->instructions[i].inst2; -                debug_printf("    2: TEX_ADDR   0x%08x: " -                        "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", -                        inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "", -                        r5xx_fs_swiz[(inst >> 8) & 0x3], -                        r5xx_fs_swiz[(inst >> 10) & 0x3], -                        r5xx_fs_swiz[(inst >> 12) & 0x3], -                        r5xx_fs_swiz[(inst >> 14) & 0x3], -                        (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "", -                        r5xx_fs_swiz[(inst >> 24) & 0x3], -                        r5xx_fs_swiz[(inst >> 26) & 0x3], -                        r5xx_fs_swiz[(inst >> 28) & 0x3], -                        r5xx_fs_swiz[(inst >> 30) & 0x3]); - -                inst = fs->instructions[i].inst3; -                debug_printf("    3: TEX_DXDY   0x%08x\n", inst); -                break; -        } -    } -} diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h deleted file mode 100644 index c551bd548e..0000000000 --- a/src/gallium/drivers/r300/r300_debug.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef R300_DEBUG_H -#define R300_DEBUG_H - -#include "r300_reg.h" -#include "r300_fs.h" -#include "r300_vs.h" - -void r5xx_fs_dump(struct r5xx_fragment_shader* fs); -void r3xx_dump_fs(struct r3xx_fragment_shader* fs); - -void r300_vs_dump(struct r300_vertex_shader* vs); - -#endif /* R300_DEBUG_H */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index e9ca4ac662..e0c38a06e4 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -24,6 +24,7 @@  #include "r300_emit.h" +#include "r300_fs.h"  #include "r300_vs.h"  void r300_emit_blend_state(struct r300_context* r300, @@ -111,73 +112,158 @@ void r300_emit_dsa_state(struct r300_context* r300,      END_CS;  } -void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r3xx_fragment_shader* fs) +static const float * get_shader_constant( +    struct r300_context * r300, +    struct rc_constant * constant, +    struct r300_constant_buffer * externals)  { +    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 }; +    switch(constant->Type) { +        case RC_CONSTANT_EXTERNAL: +            return externals->constants[constant->u.External]; + +        case RC_CONSTANT_IMMEDIATE: +            return constant->u.Immediate; + +        default: +            debug_printf("r300: Implementation error: Unhandled constant type %i\n", +                constant->Type); +            return zero; +    } +} + +/* Convert a normal single-precision float into the 7.16 format + * used by the R300 fragment shader. + */ +static uint32_t pack_float24(float f) +{ +    union { +        float fl; +        uint32_t u; +    } u; +    float mantissa; +    int exponent; +    uint32_t float24 = 0; + +    if (f == 0.0) +        return 0; + +    u.fl = f; + +    mantissa = frexpf(f, &exponent); + +    /* Handle -ve */ +    if (mantissa < 0) { +        float24 |= (1 << 23); +        mantissa = mantissa * -1.0; +    } +    /* Handle exponent, bias of 63 */ +    exponent += 62; +    float24 |= (exponent << 16); +    /* Kill 7 LSB of mantissa */ +    float24 |= (u.u & 0x7FFFFF) >> 7; + +    return float24; +} + +void r300_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals) +{ +    struct r300_fragment_program_code * code = &generic_code->code.r300; +    struct rc_constant_list * constants = &generic_code->constants;      int i;      CS_LOCALS(r300); -    BEGIN_CS(22); +    BEGIN_CS(15 + +             code->alu.length * 4 + +             (code->tex.length ? (1 + code->tex.length) : 0) + +             (constants->Count ? (1 + constants->Count * 4) : 0)); + +    OUT_CS_REG(R300_US_CONFIG, code->config); +    OUT_CS_REG(R300_US_PIXSIZE, code->pixsize); +    OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset); + +    OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4); +    for(i = 0; i < 4; ++i) +        OUT_CS(code->code_addr[i]); -    OUT_CS_REG(R300_US_CONFIG, fs->indirections); -    OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size); -    /* XXX figure out exactly how big the sizes are on this reg */ -    OUT_CS_REG(R300_US_CODE_OFFSET, 0x40); -    /* XXX figure these ones out a bit better kthnx */ -    OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); -    OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT); +    OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].rgb_inst); -    for (i = 0; i < fs->alu_instruction_count; i++) { -        OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i), -            fs->instructions[i].alu_rgb_inst); -        OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i), -            fs->instructions[i].alu_rgb_addr); -        OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i), -            fs->instructions[i].alu_alpha_inst); -        OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i), -            fs->instructions[i].alu_alpha_addr); +    OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].rgb_addr); + +    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].alpha_inst); + +    OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length); +    for (i = 0; i < code->alu.length; i++) +        OUT_CS(code->alu.inst[i].alpha_addr); + +    if (code->tex.length) { +        OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length); +        for(i = 0; i < code->tex.length; ++i) +            OUT_CS(code->tex.inst[i]); +    } + +    if (constants->Count) { +        OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4); +        for(i = 0; i < constants->Count; ++i) { +            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); +            OUT_CS(pack_float24(data[0])); +            OUT_CS(pack_float24(data[1])); +            OUT_CS(pack_float24(data[2])); +            OUT_CS(pack_float24(data[3])); +        }      }      END_CS;  } -void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r5xx_fragment_shader* fs) +void r500_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals)  { +    struct r500_fragment_program_code * code = &generic_code->code.r500; +    struct rc_constant_list * constants = &generic_code->constants;      int i; -    struct r300_constant_buffer* constants = -        &r300->shader_constants[PIPE_SHADER_FRAGMENT];      CS_LOCALS(r300); -    BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) + -            (constants->count * 4)); -    OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); -    OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size); -    OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | -            R500_US_CODE_END_ADDR(fs->instruction_count)); +    BEGIN_CS(13 + +             ((code->inst_end + 1) * 6) + +             (constants->Count ? (3 + (constants->Count * 4)) : 0)); +    OUT_CS_REG(R500_US_CONFIG, 0); +    OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx); +    OUT_CS_REG(R500_US_CODE_RANGE, +               R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); +    OUT_CS_REG(R500_US_CODE_OFFSET, 0); +    OUT_CS_REG(R500_US_CODE_ADDR, +               R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end));      OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR); -    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6); -    for (i = 0; i < fs->instruction_count; i++) { -        OUT_CS(fs->instructions[i].inst0); -        OUT_CS(fs->instructions[i].inst1); -        OUT_CS(fs->instructions[i].inst2); -        OUT_CS(fs->instructions[i].inst3); -        OUT_CS(fs->instructions[i].inst4); -        OUT_CS(fs->instructions[i].inst5); +    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6); +    for (i = 0; i <= code->inst_end; i++) { +        OUT_CS(code->inst[i].inst0); +        OUT_CS(code->inst[i].inst1); +        OUT_CS(code->inst[i].inst2); +        OUT_CS(code->inst[i].inst3); +        OUT_CS(code->inst[i].inst4); +        OUT_CS(code->inst[i].inst5);      } -    if (constants->count) { -        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, -                R500_GA_US_VECTOR_INDEX_TYPE_CONST); -        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4); -        for (i = 0; i < constants->count; i++) { -            OUT_CS_32F(constants->constants[i][0]); -            OUT_CS_32F(constants->constants[i][1]); -            OUT_CS_32F(constants->constants[i][2]); -            OUT_CS_32F(constants->constants[i][3]); +    if (constants->Count) { +        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST); +        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4); +        for (i = 0; i < constants->Count; i++) { +            const float * data = get_shader_constant(r300, &constants->Constants[i], externals); +            OUT_CS_32F(data[0]); +            OUT_CS_32F(data[1]); +            OUT_CS_32F(data[2]); +            OUT_CS_32F(data[3]);          }      } @@ -382,26 +468,6 @@ void r300_emit_vertex_format_state(struct r300_context* r300)      END_CS;  } -static const float * get_shader_constant( -    struct r300_context * r300, -    struct rc_constant * constant, -    struct r300_constant_buffer * externals) -{ -    static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 }; -    switch(constant->Type) { -        case RC_CONSTANT_EXTERNAL: -            return externals->constants[constant->u.External]; - -        case RC_CONSTANT_IMMEDIATE: -            return constant->u.Immediate; - -        default: -            debug_printf("r300: Implementation error: Unhandled constant type %i\n", -                constant->Type); -            return zero; -    } -} -  void r300_emit_vertex_program_code(struct r300_context* r300,                                     struct r300_vertex_program_code* code,                                     struct r300_constant_buffer* constants) @@ -589,11 +655,9 @@ validate:      if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {          if (r300screen->caps->is_r500) { -            r500_emit_fragment_shader(r300, -                (struct r5xx_fragment_shader*)r300->fs); +            r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);          } else { -            r300_emit_fragment_shader(r300, -                (struct r3xx_fragment_shader*)r300->fs); +            r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);          }          r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;      } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index fbc6487aa2..350691d592 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -30,6 +30,7 @@  #include "r300_screen.h"  #include "r300_state_inlines.h" +struct rX00_fragment_program_code;  struct r300_vertex_program_code;  void r300_emit_blend_state(struct r300_context* r300, @@ -44,11 +45,13 @@ void r300_emit_clip_state(struct r300_context* r300,  void r300_emit_dsa_state(struct r300_context* r300,                           struct r300_dsa_state* dsa); -void r300_emit_fragment_shader(struct r300_context* r300, -                               struct r3xx_fragment_shader* fs); +void r300_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals); -void r500_emit_fragment_shader(struct r300_context* r300, -                               struct r5xx_fragment_shader* fs); +void r500_emit_fragment_program_code(struct r300_context* r300, +                                     struct rX00_fragment_program_code* generic_code, +                                     struct r300_constant_buffer* externals);  void r300_emit_fb_state(struct r300_context* r300,                          struct pipe_framebuffer_state* fb); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index ca8ef99902..2cddb97038 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -23,89 +23,115 @@  #include "r300_fs.h" -void r300_translate_fragment_shader(struct r300_context* r300, -                                    struct r300_fragment_shader* fs) +#include "r300_tgsi_to_rc.h" + +#include "radeon_compiler.h" + +static void find_output_registers(struct r300_fragment_program_compiler * compiler, +                                  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]; +    unsigned i; -    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; +    /* Mark the outputs as not present initially */ +    compiler->OutputColor = fs->info.num_outputs; +    compiler->OutputDepth = fs->info.num_outputs; -    /* Make sure we start at the beginning of the shader. */ -    if (is_r500) { -        ((struct r5xx_fragment_shader*)fs)->instruction_count = 0; +    /* Now see where they really are. */ +    for(i = 0; i < fs->info.num_outputs; ++i) { +        switch(fs->info.output_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                compiler->OutputColor = i; +                break; +            case TGSI_SEMANTIC_POSITION: +                compiler->OutputDepth = i; +                break; +        }      } +} -    tgsi_parse_init(&parser, fs->state.tokens); - -    while (!tgsi_parse_end_of_tokens(&parser)) { -        tgsi_parse_token(&parser); +static void allocate_hardware_inputs( +    struct r300_fragment_program_compiler * c, +    void (*allocate)(void * data, unsigned input, unsigned hwreg), +    void * mydata) +{ +    struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info; +    int total_colors = 0; +    int colors = 0; +    int total_generic = 0; +    int generic = 0; +    int i; -        /* 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); +    for (i = 0; i < info->num_inputs; i++) { +        switch (info->input_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                total_colors++; +                break; +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                total_generic++;                  break; -            case TGSI_TOKEN_TYPE_IMMEDIATE: -                debug_printf("r300: Emitting immediate to constant buffer, " -                        "position %d\n", -                        assembler->imm_offset + assembler->imm_count); -                /* I am not amused by the length of these. */ -                for (i = 0; i < 4; i++) { -                    consts->constants[assembler->imm_offset + -                        assembler->imm_count][i] = -                        parser.FullToken.FullImmediate.u[i].Float; -                } -                assembler->imm_count++; +        } +    } + +    for(i = 0; i < info->num_inputs; i++) { +        switch (info->input_semantic_name[i]) { +            case TGSI_SEMANTIC_COLOR: +                allocate(mydata, i, colors); +                colors++;                  break; -            case TGSI_TOKEN_TYPE_INSTRUCTION: -                if (is_r500) { -                    r5xx_fs_instruction((struct r5xx_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } else { -                    r3xx_fs_instruction((struct r3xx_fragment_shader*)fs, -                            assembler, &parser.FullToken.FullInstruction); -                } +            case TGSI_SEMANTIC_FOG: +            case TGSI_SEMANTIC_GENERIC: +                allocate(mydata, i, total_colors + generic); +                generic++;                  break;          }      } +} + +void r300_translate_fragment_shader(struct r300_context* r300, +                                    struct r300_fragment_shader* fs) +{ +    struct r300_fragment_program_compiler compiler; +    struct tgsi_to_rc ttr; -    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); +    memset(&compiler, 0, sizeof(compiler)); +    rc_init(&compiler.Base); +    compiler.Base.Debug = 1; -    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); -    } +    compiler.code = &fs->code; +    compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; +    compiler.AllocateHwInputs = &allocate_hardware_inputs; +    compiler.UserData = fs; + +    /* TODO: Program compilation depends on texture compare modes, +     * which are sampler state. Therefore, programs need to be recompiled +     * depending on this state as in the classic Mesa driver. +     * +     * This is not yet handled correctly. +     */ + +    find_output_registers(&compiler, fs); -    tgsi_dump(fs->state.tokens, 0); -    /* XXX finish r300 dumper too */ -    if (is_r500) { -        r5xx_fs_dump((struct r5xx_fragment_shader*)fs); +    if (compiler.Base.Debug) { +        debug_printf("r300: Initial vertex program\n"); +        tgsi_dump(fs->state.tokens, 0);      } -    tgsi_parse_free(&parser); -    FREE(assembler); +    /* Translate TGSI to our internal representation */ +    ttr.compiler = &compiler.Base; +    ttr.info = &fs->info; + +    r300_tgsi_to_rc(&ttr, fs->state.tokens); + +    /* Invoke the compiler */ +    r3xx_compile_fragment_program(&compiler); +    if (compiler.Base.Error) { +        /* Todo: Fail gracefully */ +        fprintf(stderr, "r300 FP: Compiler error\n"); +        abort(); +    }      /* And, finally... */ +    rc_destroy(&compiler.Base);      fs->translated = TRUE;  } diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h index 18deb7a05e..9fab789402 100644 --- a/src/gallium/drivers/r300/r300_fs.h +++ b/src/gallium/drivers/r300/r300_fs.h @@ -30,6 +30,21 @@  #include "r3xx_fs.h"  #include "r5xx_fs.h" +#include "radeon_code.h" + +struct r300_fragment_shader { +    /* Parent class */ +    struct pipe_shader_state state; +    struct tgsi_shader_info info; + +    /* Has this shader been translated yet? */ +    boolean translated; + +    /* Compiled code */ +    struct rX00_fragment_program_code code; +}; + +  void r300_translate_fragment_shader(struct r300_context* r300,                                      struct r300_fragment_shader* fs); diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h deleted file mode 100644 index be4be9465e..0000000000 --- a/src/gallium/drivers/r300/r300_fs_inlines.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> - *                Joakim Sindholt <opensource@zhasha.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef R300_FS_INLINES_H -#define R300_FS_INLINES_H - -#include "tgsi/tgsi_parse.h" - -#include "r300_context.h" -#include "r300_debug.h" -#include "r300_reg.h" -#include "r300_screen.h" -#include "r300_shader_inlines.h" - -/* Temporary struct used to hold assembly state while putting together - * fragment programs. */ -struct r300_fs_asm { -    /* Pipe context. */ -    struct r300_context* r300; -    /* Number of colors. */ -    unsigned color_count; -    /* Number of texcoords. */ -    unsigned tex_count; -    /* Offset for temporary registers. Inputs and temporaries have no -     * distinguishing markings, so inputs start at 0 and the first usable -     * temporary register is after all inputs. */ -    unsigned temp_offset; -    /* Number of requested temporary registers. */ -    unsigned temp_count; -    /* Offset for immediate constants. Neither R300 nor R500 can do four -     * inline constants per source, so instead we copy immediates into the -     * constant buffer. */ -    unsigned imm_offset; -    /* Number of immediate constants. */ -    unsigned imm_count; -    /* Are depth writes enabled? */ -    boolean writes_depth; -    /* Depth write offset. This is the TGSI output that corresponds to -     * depth writes. */ -    unsigned depth_output; -}; - -static INLINE void r300_fs_declare(struct r300_fs_asm* assembler, -                            struct tgsi_full_declaration* decl) -{ -    switch (decl->Declaration.File) { -        case TGSI_FILE_INPUT: -            switch (decl->Semantic.SemanticName) { -                case TGSI_SEMANTIC_COLOR: -                    assembler->color_count++; -                    break; -                case TGSI_SEMANTIC_FOG: -                case TGSI_SEMANTIC_GENERIC: -                    assembler->tex_count++; -                    break; -                default: -                    debug_printf("r300: fs: Bad semantic declaration %d\n", -                        decl->Semantic.SemanticName); -                    break; -            } -            break; -        case TGSI_FILE_OUTPUT: -            /* Depth write. Mark the position of the output so we can -             * identify it later. */ -            if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { -                assembler->depth_output = decl->DeclarationRange.First; -            } -            break; -        case TGSI_FILE_CONSTANT: -            break; -        case TGSI_FILE_TEMPORARY: -            assembler->temp_count++; -            break; -        default: -            debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File); -            break; -    } - -    assembler->temp_offset = assembler->color_count + assembler->tex_count; -} - -static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler, -                                   struct tgsi_src_register* src) -{ -    switch (src->File) { -        case TGSI_FILE_NULL: -            return 0; -        case TGSI_FILE_INPUT: -            /* XXX may be wrong */ -            return src->Index; -            break; -        case TGSI_FILE_TEMPORARY: -            return src->Index + assembler->temp_offset; -            break; -        case TGSI_FILE_IMMEDIATE: -            return (src->Index + assembler->imm_offset) | (1 << 8); -            break; -        case TGSI_FILE_CONSTANT: -            /* XXX magic */ -            return src->Index | (1 << 8); -            break; -        default: -            debug_printf("r300: fs: Unimplemented src %d\n", src->File); -            break; -    } -    return 0; -} - -static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler, -                                   struct tgsi_dst_register* dst) -{ -    switch (dst->File) { -        case TGSI_FILE_NULL: -            /* This happens during KIL instructions. */ -            return 0; -            break; -        case TGSI_FILE_OUTPUT: -            return 0; -            break; -        case TGSI_FILE_TEMPORARY: -            return dst->Index + assembler->temp_offset; -            break; -        default: -            debug_printf("r300: fs: Unimplemented dst %d\n", dst->File); -            break; -    } -    return 0; -} - -static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler, -                                      struct tgsi_dst_register* dst) -{ -    return (assembler->writes_depth && -            (dst->File == TGSI_FILE_OUTPUT) && -            (dst->Index == assembler->depth_output)); -} - -#endif /* R300_FS_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 33f1d7e79f..bb4b4be50f 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -32,6 +32,7 @@  #include "r300_reg.h"  #include "r300_state_inlines.h"  #include "r300_fs.h" +#include "r300_vs.h"  /* r300_state: Functions used to intialize state context by translating   * Gallium state objects into semi-native r300 state objects. */ @@ -155,20 +156,6 @@ static void      }      r300->dirty_state |= R300_NEW_CONSTANTS; -#if 0 -    /* If the number of constants have changed, invalidate the shader. */ -    if (r300->shader_constants[shader].user_count != i) { -        if (shader == PIPE_SHADER_FRAGMENT && r300->fs && -                r300->fs->uses_imms) { -            r300->fs->translated = FALSE; -            r300_translate_fragment_shader(r300, r300->fs); -        } else if (shader == PIPE_SHADER_VERTEX && r300->vs && -                r300->vs->uses_imms) { -            r300->vs->translated = FALSE; -            r300_translate_vertex_shader(r300, r300->vs); -        } -    } -#endif  }  /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -285,14 +272,9 @@ static void  static void* r300_create_fs_state(struct pipe_context* pipe,                                    const struct pipe_shader_state* shader)  { -    struct r300_context* r300 = r300_context(pipe);      struct r300_fragment_shader* fs = NULL; -    if (r300_screen(r300->context.screen)->caps->is_r500) { -        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader); -    } else { -        fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader); -    } +    fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);      /* Copy state directly into shader. */      fs->state = *shader; @@ -325,6 +307,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)  static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)  {      struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; +    rc_constants_destroy(&fs->code.constants);      FREE(fs->state.tokens);      FREE(shader);  } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 5c67eb13ff..ea670f41fb 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -22,6 +22,7 @@  #include "r300_state_derived.h" +#include "r300_fs.h"  #include "r300_vs.h"  /* r300_state_derived: Various bits of state which are dependent upon diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index cf15333198..7dbfb64dbe 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -152,10 +152,10 @@ validate:      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader); +        r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0);          r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);      } else { -        r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader); +        r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0);          r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);      } @@ -290,10 +290,10 @@ validate:      /* Fragment shader setup */      if (caps->is_r500) { -        r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader); +        r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0);          r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);      } else { -        r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader); +        r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0);          r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);      } diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index f530b23380..3adbb715f3 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -224,6 +224,39 @@ static void transform_srcreg(      dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;  } +static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src) +{ +    switch(src.Texture) { +        case TGSI_TEXTURE_1D: +            dst->I.TexSrcTarget = TEXTURE_1D_INDEX; +            break; +        case TGSI_TEXTURE_2D: +            dst->I.TexSrcTarget = TEXTURE_2D_INDEX; +            break; +        case TGSI_TEXTURE_3D: +            dst->I.TexSrcTarget = TEXTURE_3D_INDEX; +            break; +        case TGSI_TEXTURE_CUBE: +            dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX; +            break; +        case TGSI_TEXTURE_RECT: +            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; +            break; +        case TGSI_TEXTURE_SHADOW1D: +            dst->I.TexSrcTarget = TEXTURE_1D_INDEX; +            dst->I.TexShadow = 1; +            break; +        case TGSI_TEXTURE_SHADOW2D: +            dst->I.TexSrcTarget = TEXTURE_2D_INDEX; +            dst->I.TexShadow = 1; +            break; +        case TGSI_TEXTURE_SHADOWRECT: +            dst->I.TexSrcTarget = TEXTURE_RECT_INDEX; +            dst->I.TexShadow = 1; +            break; +    } +} +  static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src)  {      if (src->Instruction.Opcode == TGSI_OPCODE_END) @@ -238,10 +271,15 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst      if (src->Instruction.NumDstRegs)          transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]); -    for(i = 0; i < src->Instruction.NumSrcRegs; ++i) -        transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]); +    for(i = 0; i < src->Instruction.NumSrcRegs; ++i) { +        if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER) +            dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index; +        else +            transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]); +    } -    /* TODO: Textures */ +    /* Texturing. */ +    transform_texture(dst, src->InstructionExtTexture);  }  static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm) diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c index 6e05d76977..c1c1194d58 100644 --- a/src/gallium/drivers/r300/r3xx_fs.c +++ b/src/gallium/drivers/r300/r3xx_fs.c @@ -23,74 +23,52 @@  #include "r3xx_fs.h" -static INLINE uint32_t r3xx_rgb_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTC_CMP; -        default: -            return 0; -    } -} +#include "r300_reg.h" -static INLINE uint32_t r3xx_alpha_op(unsigned op) -{ -    switch (op) { -        case TGSI_OPCODE_MOV: -            return R300_ALU_OUTA_CMP; -        default: -            return 0; -    } -} +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = { +    .code.r300.alu.length = 1, +    .code.r300.tex.length = 0, -static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs, -                                   struct r300_fs_asm* assembler, -                                   struct tgsi_full_src_register* src, -                                   struct tgsi_full_dst_register* dst, -                                   unsigned op, -                                   unsigned count) -{ -    int i = fs->alu_instruction_count; +    .code.r300.config = 0, +    .code.r300.pixsize = 0, +    .code.r300.code_offset = 0, +    .code.r300.code_addr[3] = R300_RGBA_OUT, -    fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |          R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |          R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        r3xx_rgb_op(op); -    fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ; -    fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALU_OUTC_CMP, +    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |          R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |          R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        r3xx_alpha_op(op); -    fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT; +        R300_ALU_OUTA_CMP, +    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; -    fs->alu_instruction_count++; -} +struct rX00_fragment_program_code r3xx_texture_fragment_shader = { +    .code.r300.alu.length = 1, +    .code.r300.tex.length = 1, -void r3xx_fs_finalize(struct r300_fragment_shader* fs, -                      struct r300_fs_asm* assembler) -{ -    fs->stack_size = assembler->temp_count + assembler->temp_offset + 1; -} +    .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX, +    .code.r300.pixsize = 0, +    .code.r300.code_offset = 0, +    .code.r300.code_addr[3] = R300_RGBA_OUT, -void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, -                         struct r300_fs_asm* assembler, -                         struct tgsi_full_instruction* inst) -{ -    switch (inst->Instruction.Opcode) { -        case TGSI_OPCODE_MOV: -            /* src0 -> src1 and src2 forced to zero */ -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r300_constant_zero; -            r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: fs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } -} +    .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT, + +    .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | +        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | +        R300_ALU_OUTC_CMP, +    .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | +        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, +    .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | +        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | +        R300_ALU_OUTA_CMP, +    .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) | +        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, +}; diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h index 592898d899..51cd245724 100644 --- a/src/gallium/drivers/r300/r3xx_fs.h +++ b/src/gallium/drivers/r300/r3xx_fs.h @@ -24,55 +24,9 @@  #ifndef R3XX_FS_H  #define R3XX_FS_H -#include "r300_fs_inlines.h" +#include "radeon_code.h" -static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = { -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -static struct r3xx_fragment_shader r3xx_texture_fragment_shader = { -    .alu_instruction_count = 1, -    .tex_instruction_count = 0, -    .indirections = 0, -    .shader.stack_size = 1, - -    .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) | -        R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) | -        R300_ALU_OUTC_CMP, -    .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) | -        R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ, -    .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) | -        R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) | -        R300_ALU_OUTA_CMP, -    .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) | -        R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT, -}; - -struct r300_fs_asm; - -void r3xx_fs_finalize(struct r300_fragment_shader* fs, -                      struct r300_fs_asm* assembler); - -void r3xx_fs_instruction(struct r3xx_fragment_shader* fs, -                         struct r300_fs_asm* assembler, -                         struct tgsi_full_instruction* inst); +struct rX00_fragment_program_code r3xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r3xx_texture_fragment_shader;  #endif /* R3XX_FS_H */ diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c index 99d826278c..f072deab0d 100644 --- a/src/gallium/drivers/r300/r5xx_fs.c +++ b/src/gallium/drivers/r300/r5xx_fs.c @@ -23,445 +23,103 @@  #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; -    } -} +#include "r300_reg.h" -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); -    } -} +/* 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 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); -} +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = { +    .code.r500.max_temp_idx = 0, +    .code.r500.inst_end = 0, -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); -} +    .code.r500.inst[0].inst0 = R500_INST_TYPE_OUT | +        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | +        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[0].inst1 = +        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | +        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, +    .code.r500.inst[0].inst2 = +        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | +        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, +    .code.r500.inst[0].inst3 = +        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | +        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | +        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | +        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, +    .code.r500.inst[0].inst4 = +        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, +    .code.r500.inst[0].inst5 = +        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | +        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | +        R500_ALU_RGBA_A_SWIZ_0, +}; -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); -} +struct rX00_fragment_program_code r5xx_texture_fragment_shader = { +    .code.r500.max_temp_idx = 0, +    .code.r500.inst_end = 1, -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)) | +    .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX | +        R500_INST_TEX_SEM_WAIT | +        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | +        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, +    .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) | +        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | +        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | +        R500_TEX_DST_ADDR(0) |          R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | -        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; - -    if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { -        fs->instructions[i].inst2 |= -            R500_TEX_DST_ADDR(assembler->temp_count + -                    assembler->temp_offset); - -        fs->instruction_count++; - -        /* Setup and emit a MOV. */ -        src[0].SrcRegister.Index = assembler->temp_count; -        src[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - -        src[1] = src[0]; -        src[2] = r300_constant_zero; -        r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3); -    } else { -        fs->instruction_count++; -    } -} - -void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, -                      struct r300_fs_asm* assembler) -{ -    /* XXX should this just go with OPCODE_END? */ -    fs->instructions[fs->instruction_count - 1].inst0 |= -        R500_INST_LAST; -} - -void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, -                         struct r300_fs_asm* assembler, -                         struct tgsi_full_instruction* inst) -{ -    /* Switch between opcodes. When possible, prefer using the official -     * AMD/ATI names for opcodes, please, as it facilitates using the -     * documentation. */ -    switch (inst->Instruction.Opcode) { -        /* XXX trig needs extra prep */ -        case TGSI_OPCODE_COS: -        case TGSI_OPCODE_SIN: -        /* The simple scalar ops. */ -        case TGSI_OPCODE_EX2: -        case TGSI_OPCODE_LG2: -        case TGSI_OPCODE_RCP: -        case TGSI_OPCODE_RSQ: -            /* Copy red swizzle to alpha for src0 */ -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = -                inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -            /* Fall through */ -        case TGSI_OPCODE_DDX: -        case TGSI_OPCODE_DDY: -        case TGSI_OPCODE_FRC: -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1); -            break; - -        /* The dot products. */ -        case TGSI_OPCODE_DPH: -            /* Set alpha swizzle to one for src0 */ -            if (!inst->FullSrcRegisters[0].SrcRegister.Extended) { -                inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleY; -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ = -                    inst->FullSrcRegisters[0].SrcRegister.SwizzleZ; -            } -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                TGSI_EXTSWIZZLE_ONE; -            /* Fall through */ -        case TGSI_OPCODE_DP3: -        case TGSI_OPCODE_DP4: -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2); -            break; - -        /* Simple three-source operations. */ -        case TGSI_OPCODE_CMP: -            /* Swap src0 and src2 */ -            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2]; -            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3]; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The MAD variants. */ -        case TGSI_OPCODE_SUB: -            /* Just like ADD, but flip the negation on src1 first */ -            inst->FullSrcRegisters[1].SrcRegister.Negate = -                !inst->FullSrcRegisters[1].SrcRegister.Negate; -            /* Fall through */ -        case TGSI_OPCODE_ADD: -            /* Force src0 to one, move all registers over */ -            inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1]; -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[0] = r300_constant_one; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_MUL: -            /* Force our src2 to zero */ -            inst->FullSrcRegisters[2] = r300_constant_zero; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; -        case TGSI_OPCODE_MAD: -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The MOV variants. */ -        case TGSI_OPCODE_ABS: -            /* Set absolute value modifiers. */ -            inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE; -            /* Fall through */ -        case TGSI_OPCODE_MOV: -        case TGSI_OPCODE_SWZ: -            /* src0 -> src1 and src2 forced to zero */ -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0]; -            inst->FullSrcRegisters[2] = r300_constant_zero; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); -            break; - -        /* The compound and hybrid insts. */ -        case TGSI_OPCODE_LRP: -            /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */ -            inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1]; -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2]; -            inst->FullSrcRegisters[0].SrcRegister.Negate = -                !(inst->FullSrcRegisters[0].SrcRegister.Negate); -            inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; -            inst->FullDstRegisters[0].DstRegister.Index = -                assembler->temp_count; -            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); -            inst->FullSrcRegisters[2].SrcRegister.Index = -                assembler->temp_count; -            inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; -            inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; -            inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; -            inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; -            inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; -            inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3]; -            inst->FullSrcRegisters[0].SrcRegister.Negate = -                !(inst->FullSrcRegisters[0].SrcRegister.Negate); -            inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3); -            break; -        case TGSI_OPCODE_POW: -            /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */ -            inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW = -                inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = -                inst->FullSrcRegisters[0].SrcRegister.SwizzleX; -            inst->FullDstRegisters[1] = inst->FullDstRegisters[0]; -            inst->FullDstRegisters[0].DstRegister.Index = -                assembler->temp_count; -            inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1); -            inst->FullSrcRegisters[0].SrcRegister.Index = -                assembler->temp_count; -            inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; -            inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; -            inst->FullSrcRegisters[2] = r300_constant_zero; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3); -            inst->FullDstRegisters[0] = inst->FullDstRegisters[1]; -            r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters, -                    &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1); -            break; - -        /* The texture instruction set. */ -        case TGSI_OPCODE_KIL: -        case TGSI_OPCODE_TEX: -        case TGSI_OPCODE_TXB: -        case TGSI_OPCODE_TXP: -            r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0], -                    &inst->FullDstRegisters[0], inst->Instruction.Opcode); -            break; - -        /* This is the end. My only friend, the end. */ -        case TGSI_OPCODE_END: -            break; -        default: -            debug_printf("r300: fs: Bad opcode %d\n", -                    inst->Instruction.Opcode); -            break; -    } +        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, +    .code.r500.inst[0].inst3 = 0x0, +    .code.r500.inst[0].inst4 = 0x0, +    .code.r500.inst[0].inst5 = 0x0, -    /* 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; -    } -} +    .code.r500.inst[1].inst0 = R500_INST_TYPE_OUT | +        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | +        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | +        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, +    .code.r500.inst[1].inst1 = +        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | +        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, +    .code.r500.inst[1].inst2 = +        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | +        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, +    .code.r500.inst[1].inst3 = +        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | +        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | +        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | +        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, +    .code.r500.inst[1].inst4 = +        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, +    .code.r500.inst[1].inst5 = +        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | +        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | +        R500_ALU_RGBA_A_SWIZ_0, +}; diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h index 7e62c3352b..a4addde32b 100644 --- a/src/gallium/drivers/r300/r5xx_fs.h +++ b/src/gallium/drivers/r300/r5xx_fs.h @@ -24,111 +24,9 @@  #ifndef R5XX_FS_H  #define R5XX_FS_H -#include "r300_fs_inlines.h" +#include "radeon_code.h" -/* XXX this all should find its way back to r300_reg */ -/* Swizzle tools */ -#define R500_SWIZZLE_ZERO 4 -#define R500_SWIZZLE_HALF 5 -#define R500_SWIZZLE_ONE 6 -#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) -#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) -#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) -#define R500_SWIZ_MOD_NEG 1 -#define R500_SWIZ_MOD_ABS 2 -#define R500_SWIZ_MOD_NEG_ABS 3 -/* Swizzles for inst2 */ -#define R500_SWIZ_TEX_STRQ(x) ((x) << 8) -#define R500_SWIZ_TEX_RGBA(x) ((x) << 24) -/* Swizzles for inst3 */ -#define R500_SWIZ_RGB_A(x) ((x) << 2) -#define R500_SWIZ_RGB_B(x) ((x) << 15) -/* Swizzles for inst4 */ -#define R500_SWIZ_ALPHA_A(x) ((x) << 14) -#define R500_SWIZ_ALPHA_B(x) ((x) << 21) -/* Swizzle for inst5 */ -#define R500_SWIZ_RGBA_C(x) ((x) << 14) -#define R500_SWIZ_ALPHA_C(x) ((x) << 27) -/* Writemasks */ -#define R500_TEX_WMASK(x) ((x) << 11) -#define R500_ALU_WMASK(x) ((x) << 11) -#define R500_ALU_OMASK(x) ((x) << 15) -#define R500_W_OMASK (1 << 31) - -static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = { -    .shader.stack_size = 0, -    .instruction_count = 1, -    .instructions[0].inst0 = R500_INST_TYPE_OUT | -        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[0].inst1 = -        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | -        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, -    .instructions[0].inst2 = -        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | -        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, -    .instructions[0].inst3 = -        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | -        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | -        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | -        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, -    .instructions[0].inst4 = -        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, -    .instructions[0].inst5 = -        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | -        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | -        R500_ALU_RGBA_A_SWIZ_0, -}; - -static struct r5xx_fragment_shader r5xx_texture_fragment_shader = { -    .shader.stack_size = 1, -    .instruction_count = 2, -    .instructions[0].inst0 = R500_INST_TYPE_TEX | -        R500_INST_TEX_SEM_WAIT | -        R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD | -        R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED, -    .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) | -        R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G | -        R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A | -        R500_TEX_DST_ADDR(0) | -        R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | -        R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A, -    .instructions[0].inst3 = 0x0, -    .instructions[0].inst4 = 0x0, -    .instructions[0].inst5 = 0x0, -    .instructions[1].inst0 = R500_INST_TYPE_OUT | -        R500_INST_TEX_SEM_WAIT | R500_INST_LAST | -        R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK | -        R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP, -    .instructions[1].inst1 = -        R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | -        R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST, -    .instructions[1].inst2 = -        R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | -        R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST, -    .instructions[1].inst3 = -        R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | -        R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | -        R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | -        R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B, -    .instructions[1].inst4 = -        R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A, -    .instructions[1].inst5 = -        R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | -        R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | -        R500_ALU_RGBA_A_SWIZ_0, -}; - -struct r300_fs_asm; - -void r5xx_fs_finalize(struct r5xx_fragment_shader* fs, -                      struct r300_fs_asm* assembler); - -void r5xx_fs_instruction(struct r5xx_fragment_shader* fs, -                         struct r300_fs_asm* assembler, -                         struct tgsi_full_instruction* inst); +struct rX00_fragment_program_code r5xx_passthrough_fragment_shader; +struct rX00_fragment_program_code r5xx_texture_fragment_shader;  #endif /* R5XX_FS_H */ | 
