summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_constant_propagation.cpp
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-09-22 11:47:03 -0700
committerEric Anholt <[email protected]>2010-09-22 13:09:51 -0700
commitb39e6f33b60ef9bbaf81f320aaca6a440d8a6a8f (patch)
treec3547819e402b729d84a4847aed95b81ec09fdbf /src/glsl/ir_constant_propagation.cpp
parent38da5c9cb636387539daaf5688c2a3badee32447 (diff)
glsl: Rework assignments with write_masks to have LHS chan count match RHS.
It turns out that most people new to this IR are surprised when an assignment to (say) 3 components on the LHS takes 4 components on the RHS. It also makes for quite strange IR output: (assign (constant bool (1)) (x) (var_ref color) (swiz x (var_ref v) )) (assign (constant bool (1)) (y) (var_ref color) (swiz yy (var_ref v) )) (assign (constant bool (1)) (z) (var_ref color) (swiz zzz (var_ref v) )) But even worse, even we get it wrong, as shown by this line of our current step(float, vec4): (assign (constant bool (1)) (w) (var_ref t) (expression float b2f (expression bool >= (swiz w (var_ref x))(var_ref edge)))) where we try to assign a float to the writemasked-out x channel and don't supply anything for the actual w channel we're writing. Drivers right now just get lucky since ir_to_mesa spams the float value across all the source channels of a vec4. Instead, the RHS will now have a number of components equal to the number of components actually being written. Hopefully this confuses everyone less, and it also makes codegen for a scalar target simpler. Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/ir_constant_propagation.cpp')
-rw-r--r--src/glsl/ir_constant_propagation.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/glsl/ir_constant_propagation.cpp b/src/glsl/ir_constant_propagation.cpp
index f7a0599f425..390f295d6e9 100644
--- a/src/glsl/ir_constant_propagation.cpp
+++ b/src/glsl/ir_constant_propagation.cpp
@@ -168,18 +168,26 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
if (!found)
return;
+ int rhs_channel = 0;
+ for (int j = 0; j < 4; j++) {
+ if (j == channel)
+ break;
+ if (found->write_mask & (1 << j))
+ rhs_channel++;
+ }
+
switch (type->base_type) {
case GLSL_TYPE_FLOAT:
- data.f[i] = found->constant->value.f[channel];
+ data.f[i] = found->constant->value.f[rhs_channel];
break;
case GLSL_TYPE_INT:
- data.i[i] = found->constant->value.i[channel];
+ data.i[i] = found->constant->value.i[rhs_channel];
break;
case GLSL_TYPE_UINT:
- data.u[i] = found->constant->value.u[channel];
+ data.u[i] = found->constant->value.u[rhs_channel];
break;
case GLSL_TYPE_BOOL:
- data.b[i] = found->constant->value.b[channel];
+ data.b[i] = found->constant->value.b[rhs_channel];
break;
default:
assert(!"not reached");