summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_state_shader.c
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2009-03-16 10:23:45 -0700
committerCorbin Simpson <[email protected]>2009-03-17 02:13:02 -0700
commitf1d93f60826cb95d4d19348d1ca505705c4455c6 (patch)
treef871c4bcdfe9c78c009d9d19478517f090e801d7 /src/gallium/drivers/r300/r300_state_shader.c
parentadd896aec8783aedbaf8d0127d8da046ce2657b5 (diff)
r300-gallium: r500-fs: CMP/MOV/SWZ, negation, ADD/MAD/MUL/SUB.
Also a fair amount of cleanup.
Diffstat (limited to 'src/gallium/drivers/r300/r300_state_shader.c')
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
index 564acad83b3..575d771c073 100644
--- a/src/gallium/drivers/r300/r300_state_shader.c
+++ b/src/gallium/drivers/r300/r300_state_shader.c
@@ -76,6 +76,8 @@ 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;
@@ -152,19 +154,22 @@ static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg)
static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg)
{
/* Only the first 9 bits... */
- return r500_rgba_swiz(reg) & 0x1ff;
+ return (r500_rgba_swiz(reg) & 0x1ff) |
+ (reg->SrcRegister.Negate ? (1 << 9) : 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;
+ return (r500_rgba_swiz(reg) >> 9) |
+ (reg->SrcRegister.Negate ? (1 << 9) : 0);
}
static INLINE uint32_t r500_sop_swiz(struct tgsi_full_src_register* reg)
{
/* Only the first 3 bits... */
- return r500_rgba_swiz(reg) & 0x7;
+ return (r500_rgba_swiz(reg) & 0x7) |
+ (reg->SrcRegister.Negate ? (1 << 9) : 0);
}
static INLINE uint32_t r500_rgba_op(unsigned op)
@@ -182,7 +187,14 @@ 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_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;
@@ -206,7 +218,14 @@ 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_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;
@@ -293,34 +312,6 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
fs->instruction_count++;
}
-static INLINE void r500_emit_mov(struct r500_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst)
-{
- int i = fs->instruction_count;
-
- r500_emit_alu(fs, assembler, dst);
-
- fs->instructions[i].inst1 =
- R500_RGB_ADDR0(r300_fs_src(assembler, &src->SrcRegister));
- fs->instructions[i].inst2 =
- R500_ALPHA_ADDR0(r300_fs_src(assembler, &src->SrcRegister));
- fs->instructions[i].inst3 = R500_ALU_RGB_SEL_A_SRC0 |
- R500_SWIZ_RGB_A(r500_rgb_swiz(src)) |
- R500_ALU_RGB_SEL_B_SRC0 |
- R500_SWIZ_RGB_B(r500_rgb_swiz(src));
- fs->instructions[i].inst4 |= R500_ALPHA_OP_CMP |
- R500_SWIZ_ALPHA_A(r500_alpha_swiz(src)) |
- R500_SWIZ_ALPHA_B(r500_alpha_swiz(src));
- fs->instructions[i].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;
-
- fs->instruction_count++;
-}
-
static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
uint32_t op,
@@ -382,6 +373,11 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
fs->instructions[i].inst4 &= ~R500_SWIZ_ALPHA_A(0x7);
fs->instructions[i].inst4 |= R500_SWIZ_ALPHA_A(R500_SWIZZLE_ONE);
break;
+ 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];
@@ -391,6 +387,15 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3,
false);
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,
+ false);
+ break;
case TGSI_OPCODE_MUL:
/* Force our src2 to zero */
inst->FullSrcRegisters[2] = r500_constant_zero;
@@ -418,8 +423,12 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
break;
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
- r500_emit_mov(fs, assembler, &inst->FullSrcRegisters[0],
- &inst->FullDstRegisters[0]);
+ /* 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,
+ false);
break;
case TGSI_OPCODE_TXP:
r500_emit_tex(fs, assembler, 0, &inst->FullSrcRegisters[0],