diff options
author | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-03-16 16:47:05 -0700 |
---|---|---|
committer | Corbin Simpson <MostAwesomeDude@gmail.com> | 2009-03-17 02:13:03 -0700 |
commit | 307e68f73996160cdf4a05a84c112e11e0d7a3c2 (patch) | |
tree | 8655539587a20287caffe1323fed30a603c07e03 /src/gallium/drivers/r300 | |
parent | 93ef9ec5eb3422673bfc307a27d291ff18f22f0d (diff) |
r300-gallium: r500-fs: Texture insts, ABS, moar comments.
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r-- | src/gallium/drivers/r300/r300_state_shader.c | 94 |
1 files changed, 66 insertions, 28 deletions
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c index f7ca5c9139..7803494130 100644 --- a/src/gallium/drivers/r300/r300_state_shader.c +++ b/src/gallium/drivers/r300/r300_state_shader.c @@ -103,6 +103,10 @@ 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; @@ -155,14 +159,16 @@ 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->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->SrcRegister.Negate ? (1 << 9) : 0) | + (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0); } static INLINE uint32_t r500_rgba_op(unsigned op) @@ -180,6 +186,7 @@ static INLINE uint32_t r500_rgba_op(unsigned op) 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: @@ -211,6 +218,7 @@ static INLINE uint32_t r500_alpha_op(unsigned op) 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: @@ -225,6 +233,22 @@ static INLINE uint32_t r500_alpha_op(unsigned op) } } +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; + } +} + /* Setup an ALU operation. */ static INLINE void r500_emit_alu(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, @@ -305,9 +329,9 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs, static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, struct r300_fs_asm* assembler, - uint32_t op, struct tgsi_full_src_register* src, - struct tgsi_full_dst_register* dst) + struct tgsi_full_dst_register* dst, + uint32_t op) { int i = fs->instruction_count; @@ -315,8 +339,8 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, 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_INST_PROJ; + 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)) | @@ -324,6 +348,12 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs, 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_offset + + assembler->temp_count); + } + fs->instruction_count++; } @@ -336,6 +366,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, * AMD/ATI names for opcodes, please, as it facilitates using the * documentation. */ switch (inst->Instruction.Opcode) { + /* The simple scalar ops. */ case TGSI_OPCODE_EX2: case TGSI_OPCODE_LG2: case TGSI_OPCODE_RCP: @@ -350,6 +381,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, 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) { @@ -369,6 +402,18 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, 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 = @@ -382,36 +427,22 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, r500_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); break; - 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; 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_ABS: - r500_emit_maths(fs, assembler, inst->FullSrcRegisters, - &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); - /* Set absolute value modifiers. */ - i = fs->instruction_count - 1; - fs->instructions[i].inst3 |= - R500_ALU_RGB_MOD_A_ABS | - R500_ALU_RGB_MOD_B_ABS; - fs->instructions[i].inst4 |= - R500_ALPHA_MOD_A_ABS | - R500_ALPHA_MOD_B_ABS; - 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 */ @@ -420,10 +451,17 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs, r500_emit_maths(fs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3); 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, 0, &inst->FullSrcRegisters[0], - &inst->FullDstRegisters[0]); + 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: |