aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2009-03-25 06:24:39 -0700
committerCorbin Simpson <[email protected]>2009-03-25 07:15:49 -0700
commit1db736f74a911f74228d6843f4d981eeafb8669d (patch)
tree1afaa9c6a34610b348a07ec5cb6837f769f35b25 /src/gallium/drivers/r300
parente36f01a7a195a747c7d40bc0bab0bfbd00f0a5a7 (diff)
r300-gallium: Unify shader interfaces, enable r300 shader, start unbreaking.
progs/trivial/clear no longer is horrifically wrong, just kind of wrong.
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c2
-rw-r--r--src/gallium/drivers/r300/r300_state.c6
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.c102
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.h5
4 files changed, 84 insertions, 31 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 9bfb89626cd..bf190a7dcdc 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -87,7 +87,7 @@ void r300_emit_fragment_shader(struct r300_context* r300,
BEGIN_CS(22);
- OUT_CS_REG(R300_US_CONFIG, MAX2(fs->indirections - 1, 0));
+ 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, 0x0);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 2a026e7fcac..8c38f7c706e 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -293,11 +293,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
r300->fs = NULL;
return;
} else if (!fs->translated) {
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- r500_translate_fragment_shader(r300, (struct r500_fragment_shader*)fs);
- } else {
- r300_translate_fragment_shader(r300, (struct r300_fragment_shader*)fs);
- }
+ r300_translate_fragment_shader(r300, fs);
}
fs->translated = TRUE;
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
index b5dc1a61b0e..7d81cb87a24 100644
--- a/src/gallium/drivers/r300/r300_state_shader.c
+++ b/src/gallium/drivers/r300/r300_state_shader.c
@@ -171,6 +171,26 @@ static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg)
(reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
}
+static INLINE uint32_t r300_rgb_op(unsigned op)
+{
+ switch (op) {
+ case TGSI_OPCODE_MOV:
+ return R300_ALU_OUTC_CMP;
+ default:
+ return 0;
+ }
+}
+
+static INLINE uint32_t r300_alpha_op(unsigned op)
+{
+ switch (op) {
+ case TGSI_OPCODE_MOV:
+ return R300_ALU_OUTA_CMP;
+ default:
+ return 0;
+ }
+}
+
static INLINE uint32_t r500_rgba_op(unsigned op)
{
switch (op) {
@@ -249,6 +269,33 @@ static INLINE uint32_t r500_tex_op(unsigned op)
}
}
+static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,
+ struct r300_fs_asm* assembler,
+ struct tgsi_full_src_register* src,
+ struct tgsi_full_dst_register* dst,
+ unsigned op,
+ unsigned count)
+{
+ int i = fs->alu_instruction_count;
+
+ fs->instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZB(R300_ALU_ARGC_ONE) |
+ R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
+ R300_ALU_OUTC_MAD;
+ fs->instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
+ fs->instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZB(R300_ALU_ARGA_ONE) |
+ R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
+ R300_ALU_OUTA_MAD;
+ fs->instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
+
+ fs->alu_instruction_count++;
+ fs->indirections = 0;
+ fs->shader.stack_size = 2;
+}
+
/* Setup an ALU operation. */
static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
@@ -367,6 +414,27 @@ static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
}
}
+static void r300_fs_instruction(struct r300_fragment_shader* fs,
+ struct r300_fs_asm* assembler,
+ struct tgsi_full_instruction* inst)
+{
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_MOV:
+ /* src0 -> src1 and src2 forced to zero */
+ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
+ inst->FullSrcRegisters[2] = r500_constant_zero;
+ r300_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
+ break;
+ case TGSI_OPCODE_END:
+ break;
+ default:
+ debug_printf("r300: fs: Bad opcode %d\n",
+ inst->Instruction.Opcode);
+ break;
+ }
+}
+
static void r500_fs_instruction(struct r500_fragment_shader* fs,
struct r300_fs_asm* assembler,
struct tgsi_full_instruction* inst)
@@ -497,24 +565,11 @@ static void r500_fs_finalize(struct r500_fragment_shader* fs,
}
void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs)
-{
- struct tgsi_parse_context parser;
-
- tgsi_parse_init(&parser, fs->shader.state.tokens);
-
- while (!tgsi_parse_end_of_tokens(&parser)) {
- tgsi_parse_token(&parser);
- }
-
- r300_copy_passthrough_shader(fs);
-}
-
-void r500_translate_fragment_shader(struct r300_context* r300,
- struct r500_fragment_shader* fs)
+ struct r3xx_fragment_shader* fs)
{
struct tgsi_parse_context parser;
int i;
+ boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
struct r300_constant_buffer* consts =
&r300->shader_constants[PIPE_SHADER_FRAGMENT];
@@ -525,7 +580,7 @@ void r500_translate_fragment_shader(struct r300_context* r300,
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
- tgsi_parse_init(&parser, fs->shader.state.tokens);
+ tgsi_parse_init(&parser, fs->state.tokens);
while (!tgsi_parse_end_of_tokens(&parser)) {
tgsi_parse_token(&parser);
@@ -552,8 +607,13 @@ void r500_translate_fragment_shader(struct r300_context* r300,
assembler->imm_count++;
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
- r500_fs_instruction(fs, assembler,
- &parser.FullToken.FullInstruction);
+ if (is_r500) {
+ r500_fs_instruction((struct r500_fragment_shader*)fs,
+ assembler, &parser.FullToken.FullInstruction);
+ } else {
+ r300_fs_instruction((struct r300_fragment_shader*)fs,
+ assembler, &parser.FullToken.FullInstruction);
+ }
break;
}
@@ -567,10 +627,10 @@ void r500_translate_fragment_shader(struct r300_context* r300,
debug_printf("r300: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
- r500_fs_finalize(fs, assembler);
+ //r500_fs_finalize(fs, assembler);
- tgsi_dump(fs->shader.state.tokens);
- r500_fs_dump(fs);
+ tgsi_dump(fs->state.tokens);
+ //r500_fs_dump(fs);
tgsi_parse_free(&parser);
FREE(assembler);
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
index 06c0bb73789..fdba207e183 100644
--- a/src/gallium/drivers/r300/r300_state_shader.h
+++ b/src/gallium/drivers/r300/r300_state_shader.h
@@ -102,10 +102,7 @@ struct r300_fs_asm {
};
void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs);
-
-void r500_translate_fragment_shader(struct r300_context* r300,
- struct r500_fragment_shader* fs);
+ struct r3xx_fragment_shader* fs);
static const struct r300_fragment_shader r300_passthrough_fragment_shader = {
/* XXX This is the emission code. TODO: decode