X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_tgsi_to_rc.c;h=21a1c45982d3b09d7ca54c24ca0d19dfc6d71ed5;hb=24ceef7a6969ccb2243e7bb32f86d6429d9689b9;hp=9fb2de24032730c4c8800efa8a27b511fbcce1cb;hpb=91a4e6d53f83c45c1da9240b6325011d96b61386;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 9fb2de24032..21a1c45982d 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -25,11 +25,11 @@ #include "radeon_compiler.h" #include "radeon_program.h" +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_util.h" - static unsigned translate_opcode(unsigned opcode) { switch(opcode) { @@ -120,7 +120,7 @@ static unsigned translate_opcode(unsigned opcode) /* case TGSI_OPCODE_NOT: return RC_OPCODE_NOT; */ /* case TGSI_OPCODE_TRUNC: return RC_OPCODE_TRUNC; */ /* case TGSI_OPCODE_SHL: return RC_OPCODE_SHL; */ - /* case TGSI_OPCODE_SHR: return RC_OPCODE_SHR; */ + /* case TGSI_OPCODE_ISHR: return RC_OPCODE_SHR; */ /* case TGSI_OPCODE_AND: return RC_OPCODE_AND; */ /* case TGSI_OPCODE_OR: return RC_OPCODE_OR; */ /* case TGSI_OPCODE_MOD: return RC_OPCODE_MOD; */ @@ -144,7 +144,7 @@ static unsigned translate_opcode(unsigned opcode) case TGSI_OPCODE_KIL: return RC_OPCODE_KIL; } - fprintf(stderr, "Unknown opcode: %i\n", opcode); + fprintf(stderr, "r300: Unknown TGSI/RC opcode: %s\n", tgsi_get_opcode_name(opcode)); return RC_OPCODE_ILLEGAL_OPCODE; } @@ -201,6 +201,8 @@ static void transform_srcreg( struct rc_src_register * dst, struct tgsi_full_src_register * src) { + unsigned i, j; + dst->File = translate_register_file(src->Register.File); dst->Index = translate_register_index(ttr, src->Register.File, src->Register.Index); dst->RelAddr = src->Register.Indirect; @@ -210,9 +212,25 @@ static void transform_srcreg( dst->Swizzle |= tgsi_util_get_full_src_register_swizzle(src, 3) << 9; dst->Abs = src->Register.Absolute; dst->Negate = src->Register.Negate ? RC_MASK_XYZW : 0; + + if (src->Register.File == TGSI_FILE_IMMEDIATE) { + for (i = 0; i < ttr->imms_to_swizzle_count; i++) { + if (ttr->imms_to_swizzle[i].index == src->Register.Index) { + dst->File = RC_FILE_TEMPORARY; + dst->Index = 0; + dst->Swizzle = 0; + for (j = 0; j < 4; j++) { + dst->Swizzle |= GET_SWZ(ttr->imms_to_swizzle[i].swizzle, + tgsi_util_get_full_src_register_swizzle(src, j)) << (j * 3); + } + break; + } + } + } } -static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src) +static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src, + uint32_t *shadowSamplers) { switch(src.Texture) { case TGSI_TEXTURE_1D: @@ -233,14 +251,17 @@ static void transform_texture(struct rc_instruction * dst, struct tgsi_instructi case TGSI_TEXTURE_SHADOW1D: dst->U.I.TexSrcTarget = RC_TEXTURE_1D; dst->U.I.TexShadow = 1; + *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; case TGSI_TEXTURE_SHADOW2D: dst->U.I.TexSrcTarget = RC_TEXTURE_2D; dst->U.I.TexShadow = 1; + *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; case TGSI_TEXTURE_SHADOWRECT: dst->U.I.TexSrcTarget = RC_TEXTURE_RECT; dst->U.I.TexShadow = 1; + *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; } } @@ -250,9 +271,6 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst struct rc_instruction * dst; int i; - if (src->Instruction.Opcode == TGSI_OPCODE_END) - return; - dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev); dst->U.I.Opcode = translate_opcode(src->Instruction.Opcode); dst->U.I.SaturateMode = translate_saturate(src->Instruction.Saturate); @@ -269,24 +287,51 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst /* Texturing. */ if (src->Instruction.Texture) - transform_texture(dst, src->Texture); + transform_texture(dst, src->Texture, + &ttr->compiler->Program.ShadowSamplers); } -static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm) +static void handle_immediate(struct tgsi_to_rc * ttr, + struct tgsi_full_immediate * imm, + unsigned index) { struct rc_constant constant; - int i; + unsigned swizzle = 0; + boolean can_swizzle = TRUE; + unsigned i; - constant.Type = RC_CONSTANT_IMMEDIATE; - constant.Size = 4; - for(i = 0; i < 4; ++i) - constant.u.Immediate[i] = imm->u[i].Float; - rc_constants_add(&ttr->compiler->Program.Constants, &constant); + for (i = 0; i < 4; i++) { + if (imm->u[i].Float == 0.0f) { + swizzle |= RC_SWIZZLE_ZERO << (i * 3); + } else if (imm->u[i].Float == 0.5f && ttr->use_half_swizzles) { + swizzle |= RC_SWIZZLE_HALF << (i * 3); + } else if (imm->u[i].Float == 1.0f) { + swizzle |= RC_SWIZZLE_ONE << (i * 3); + } else { + can_swizzle = FALSE; + break; + } + } + + if (can_swizzle) { + ttr->imms_to_swizzle[ttr->imms_to_swizzle_count].index = index; + ttr->imms_to_swizzle[ttr->imms_to_swizzle_count].swizzle = swizzle; + ttr->imms_to_swizzle_count++; + } else { + constant.Type = RC_CONSTANT_IMMEDIATE; + constant.Size = 4; + for(i = 0; i < 4; ++i) + constant.u.Immediate[i] = imm->u[i].Float; + rc_constants_add(&ttr->compiler->Program.Constants, &constant); + } } -void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) +void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, + const struct tgsi_token * tokens) { + struct tgsi_full_instruction *inst; struct tgsi_parse_context parser; + unsigned imm_index = 0; int i; /* Allocate constants placeholders. @@ -303,6 +348,9 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) ttr->immediate_offset = ttr->compiler->Program.Constants.Count; + ttr->imms_to_swizzle = malloc(ttr->info->immediate_count * sizeof(struct swizzled_imms)); + ttr->imms_to_swizzle_count = 0; + tgsi_parse_init(&parser, tokens); while (!tgsi_parse_end_of_tokens(&parser)) { @@ -312,16 +360,26 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) case TGSI_TOKEN_TYPE_DECLARATION: break; case TGSI_TOKEN_TYPE_IMMEDIATE: - handle_immediate(ttr, &parser.FullToken.FullImmediate); + handle_immediate(ttr, &parser.FullToken.FullImmediate, imm_index); + imm_index++; break; case TGSI_TOKEN_TYPE_INSTRUCTION: - transform_instruction(ttr, &parser.FullToken.FullInstruction); + inst = &parser.FullToken.FullInstruction; + /* This hack with the RET opcode woudn't work with + * conditionals. */ + if (inst->Instruction.Opcode == TGSI_OPCODE_END || + inst->Instruction.Opcode == TGSI_OPCODE_RET) { + break; + } + + transform_instruction(ttr, inst); break; } } tgsi_parse_free(&parser); + free(ttr->imms_to_swizzle); + rc_calculate_inputs_outputs(ttr->compiler); } -