i965/vs: Add a function to fix-up uniform arguments for 3-src insts.
authorMatt Turner <mattst88@gmail.com>
Thu, 25 Apr 2013 18:02:02 +0000 (11:02 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 26 Apr 2013 01:27:39 +0000 (18:27 -0700)
Three-source instructions have a vertical stride overloaded to 4, which
prevents directly using vec4 uniforms as arguments. Instead we need to
insert a MOV instruction to do the replication for the three-source
instruction.

With this in place, we can use three-source instructions in the vertex
shader. While some thought needs to go into deciding whether its better
to use a three-source instruction rather than a sequence of equivalent
instructions (when one or more sources are uniforms or immediates), this
will allow us to skip a lot of ugly lowering code and use the BFE and
BFI2 instructions directly.

Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 697ab86918b1ed0bb45464554b613ac2601298bb..c28092244a4b5c2a7d2405119c0e26df14525e28 100644 (file)
@@ -430,6 +430,8 @@ public:
    void emit_scs(ir_instruction *ir, enum prog_opcode op,
                 dst_reg dst, const src_reg &src);
 
+   src_reg fix_3src_operand(src_reg src);
+
    void emit_math1_gen6(enum opcode opcode, dst_reg dst, src_reg src);
    void emit_math1_gen4(enum opcode opcode, dst_reg dst, src_reg src);
    void emit_math(enum opcode opcode, dst_reg dst, src_reg src);
index 2fb848293f65edcbfaaea89a97b988dc0b7376db..69e805d1e1a2472036f9ae44160983ea114af0a1 100644 (file)
@@ -223,6 +223,29 @@ vec4_visitor::emit_dp(dst_reg dst, src_reg src0, src_reg src1, unsigned elements
    emit(dot_opcodes[elements - 2], dst, src0, src1);
 }
 
+src_reg
+vec4_visitor::fix_3src_operand(src_reg src)
+{
+   /* Using vec4 uniforms in SIMD4x2 programs is difficult. You'd like to be
+    * able to use vertical stride of zero to replicate the vec4 uniform, like
+    *
+    *    g3<0;4,1>:f - [0, 4][1, 5][2, 6][3, 7]
+    *
+    * But you can't, since vertical stride is always four in three-source
+    * instructions. Instead, insert a MOV instruction to do the replication so
+    * that the three-source instruction can consume it.
+    */
+
+   /* The MOV is only needed if the source is a uniform or immediate. */
+   if (src.file != UNIFORM && src.file != IMM)
+      return src;
+
+   dst_reg expanded = dst_reg(this, glsl_type::vec4_type);
+   expanded.type = src.type;
+   emit(MOV(expanded, src));
+   return src_reg(expanded);
+}
+
 src_reg
 vec4_visitor::fix_math_operand(src_reg src)
 {