From 1db736f74a911f74228d6843f4d981eeafb8669d Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 25 Mar 2009 06:24:39 -0700 Subject: [PATCH] r300-gallium: Unify shader interfaces, enable r300 shader, start unbreaking. progs/trivial/clear no longer is horrifically wrong, just kind of wrong. --- src/gallium/drivers/r300/r300_emit.c | 2 +- src/gallium/drivers/r300/r300_state.c | 6 +- src/gallium/drivers/r300/r300_state_shader.c | 102 +++++++++++++++---- src/gallium/drivers/r300/r300_state_shader.h | 5 +- 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 -- 2.30.2