Mesa (master): i965: Use immediate float operands for some VS instructions.

Eric Anholt anholt at kemper.freedesktop.org
Thu Apr 29 15:34:53 UTC 2010


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

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 28 12:39:39 2010 -0700

i965: Use immediate float operands for some VS instructions.

We could use this to reduce constant register pressure, but for now it
makes the resulting program assembly much more readable.

---

 src/mesa/drivers/dri/i965/brw_vs_emit.c |   86 +++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index eeb3f36..e83c9bf 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -37,6 +37,43 @@
 #include "brw_context.h"
 #include "brw_vs.h"
 
+/* Return the SrcReg index of the channels that can be immediate float operands
+ * instead of usage of PROGRAM_CONSTANT values through push/pull.
+ */
+static GLboolean
+brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
+{
+   int opcode_array[] = {
+      [OPCODE_ADD] = 2,
+      [OPCODE_CMP] = 3,
+      [OPCODE_DP3] = 2,
+      [OPCODE_DP4] = 2,
+      [OPCODE_DPH] = 2,
+      [OPCODE_MAX] = 1,
+      [OPCODE_MIN] = 2,
+      [OPCODE_MUL] = 2,
+      [OPCODE_SEQ] = 2,
+      [OPCODE_SGE] = 2,
+      [OPCODE_SGT] = 2,
+      [OPCODE_SLE] = 2,
+      [OPCODE_SLT] = 2,
+      [OPCODE_SNE] = 2,
+      [OPCODE_XPD] = 2,
+   };
+
+   /* These opcodes get broken down in a way that allow two
+    * args to be immediates.
+    */
+   if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) {
+      if (arg == 1 || arg == 2)
+	 return GL_TRUE;
+   }
+
+   if (opcode > ARRAY_SIZE(opcode_array))
+      return GL_FALSE;
+
+   return arg == opcode_array[opcode] - 1;
+}
 
 static struct brw_reg get_tmp( struct brw_vs_compile *c )
 {
@@ -983,6 +1020,55 @@ get_src_reg( struct brw_vs_compile *c,
    const GLint index = inst->SrcReg[argIndex].Index;
    const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;
 
+   if (brw_vs_arg_can_be_immediate(inst->Opcode, argIndex)) {
+      const struct prog_src_register *src = &inst->SrcReg[argIndex];
+
+      if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ZERO,
+					SWIZZLE_ZERO,
+					SWIZZLE_ZERO,
+					SWIZZLE_ZERO)) {
+	  return brw_imm_f(0.0f);
+      } else if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ONE,
+					       SWIZZLE_ONE,
+					       SWIZZLE_ONE,
+					       SWIZZLE_ONE)) {
+	 if (src->Negate)
+	    return brw_imm_f(-1.0F);
+	 else
+	    return brw_imm_f(1.0F);
+      } else if (src->File == PROGRAM_CONSTANT) {
+	 const struct gl_program_parameter_list *params;
+	 float f;
+	 int component = -1;
+
+	 switch (src->Swizzle) {
+	 case SWIZZLE_XXXX:
+	    component = 0;
+	    break;
+	 case SWIZZLE_YYYY:
+	    component = 1;
+	    break;
+	 case SWIZZLE_ZZZZ:
+	    component = 2;
+	    break;
+	 case SWIZZLE_WWWW:
+	    component = 3;
+	    break;
+	 }
+
+	 if (component >= 0) {
+	    params = c->vp->program.Base.Parameters;
+	    f = params->ParameterValues[src->Index][component];
+
+	    if (src->Abs)
+	       f = fabs(f);
+	    if (src->Negate)
+	       f = -f;
+	    return brw_imm_f(f);
+	 }
+      }
+   }
+
    switch (file) {
    case PROGRAM_TEMPORARY:
    case PROGRAM_INPUT:




More information about the mesa-commit mailing list