From dca190e9432d4ed122bdd534922d0c3d85791c6a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 29 Apr 2009 11:52:06 -0600 Subject: mesa: added _mesa_check_soa_dependencies() function This function will check an instruction to see if there's data dependencies between the dst and src registers if executed in an SOA manner. --- src/mesa/shader/prog_instruction.c | 50 ++++++++++++++++++++++++++++++++++++++ src/mesa/shader/prog_instruction.h | 3 +++ 2 files changed, 53 insertions(+) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index ca7565c0911..ae3a003feed 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -285,6 +285,56 @@ _mesa_is_tex_instruction(gl_inst_opcode opcode) } +/** + * Check if there's a potential src/dst register data dependency when + * using SOA execution. + * Example: + * MOV T, T.yxwz; + * This would expand into: + * MOV t0, t1; + * MOV t1, t0; + * MOV t2, t3; + * MOV t3, t2; + * The second instruction will have the wrong value for t0 if executed as-is. + */ +GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst) +{ + GLuint i, chan; + + if (inst->DstReg.WriteMask == WRITEMASK_X || + inst->DstReg.WriteMask == WRITEMASK_Y || + inst->DstReg.WriteMask == WRITEMASK_Z || + inst->DstReg.WriteMask == WRITEMASK_W || + inst->DstReg.WriteMask == 0x0) { + /* no chance of data dependency */ + return GL_FALSE; + } + + /* loop over src regs */ + for (i = 0; i < 3; i++) { + if (inst->SrcReg[i].File == inst->DstReg.File && + inst->SrcReg[i].Index == inst->DstReg.Index) { + /* loop over dest channels */ + GLuint channelsWritten = 0x0; + for (chan = 0; chan < 4; chan++) { + if (inst->DstReg.WriteMask & (1 << chan)) { + /* check if we're reading a channel that's been written */ + GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan); + if (swizzle <= SWIZZLE_W && + (channelsWritten & (1 << swizzle))) { + return GL_TRUE; + } + + channelsWritten |= (1 << chan); + } + } + } + } + return GL_FALSE; +} + + /** * Return string name for given program opcode. */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 3109f6cbae5..40ad998f79d 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -428,6 +428,9 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode); extern GLboolean _mesa_is_tex_instruction(gl_inst_opcode opcode); +extern GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst); + extern const char * _mesa_opcode_string(gl_inst_opcode opcode); -- cgit v1.2.3