diff options
Diffstat (limited to 'src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c')
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c | 128 |
1 files changed, 98 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c index 0e6c62541f..e73700f84a 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c @@ -29,6 +29,25 @@ #include "radeon_program.h" +static void reads_normal_callback( + rc_read_write_chan_fn cb, + struct rc_instruction * fullinst, + struct rc_src_register src, + void * userdata) +{ + unsigned int refmask = 0; + unsigned int chan; + for(chan = 0; chan < 4; chan++) { + refmask |= 1 << GET_SWZ(src.Swizzle, chan); + } + refmask &= RC_MASK_XYZW; + + if (refmask) + cb(userdata, fullinst, src.File, src.Index, refmask); + + if (refmask && src.RelAddr) + cb(userdata, fullinst, RC_FILE_ADDRESS, 0, RC_MASK_X); +} static void reads_normal(struct rc_instruction * fullinst, rc_read_write_chan_fn cb, void * userdata) { @@ -36,47 +55,81 @@ static void reads_normal(struct rc_instruction * fullinst, rc_read_write_chan_fn const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { - unsigned int refmask = 0; if (inst->SrcReg[src].File == RC_FILE_NONE) return; - for(unsigned int chan = 0; chan < 4; ++chan) - refmask |= 1 << GET_SWZ(inst->SrcReg[src].Swizzle, chan); - - refmask &= RC_MASK_XYZW; - - if (refmask) - cb(userdata, fullinst, inst->SrcReg[src].File, inst->SrcReg[src].Index, refmask); - - if (refmask && inst->SrcReg[src].RelAddr) - cb(userdata, fullinst, RC_FILE_ADDRESS, 0, RC_MASK_X); + if (inst->SrcReg[src].File == RC_FILE_PRESUB) { + unsigned int i; + unsigned int srcp_regs = rc_presubtract_src_reg_count( + inst->PreSub.Opcode); + for( i = 0; i < srcp_regs; i++) { + reads_normal_callback(cb, fullinst, + inst->PreSub.SrcReg[i], + userdata); + } + } else { + reads_normal_callback(cb, fullinst, + inst->SrcReg[src], userdata); + } } } -static void reads_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) +static void pair_get_src_refmasks(unsigned int * refmasks, + struct rc_pair_instruction * inst, + unsigned int swz, unsigned int src) { - struct rc_pair_instruction * inst = &fullinst->U.P; - unsigned int refmasks[3] = { 0, 0, 0 }; - - if (inst->RGB.Opcode != RC_OPCODE_NOP) { - const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->RGB.Opcode); + if (swz >= 4) + return; + + if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y || swz == RC_SWIZZLE_Z) { + if(src == RC_PAIR_PRESUB_SRC) { + unsigned int i; + int srcp_regs = + rc_presubtract_src_reg_count( + inst->RGB.Src[src].Index); + for(i = 0; i < srcp_regs; i++) { + refmasks[i] |= 1 << swz; + } + } + else { + refmasks[src] |= 1 << swz; + } + } - for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) { - for(unsigned int chan = 0; chan < 3; ++chan) { - unsigned int swz = GET_SWZ(inst->RGB.Arg[arg].Swizzle, chan); - if (swz < 4) - refmasks[inst->RGB.Arg[arg].Source] |= 1 << swz; + if (swz == RC_SWIZZLE_W) { + if (src == RC_PAIR_PRESUB_SRC) { + unsigned int i; + int srcp_regs = rc_presubtract_src_reg_count( + inst->Alpha.Src[src].Index); + for(i = 0; i < srcp_regs; i++) { + refmasks[i] |= 1 << swz; } } + else { + refmasks[src] |= 1 << swz; + } } +} - if (inst->Alpha.Opcode != RC_OPCODE_NOP) { - const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Alpha.Opcode); +static void reads_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata) +{ + struct rc_pair_instruction * inst = &fullinst->U.P; + unsigned int refmasks[3] = { 0, 0, 0 }; - for(unsigned int arg = 0; arg < opcode->NumSrcRegs; ++arg) { - if (inst->Alpha.Arg[arg].Swizzle < 4) - refmasks[inst->Alpha.Arg[arg].Source] |= 1 << inst->Alpha.Arg[arg].Swizzle; + unsigned int arg; + + for(arg = 0; arg < 3; ++arg) { + unsigned int chan; + for(chan = 0; chan < 3; ++chan) { + unsigned int swz_rgb = + GET_SWZ(inst->RGB.Arg[arg].Swizzle, chan); + unsigned int swz_alpha = + GET_SWZ(inst->Alpha.Arg[arg].Swizzle, chan); + pair_get_src_refmasks(refmasks, inst, swz_rgb, + inst->RGB.Arg[arg].Source); + pair_get_src_refmasks(refmasks, inst, swz_alpha, + inst->Alpha.Arg[arg].Source); } } @@ -212,10 +265,25 @@ static void remap_normal_instruction(struct rc_instruction * fullinst, rc_register_file file = inst->SrcReg[src].File; unsigned int index = inst->SrcReg[src].Index; - cb(userdata, fullinst, &file, &index); + if (file == RC_FILE_PRESUB) { + unsigned int i; + unsigned int srcp_srcs = rc_presubtract_src_reg_count( + inst->PreSub.Opcode); + for(i = 0; i < srcp_srcs; i++) { + file = inst->PreSub.SrcReg[i].File; + index = inst->PreSub.SrcReg[i].Index; + cb(userdata, fullinst, &file, &index); + inst->PreSub.SrcReg[i].File = file; + inst->PreSub.SrcReg[i].Index = index; + } - inst->SrcReg[src].File = file; - inst->SrcReg[src].Index = index; + } + else { + cb(userdata, fullinst, &file, &index); + + inst->SrcReg[src].File = file; + inst->SrcReg[src].Index = index; + } } } |