[Mesa-dev] [PATCH 6/6] glsl: fix function inlining with opaque parameters

Rhys Perry pendingchaos02 at gmail.com
Wed Jun 6 19:55:08 UTC 2018


Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
---
 src/compiler/glsl/opt_function_inlining.cpp | 52 ++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/src/compiler/glsl/opt_function_inlining.cpp b/src/compiler/glsl/opt_function_inlining.cpp
index 04690b6cf4..52f57da936 100644
--- a/src/compiler/glsl/opt_function_inlining.cpp
+++ b/src/compiler/glsl/opt_function_inlining.cpp
@@ -131,6 +131,18 @@ ir_save_lvalue_visitor::visit_enter(ir_dereference_array *deref)
    return visit_stop;
 }
 
+static bool
+should_replace_variable(ir_variable *sig_param, ir_rvalue *param) {
+   /* For opaque types, we want the inlined variable references
+    * referencing the passed in variable, since that will have
+    * the location information, which an assignment of an opaque
+    * variable wouldn't.
+    */
+   return sig_param->type->contains_opaque() &&
+          param->is_dereference() &&
+          sig_param->data.mode == ir_var_function_in;
+}
+
 void
 ir_call::generate_inline(ir_instruction *next_ir)
 {
@@ -155,12 +167,8 @@ ir_call::generate_inline(ir_instruction *next_ir)
       ir_rvalue *param = (ir_rvalue *) actual_node;
 
       /* Generate a new variable for the parameter. */
-      if (sig_param->type->contains_opaque()) {
-	 /* For opaque types, we want the inlined variable references
-	  * referencing the passed in variable, since that will have
-	  * the location information, which an assignment of an opaque
-	  * variable wouldn't.  Fix it up below.
-	  */
+      if (should_replace_variable(sig_param, param)) {
+         /* Actual replacement happens below */
 	 parameters[i] = NULL;
       } else {
 	 parameters[i] = sig_param->clone(ctx, ht);
@@ -242,10 +250,9 @@ ir_call::generate_inline(ir_instruction *next_ir)
       ir_rvalue *const param = (ir_rvalue *) actual_node;
       ir_variable *sig_param = (ir_variable *) formal_node;
 
-      if (sig_param->type->contains_opaque()) {
+      if (should_replace_variable(sig_param, param)) {
 	 ir_dereference *deref = param->as_dereference();
 
-	 assert(deref);
 	 do_variable_replacement(&new_instructions, sig_param, deref);
       }
    }
@@ -351,6 +358,9 @@ public:
    virtual ir_visitor_status visit_leave(ir_dereference_array *);
    virtual ir_visitor_status visit_leave(ir_dereference_record *);
    virtual ir_visitor_status visit_leave(ir_texture *);
+   virtual ir_visitor_status visit_leave(ir_assignment *);
+   virtual ir_visitor_status visit_leave(ir_expression *);
+   virtual ir_visitor_status visit_leave(ir_return *);
 
    void replace_deref(ir_dereference **deref);
    void replace_rvalue(ir_rvalue **rvalue);
@@ -391,6 +401,32 @@ ir_variable_replacement_visitor::visit_leave(ir_texture *ir)
    return visit_continue;
 }
 
+ir_visitor_status
+ir_variable_replacement_visitor::visit_leave(ir_assignment *ir)
+{
+   replace_deref(&ir->lhs);
+   replace_rvalue(&ir->rhs);
+
+   return visit_continue;
+}
+
+ir_visitor_status
+ir_variable_replacement_visitor::visit_leave(ir_expression *ir)
+{
+   for (uint8_t i = 0; i < ir->num_operands; i++)
+      replace_rvalue(&ir->operands[i]);
+
+   return visit_continue;
+}
+
+ir_visitor_status
+ir_variable_replacement_visitor::visit_leave(ir_return *ir)
+{
+   replace_rvalue(&ir->value);
+
+   return visit_continue;
+}
+
 ir_visitor_status
 ir_variable_replacement_visitor::visit_leave(ir_dereference_array *ir)
 {
-- 
2.14.4



More information about the mesa-dev mailing list