summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/shader/prog_instruction.c50
-rw-r--r--src/mesa/shader/prog_instruction.h3
2 files changed, 53 insertions, 0 deletions
diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
index ca7565c091..ae3a003fee 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 3109f6cbae..40ad998f79 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);