[Mesa-dev] [PATCH 03/10] glsl: add function support to glsl_to_nir

Timothy Arceri tarceri at itsqueeze.com
Tue Apr 10 04:34:28 UTC 2018


This support was missing because currently we always let GLSL IR
inline the functions.
---
 src/compiler/glsl/glsl_to_nir.cpp | 76 +++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 8 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index dbb58d82e8f..c4b3b4315d4 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -489,8 +489,24 @@ nir_visitor::create_function(ir_function_signature *ir)
 
    nir_function *func = nir_function_create(shader, ir->function_name());
 
-   assert(ir->parameters.is_empty());
-   assert(ir->return_type == glsl_type::void_type);
+   func->num_params = ir->parameters.length();
+   func->params = ralloc_array(shader, nir_parameter, func->num_params);
+
+   unsigned np = 0;
+   foreach_in_list(ir_variable, param, &ir->parameters) {
+       func->params[np].type = param->type;
+      if (param->data.mode == ir_var_function_inout) {
+         func->params[np].param_type = nir_parameter_inout;
+      } else if (param->data.mode == ir_var_function_out) {
+         func->params[np].param_type = nir_parameter_out;
+      } else {
+         func->params[np].param_type = nir_parameter_in;
+      }
+      np++;
+   }
+   assert(np == func->num_params);
+
+   func->return_type = ir->return_type;
 
    _mesa_hash_table_insert(this->overload_table, ir, func);
 }
@@ -518,9 +534,11 @@ nir_visitor::visit(ir_function_signature *ir)
       nir_function_impl *impl = nir_function_impl_create(func);
       this->impl = impl;
 
-      assert(strcmp(func->name, "main") == 0);
-      assert(ir->parameters.is_empty());
-      assert(func->return_type == glsl_type::void_type);
+      unsigned i = 0;
+      foreach_in_list(ir_variable, param, &ir->parameters) {
+         _mesa_hash_table_insert(var_table, param, impl->params[i]);
+         i++;
+      }
 
       this->is_global = false;
 
@@ -620,7 +638,24 @@ nir_visitor::visit(ir_return *ir)
          nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);
 
       copy->variables[0] = nir_deref_var_create(copy, this->impl->return_var);
-      copy->variables[1] = evaluate_deref(&copy->instr, ir->value);
+
+      nir_ssa_def *val = evaluate_rvalue(ir->value);
+
+      nir_variable *var =
+         nir_local_variable_create(this->impl, ir->value->type, "return_temp");
+
+      nir_intrinsic_instr *store =
+         nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
+      store->num_components = ir->value->type->vector_elements;
+      nir_intrinsic_set_write_mask(store, (1 << store->num_components) - 1);
+      store->variables[0] = nir_deref_var_create(store, var);
+      store->src[0] = nir_src_for_ssa(val);
+
+      nir_builder_instr_insert(&b, &store->instr);
+
+      copy->variables[1] = nir_deref_var_clone(store->variables[0], &copy->instr);
+
+      nir_builder_instr_insert(&b, &copy->instr);
    }
 
    nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return);
@@ -1241,11 +1276,36 @@ nir_visitor::visit(ir_call *ir)
 
    unsigned i = 0;
    foreach_in_list(ir_dereference, param, &ir->actual_parameters) {
-      instr->params[i] = evaluate_deref(&instr->instr, param);
+
+      nir_deref_var *param_deref;
+      if (!param->as_dereference_variable()) {
+         ir_rvalue *param_rvalue = param->as_rvalue();
+         nir_variable *var =
+            nir_local_variable_create(this->impl, param_rvalue->type,
+                                      "param_temp");
+
+         nir_ssa_def *val = evaluate_rvalue(param_rvalue);
+
+         nir_intrinsic_instr *store =
+            nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
+         store->num_components = param_rvalue->type->vector_elements;
+         nir_intrinsic_set_write_mask(store, (1 << store->num_components) - 1);
+         store->variables[0] = nir_deref_var_create(store, var);
+         store->src[0] = nir_src_for_ssa(val);
+
+         nir_builder_instr_insert(&b, &store->instr);
+         param_deref = nir_deref_var_clone(store->variables[0], &instr->instr);
+      } else {
+         param_deref = evaluate_deref(&instr->instr, param);
+      }
+
+      instr->params[i] = param_deref;
       i++;
    }
 
-   instr->return_deref = evaluate_deref(&instr->instr, ir->return_deref);
+   if (ir->return_deref)
+      instr->return_deref = evaluate_deref(&instr->instr, ir->return_deref);
+
    nir_builder_instr_insert(&b, &instr->instr);
 }
 
-- 
2.17.0



More information about the mesa-dev mailing list