Mesa (master): mesa: added _mesa_check_soa_dependencies() function

Brian Paul brianp at kemper.freedesktop.org
Wed Apr 29 17:58:54 UTC 2009


Module: Mesa
Branch: master
Commit: 0e85dcb66b990a63d60032816798ff693f9248e7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0e85dcb66b990a63d60032816798ff693f9248e7

Author: Brian Paul <brianp at vmware.com>
Date:   Wed Apr 29 11:52:06 2009 -0600

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(+), 0 deletions(-)

diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
index ca7565c..ae3a003 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 3109f6c..40ad998 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);
 




More information about the mesa-commit mailing list