glsl2: Write vector constructor constants in a single assignment
Make two passes over the constructor parameters. Write all of the constants in a single write, then write the non-constants one at a time. This causes the fragment shader varying float g; void main() { gl_FragColor = vec4(0.0, g, 0.0, 1.0); } to generate (function main (signature void (parameters ) ( (declare (temporary ) vec4 vec_ctor@0x8580058) (assign (constant bool (1)) (xzw) (var_ref vec_ctor@0x8580058) (constant vec4 (0.000000 0.000000 0.000000 1.000000)) ) (assign (constant bool (1)) (y) (var_ref vec_ctor@0x8580058) (swiz xxxx (var_ref g@0x8580218) )) (assign (constant bool (1)) (xyzw) (var_ref gl_FragColor@0x84d32a0) (var_ref vec_ctor@0x8580058) ) )) ) instead of (function main (signature void (parameters ) ( (declare (temporary ) vec4 vec_ctor@0x8580058) (assign (constant bool (1)) (x) (var_ref vec_ctor@0x8580058) (constant vec4 (0.000000 0.000000 0.000000 1.000000)) ) (assign (constant bool (1)) (y) (var_ref vec_ctor@0x8580058) (swiz xxxx (var_ref g@0x8580218) )) (assign (constant bool (1)) (z) (var_ref vec_ctor@0x8580058) (constant vec4 (0.000000 0.000000 0.000000 1.000000)) ) (assign (constant bool (1)) (w) (var_ref vec_ctor@0x8580058) (constant vec4 (0.000000 0.000000 0.000000 1.000000)) ) (assign (constant bool (1)) (xyzw) (var_ref gl_FragColor@0x84d32a0) (var_ref vec_ctor@0x8580058) ) )) ) A similar optimization could be done for matrix constructors, but it is a little more complicate there.
This commit is contained in:
parent
99f3c9caa3
commit
a6c3cd5ca6
|
@ -621,6 +621,11 @@ emit_inline_vector_constructor(const glsl_type *type,
|
|||
instructions->push_tail(inst);
|
||||
} else {
|
||||
unsigned base_component = 0;
|
||||
ir_constant_data data;
|
||||
unsigned constant_mask = 0;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
foreach_list(node, parameters) {
|
||||
ir_rvalue *param = (ir_rvalue *) node;
|
||||
unsigned rhs_components = param->type->components();
|
||||
|
@ -631,6 +636,61 @@ emit_inline_vector_constructor(const glsl_type *type,
|
|||
rhs_components = lhs_components - base_component;
|
||||
}
|
||||
|
||||
const ir_constant *const c = param->as_constant();
|
||||
if (c != NULL) {
|
||||
for (unsigned i = 0; i < rhs_components; i++) {
|
||||
switch (c->type->base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
data.u[i + base_component] = c->get_uint_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_INT:
|
||||
data.i[i + base_component] = c->get_int_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_FLOAT:
|
||||
data.f[i + base_component] = c->get_float_component(i);
|
||||
break;
|
||||
case GLSL_TYPE_BOOL:
|
||||
data.b[i + base_component] = c->get_bool_component(i);
|
||||
break;
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask of fields to be written in the assignment.
|
||||
*/
|
||||
constant_mask |= ((1U << rhs_components) - 1) << base_component;
|
||||
}
|
||||
|
||||
/* Advance the component index by the number of components that were
|
||||
* just assigned.
|
||||
*/
|
||||
base_component += rhs_components;
|
||||
}
|
||||
|
||||
if (constant_mask != 0) {
|
||||
ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
|
||||
ir_rvalue *rhs = new(ctx) ir_constant(var->type, &data);
|
||||
|
||||
ir_instruction *inst =
|
||||
new(ctx) ir_assignment(lhs, rhs, NULL, constant_mask);
|
||||
instructions->push_tail(inst);
|
||||
}
|
||||
|
||||
base_component = 0;
|
||||
foreach_list(node, parameters) {
|
||||
ir_rvalue *param = (ir_rvalue *) node;
|
||||
unsigned rhs_components = param->type->components();
|
||||
|
||||
/* Do not try to assign more components to the vector than it has!
|
||||
*/
|
||||
if ((rhs_components + base_component) > lhs_components) {
|
||||
rhs_components = lhs_components - base_component;
|
||||
}
|
||||
|
||||
const ir_constant *const c = param->as_constant();
|
||||
if (c == NULL) {
|
||||
/* Generate a swizzle that puts the first element of the source at
|
||||
* the location of the first element of the destination.
|
||||
*/
|
||||
|
@ -649,6 +709,7 @@ emit_inline_vector_constructor(const glsl_type *type,
|
|||
ir_instruction *inst =
|
||||
new(ctx) ir_assignment(lhs, rhs, NULL, write_mask);
|
||||
instructions->push_tail(inst);
|
||||
}
|
||||
|
||||
/* Advance the component index by the number of components that were
|
||||
* just assigned.
|
||||
|
|
Loading…
Reference in New Issue