aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2011-07-30 11:55:53 -0700
committerPaul Berry <[email protected]>2011-08-08 12:43:45 -0700
commit789ee6516bfca289e1948ff8f2c147b94286a0e0 (patch)
tree190cb9a1c2cd6662fffdefaf4d125cf8a832dbb1
parent0d81b0e18494a80c4326fbc98837842959675869 (diff)
glsl: Constant-fold built-in functions before outputting IR
Rearranged the logic for converting the ast for a function call to hir, so that we constant fold before emitting any IR. Previously we would emit some IR, and then only later detect whether we could constant fold. The unnecessary IR would usually get cleaned up by a later optimization step, however in the case of a builtin function being used to compute an array size, it was causing an assertion. Fixes Piglit test array-size-constant-relational.vert. Reviewed-by: Kenneth Graunke <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38625
-rw-r--r--src/glsl/ast_function.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 34a82f8ab75..5b6ed3bc8f5 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -199,6 +199,20 @@ match_function_by_name(exec_list *instructions, const char *name,
*/
ir_call *call = new(ctx) ir_call(sig, actual_parameters);
if (!sig->return_type->is_void()) {
+ /* If the function call is a constant expression, don't
+ * generate the instructions to call it; just generate an
+ * ir_constant representing the constant value.
+ *
+ * Function calls can only be constant expressions starting
+ * in GLSL 1.20.
+ */
+ if (state->language_version >= 120) {
+ ir_constant *const_val = call->constant_expression_value();
+ if (const_val) {
+ return const_val;
+ }
+ }
+
ir_variable *var;
ir_dereference_variable *deref;
@@ -211,8 +225,6 @@ match_function_by_name(exec_list *instructions, const char *name,
deref = new(ctx) ir_dereference_variable(var);
ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL);
instructions->push_tail(assign);
- if (state->language_version >= 120)
- var->constant_value = call->constant_expression_value();
deref = new(ctx) ir_dereference_variable(var);
return deref;