From 3b42468fc7cbae314aac9cfeb3cb1c215e684e76 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 13 Jul 2010 21:25:27 -0700 Subject: [PATCH] Temp --- .../drivers/dri/r300/compiler/r500_fragprog_emit.c | 37 +++++ .../drivers/dri/r300/compiler/radeon_optimize.c | 145 ++++++++++++++++++-- .../dri/r300/compiler/radeon_pair_schedule.c | 46 ++++++ .../dri/r300/compiler/radeon_pair_translate.c | 33 +++++ .../drivers/dri/r300/compiler/radeon_program.h | 9 +- .../dri/r300/compiler/radeon_program_constants.h | 29 ++++- .../dri/r300/compiler/radeon_program_pair.c | 2 + .../dri/r300/compiler/radeon_program_pair.h | 17 ++- .../dri/r300/compiler/radeon_program_print.c | 72 +++++++++- 9 files changed, 371 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index 0bd8f0a..9949e8e 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -251,6 +251,9 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair code->inst[ip].inst0 |= (inst->RGB.WriteMask << 11) | (inst->Alpha.WriteMask << 14); code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18); + if (inst->Nop) { + code->inst[ip].inst0 |= R500_INST_NOP; + } if (inst->Alpha.DepthWriteMask) { code->inst[ip].inst4 |= R500_ALPHA_W_OMASK; c->code->writes_depth = 1; @@ -266,6 +269,40 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair if (inst->Alpha.Saturate) code->inst[ip].inst0 |= R500_INST_ALPHA_CLAMP; + /* Set the presubtract operation. */ + switch(inst->RGB.PreSub) { + case RC_PRESUB_BIAS: + code->inst[ip].inst1 |= R500_RGB_SRCP_OP_1_MINUS_2RGB0; + break; + case RC_PRESUB_SUB: + code->inst[ip].inst1 |= R500_RGB_SRCP_OP_RGB1_MINUS_RGB0; + break; + case RC_PRESUB_ADD: + code->inst[ip].inst1 |= R500_RGB_SRCP_OP_RGB1_PLUS_RGB0; + break; + case RC_PRESUB_INV: + code->inst[ip].inst1 |= R500_RGB_SRCP_OP_1_MINUS_RGB0; + break; + default: + break; + } + switch(inst->Alpha.PreSub) { + case RC_PRESUB_BIAS: + code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_1_MINUS_2A0; + break; + case RC_PRESUB_SUB: + code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_A1_MINUS_A0; + break; + case RC_PRESUB_ADD: + code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_A1_PLUS_A0; + break; + case RC_PRESUB_INV: + code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_1_MINUS_A0; + break; + default: + break; + } + code->inst[ip].inst1 |= R500_RGB_ADDR0(use_source(code, inst->RGB.Src[0])); code->inst[ip].inst1 |= R500_RGB_ADDR1(use_source(code, inst->RGB.Src[1])); code->inst[ip].inst1 |= R500_RGB_ADDR2(use_source(code, inst->RGB.Src[2])); diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c index eca0651..31d0f7d 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c @@ -54,7 +54,7 @@ static struct rc_src_register chain_srcregs(struct rc_src_register outer, struct return combine; } -struct peephole_state { +struct copy_propagate_state { struct radeon_compiler * C; struct rc_instruction * Mov; unsigned int Conflict:1; @@ -84,10 +84,10 @@ struct peephole_state { * @param index The index of the source register. * @param mask The components of the source register that are being read from. */ -static void peephole_scan_read(void * data, struct rc_instruction * inst, +static void copy_propagate_scan_read(void * data, struct rc_instruction * inst, rc_register_file file, unsigned int index, unsigned int mask) { - struct peephole_state * s = data; + struct copy_propagate_state * s = data; if (file != RC_FILE_TEMPORARY || index != s->Mov->U.I.DstReg.Index) return; @@ -117,10 +117,10 @@ static void peephole_scan_read(void * data, struct rc_instruction * inst, } } -static void peephole_scan_write(void * data, struct rc_instruction * inst, +static void copy_propagate_scan_write(void * data, struct rc_instruction * inst, rc_register_file file, unsigned int index, unsigned int mask) { - struct peephole_state * s = data; + struct copy_propagate_state * s = data; if (s->BranchDepth < 0) return; @@ -140,9 +140,9 @@ static void peephole_scan_write(void * data, struct rc_instruction * inst, } } -static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mov) +static void copy_propagate(struct radeon_compiler * c, struct rc_instruction * inst_mov) { - struct peephole_state s; + struct copy_propagate_state s; if (inst_mov->U.I.DstReg.File != RC_FILE_TEMPORARY || inst_mov->U.I.WriteALUResult) return; @@ -167,8 +167,8 @@ static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mo if(inst->U.I.Opcode == RC_OPCODE_BGNLOOP){ return; } - rc_for_all_reads_mask(inst, peephole_scan_read, &s); - rc_for_all_writes_mask(inst, peephole_scan_write, &s); + rc_for_all_reads_mask(inst, copy_propagate_scan_read, &s); + rc_for_all_writes_mask(inst, copy_propagate_scan_write, &s); if (s.Conflict) return; @@ -445,6 +445,128 @@ static void constant_folding(struct radeon_compiler * c, struct rc_instruction * constant_folding_add(inst); } +static unsigned int src_reads_dst(struct rc_src_register src, + struct rc_dst_register dst) +{ + unsigned int mask = 0; + unsigned int i; + if(dst.File != src.File) { + return 0; + } + if(dst.Index != src.Index) { + return 0; + } + for(i = 0; i < 4; i++) { + mask |= 1 << GET_SWZ(src.Swizzle, i); + } + mask &= RC_MASK_XYZW; + + if((dst.WriteMask & mask) != mask) { + return 0; + } + return mask; +} + +static int presub_inv(struct rc_dst_register dest_reg, + struct rc_src_register presub_src, + struct rc_instruction * inst) +{ + int ret = 0; + unsigned int i; + const struct rc_opcode_info * info = + rc_get_opcode_info(inst->U.I.Opcode); + for(i = 0; i < info->NumSrcRegs; i++) { + if(src_reads_dst(inst->U.I.SrcReg[i], dest_reg)) { + inst->U.I.PreSub.SrcReg[0] = presub_src; + /* XXX This should be done elsewhere. */ + inst->U.I.PreSub.SrcReg[0].Negate = 0; + /* XXX Only use necessary swizzle values in presbu. */ + /* XXX Clear old values */ + /* XXX Can presub value be used twice? */ + inst->U.I.SrcReg[i].File = RC_FILE_PRESUB; + /* XXX Maybe PreSub should not use rc_src_register, + * because it has less fields. */ + inst->U.I.PreSub.Opcode = RC_PRESUB_INV; + ret = 1; + } + } + return ret; +} + +struct peephole_state { + struct rc_instruction * Inst; + unsigned int WriteMask; +}; + +static void peephole_scan_write(void * data, struct rc_instruction * inst, + rc_register_file file, unsigned int index, unsigned int mask) +{ + struct peephole_state * s = data; + if(s->Inst->U.I.DstReg.File == file + && s->Inst->U.I.DstReg.Index == index) { + unsigned int common_mask = s->WriteMask & s->WriteMask && mask; + s->WriteMask &= ~common_mask; + } +} + +/* Return of 1 means instruction has been removed. */ +static int peephole_add(struct radeon_compiler * c, + struct rc_instruction * inst_add) +{ + unsigned int i, swz, mask; + unsigned int modified = 0; + struct rc_instruction * inst; + struct peephole_state s; + + /* PRESUB_INV: ADD TEMP[0], 1, -TEMP[1] + * Use the presubtract 1 - src0 for all readers of TEMP[0] + */ + swz = inst_add->U.I.SrcReg[0].Swizzle; + mask = inst_add->U.I.DstReg.WriteMask; + /* Check if src0 is the 1. */ + for(i = 0; i < 4; i++ ) { + if(GET_BIT(mask, i) && GET_SWZ(swz, i) != RC_SWIZZLE_ONE){ + return 0; + } + } +// fprintf(stderr, "src0 is 1.\n"); + /* Check if src1 is negative. */ + if(!(inst_add->U.I.SrcReg[1].Negate & mask)){ + return 0; + } +// fprintf(stderr, "src1 is negative.\n"); + s.Inst = inst_add; + s.WriteMask = inst_add->U.I.DstReg.WriteMask; + for(inst = inst_add->Next; inst != &c->Program.Instructions; + inst = inst->Next) { + if(presub_inv(s.Inst->U.I.DstReg,s.Inst->U.I.SrcReg[1],inst)) { + modified++; + } + rc_for_all_writes_mask(inst, peephole_scan_write, &s); + if (!s.WriteMask){ + break; + } + } + if(!modified) { + return 0; + } else { + rc_remove_instruction(inst_add); + return 1; + } +} + +static int peephole(struct radeon_compiler * c, struct rc_instruction * inst) +{ + switch(inst->U.I.Opcode){ + case RC_OPCODE_ADD: + return peephole_add(c, inst); + break; + default: + break; + } + return 0; +} + void rc_optimize(struct radeon_compiler * c) { struct rc_instruction * inst = c->Program.Instructions.Next; @@ -454,8 +576,11 @@ void rc_optimize(struct radeon_compiler * c) constant_folding(c, cur); + if(peephole(c, cur)) + continue; + if (cur->U.I.Opcode == RC_OPCODE_MOV) { - peephole(c, cur); + copy_propagate(c, cur); /* cur may no longer be part of the program */ } } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c index fc54049..4b39d44 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c @@ -351,7 +351,48 @@ static int merge_instructions(struct rc_pair_instruction * rgb, struct rc_pair_i return 0; } +static void presub_nop(struct rc_instruction * emitted) { + int prev_rgb_index, prev_alpha_index, i, num_src; + /* We don't need a nop if the previous instruction is a TEX. */ + if (emitted->Prev->Type != RC_INSTRUCTION_PAIR) { + return; + } + if (emitted->Prev->U.P.RGB.WriteMask) + prev_rgb_index = emitted->Prev->U.P.RGB.DestIndex; + else + prev_rgb_index = -1; + if (emitted->Prev->U.P.Alpha.WriteMask) + prev_alpha_index = emitted->Prev->U.P.Alpha.DestIndex; + else + prev_alpha_index = 1; + if (emitted->U.P.RGB.PreSub != RC_PRESUB_NONE) { + num_src = + rc_presubtract_src_reg_count(emitted->U.P.RGB.PreSub); + for (i = 0; i < num_src; i++) { + unsigned int index = emitted->U.P.RGB.Src[i].Index; + if (emitted->U.P.RGB.Src[i].File == RC_FILE_TEMPORARY + && (index == prev_rgb_index + || index == prev_alpha_index)) { + emitted->Prev->U.P.Nop = 1; + return; + } + } + } + + if (emitted->U.P.Alpha.PreSub == RC_PRESUB_NONE) + return; + + num_src = rc_presubtract_src_reg_count(emitted->U.P.Alpha.PreSub); + for (i = 0; i < num_src; i++) { + unsigned int index = emitted->U.P.Alpha.Src[i].Index; + if(emitted->U.P.Alpha.Src[i].File == RC_FILE_TEMPORARY + && (index == prev_rgb_index || index == prev_alpha_index)) { + emitted->Prev->U.P.Nop = 1; + return; + } + } +} /** * Find a good ALU instruction or pair of ALU instruction and emit it. * @@ -362,6 +403,7 @@ static int merge_instructions(struct rc_pair_instruction * rgb, struct rc_pair_i static void emit_one_alu(struct schedule_state *s, struct rc_instruction * before) { struct schedule_instruction * sinst; + struct rc_instruction * emitted; if (s->ReadyFullALU || !(s->ReadyRGB && s->ReadyAlpha)) { if (s->ReadyFullALU) { @@ -408,6 +450,10 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor commit_alu_instruction(s, sinst); success: ; } + /* If the instruction we just emitted uses a presubtract value, and + * the presubtract sources were written by the previous intstruction, + * the previous instruction needs a nop. */ + presub_nop(before->Prev); } static void scan_read(void * data, struct rc_instruction * inst, diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c index 407a0a5..d16e52b 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c @@ -158,6 +158,39 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c, const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); int i; + /* Presubtract handling */ + if(inst->PreSub.Opcode != RC_PRESUB_NONE) { + int src_regs =rc_presubtract_src_reg_count(inst->PreSub.Opcode); + /* XXX are these needrgb and needalpha's necessary. */ + if(needrgb) { + pair->RGB.PreSub = inst->PreSub.Opcode; + pair->RGB.Src[PRESUB_SOURCE].File = RC_FILE_PRESUB; + pair->RGB.Src[PRESUB_SOURCE].Used = 1; + } + if(needalpha) { + pair->Alpha.PreSub = inst->PreSub.Opcode; + pair->Alpha.Src[PRESUB_SOURCE].File = RC_FILE_PRESUB; + pair->Alpha.Src[PRESUB_SOURCE].Used = 1; + } + for(i = 0; i < src_regs; i++) { + /* XXX Do we need !istranscendent here? */ + if(needrgb) { + pair->RGB.Src[i].File = + inst->PreSub.SrcReg[i].File; + pair->RGB.Src[i].Index = + inst->PreSub.SrcReg[i].Index; + pair->RGB.Src[i].Used = 1; + } + if(needalpha) { + pair->Alpha.Src[i].File = + inst->PreSub.SrcReg[i].File; + pair->Alpha.Src[i].Index = + inst->PreSub.SrcReg[i].Index; + pair->RGB.Src[i].Used = 1; + } + } + } + for(i = 0; i < opcode->NumSrcRegs; ++i) { int source; if (needrgb && !istranscendent) { diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.h b/src/mesa/drivers/dri/r300/compiler/radeon_program.h index e318867..d522a62 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.h @@ -39,7 +39,7 @@ struct radeon_compiler; struct rc_src_register { - unsigned int File:3; + unsigned int File:4; /** Negative values may be used for relative addressing. */ signed int Index:(RC_REGISTER_INDEX_BITS+1); @@ -64,6 +64,11 @@ struct rc_dst_register { unsigned int WriteMask:4; }; +struct rc_presub_instruction { + rc_presubtract_op Opcode; + struct rc_src_register SrcReg[2]; +}; + /** * Instructions are maintained by the compiler in a doubly linked list * of these structures. @@ -108,6 +113,8 @@ struct rc_sub_instruction { /** True if tex instruction should do shadow comparison */ unsigned int TexShadow:1; /*@}*/ + + struct rc_presub_instruction PreSub; }; typedef enum { diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h index 2ddf60b..405efb9 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_constants.h @@ -79,7 +79,13 @@ typedef enum { /** * Indicates a special register, see RC_SPECIAL_xxx. */ - RC_FILE_SPECIAL + RC_FILE_SPECIAL, + + /** + * Indicates this register should use the result of the pre-subtract + * operation. + */ + RC_FILE_PRESUB } rc_register_file; enum { @@ -147,4 +153,25 @@ typedef enum { RC_ALURESULT_W } rc_write_aluresult; +typedef enum { + RC_PRESUB_NONE = 0, + RC_PRESUB_BIAS, + RC_PRESUB_SUB, + RC_PRESUB_ADD, + RC_PRESUB_INV +} rc_presubtract_op; + +static inline int rc_presubtract_src_reg_count(rc_presubtract_op op){ + switch(op){ + case RC_PRESUB_BIAS: + case RC_PRESUB_INV: + return 1; + case RC_PRESUB_ADD: + case RC_PRESUB_SUB: + return 2; + default: + return 0; + } + return 0; +} #endif /* RADEON_PROGRAM_CONSTANTS_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c index ee83959..4537e56 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c @@ -42,6 +42,8 @@ int rc_pair_alloc_source(struct rc_pair_instruction *pair, if ((!rgb && !alpha) || file == RC_FILE_NONE) return 0; + if(file == RC_FILE_PRESUB) + return PRESUB_SOURCE; for(i = 0; i < 3; ++i) { int q = 0; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 511cc70..f179323 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -49,6 +49,12 @@ struct r300_fragment_program_compiler; * see \ref rc_pair_translate */ +/* For rgb and alpha instructions when arg[n].Sourc = PRESUB_SOURCE, then + * the presubtract value will be used. Also Src[PRESUB_SOURCE].File will + * be set to RC_FILE_PRESUB. + */ +/* XXX Change this name */ +#define PRESUB_SOURCE 3 struct radeon_pair_instruction_source { unsigned int Used:1; @@ -63,15 +69,16 @@ struct radeon_pair_instruction_rgb { unsigned int Target:2; unsigned int OutputWriteMask:3; unsigned int Saturate:1; + rc_presubtract_op PreSub; - struct radeon_pair_instruction_source Src[3]; + struct radeon_pair_instruction_source Src[4]; struct { unsigned int Source:2; unsigned int Swizzle:9; unsigned int Abs:1; unsigned int Negate:1; - } Arg[3]; + } Arg[4]; }; struct radeon_pair_instruction_alpha { @@ -82,15 +89,16 @@ struct radeon_pair_instruction_alpha { unsigned int OutputWriteMask:1; unsigned int DepthWriteMask:1; unsigned int Saturate:1; + rc_presubtract_op PreSub; - struct radeon_pair_instruction_source Src[3]; + struct radeon_pair_instruction_source Src[4]; struct { unsigned int Source:2; unsigned int Swizzle:3; unsigned int Abs:1; unsigned int Negate:1; - } Arg[3]; + } Arg[4]; }; struct rc_pair_instruction { @@ -99,6 +107,7 @@ struct rc_pair_instruction { unsigned int WriteALUResult:2; unsigned int ALUResultCompare:3; + unsigned int Nop:1; }; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c index 28fb9ea..8654970 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c @@ -38,6 +38,24 @@ static const char * textarget_to_string(rc_texture_target target) } } +static const char * presubtract_op_to_string(rc_presubtract_op op) +{ + switch(op) { + case RC_PRESUB_NONE: + return "NONE"; + case RC_PRESUB_BIAS: + return "BIAS"; + case RC_PRESUB_SUB: + return "SUB"; + case RC_PRESUB_ADD: + return "ADD"; + case RC_PRESUB_INV: + return "INV:"; + default: + return "BAD_PRESUBTRACT_OP"; + } +} + static void rc_print_comparefunc(FILE * f, const char * lhs, rc_compare_func func, const char * rhs) { if (func == RC_COMPARE_FUNC_NEVER) { @@ -148,6 +166,33 @@ static void rc_print_src_register(FILE * f, struct rc_src_register src) fprintf(f, "|"); } +static void rc_print_presub_instruction(FILE * f, + struct rc_presub_instruction inst) +{ + switch(inst.Opcode){ + case RC_PRESUB_BIAS: + fprintf(f, "1 - 2 * "); + rc_print_src_register(f, inst.SrcReg[0]); + break; + case RC_PRESUB_SUB: + rc_print_src_register(f, inst.SrcReg[0]); + fprintf(f, " - "); + rc_print_src_register(f, inst.SrcReg[1]); + break; + case RC_PRESUB_ADD: + rc_print_src_register(f, inst.SrcReg[0]); + fprintf(f, " + "); + rc_print_src_register(f, inst.SrcReg[1]); + break; + case RC_PRESUB_INV: + fprintf(f, "1 - "); + rc_print_src_register(f, inst.SrcReg[0]); + break; + default: + break; + } +} + static void rc_print_normal_instruction(FILE * f, struct rc_instruction * inst) { const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); @@ -173,7 +218,10 @@ static void rc_print_normal_instruction(FILE * f, struct rc_instruction * inst) if (reg > 0) fprintf(f, ","); fprintf(f, " "); - rc_print_src_register(f, inst->U.I.SrcReg[reg]); + if(inst->U.I.SrcReg[reg].File == RC_FILE_PRESUB) + rc_print_presub_instruction(f, inst->U.I.PreSub); + else + rc_print_src_register(f, inst->U.I.SrcReg[reg]); } if (opcode->HasTexture) { @@ -217,6 +265,14 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst printedsrc = 1; } } + if(inst->RGB.Src[PRESUB_SOURCE].Used) { + fprintf(f, ", srcp.xyz = %s", + presubtract_op_to_string(inst->RGB.PreSub)); + } + if(inst->Alpha.Src[PRESUB_SOURCE].Used) { + fprintf(f, ", srcp.w = %s", + presubtract_op_to_string(inst->Alpha.PreSub)); + } fprintf(f, "\n"); if (inst->RGB.Opcode != RC_OPCODE_NOP) { @@ -239,7 +295,12 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) { const char* abs = inst->RGB.Arg[arg].Abs ? "|" : ""; const char* neg = inst->RGB.Arg[arg].Negate ? "-" : ""; - fprintf(f, ", %s%ssrc%i.%c%c%c%s", neg, abs, inst->RGB.Arg[arg].Source, + fprintf(f, ", %s%ssrc", neg, abs); + if(inst->RGB.Arg[arg].Source == PRESUB_SOURCE) + fprintf(f,"p"); + else + fprintf(f,"%d", inst->RGB.Arg[arg].Source); + fprintf(f,".%c%c%c%s", rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 0)), rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 1)), rc_swizzle_char(GET_SWZ(inst->RGB.Arg[arg].Swizzle, 2)), @@ -264,7 +325,12 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) { const char* abs = inst->Alpha.Arg[arg].Abs ? "|" : ""; const char* neg = inst->Alpha.Arg[arg].Negate ? "-" : ""; - fprintf(f, ", %s%ssrc%i.%c%s", neg, abs, inst->Alpha.Arg[arg].Source, + fprintf(f, ", %s%ssrc", neg, abs); + if(inst->Alpha.Arg[arg].Source == PRESUB_SOURCE) + fprintf(f,"p"); + else + fprintf(f,"%d", inst->Alpha.Arg[arg].Source); + fprintf(f,".%c%s", rc_swizzle_char(inst->Alpha.Arg[arg].Swizzle), abs); } fprintf(f, "\n"); -- 1.6.4.4