diff options
author | Matt Turner <[email protected]> | 2013-04-25 11:02:02 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2013-04-25 18:27:39 -0700 |
commit | c0f67a127b0b3e4bb715d1562a82c984d160280e (patch) | |
tree | 6497e19c98df7e7b1386278049b8789e0dfe534b /src | |
parent | abb96fdea70546f974ba59cbd00bc54afee9cfdb (diff) |
i965/vs: Add a function to fix-up uniform arguments for 3-src insts.
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 <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 23 |
2 files changed, 25 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 697ab86918b..c28092244a4 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 2fb848293f6..69e805d1e1a 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -224,6 +224,29 @@ vec4_visitor::emit_dp(dst_reg dst, src_reg src0, src_reg src1, unsigned elements } 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) { /* The gen6 math instruction ignores the source modifiers -- |