diff options
author | Brian Paul <[email protected]> | 2009-04-29 11:52:06 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2009-04-29 11:52:06 -0600 |
commit | 0e85dcb66b990a63d60032816798ff693f9248e7 (patch) | |
tree | 24969bbd2c3748678c56ce08b48808e95599a008 | |
parent | 46ddcbc1a9e70d5dba257e6421eb69ed942dd1da (diff) |
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.
-rw-r--r-- | src/mesa/shader/prog_instruction.c | 50 | ||||
-rw-r--r-- | src/mesa/shader/prog_instruction.h | 3 |
2 files changed, 53 insertions, 0 deletions
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 @@ -286,6 +286,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. */ const char * 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); |