101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2014 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Connor Abbott (cwabbott0@gmail.com)
2501e04c3fSmrg *
2601e04c3fSmrg */
2701e04c3fSmrg
287e102996Smaya#include "float64_glsl.h"
2901e04c3fSmrg#include "glsl_to_nir.h"
3001e04c3fSmrg#include "ir_visitor.h"
3101e04c3fSmrg#include "ir_hierarchical_visitor.h"
3201e04c3fSmrg#include "ir.h"
337e102996Smaya#include "ir_optimization.h"
347e102996Smaya#include "program.h"
3501e04c3fSmrg#include "compiler/nir/nir_control_flow.h"
3601e04c3fSmrg#include "compiler/nir/nir_builder.h"
377ec681f3Smrg#include "compiler/nir/nir_builtin_builder.h"
387ec681f3Smrg#include "compiler/nir/nir_deref.h"
397e102996Smaya#include "main/errors.h"
4001e04c3fSmrg#include "main/mtypes.h"
417e102996Smaya#include "main/shaderobj.h"
427ec681f3Smrg#include "main/context.h"
437e102996Smaya#include "util/u_math.h"
4401e04c3fSmrg
4501e04c3fSmrg/*
4601e04c3fSmrg * pass to lower GLSL IR to NIR
4701e04c3fSmrg *
4801e04c3fSmrg * This will lower variable dereferences to loads/stores of corresponding
4901e04c3fSmrg * variables in NIR - the variables will be converted to registers in a later
5001e04c3fSmrg * pass.
5101e04c3fSmrg */
5201e04c3fSmrg
5301e04c3fSmrgnamespace {
5401e04c3fSmrg
5501e04c3fSmrgclass nir_visitor : public ir_visitor
5601e04c3fSmrg{
5701e04c3fSmrgpublic:
587e102996Smaya   nir_visitor(gl_context *ctx, nir_shader *shader);
5901e04c3fSmrg   ~nir_visitor();
6001e04c3fSmrg
6101e04c3fSmrg   virtual void visit(ir_variable *);
6201e04c3fSmrg   virtual void visit(ir_function *);
6301e04c3fSmrg   virtual void visit(ir_function_signature *);
6401e04c3fSmrg   virtual void visit(ir_loop *);
6501e04c3fSmrg   virtual void visit(ir_if *);
6601e04c3fSmrg   virtual void visit(ir_discard *);
677ec681f3Smrg   virtual void visit(ir_demote *);
6801e04c3fSmrg   virtual void visit(ir_loop_jump *);
6901e04c3fSmrg   virtual void visit(ir_return *);
7001e04c3fSmrg   virtual void visit(ir_call *);
7101e04c3fSmrg   virtual void visit(ir_assignment *);
7201e04c3fSmrg   virtual void visit(ir_emit_vertex *);
7301e04c3fSmrg   virtual void visit(ir_end_primitive *);
7401e04c3fSmrg   virtual void visit(ir_expression *);
7501e04c3fSmrg   virtual void visit(ir_swizzle *);
7601e04c3fSmrg   virtual void visit(ir_texture *);
7701e04c3fSmrg   virtual void visit(ir_constant *);
7801e04c3fSmrg   virtual void visit(ir_dereference_variable *);
7901e04c3fSmrg   virtual void visit(ir_dereference_record *);
8001e04c3fSmrg   virtual void visit(ir_dereference_array *);
8101e04c3fSmrg   virtual void visit(ir_barrier *);
8201e04c3fSmrg
8301e04c3fSmrg   void create_function(ir_function_signature *ir);
8401e04c3fSmrg
8501e04c3fSmrgprivate:
8601e04c3fSmrg   void add_instr(nir_instr *instr, unsigned num_components, unsigned bit_size);
8701e04c3fSmrg   nir_ssa_def *evaluate_rvalue(ir_rvalue *ir);
8801e04c3fSmrg
8901e04c3fSmrg   nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def **srcs);
9001e04c3fSmrg   nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1);
9101e04c3fSmrg   nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1,
9201e04c3fSmrg                       nir_ssa_def *src2);
9301e04c3fSmrg   nir_alu_instr *emit(nir_op op, unsigned dest_size, nir_ssa_def *src1,
9401e04c3fSmrg                       nir_ssa_def *src2, nir_ssa_def *src3);
9501e04c3fSmrg
967e102996Smaya   bool supports_std430;
9701e04c3fSmrg
9801e04c3fSmrg   nir_shader *shader;
9901e04c3fSmrg   nir_function_impl *impl;
10001e04c3fSmrg   nir_builder b;
10101e04c3fSmrg   nir_ssa_def *result; /* result of the expression tree last visited */
10201e04c3fSmrg
10301e04c3fSmrg   nir_deref_instr *evaluate_deref(ir_instruction *ir);
10401e04c3fSmrg
1057e102996Smaya   nir_constant *constant_copy(ir_constant *ir, void *mem_ctx);
1067e102996Smaya
10701e04c3fSmrg   /* most recent deref instruction created */
10801e04c3fSmrg   nir_deref_instr *deref;
10901e04c3fSmrg
11001e04c3fSmrg   /* whether the IR we're operating on is per-function or global */
11101e04c3fSmrg   bool is_global;
11201e04c3fSmrg
1137e102996Smaya   ir_function_signature *sig;
1147e102996Smaya
11501e04c3fSmrg   /* map of ir_variable -> nir_variable */
11601e04c3fSmrg   struct hash_table *var_table;
11701e04c3fSmrg
11801e04c3fSmrg   /* map of ir_function_signature -> nir_function_overload */
11901e04c3fSmrg   struct hash_table *overload_table;
12001e04c3fSmrg};
12101e04c3fSmrg
12201e04c3fSmrg/*
12301e04c3fSmrg * This visitor runs before the main visitor, calling create_function() for
12401e04c3fSmrg * each function so that the main visitor can resolve forward references in
12501e04c3fSmrg * calls.
12601e04c3fSmrg */
12701e04c3fSmrg
12801e04c3fSmrgclass nir_function_visitor : public ir_hierarchical_visitor
12901e04c3fSmrg{
13001e04c3fSmrgpublic:
13101e04c3fSmrg   nir_function_visitor(nir_visitor *v) : visitor(v)
13201e04c3fSmrg   {
13301e04c3fSmrg   }
13401e04c3fSmrg   virtual ir_visitor_status visit_enter(ir_function *);
13501e04c3fSmrg
13601e04c3fSmrgprivate:
13701e04c3fSmrg   nir_visitor *visitor;
13801e04c3fSmrg};
13901e04c3fSmrg
1407e102996Smaya/* glsl_to_nir can only handle converting certain function paramaters
1417e102996Smaya * to NIR. This visitor checks for parameters it can't currently handle.
1427e102996Smaya */
1437e102996Smayaclass ir_function_param_visitor : public ir_hierarchical_visitor
1447e102996Smaya{
1457e102996Smayapublic:
1467e102996Smaya   ir_function_param_visitor()
1477e102996Smaya      : unsupported(false)
1487e102996Smaya   {
1497e102996Smaya   }
1507e102996Smaya
1517e102996Smaya   virtual ir_visitor_status visit_enter(ir_function_signature *ir)
1527e102996Smaya   {
1537e102996Smaya
1547e102996Smaya      if (ir->is_intrinsic())
1557e102996Smaya         return visit_continue;
1567e102996Smaya
1577e102996Smaya      foreach_in_list(ir_variable, param, &ir->parameters) {
1587e102996Smaya         if (!param->type->is_vector() || !param->type->is_scalar()) {
1597e102996Smaya            unsupported = true;
1607e102996Smaya            return visit_stop;
1617e102996Smaya         }
1627e102996Smaya
1637e102996Smaya         if (param->data.mode == ir_var_function_inout) {
1647e102996Smaya            unsupported = true;
1657e102996Smaya            return visit_stop;
1667e102996Smaya         }
1677e102996Smaya      }
1687e102996Smaya
1697ec681f3Smrg      if (!glsl_type_is_vector_or_scalar(ir->return_type) &&
1707ec681f3Smrg          !ir->return_type->is_void()) {
1717ec681f3Smrg         unsupported = true;
1727ec681f3Smrg         return visit_stop;
1737ec681f3Smrg      }
1747ec681f3Smrg
1757e102996Smaya      return visit_continue;
1767e102996Smaya   }
1777e102996Smaya
1787e102996Smaya   bool unsupported;
1797e102996Smaya};
1807e102996Smaya
18101e04c3fSmrg} /* end of anonymous namespace */
18201e04c3fSmrg
1837e102996Smaya
1847e102996Smayastatic bool
1857e102996Smayahas_unsupported_function_param(exec_list *ir)
1867e102996Smaya{
1877e102996Smaya   ir_function_param_visitor visitor;
1887e102996Smaya   visit_list_elements(&visitor, ir);
1897e102996Smaya   return visitor.unsupported;
1907e102996Smaya}
1917e102996Smaya
19201e04c3fSmrgnir_shader *
1937e102996Smayaglsl_to_nir(struct gl_context *ctx,
1947e102996Smaya            const struct gl_shader_program *shader_prog,
19501e04c3fSmrg            gl_shader_stage stage,
19601e04c3fSmrg            const nir_shader_compiler_options *options)
19701e04c3fSmrg{
19801e04c3fSmrg   struct gl_linked_shader *sh = shader_prog->_LinkedShaders[stage];
19901e04c3fSmrg
2007e102996Smaya   const struct gl_shader_compiler_options *gl_options =
2017e102996Smaya      &ctx->Const.ShaderCompilerOptions[stage];
2027e102996Smaya
2037e102996Smaya   /* glsl_to_nir can only handle converting certain function paramaters
2047e102996Smaya    * to NIR. If we find something we can't handle then we get the GLSL IR
2057e102996Smaya    * opts to remove it before we continue on.
2067e102996Smaya    *
2077e102996Smaya    * TODO: add missing glsl ir to nir support and remove this loop.
2087e102996Smaya    */
2097e102996Smaya   while (has_unsupported_function_param(sh->ir)) {
2107e102996Smaya      do_common_optimization(sh->ir, true, true, gl_options,
2117e102996Smaya                             ctx->Const.NativeIntegers);
2127e102996Smaya   }
2137e102996Smaya
21401e04c3fSmrg   nir_shader *shader = nir_shader_create(NULL, stage, options,
21501e04c3fSmrg                                          &sh->Program->info);
21601e04c3fSmrg
2177e102996Smaya   nir_visitor v1(ctx, shader);
21801e04c3fSmrg   nir_function_visitor v2(&v1);
21901e04c3fSmrg   v2.run(sh->ir);
22001e04c3fSmrg   visit_exec_list(sh->ir, &v1);
22101e04c3fSmrg
2227e102996Smaya   nir_validate_shader(shader, "after glsl to nir, before function inline");
2237e102996Smaya
2247e102996Smaya   /* We have to lower away local constant initializers right before we
2257e102996Smaya    * inline functions.  That way they get properly initialized at the top
2267e102996Smaya    * of the function and not at the top of its caller.
2277e102996Smaya    */
2287ec681f3Smrg   nir_lower_variable_initializers(shader, nir_var_all);
2297e102996Smaya   nir_lower_returns(shader);
2307e102996Smaya   nir_inline_functions(shader);
2317e102996Smaya   nir_opt_deref(shader);
2327e102996Smaya
2337e102996Smaya   nir_validate_shader(shader, "after function inlining and return lowering");
2347e102996Smaya
2357e102996Smaya   /* Now that we have inlined everything remove all of the functions except
2367e102996Smaya    * main().
2377e102996Smaya    */
2387e102996Smaya   foreach_list_typed_safe(nir_function, function, node, &(shader)->functions){
2397e102996Smaya      if (strcmp("main", function->name) != 0) {
2407e102996Smaya         exec_node_remove(&function->node);
2417e102996Smaya      }
2427e102996Smaya   }
24301e04c3fSmrg
24401e04c3fSmrg   shader->info.name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name);
24501e04c3fSmrg   if (shader_prog->Label)
24601e04c3fSmrg      shader->info.label = ralloc_strdup(shader, shader_prog->Label);
24701e04c3fSmrg
24801e04c3fSmrg   /* Check for transform feedback varyings specified via the API */
24901e04c3fSmrg   shader->info.has_transform_feedback_varyings =
25001e04c3fSmrg      shader_prog->TransformFeedback.NumVarying > 0;
25101e04c3fSmrg
25201e04c3fSmrg   /* Check for transform feedback varyings specified in the Shader */
25301e04c3fSmrg   if (shader_prog->last_vert_prog)
25401e04c3fSmrg      shader->info.has_transform_feedback_varyings |=
25501e04c3fSmrg         shader_prog->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0;
25601e04c3fSmrg
2577e102996Smaya   if (shader->info.stage == MESA_SHADER_FRAGMENT) {
2587e102996Smaya      shader->info.fs.pixel_center_integer = sh->Program->info.fs.pixel_center_integer;
2597e102996Smaya      shader->info.fs.origin_upper_left = sh->Program->info.fs.origin_upper_left;
2607ec681f3Smrg      shader->info.fs.advanced_blend_modes = sh->Program->info.fs.advanced_blend_modes;
2617e102996Smaya   }
2627e102996Smaya
26301e04c3fSmrg   return shader;
26401e04c3fSmrg}
26501e04c3fSmrg
2667e102996Smayanir_visitor::nir_visitor(gl_context *ctx, nir_shader *shader)
26701e04c3fSmrg{
2687e102996Smaya   this->supports_std430 = ctx->Const.UseSTD430AsDefaultPacking;
26901e04c3fSmrg   this->shader = shader;
27001e04c3fSmrg   this->is_global = true;
2717e102996Smaya   this->var_table = _mesa_pointer_hash_table_create(NULL);
2727e102996Smaya   this->overload_table = _mesa_pointer_hash_table_create(NULL);
27301e04c3fSmrg   this->result = NULL;
27401e04c3fSmrg   this->impl = NULL;
2757e102996Smaya   this->deref = NULL;
2767ec681f3Smrg   this->sig = NULL;
27701e04c3fSmrg   memset(&this->b, 0, sizeof(this->b));
27801e04c3fSmrg}
27901e04c3fSmrg
28001e04c3fSmrgnir_visitor::~nir_visitor()
28101e04c3fSmrg{
28201e04c3fSmrg   _mesa_hash_table_destroy(this->var_table, NULL);
28301e04c3fSmrg   _mesa_hash_table_destroy(this->overload_table, NULL);
28401e04c3fSmrg}
28501e04c3fSmrg
28601e04c3fSmrgnir_deref_instr *
28701e04c3fSmrgnir_visitor::evaluate_deref(ir_instruction *ir)
28801e04c3fSmrg{
28901e04c3fSmrg   ir->accept(this);
29001e04c3fSmrg   return this->deref;
29101e04c3fSmrg}
29201e04c3fSmrg
2937e102996Smayanir_constant *
2947e102996Smayanir_visitor::constant_copy(ir_constant *ir, void *mem_ctx)
29501e04c3fSmrg{
29601e04c3fSmrg   if (ir == NULL)
29701e04c3fSmrg      return NULL;
29801e04c3fSmrg
29901e04c3fSmrg   nir_constant *ret = rzalloc(mem_ctx, nir_constant);
30001e04c3fSmrg
30101e04c3fSmrg   const unsigned rows = ir->type->vector_elements;
30201e04c3fSmrg   const unsigned cols = ir->type->matrix_columns;
30301e04c3fSmrg   unsigned i;
30401e04c3fSmrg
30501e04c3fSmrg   ret->num_elements = 0;
30601e04c3fSmrg   switch (ir->type->base_type) {
30701e04c3fSmrg   case GLSL_TYPE_UINT:
30801e04c3fSmrg      /* Only float base types can be matrices. */
30901e04c3fSmrg      assert(cols == 1);
31001e04c3fSmrg
31101e04c3fSmrg      for (unsigned r = 0; r < rows; r++)
3127ec681f3Smrg         ret->values[r].u32 = ir->value.u[r];
3137ec681f3Smrg
3147ec681f3Smrg      break;
3157ec681f3Smrg
3167ec681f3Smrg   case GLSL_TYPE_UINT16:
3177ec681f3Smrg      /* Only float base types can be matrices. */
3187ec681f3Smrg      assert(cols == 1);
31901e04c3fSmrg
3207ec681f3Smrg      for (unsigned r = 0; r < rows; r++)
3217ec681f3Smrg         ret->values[r].u16 = ir->value.u16[r];
32201e04c3fSmrg      break;
32301e04c3fSmrg
32401e04c3fSmrg   case GLSL_TYPE_INT:
32501e04c3fSmrg      /* Only float base types can be matrices. */
32601e04c3fSmrg      assert(cols == 1);
32701e04c3fSmrg
32801e04c3fSmrg      for (unsigned r = 0; r < rows; r++)
3297ec681f3Smrg         ret->values[r].i32 = ir->value.i[r];
33001e04c3fSmrg
33101e04c3fSmrg      break;
33201e04c3fSmrg
3337ec681f3Smrg   case GLSL_TYPE_INT16:
3347ec681f3Smrg      /* Only float base types can be matrices. */
3357ec681f3Smrg      assert(cols == 1);
3367ec681f3Smrg
3377ec681f3Smrg      for (unsigned r = 0; r < rows; r++)
3387ec681f3Smrg         ret->values[r].i16 = ir->value.i16[r];
33901e04c3fSmrg      break;
34001e04c3fSmrg
3417ec681f3Smrg   case GLSL_TYPE_FLOAT:
3427ec681f3Smrg   case GLSL_TYPE_FLOAT16:
34301e04c3fSmrg   case GLSL_TYPE_DOUBLE:
3447ec681f3Smrg      if (cols > 1) {
3457ec681f3Smrg         ret->elements = ralloc_array(mem_ctx, nir_constant *, cols);
3467ec681f3Smrg         ret->num_elements = cols;
3477ec681f3Smrg         for (unsigned c = 0; c < cols; c++) {
3487ec681f3Smrg            nir_constant *col_const = rzalloc(mem_ctx, nir_constant);
3497ec681f3Smrg            col_const->num_elements = 0;
3507ec681f3Smrg            switch (ir->type->base_type) {
3517ec681f3Smrg            case GLSL_TYPE_FLOAT:
3527ec681f3Smrg               for (unsigned r = 0; r < rows; r++)
3537ec681f3Smrg                  col_const->values[r].f32 = ir->value.f[c * rows + r];
3547ec681f3Smrg               break;
3557ec681f3Smrg
3567ec681f3Smrg            case GLSL_TYPE_FLOAT16:
3577ec681f3Smrg               for (unsigned r = 0; r < rows; r++)
3587ec681f3Smrg                  col_const->values[r].u16 = ir->value.f16[c * rows + r];
3597ec681f3Smrg               break;
3607ec681f3Smrg
3617ec681f3Smrg            case GLSL_TYPE_DOUBLE:
3627ec681f3Smrg               for (unsigned r = 0; r < rows; r++)
3637ec681f3Smrg                  col_const->values[r].f64 = ir->value.d[c * rows + r];
3647ec681f3Smrg               break;
3657ec681f3Smrg
3667ec681f3Smrg            default:
3677ec681f3Smrg               unreachable("Cannot get here from the first level switch");
3687ec681f3Smrg            }
3697ec681f3Smrg            ret->elements[c] = col_const;
3707ec681f3Smrg         }
3717ec681f3Smrg      } else {
3727ec681f3Smrg         switch (ir->type->base_type) {
3737ec681f3Smrg         case GLSL_TYPE_FLOAT:
3747ec681f3Smrg            for (unsigned r = 0; r < rows; r++)
3757ec681f3Smrg               ret->values[r].f32 = ir->value.f[r];
3767ec681f3Smrg            break;
3777ec681f3Smrg
3787ec681f3Smrg         case GLSL_TYPE_FLOAT16:
3797ec681f3Smrg            for (unsigned r = 0; r < rows; r++)
3807ec681f3Smrg               ret->values[r].u16 = ir->value.f16[r];
3817ec681f3Smrg            break;
3827ec681f3Smrg
3837ec681f3Smrg         case GLSL_TYPE_DOUBLE:
3847ec681f3Smrg            for (unsigned r = 0; r < rows; r++)
3857ec681f3Smrg               ret->values[r].f64 = ir->value.d[r];
3867ec681f3Smrg            break;
3877ec681f3Smrg
3887ec681f3Smrg         default:
3897ec681f3Smrg            unreachable("Cannot get here from the first level switch");
3907ec681f3Smrg         }
39101e04c3fSmrg      }
39201e04c3fSmrg      break;
39301e04c3fSmrg
39401e04c3fSmrg   case GLSL_TYPE_UINT64:
39501e04c3fSmrg      /* Only float base types can be matrices. */
39601e04c3fSmrg      assert(cols == 1);
39701e04c3fSmrg
39801e04c3fSmrg      for (unsigned r = 0; r < rows; r++)
3997ec681f3Smrg         ret->values[r].u64 = ir->value.u64[r];
40001e04c3fSmrg      break;
40101e04c3fSmrg
40201e04c3fSmrg   case GLSL_TYPE_INT64:
40301e04c3fSmrg      /* Only float base types can be matrices. */
40401e04c3fSmrg      assert(cols == 1);
40501e04c3fSmrg
40601e04c3fSmrg      for (unsigned r = 0; r < rows; r++)
4077ec681f3Smrg         ret->values[r].i64 = ir->value.i64[r];
40801e04c3fSmrg      break;
40901e04c3fSmrg
41001e04c3fSmrg   case GLSL_TYPE_BOOL:
41101e04c3fSmrg      /* Only float base types can be matrices. */
41201e04c3fSmrg      assert(cols == 1);
41301e04c3fSmrg
41401e04c3fSmrg      for (unsigned r = 0; r < rows; r++)
4157ec681f3Smrg         ret->values[r].b = ir->value.b[r];
41601e04c3fSmrg
41701e04c3fSmrg      break;
41801e04c3fSmrg
41901e04c3fSmrg   case GLSL_TYPE_STRUCT:
42001e04c3fSmrg   case GLSL_TYPE_ARRAY:
42101e04c3fSmrg      ret->elements = ralloc_array(mem_ctx, nir_constant *,
42201e04c3fSmrg                                   ir->type->length);
42301e04c3fSmrg      ret->num_elements = ir->type->length;
42401e04c3fSmrg
42501e04c3fSmrg      for (i = 0; i < ir->type->length; i++)
42601e04c3fSmrg         ret->elements[i] = constant_copy(ir->const_elements[i], mem_ctx);
42701e04c3fSmrg      break;
42801e04c3fSmrg
42901e04c3fSmrg   default:
43001e04c3fSmrg      unreachable("not reached");
43101e04c3fSmrg   }
43201e04c3fSmrg
43301e04c3fSmrg   return ret;
43401e04c3fSmrg}
43501e04c3fSmrg
4367e102996Smayastatic const glsl_type *
4377e102996Smayawrap_type_in_array(const glsl_type *elem_type, const glsl_type *array_type)
4387e102996Smaya{
4397e102996Smaya   if (!array_type->is_array())
4407e102996Smaya      return elem_type;
4417e102996Smaya
4427e102996Smaya   elem_type = wrap_type_in_array(elem_type, array_type->fields.array);
4437e102996Smaya
4447e102996Smaya   return glsl_type::get_array_instance(elem_type, array_type->length);
4457e102996Smaya}
4467e102996Smaya
4477ec681f3Smrgstatic unsigned
4487ec681f3Smrgget_nir_how_declared(unsigned how_declared)
4497ec681f3Smrg{
4507ec681f3Smrg   if (how_declared == ir_var_hidden)
4517ec681f3Smrg      return nir_var_hidden;
4527ec681f3Smrg
4537ec681f3Smrg   return nir_var_declared_normally;
4547ec681f3Smrg}
4557ec681f3Smrg
45601e04c3fSmrgvoid
45701e04c3fSmrgnir_visitor::visit(ir_variable *ir)
45801e04c3fSmrg{
45901e04c3fSmrg   /* TODO: In future we should switch to using the NIR lowering pass but for
46001e04c3fSmrg    * now just ignore these variables as GLSL IR should have lowered them.
46101e04c3fSmrg    * Anything remaining are just dead vars that weren't cleaned up.
46201e04c3fSmrg    */
46301e04c3fSmrg   if (ir->data.mode == ir_var_shader_shared)
46401e04c3fSmrg      return;
46501e04c3fSmrg
4667e102996Smaya   /* FINISHME: inout parameters */
4677e102996Smaya   assert(ir->data.mode != ir_var_function_inout);
4687e102996Smaya
4697e102996Smaya   if (ir->data.mode == ir_var_function_out)
4707e102996Smaya      return;
4717e102996Smaya
47201e04c3fSmrg   nir_variable *var = rzalloc(shader, nir_variable);
47301e04c3fSmrg   var->type = ir->type;
47401e04c3fSmrg   var->name = ralloc_strdup(var, ir->name);
47501e04c3fSmrg
47601e04c3fSmrg   var->data.always_active_io = ir->data.always_active_io;
47701e04c3fSmrg   var->data.read_only = ir->data.read_only;
47801e04c3fSmrg   var->data.centroid = ir->data.centroid;
47901e04c3fSmrg   var->data.sample = ir->data.sample;
48001e04c3fSmrg   var->data.patch = ir->data.patch;
4817ec681f3Smrg   var->data.how_declared = get_nir_how_declared(ir->data.how_declared);
48201e04c3fSmrg   var->data.invariant = ir->data.invariant;
48301e04c3fSmrg   var->data.location = ir->data.location;
48401e04c3fSmrg   var->data.stream = ir->data.stream;
4857ec681f3Smrg   if (ir->data.stream & (1u << 31))
4867ec681f3Smrg      var->data.stream |= NIR_STREAM_PACKED;
4877ec681f3Smrg
4887ec681f3Smrg   var->data.precision = ir->data.precision;
4897ec681f3Smrg   var->data.explicit_location = ir->data.explicit_location;
4907ec681f3Smrg   var->data.matrix_layout = ir->data.matrix_layout;
4917ec681f3Smrg   var->data.from_named_ifc_block = ir->data.from_named_ifc_block;
49201e04c3fSmrg   var->data.compact = false;
49301e04c3fSmrg
49401e04c3fSmrg   switch(ir->data.mode) {
49501e04c3fSmrg   case ir_var_auto:
49601e04c3fSmrg   case ir_var_temporary:
49701e04c3fSmrg      if (is_global)
4987e102996Smaya         var->data.mode = nir_var_shader_temp;
49901e04c3fSmrg      else
5007e102996Smaya         var->data.mode = nir_var_function_temp;
50101e04c3fSmrg      break;
50201e04c3fSmrg
50301e04c3fSmrg   case ir_var_function_in:
50401e04c3fSmrg   case ir_var_const_in:
5057e102996Smaya      var->data.mode = nir_var_function_temp;
50601e04c3fSmrg      break;
50701e04c3fSmrg
50801e04c3fSmrg   case ir_var_shader_in:
5097ec681f3Smrg      if (shader->info.stage == MESA_SHADER_GEOMETRY &&
5107ec681f3Smrg          ir->data.location == VARYING_SLOT_PRIMITIVE_ID) {
51101e04c3fSmrg         /* For whatever reason, GLSL IR makes gl_PrimitiveIDIn an input */
51201e04c3fSmrg         var->data.location = SYSTEM_VALUE_PRIMITIVE_ID;
51301e04c3fSmrg         var->data.mode = nir_var_system_value;
51401e04c3fSmrg      } else {
51501e04c3fSmrg         var->data.mode = nir_var_shader_in;
51601e04c3fSmrg
51701e04c3fSmrg         if (shader->info.stage == MESA_SHADER_TESS_EVAL &&
51801e04c3fSmrg             (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
51901e04c3fSmrg              ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
52001e04c3fSmrg            var->data.compact = ir->type->without_array()->is_scalar();
52101e04c3fSmrg         }
5227e102996Smaya
5237e102996Smaya         if (shader->info.stage > MESA_SHADER_VERTEX &&
5247e102996Smaya             ir->data.location >= VARYING_SLOT_CLIP_DIST0 &&
5257e102996Smaya             ir->data.location <= VARYING_SLOT_CULL_DIST1) {
5267e102996Smaya            var->data.compact = ir->type->without_array()->is_scalar();
5277e102996Smaya         }
52801e04c3fSmrg      }
52901e04c3fSmrg      break;
53001e04c3fSmrg
53101e04c3fSmrg   case ir_var_shader_out:
53201e04c3fSmrg      var->data.mode = nir_var_shader_out;
53301e04c3fSmrg      if (shader->info.stage == MESA_SHADER_TESS_CTRL &&
53401e04c3fSmrg          (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
53501e04c3fSmrg           ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
53601e04c3fSmrg         var->data.compact = ir->type->without_array()->is_scalar();
53701e04c3fSmrg      }
5387e102996Smaya
5397e102996Smaya      if (shader->info.stage <= MESA_SHADER_GEOMETRY &&
5407e102996Smaya          ir->data.location >= VARYING_SLOT_CLIP_DIST0 &&
5417e102996Smaya          ir->data.location <= VARYING_SLOT_CULL_DIST1) {
5427e102996Smaya         var->data.compact = ir->type->without_array()->is_scalar();
5437e102996Smaya      }
54401e04c3fSmrg      break;
54501e04c3fSmrg
54601e04c3fSmrg   case ir_var_uniform:
5477e102996Smaya      if (ir->get_interface_type())
5487e102996Smaya         var->data.mode = nir_var_mem_ubo;
5497e102996Smaya      else
5507e102996Smaya         var->data.mode = nir_var_uniform;
55101e04c3fSmrg      break;
55201e04c3fSmrg
55301e04c3fSmrg   case ir_var_shader_storage:
5547e102996Smaya      var->data.mode = nir_var_mem_ssbo;
55501e04c3fSmrg      break;
55601e04c3fSmrg
55701e04c3fSmrg   case ir_var_system_value:
55801e04c3fSmrg      var->data.mode = nir_var_system_value;
55901e04c3fSmrg      break;
56001e04c3fSmrg
56101e04c3fSmrg   default:
56201e04c3fSmrg      unreachable("not reached");
56301e04c3fSmrg   }
56401e04c3fSmrg
5657ec681f3Smrg   unsigned mem_access = 0;
5667e102996Smaya   if (ir->data.memory_read_only)
5677ec681f3Smrg      mem_access |= ACCESS_NON_WRITEABLE;
5687e102996Smaya   if (ir->data.memory_write_only)
5697ec681f3Smrg      mem_access |= ACCESS_NON_READABLE;
5707e102996Smaya   if (ir->data.memory_coherent)
5717ec681f3Smrg      mem_access |= ACCESS_COHERENT;
5727e102996Smaya   if (ir->data.memory_volatile)
5737ec681f3Smrg      mem_access |= ACCESS_VOLATILE;
5747e102996Smaya   if (ir->data.memory_restrict)
5757ec681f3Smrg      mem_access |= ACCESS_RESTRICT;
5767ec681f3Smrg
5777ec681f3Smrg   var->interface_type = ir->get_interface_type();
5787e102996Smaya
5797e102996Smaya   /* For UBO and SSBO variables, we need explicit types */
5807e102996Smaya   if (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) {
5817e102996Smaya      const glsl_type *explicit_ifc_type =
5827e102996Smaya         ir->get_interface_type()->get_explicit_interface_type(supports_std430);
58301e04c3fSmrg
5847ec681f3Smrg      var->interface_type = explicit_ifc_type;
5857ec681f3Smrg
5867e102996Smaya      if (ir->type->without_array()->is_interface()) {
5877e102996Smaya         /* If the type contains the interface, wrap the explicit type in the
5887e102996Smaya          * right number of arrays.
5897e102996Smaya          */
5907e102996Smaya         var->type = wrap_type_in_array(explicit_ifc_type, ir->type);
5917e102996Smaya      } else {
5927e102996Smaya         /* Otherwise, this variable is one entry in the interface */
5937e102996Smaya         UNUSED bool found = false;
5947e102996Smaya         for (unsigned i = 0; i < explicit_ifc_type->length; i++) {
5957e102996Smaya            const glsl_struct_field *field =
5967e102996Smaya               &explicit_ifc_type->fields.structure[i];
5977e102996Smaya            if (strcmp(ir->name, field->name) != 0)
5987e102996Smaya               continue;
5997e102996Smaya
6007e102996Smaya            var->type = field->type;
6017e102996Smaya            if (field->memory_read_only)
6027ec681f3Smrg               mem_access |= ACCESS_NON_WRITEABLE;
6037e102996Smaya            if (field->memory_write_only)
6047ec681f3Smrg               mem_access |= ACCESS_NON_READABLE;
6057e102996Smaya            if (field->memory_coherent)
6067ec681f3Smrg               mem_access |= ACCESS_COHERENT;
6077e102996Smaya            if (field->memory_volatile)
6087ec681f3Smrg               mem_access |= ACCESS_VOLATILE;
6097e102996Smaya            if (field->memory_restrict)
6107ec681f3Smrg               mem_access |= ACCESS_RESTRICT;
6117e102996Smaya
6127e102996Smaya            found = true;
6137e102996Smaya            break;
6147e102996Smaya         }
6157e102996Smaya         assert(found);
6167e102996Smaya      }
61701e04c3fSmrg   }
61801e04c3fSmrg
6197e102996Smaya   var->data.interpolation = ir->data.interpolation;
6207e102996Smaya   var->data.location_frac = ir->data.location_frac;
6217e102996Smaya
62201e04c3fSmrg   switch (ir->data.depth_layout) {
62301e04c3fSmrg   case ir_depth_layout_none:
62401e04c3fSmrg      var->data.depth_layout = nir_depth_layout_none;
62501e04c3fSmrg      break;
62601e04c3fSmrg   case ir_depth_layout_any:
62701e04c3fSmrg      var->data.depth_layout = nir_depth_layout_any;
62801e04c3fSmrg      break;
62901e04c3fSmrg   case ir_depth_layout_greater:
63001e04c3fSmrg      var->data.depth_layout = nir_depth_layout_greater;
63101e04c3fSmrg      break;
63201e04c3fSmrg   case ir_depth_layout_less:
63301e04c3fSmrg      var->data.depth_layout = nir_depth_layout_less;
63401e04c3fSmrg      break;
63501e04c3fSmrg   case ir_depth_layout_unchanged:
63601e04c3fSmrg      var->data.depth_layout = nir_depth_layout_unchanged;
63701e04c3fSmrg      break;
63801e04c3fSmrg   default:
63901e04c3fSmrg      unreachable("not reached");
64001e04c3fSmrg   }
64101e04c3fSmrg
64201e04c3fSmrg   var->data.index = ir->data.index;
64301e04c3fSmrg   var->data.descriptor_set = 0;
64401e04c3fSmrg   var->data.binding = ir->data.binding;
64501e04c3fSmrg   var->data.explicit_binding = ir->data.explicit_binding;
64601e04c3fSmrg   var->data.bindless = ir->data.bindless;
64701e04c3fSmrg   var->data.offset = ir->data.offset;
6487ec681f3Smrg   var->data.access = (gl_access_qualifier)mem_access;
64901e04c3fSmrg
6507ec681f3Smrg   if (var->type->without_array()->is_image()) {
6517ec681f3Smrg      var->data.image.format = ir->data.image_format;
6527ec681f3Smrg   } else if (var->data.mode == nir_var_shader_out) {
6537ec681f3Smrg      var->data.xfb.buffer = ir->data.xfb_buffer;
6547ec681f3Smrg      var->data.xfb.stride = ir->data.xfb_stride;
6557ec681f3Smrg   }
65601e04c3fSmrg
65701e04c3fSmrg   var->data.fb_fetch_output = ir->data.fb_fetch_output;
65801e04c3fSmrg   var->data.explicit_xfb_buffer = ir->data.explicit_xfb_buffer;
65901e04c3fSmrg   var->data.explicit_xfb_stride = ir->data.explicit_xfb_stride;
66001e04c3fSmrg
66101e04c3fSmrg   var->num_state_slots = ir->get_num_state_slots();
66201e04c3fSmrg   if (var->num_state_slots > 0) {
66301e04c3fSmrg      var->state_slots = rzalloc_array(var, nir_state_slot,
66401e04c3fSmrg                                       var->num_state_slots);
66501e04c3fSmrg
66601e04c3fSmrg      ir_state_slot *state_slots = ir->get_state_slots();
66701e04c3fSmrg      for (unsigned i = 0; i < var->num_state_slots; i++) {
6687ec681f3Smrg         for (unsigned j = 0; j < 4; j++)
66901e04c3fSmrg            var->state_slots[i].tokens[j] = state_slots[i].tokens[j];
67001e04c3fSmrg         var->state_slots[i].swizzle = state_slots[i].swizzle;
67101e04c3fSmrg      }
67201e04c3fSmrg   } else {
67301e04c3fSmrg      var->state_slots = NULL;
67401e04c3fSmrg   }
67501e04c3fSmrg
67601e04c3fSmrg   var->constant_initializer = constant_copy(ir->constant_initializer, var);
67701e04c3fSmrg
6787e102996Smaya   if (var->data.mode == nir_var_function_temp)
67901e04c3fSmrg      nir_function_impl_add_variable(impl, var);
68001e04c3fSmrg   else
68101e04c3fSmrg      nir_shader_add_variable(shader, var);
68201e04c3fSmrg
68301e04c3fSmrg   _mesa_hash_table_insert(var_table, ir, var);
68401e04c3fSmrg}
68501e04c3fSmrg
68601e04c3fSmrgir_visitor_status
68701e04c3fSmrgnir_function_visitor::visit_enter(ir_function *ir)
68801e04c3fSmrg{
68901e04c3fSmrg   foreach_in_list(ir_function_signature, sig, &ir->signatures) {
69001e04c3fSmrg      visitor->create_function(sig);
69101e04c3fSmrg   }
69201e04c3fSmrg   return visit_continue_with_parent;
69301e04c3fSmrg}
69401e04c3fSmrg
69501e04c3fSmrgvoid
69601e04c3fSmrgnir_visitor::create_function(ir_function_signature *ir)
69701e04c3fSmrg{
69801e04c3fSmrg   if (ir->is_intrinsic())
69901e04c3fSmrg      return;
70001e04c3fSmrg
70101e04c3fSmrg   nir_function *func = nir_function_create(shader, ir->function_name());
7027e102996Smaya   if (strcmp(ir->function_name(), "main") == 0)
7037e102996Smaya      func->is_entrypoint = true;
7047e102996Smaya
7057e102996Smaya   func->num_params = ir->parameters.length() +
7067e102996Smaya                      (ir->return_type != glsl_type::void_type);
7077e102996Smaya   func->params = ralloc_array(shader, nir_parameter, func->num_params);
7087e102996Smaya
7097e102996Smaya   unsigned np = 0;
7107e102996Smaya
7117e102996Smaya   if (ir->return_type != glsl_type::void_type) {
7127e102996Smaya      /* The return value is a variable deref (basically an out parameter) */
7137e102996Smaya      func->params[np].num_components = 1;
7147e102996Smaya      func->params[np].bit_size = 32;
7157e102996Smaya      np++;
7167e102996Smaya   }
71701e04c3fSmrg
7187e102996Smaya   foreach_in_list(ir_variable, param, &ir->parameters) {
7197e102996Smaya      /* FINISHME: pass arrays, structs, etc by reference? */
7207e102996Smaya      assert(param->type->is_vector() || param->type->is_scalar());
7217e102996Smaya
7227e102996Smaya      if (param->data.mode == ir_var_function_in) {
7237e102996Smaya         func->params[np].num_components = param->type->vector_elements;
7247e102996Smaya         func->params[np].bit_size = glsl_get_bit_size(param->type);
7257e102996Smaya      } else {
7267e102996Smaya         func->params[np].num_components = 1;
7277e102996Smaya         func->params[np].bit_size = 32;
7287e102996Smaya      }
7297e102996Smaya      np++;
7307e102996Smaya   }
7317e102996Smaya   assert(np == func->num_params);
73201e04c3fSmrg
73301e04c3fSmrg   _mesa_hash_table_insert(this->overload_table, ir, func);
73401e04c3fSmrg}
73501e04c3fSmrg
73601e04c3fSmrgvoid
73701e04c3fSmrgnir_visitor::visit(ir_function *ir)
73801e04c3fSmrg{
73901e04c3fSmrg   foreach_in_list(ir_function_signature, sig, &ir->signatures)
74001e04c3fSmrg      sig->accept(this);
74101e04c3fSmrg}
74201e04c3fSmrg
74301e04c3fSmrgvoid
74401e04c3fSmrgnir_visitor::visit(ir_function_signature *ir)
74501e04c3fSmrg{
74601e04c3fSmrg   if (ir->is_intrinsic())
74701e04c3fSmrg      return;
74801e04c3fSmrg
7497e102996Smaya   this->sig = ir;
7507e102996Smaya
75101e04c3fSmrg   struct hash_entry *entry =
75201e04c3fSmrg      _mesa_hash_table_search(this->overload_table, ir);
75301e04c3fSmrg
75401e04c3fSmrg   assert(entry);
75501e04c3fSmrg   nir_function *func = (nir_function *) entry->data;
75601e04c3fSmrg
75701e04c3fSmrg   if (ir->is_defined) {
75801e04c3fSmrg      nir_function_impl *impl = nir_function_impl_create(func);
75901e04c3fSmrg      this->impl = impl;
76001e04c3fSmrg
76101e04c3fSmrg      this->is_global = false;
76201e04c3fSmrg
76301e04c3fSmrg      nir_builder_init(&b, impl);
76401e04c3fSmrg      b.cursor = nir_after_cf_list(&impl->body);
7657e102996Smaya
7667e102996Smaya      unsigned i = (ir->return_type != glsl_type::void_type) ? 1 : 0;
7677e102996Smaya
7687e102996Smaya      foreach_in_list(ir_variable, param, &ir->parameters) {
7697e102996Smaya         nir_variable *var =
7707e102996Smaya            nir_local_variable_create(impl, param->type, param->name);
7717e102996Smaya
7727e102996Smaya         if (param->data.mode == ir_var_function_in) {
7737e102996Smaya            nir_store_var(&b, var, nir_load_param(&b, i), ~0);
7747e102996Smaya         }
7757e102996Smaya
7767e102996Smaya         _mesa_hash_table_insert(var_table, param, var);
7777e102996Smaya         i++;
7787e102996Smaya      }
7797e102996Smaya
78001e04c3fSmrg      visit_exec_list(&ir->body, this);
78101e04c3fSmrg
78201e04c3fSmrg      this->is_global = true;
78301e04c3fSmrg   } else {
78401e04c3fSmrg      func->impl = NULL;
78501e04c3fSmrg   }
78601e04c3fSmrg}
78701e04c3fSmrg
78801e04c3fSmrgvoid
78901e04c3fSmrgnir_visitor::visit(ir_loop *ir)
79001e04c3fSmrg{
79101e04c3fSmrg   nir_push_loop(&b);
79201e04c3fSmrg   visit_exec_list(&ir->body_instructions, this);
79301e04c3fSmrg   nir_pop_loop(&b, NULL);
79401e04c3fSmrg}
79501e04c3fSmrg
79601e04c3fSmrgvoid
79701e04c3fSmrgnir_visitor::visit(ir_if *ir)
79801e04c3fSmrg{
79901e04c3fSmrg   nir_push_if(&b, evaluate_rvalue(ir->condition));
80001e04c3fSmrg   visit_exec_list(&ir->then_instructions, this);
80101e04c3fSmrg   nir_push_else(&b, NULL);
80201e04c3fSmrg   visit_exec_list(&ir->else_instructions, this);
80301e04c3fSmrg   nir_pop_if(&b, NULL);
80401e04c3fSmrg}
80501e04c3fSmrg
80601e04c3fSmrgvoid
80701e04c3fSmrgnir_visitor::visit(ir_discard *ir)
80801e04c3fSmrg{
80901e04c3fSmrg   /*
81001e04c3fSmrg    * discards aren't treated as control flow, because before we lower them
81101e04c3fSmrg    * they can appear anywhere in the shader and the stuff after them may still
81201e04c3fSmrg    * be executed (yay, crazy GLSL rules!). However, after lowering, all the
81301e04c3fSmrg    * discards will be immediately followed by a return.
81401e04c3fSmrg    */
81501e04c3fSmrg
8167ec681f3Smrg   if (ir->condition)
8177ec681f3Smrg      nir_discard_if(&b, evaluate_rvalue(ir->condition));
8187ec681f3Smrg   else
8197ec681f3Smrg      nir_discard(&b);
8207ec681f3Smrg}
82101e04c3fSmrg
8227ec681f3Smrgvoid
8237ec681f3Smrgnir_visitor::visit(ir_demote *ir)
8247ec681f3Smrg{
8257ec681f3Smrg   nir_demote(&b);
82601e04c3fSmrg}
82701e04c3fSmrg
82801e04c3fSmrgvoid
82901e04c3fSmrgnir_visitor::visit(ir_emit_vertex *ir)
83001e04c3fSmrg{
8317ec681f3Smrg   nir_emit_vertex(&b, (unsigned)ir->stream_id());
83201e04c3fSmrg}
83301e04c3fSmrg
83401e04c3fSmrgvoid
83501e04c3fSmrgnir_visitor::visit(ir_end_primitive *ir)
83601e04c3fSmrg{
8377ec681f3Smrg   nir_end_primitive(&b, (unsigned)ir->stream_id());
83801e04c3fSmrg}
83901e04c3fSmrg
84001e04c3fSmrgvoid
84101e04c3fSmrgnir_visitor::visit(ir_loop_jump *ir)
84201e04c3fSmrg{
84301e04c3fSmrg   nir_jump_type type;
84401e04c3fSmrg   switch (ir->mode) {
84501e04c3fSmrg   case ir_loop_jump::jump_break:
84601e04c3fSmrg      type = nir_jump_break;
84701e04c3fSmrg      break;
84801e04c3fSmrg   case ir_loop_jump::jump_continue:
84901e04c3fSmrg      type = nir_jump_continue;
85001e04c3fSmrg      break;
85101e04c3fSmrg   default:
85201e04c3fSmrg      unreachable("not reached");
85301e04c3fSmrg   }
85401e04c3fSmrg
85501e04c3fSmrg   nir_jump_instr *instr = nir_jump_instr_create(this->shader, type);
85601e04c3fSmrg   nir_builder_instr_insert(&b, &instr->instr);
85701e04c3fSmrg}
85801e04c3fSmrg
85901e04c3fSmrgvoid
86001e04c3fSmrgnir_visitor::visit(ir_return *ir)
86101e04c3fSmrg{
8627e102996Smaya   if (ir->value != NULL) {
8637e102996Smaya      nir_deref_instr *ret_deref =
8647e102996Smaya         nir_build_deref_cast(&b, nir_load_param(&b, 0),
8657e102996Smaya                              nir_var_function_temp, ir->value->type, 0);
8667e102996Smaya
8677e102996Smaya      nir_ssa_def *val = evaluate_rvalue(ir->value);
8687e102996Smaya      nir_store_deref(&b, ret_deref, val, ~0);
8697e102996Smaya   }
8707e102996Smaya
87101e04c3fSmrg   nir_jump_instr *instr = nir_jump_instr_create(this->shader, nir_jump_return);
87201e04c3fSmrg   nir_builder_instr_insert(&b, &instr->instr);
87301e04c3fSmrg}
87401e04c3fSmrg
8757e102996Smayastatic void
8767e102996Smayaintrinsic_set_std430_align(nir_intrinsic_instr *intrin, const glsl_type *type)
8777e102996Smaya{
8787e102996Smaya   unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type);
8797e102996Smaya   unsigned pow2_components = util_next_power_of_two(type->vector_elements);
8807e102996Smaya   nir_intrinsic_set_align(intrin, (bit_size / 8) * pow2_components, 0);
8817e102996Smaya}
8827e102996Smaya
8837ec681f3Smrg/* Accumulate any qualifiers along the deref chain to get the actual
8847ec681f3Smrg * load/store qualifier.
8857ec681f3Smrg */
8867ec681f3Smrg
8877ec681f3Smrgstatic enum gl_access_qualifier
8887ec681f3Smrgderef_get_qualifier(nir_deref_instr *deref)
8897ec681f3Smrg{
8907ec681f3Smrg   nir_deref_path path;
8917ec681f3Smrg   nir_deref_path_init(&path, deref, NULL);
8927ec681f3Smrg
8937ec681f3Smrg   unsigned qualifiers = path.path[0]->var->data.access;
8947ec681f3Smrg
8957ec681f3Smrg   const glsl_type *parent_type = path.path[0]->type;
8967ec681f3Smrg   for (nir_deref_instr **cur_ptr = &path.path[1]; *cur_ptr; cur_ptr++) {
8977ec681f3Smrg      nir_deref_instr *cur = *cur_ptr;
8987ec681f3Smrg
8997ec681f3Smrg      if (parent_type->is_interface()) {
9007ec681f3Smrg         const struct glsl_struct_field *field =
9017ec681f3Smrg            &parent_type->fields.structure[cur->strct.index];
9027ec681f3Smrg         if (field->memory_read_only)
9037ec681f3Smrg            qualifiers |= ACCESS_NON_WRITEABLE;
9047ec681f3Smrg         if (field->memory_write_only)
9057ec681f3Smrg            qualifiers |= ACCESS_NON_READABLE;
9067ec681f3Smrg         if (field->memory_coherent)
9077ec681f3Smrg            qualifiers |= ACCESS_COHERENT;
9087ec681f3Smrg         if (field->memory_volatile)
9097ec681f3Smrg            qualifiers |= ACCESS_VOLATILE;
9107ec681f3Smrg         if (field->memory_restrict)
9117ec681f3Smrg            qualifiers |= ACCESS_RESTRICT;
9127ec681f3Smrg      }
9137ec681f3Smrg
9147ec681f3Smrg      parent_type = cur->type;
9157ec681f3Smrg   }
9167ec681f3Smrg
9177ec681f3Smrg   nir_deref_path_finish(&path);
9187ec681f3Smrg
9197ec681f3Smrg   return (gl_access_qualifier) qualifiers;
9207ec681f3Smrg}
9217ec681f3Smrg
92201e04c3fSmrgvoid
92301e04c3fSmrgnir_visitor::visit(ir_call *ir)
92401e04c3fSmrg{
92501e04c3fSmrg   if (ir->callee->is_intrinsic()) {
92601e04c3fSmrg      nir_intrinsic_op op;
92701e04c3fSmrg
92801e04c3fSmrg      switch (ir->callee->intrinsic_id) {
9297e102996Smaya      case ir_intrinsic_generic_atomic_add:
9307e102996Smaya         op = ir->return_deref->type->is_integer_32_64()
9317e102996Smaya            ? nir_intrinsic_deref_atomic_add : nir_intrinsic_deref_atomic_fadd;
9327e102996Smaya         break;
9337e102996Smaya      case ir_intrinsic_generic_atomic_and:
9347e102996Smaya         op = nir_intrinsic_deref_atomic_and;
9357e102996Smaya         break;
9367e102996Smaya      case ir_intrinsic_generic_atomic_or:
9377e102996Smaya         op = nir_intrinsic_deref_atomic_or;
9387e102996Smaya         break;
9397e102996Smaya      case ir_intrinsic_generic_atomic_xor:
9407e102996Smaya         op = nir_intrinsic_deref_atomic_xor;
9417e102996Smaya         break;
9427e102996Smaya      case ir_intrinsic_generic_atomic_min:
9437e102996Smaya         assert(ir->return_deref);
9447ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type ||
9457ec681f3Smrg             ir->return_deref->type == glsl_type::int64_t_type)
9467e102996Smaya            op = nir_intrinsic_deref_atomic_imin;
9477ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type ||
9487ec681f3Smrg                  ir->return_deref->type == glsl_type::uint64_t_type)
9497e102996Smaya            op = nir_intrinsic_deref_atomic_umin;
9507e102996Smaya         else if (ir->return_deref->type == glsl_type::float_type)
9517e102996Smaya            op = nir_intrinsic_deref_atomic_fmin;
9527e102996Smaya         else
9537e102996Smaya            unreachable("Invalid type");
9547e102996Smaya         break;
9557e102996Smaya      case ir_intrinsic_generic_atomic_max:
9567e102996Smaya         assert(ir->return_deref);
9577ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type ||
9587ec681f3Smrg             ir->return_deref->type == glsl_type::int64_t_type)
9597e102996Smaya            op = nir_intrinsic_deref_atomic_imax;
9607ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type ||
9617ec681f3Smrg                  ir->return_deref->type == glsl_type::uint64_t_type)
9627e102996Smaya            op = nir_intrinsic_deref_atomic_umax;
9637e102996Smaya         else if (ir->return_deref->type == glsl_type::float_type)
9647e102996Smaya            op = nir_intrinsic_deref_atomic_fmax;
9657e102996Smaya         else
9667e102996Smaya            unreachable("Invalid type");
9677e102996Smaya         break;
9687e102996Smaya      case ir_intrinsic_generic_atomic_exchange:
9697e102996Smaya         op = nir_intrinsic_deref_atomic_exchange;
9707e102996Smaya         break;
9717e102996Smaya      case ir_intrinsic_generic_atomic_comp_swap:
9727e102996Smaya         op = ir->return_deref->type->is_integer_32_64()
9737e102996Smaya            ? nir_intrinsic_deref_atomic_comp_swap
9747e102996Smaya            : nir_intrinsic_deref_atomic_fcomp_swap;
9757e102996Smaya         break;
97601e04c3fSmrg      case ir_intrinsic_atomic_counter_read:
97701e04c3fSmrg         op = nir_intrinsic_atomic_counter_read_deref;
97801e04c3fSmrg         break;
97901e04c3fSmrg      case ir_intrinsic_atomic_counter_increment:
98001e04c3fSmrg         op = nir_intrinsic_atomic_counter_inc_deref;
98101e04c3fSmrg         break;
98201e04c3fSmrg      case ir_intrinsic_atomic_counter_predecrement:
98301e04c3fSmrg         op = nir_intrinsic_atomic_counter_pre_dec_deref;
98401e04c3fSmrg         break;
98501e04c3fSmrg      case ir_intrinsic_atomic_counter_add:
98601e04c3fSmrg         op = nir_intrinsic_atomic_counter_add_deref;
98701e04c3fSmrg         break;
98801e04c3fSmrg      case ir_intrinsic_atomic_counter_and:
98901e04c3fSmrg         op = nir_intrinsic_atomic_counter_and_deref;
99001e04c3fSmrg         break;
99101e04c3fSmrg      case ir_intrinsic_atomic_counter_or:
99201e04c3fSmrg         op = nir_intrinsic_atomic_counter_or_deref;
99301e04c3fSmrg         break;
99401e04c3fSmrg      case ir_intrinsic_atomic_counter_xor:
99501e04c3fSmrg         op = nir_intrinsic_atomic_counter_xor_deref;
99601e04c3fSmrg         break;
99701e04c3fSmrg      case ir_intrinsic_atomic_counter_min:
99801e04c3fSmrg         op = nir_intrinsic_atomic_counter_min_deref;
99901e04c3fSmrg         break;
100001e04c3fSmrg      case ir_intrinsic_atomic_counter_max:
100101e04c3fSmrg         op = nir_intrinsic_atomic_counter_max_deref;
100201e04c3fSmrg         break;
100301e04c3fSmrg      case ir_intrinsic_atomic_counter_exchange:
100401e04c3fSmrg         op = nir_intrinsic_atomic_counter_exchange_deref;
100501e04c3fSmrg         break;
100601e04c3fSmrg      case ir_intrinsic_atomic_counter_comp_swap:
100701e04c3fSmrg         op = nir_intrinsic_atomic_counter_comp_swap_deref;
100801e04c3fSmrg         break;
100901e04c3fSmrg      case ir_intrinsic_image_load:
101001e04c3fSmrg         op = nir_intrinsic_image_deref_load;
101101e04c3fSmrg         break;
101201e04c3fSmrg      case ir_intrinsic_image_store:
101301e04c3fSmrg         op = nir_intrinsic_image_deref_store;
101401e04c3fSmrg         break;
101501e04c3fSmrg      case ir_intrinsic_image_atomic_add:
101601e04c3fSmrg         op = ir->return_deref->type->is_integer_32_64()
101701e04c3fSmrg            ? nir_intrinsic_image_deref_atomic_add
101801e04c3fSmrg            : nir_intrinsic_image_deref_atomic_fadd;
101901e04c3fSmrg         break;
102001e04c3fSmrg      case ir_intrinsic_image_atomic_min:
10217ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type)
10227ec681f3Smrg            op = nir_intrinsic_image_deref_atomic_imin;
10237ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type)
10247ec681f3Smrg            op = nir_intrinsic_image_deref_atomic_umin;
10257ec681f3Smrg         else
10267ec681f3Smrg            unreachable("Invalid type");
102701e04c3fSmrg         break;
102801e04c3fSmrg      case ir_intrinsic_image_atomic_max:
10297ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type)
10307ec681f3Smrg            op = nir_intrinsic_image_deref_atomic_imax;
10317ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type)
10327ec681f3Smrg            op = nir_intrinsic_image_deref_atomic_umax;
10337ec681f3Smrg         else
10347ec681f3Smrg            unreachable("Invalid type");
103501e04c3fSmrg         break;
103601e04c3fSmrg      case ir_intrinsic_image_atomic_and:
103701e04c3fSmrg         op = nir_intrinsic_image_deref_atomic_and;
103801e04c3fSmrg         break;
103901e04c3fSmrg      case ir_intrinsic_image_atomic_or:
104001e04c3fSmrg         op = nir_intrinsic_image_deref_atomic_or;
104101e04c3fSmrg         break;
104201e04c3fSmrg      case ir_intrinsic_image_atomic_xor:
104301e04c3fSmrg         op = nir_intrinsic_image_deref_atomic_xor;
104401e04c3fSmrg         break;
104501e04c3fSmrg      case ir_intrinsic_image_atomic_exchange:
104601e04c3fSmrg         op = nir_intrinsic_image_deref_atomic_exchange;
104701e04c3fSmrg         break;
104801e04c3fSmrg      case ir_intrinsic_image_atomic_comp_swap:
104901e04c3fSmrg         op = nir_intrinsic_image_deref_atomic_comp_swap;
105001e04c3fSmrg         break;
10517ec681f3Smrg      case ir_intrinsic_image_atomic_inc_wrap:
10527ec681f3Smrg         op = nir_intrinsic_image_deref_atomic_inc_wrap;
10537ec681f3Smrg         break;
10547ec681f3Smrg      case ir_intrinsic_image_atomic_dec_wrap:
10557ec681f3Smrg         op = nir_intrinsic_image_deref_atomic_dec_wrap;
10567ec681f3Smrg         break;
105701e04c3fSmrg      case ir_intrinsic_memory_barrier:
105801e04c3fSmrg         op = nir_intrinsic_memory_barrier;
105901e04c3fSmrg         break;
106001e04c3fSmrg      case ir_intrinsic_image_size:
106101e04c3fSmrg         op = nir_intrinsic_image_deref_size;
106201e04c3fSmrg         break;
106301e04c3fSmrg      case ir_intrinsic_image_samples:
106401e04c3fSmrg         op = nir_intrinsic_image_deref_samples;
106501e04c3fSmrg         break;
106601e04c3fSmrg      case ir_intrinsic_ssbo_store:
106701e04c3fSmrg      case ir_intrinsic_ssbo_load:
106801e04c3fSmrg      case ir_intrinsic_ssbo_atomic_add:
106901e04c3fSmrg      case ir_intrinsic_ssbo_atomic_and:
107001e04c3fSmrg      case ir_intrinsic_ssbo_atomic_or:
107101e04c3fSmrg      case ir_intrinsic_ssbo_atomic_xor:
107201e04c3fSmrg      case ir_intrinsic_ssbo_atomic_min:
107301e04c3fSmrg      case ir_intrinsic_ssbo_atomic_max:
107401e04c3fSmrg      case ir_intrinsic_ssbo_atomic_exchange:
107501e04c3fSmrg      case ir_intrinsic_ssbo_atomic_comp_swap:
10767ec681f3Smrg         /* SSBO store/loads should only have been lowered in GLSL IR for
10777ec681f3Smrg          * non-nir drivers, NIR drivers make use of gl_nir_lower_buffers()
10787ec681f3Smrg          * instead.
10797ec681f3Smrg          */
10807ec681f3Smrg         unreachable("Invalid operation nir doesn't want lowered ssbo "
10817ec681f3Smrg                     "store/loads");
108201e04c3fSmrg      case ir_intrinsic_shader_clock:
108301e04c3fSmrg         op = nir_intrinsic_shader_clock;
108401e04c3fSmrg         break;
108501e04c3fSmrg      case ir_intrinsic_begin_invocation_interlock:
108601e04c3fSmrg         op = nir_intrinsic_begin_invocation_interlock;
108701e04c3fSmrg         break;
108801e04c3fSmrg      case ir_intrinsic_end_invocation_interlock:
108901e04c3fSmrg         op = nir_intrinsic_end_invocation_interlock;
109001e04c3fSmrg         break;
109101e04c3fSmrg      case ir_intrinsic_group_memory_barrier:
109201e04c3fSmrg         op = nir_intrinsic_group_memory_barrier;
109301e04c3fSmrg         break;
109401e04c3fSmrg      case ir_intrinsic_memory_barrier_atomic_counter:
109501e04c3fSmrg         op = nir_intrinsic_memory_barrier_atomic_counter;
109601e04c3fSmrg         break;
109701e04c3fSmrg      case ir_intrinsic_memory_barrier_buffer:
109801e04c3fSmrg         op = nir_intrinsic_memory_barrier_buffer;
109901e04c3fSmrg         break;
110001e04c3fSmrg      case ir_intrinsic_memory_barrier_image:
110101e04c3fSmrg         op = nir_intrinsic_memory_barrier_image;
110201e04c3fSmrg         break;
110301e04c3fSmrg      case ir_intrinsic_memory_barrier_shared:
110401e04c3fSmrg         op = nir_intrinsic_memory_barrier_shared;
110501e04c3fSmrg         break;
110601e04c3fSmrg      case ir_intrinsic_shared_load:
110701e04c3fSmrg         op = nir_intrinsic_load_shared;
110801e04c3fSmrg         break;
110901e04c3fSmrg      case ir_intrinsic_shared_store:
111001e04c3fSmrg         op = nir_intrinsic_store_shared;
111101e04c3fSmrg         break;
111201e04c3fSmrg      case ir_intrinsic_shared_atomic_add:
111301e04c3fSmrg         op = ir->return_deref->type->is_integer_32_64()
111401e04c3fSmrg            ? nir_intrinsic_shared_atomic_add
111501e04c3fSmrg            : nir_intrinsic_shared_atomic_fadd;
111601e04c3fSmrg         break;
111701e04c3fSmrg      case ir_intrinsic_shared_atomic_and:
111801e04c3fSmrg         op = nir_intrinsic_shared_atomic_and;
111901e04c3fSmrg         break;
112001e04c3fSmrg      case ir_intrinsic_shared_atomic_or:
112101e04c3fSmrg         op = nir_intrinsic_shared_atomic_or;
112201e04c3fSmrg         break;
112301e04c3fSmrg      case ir_intrinsic_shared_atomic_xor:
112401e04c3fSmrg         op = nir_intrinsic_shared_atomic_xor;
112501e04c3fSmrg         break;
112601e04c3fSmrg      case ir_intrinsic_shared_atomic_min:
112701e04c3fSmrg         assert(ir->return_deref);
11287ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type ||
11297ec681f3Smrg             ir->return_deref->type == glsl_type::int64_t_type)
113001e04c3fSmrg            op = nir_intrinsic_shared_atomic_imin;
11317ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type ||
11327ec681f3Smrg                  ir->return_deref->type == glsl_type::uint64_t_type)
113301e04c3fSmrg            op = nir_intrinsic_shared_atomic_umin;
113401e04c3fSmrg         else if (ir->return_deref->type == glsl_type::float_type)
113501e04c3fSmrg            op = nir_intrinsic_shared_atomic_fmin;
113601e04c3fSmrg         else
113701e04c3fSmrg            unreachable("Invalid type");
113801e04c3fSmrg         break;
113901e04c3fSmrg      case ir_intrinsic_shared_atomic_max:
114001e04c3fSmrg         assert(ir->return_deref);
11417ec681f3Smrg         if (ir->return_deref->type == glsl_type::int_type ||
11427ec681f3Smrg             ir->return_deref->type == glsl_type::int64_t_type)
114301e04c3fSmrg            op = nir_intrinsic_shared_atomic_imax;
11447ec681f3Smrg         else if (ir->return_deref->type == glsl_type::uint_type ||
11457ec681f3Smrg                  ir->return_deref->type == glsl_type::uint64_t_type)
114601e04c3fSmrg            op = nir_intrinsic_shared_atomic_umax;
114701e04c3fSmrg         else if (ir->return_deref->type == glsl_type::float_type)
114801e04c3fSmrg            op = nir_intrinsic_shared_atomic_fmax;
114901e04c3fSmrg         else
115001e04c3fSmrg            unreachable("Invalid type");
115101e04c3fSmrg         break;
115201e04c3fSmrg      case ir_intrinsic_shared_atomic_exchange:
115301e04c3fSmrg         op = nir_intrinsic_shared_atomic_exchange;
115401e04c3fSmrg         break;
115501e04c3fSmrg      case ir_intrinsic_shared_atomic_comp_swap:
115601e04c3fSmrg         op = ir->return_deref->type->is_integer_32_64()
115701e04c3fSmrg            ? nir_intrinsic_shared_atomic_comp_swap
115801e04c3fSmrg            : nir_intrinsic_shared_atomic_fcomp_swap;
115901e04c3fSmrg         break;
116001e04c3fSmrg      case ir_intrinsic_vote_any:
116101e04c3fSmrg         op = nir_intrinsic_vote_any;
116201e04c3fSmrg         break;
116301e04c3fSmrg      case ir_intrinsic_vote_all:
116401e04c3fSmrg         op = nir_intrinsic_vote_all;
116501e04c3fSmrg         break;
116601e04c3fSmrg      case ir_intrinsic_vote_eq:
116701e04c3fSmrg         op = nir_intrinsic_vote_ieq;
116801e04c3fSmrg         break;
116901e04c3fSmrg      case ir_intrinsic_ballot:
117001e04c3fSmrg         op = nir_intrinsic_ballot;
117101e04c3fSmrg         break;
117201e04c3fSmrg      case ir_intrinsic_read_invocation:
117301e04c3fSmrg         op = nir_intrinsic_read_invocation;
117401e04c3fSmrg         break;
117501e04c3fSmrg      case ir_intrinsic_read_first_invocation:
117601e04c3fSmrg         op = nir_intrinsic_read_first_invocation;
117701e04c3fSmrg         break;
11787ec681f3Smrg      case ir_intrinsic_helper_invocation:
11797ec681f3Smrg         op = nir_intrinsic_is_helper_invocation;
11807ec681f3Smrg         break;
118101e04c3fSmrg      default:
118201e04c3fSmrg         unreachable("not reached");
118301e04c3fSmrg      }
118401e04c3fSmrg
118501e04c3fSmrg      nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op);
118601e04c3fSmrg      nir_ssa_def *ret = &instr->dest.ssa;
118701e04c3fSmrg
118801e04c3fSmrg      switch (op) {
11897e102996Smaya      case nir_intrinsic_deref_atomic_add:
11907e102996Smaya      case nir_intrinsic_deref_atomic_imin:
11917e102996Smaya      case nir_intrinsic_deref_atomic_umin:
11927e102996Smaya      case nir_intrinsic_deref_atomic_imax:
11937e102996Smaya      case nir_intrinsic_deref_atomic_umax:
11947e102996Smaya      case nir_intrinsic_deref_atomic_and:
11957e102996Smaya      case nir_intrinsic_deref_atomic_or:
11967e102996Smaya      case nir_intrinsic_deref_atomic_xor:
11977e102996Smaya      case nir_intrinsic_deref_atomic_exchange:
11987e102996Smaya      case nir_intrinsic_deref_atomic_comp_swap:
11997e102996Smaya      case nir_intrinsic_deref_atomic_fadd:
12007e102996Smaya      case nir_intrinsic_deref_atomic_fmin:
12017e102996Smaya      case nir_intrinsic_deref_atomic_fmax:
12027e102996Smaya      case nir_intrinsic_deref_atomic_fcomp_swap: {
12037e102996Smaya         int param_count = ir->actual_parameters.length();
12047e102996Smaya         assert(param_count == 2 || param_count == 3);
12057e102996Smaya
12067e102996Smaya         /* Deref */
12077e102996Smaya         exec_node *param = ir->actual_parameters.get_head();
12087e102996Smaya         ir_rvalue *rvalue = (ir_rvalue *) param;
12097e102996Smaya         ir_dereference *deref = rvalue->as_dereference();
12107e102996Smaya         ir_swizzle *swizzle = NULL;
12117e102996Smaya         if (!deref) {
12127e102996Smaya            /* We may have a swizzle to pick off a single vec4 component */
12137e102996Smaya            swizzle = rvalue->as_swizzle();
12147e102996Smaya            assert(swizzle && swizzle->type->vector_elements == 1);
12157e102996Smaya            deref = swizzle->val->as_dereference();
12167e102996Smaya            assert(deref);
12177e102996Smaya         }
12187e102996Smaya         nir_deref_instr *nir_deref = evaluate_deref(deref);
12197e102996Smaya         if (swizzle) {
12207e102996Smaya            nir_deref = nir_build_deref_array_imm(&b, nir_deref,
12217e102996Smaya                                                  swizzle->mask.x);
12227e102996Smaya         }
12237e102996Smaya         instr->src[0] = nir_src_for_ssa(&nir_deref->dest.ssa);
12247e102996Smaya
12257ec681f3Smrg         nir_intrinsic_set_access(instr, deref_get_qualifier(nir_deref));
12267ec681f3Smrg
12277e102996Smaya         /* data1 parameter (this is always present) */
12287e102996Smaya         param = param->get_next();
12297e102996Smaya         ir_instruction *inst = (ir_instruction *) param;
12307e102996Smaya         instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
12317e102996Smaya
12327e102996Smaya         /* data2 parameter (only with atomic_comp_swap) */
12337e102996Smaya         if (param_count == 3) {
12347e102996Smaya            assert(op == nir_intrinsic_deref_atomic_comp_swap ||
12357e102996Smaya                   op == nir_intrinsic_deref_atomic_fcomp_swap);
12367e102996Smaya            param = param->get_next();
12377e102996Smaya            inst = (ir_instruction *) param;
12387e102996Smaya            instr->src[2] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
12397e102996Smaya         }
12407e102996Smaya
12417e102996Smaya         /* Atomic result */
12427e102996Smaya         assert(ir->return_deref);
12437ec681f3Smrg         if (ir->return_deref->type->is_integer_64()) {
12447ec681f3Smrg            nir_ssa_dest_init(&instr->instr, &instr->dest,
12457ec681f3Smrg                              ir->return_deref->type->vector_elements, 64, NULL);
12467ec681f3Smrg         } else {
12477ec681f3Smrg            nir_ssa_dest_init(&instr->instr, &instr->dest,
12487ec681f3Smrg                              ir->return_deref->type->vector_elements, 32, NULL);
12497ec681f3Smrg         }
12507e102996Smaya         nir_builder_instr_insert(&b, &instr->instr);
12517e102996Smaya         break;
12527e102996Smaya      }
125301e04c3fSmrg      case nir_intrinsic_atomic_counter_read_deref:
125401e04c3fSmrg      case nir_intrinsic_atomic_counter_inc_deref:
125501e04c3fSmrg      case nir_intrinsic_atomic_counter_pre_dec_deref:
125601e04c3fSmrg      case nir_intrinsic_atomic_counter_add_deref:
125701e04c3fSmrg      case nir_intrinsic_atomic_counter_min_deref:
125801e04c3fSmrg      case nir_intrinsic_atomic_counter_max_deref:
125901e04c3fSmrg      case nir_intrinsic_atomic_counter_and_deref:
126001e04c3fSmrg      case nir_intrinsic_atomic_counter_or_deref:
126101e04c3fSmrg      case nir_intrinsic_atomic_counter_xor_deref:
126201e04c3fSmrg      case nir_intrinsic_atomic_counter_exchange_deref:
126301e04c3fSmrg      case nir_intrinsic_atomic_counter_comp_swap_deref: {
126401e04c3fSmrg         /* Set the counter variable dereference. */
126501e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
126601e04c3fSmrg         ir_dereference *counter = (ir_dereference *)param;
126701e04c3fSmrg
126801e04c3fSmrg         instr->src[0] = nir_src_for_ssa(&evaluate_deref(counter)->dest.ssa);
126901e04c3fSmrg         param = param->get_next();
127001e04c3fSmrg
127101e04c3fSmrg         /* Set the intrinsic destination. */
127201e04c3fSmrg         if (ir->return_deref) {
127301e04c3fSmrg            nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
127401e04c3fSmrg         }
127501e04c3fSmrg
127601e04c3fSmrg         /* Set the intrinsic parameters. */
127701e04c3fSmrg         if (!param->is_tail_sentinel()) {
127801e04c3fSmrg            instr->src[1] =
127901e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
128001e04c3fSmrg            param = param->get_next();
128101e04c3fSmrg         }
128201e04c3fSmrg
128301e04c3fSmrg         if (!param->is_tail_sentinel()) {
128401e04c3fSmrg            instr->src[2] =
128501e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
128601e04c3fSmrg            param = param->get_next();
128701e04c3fSmrg         }
128801e04c3fSmrg
128901e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
129001e04c3fSmrg         break;
129101e04c3fSmrg      }
129201e04c3fSmrg      case nir_intrinsic_image_deref_load:
129301e04c3fSmrg      case nir_intrinsic_image_deref_store:
129401e04c3fSmrg      case nir_intrinsic_image_deref_atomic_add:
12957ec681f3Smrg      case nir_intrinsic_image_deref_atomic_imin:
12967ec681f3Smrg      case nir_intrinsic_image_deref_atomic_umin:
12977ec681f3Smrg      case nir_intrinsic_image_deref_atomic_imax:
12987ec681f3Smrg      case nir_intrinsic_image_deref_atomic_umax:
129901e04c3fSmrg      case nir_intrinsic_image_deref_atomic_and:
130001e04c3fSmrg      case nir_intrinsic_image_deref_atomic_or:
130101e04c3fSmrg      case nir_intrinsic_image_deref_atomic_xor:
130201e04c3fSmrg      case nir_intrinsic_image_deref_atomic_exchange:
130301e04c3fSmrg      case nir_intrinsic_image_deref_atomic_comp_swap:
130401e04c3fSmrg      case nir_intrinsic_image_deref_atomic_fadd:
130501e04c3fSmrg      case nir_intrinsic_image_deref_samples:
13067ec681f3Smrg      case nir_intrinsic_image_deref_size:
13077ec681f3Smrg      case nir_intrinsic_image_deref_atomic_inc_wrap:
13087ec681f3Smrg      case nir_intrinsic_image_deref_atomic_dec_wrap: {
130901e04c3fSmrg         /* Set the image variable dereference. */
131001e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
131101e04c3fSmrg         ir_dereference *image = (ir_dereference *)param;
13127e102996Smaya         nir_deref_instr *deref = evaluate_deref(image);
13137e102996Smaya         const glsl_type *type = deref->type;
131401e04c3fSmrg
13157ec681f3Smrg         nir_intrinsic_set_access(instr, deref_get_qualifier(deref));
13167ec681f3Smrg
13177e102996Smaya         instr->src[0] = nir_src_for_ssa(&deref->dest.ssa);
131801e04c3fSmrg         param = param->get_next();
13197ec681f3Smrg         nir_intrinsic_set_image_dim(instr,
13207ec681f3Smrg            (glsl_sampler_dim)type->sampler_dimensionality);
13217ec681f3Smrg         nir_intrinsic_set_image_array(instr, type->sampler_array);
132201e04c3fSmrg
132301e04c3fSmrg         /* Set the intrinsic destination. */
132401e04c3fSmrg         if (ir->return_deref) {
132501e04c3fSmrg            unsigned num_components = ir->return_deref->type->vector_elements;
132601e04c3fSmrg            nir_ssa_dest_init(&instr->instr, &instr->dest,
132701e04c3fSmrg                              num_components, 32, NULL);
132801e04c3fSmrg         }
132901e04c3fSmrg
133001e04c3fSmrg         if (op == nir_intrinsic_image_deref_size) {
133101e04c3fSmrg            instr->num_components = instr->dest.ssa.num_components;
13327ec681f3Smrg         } else if (op == nir_intrinsic_image_deref_load) {
13337ec681f3Smrg            instr->num_components = 4;
13347ec681f3Smrg            nir_intrinsic_set_dest_type(instr,
13357ec681f3Smrg               nir_get_nir_type_for_glsl_base_type(type->sampled_type));
13367ec681f3Smrg         } else if (op == nir_intrinsic_image_deref_store) {
133701e04c3fSmrg            instr->num_components = 4;
13387ec681f3Smrg            nir_intrinsic_set_src_type(instr,
13397ec681f3Smrg               nir_get_nir_type_for_glsl_base_type(type->sampled_type));
134001e04c3fSmrg         }
134101e04c3fSmrg
134201e04c3fSmrg         if (op == nir_intrinsic_image_deref_size ||
134301e04c3fSmrg             op == nir_intrinsic_image_deref_samples) {
13447ec681f3Smrg            /* image_deref_size takes an LOD parameter which is always 0
13457ec681f3Smrg             * coming from GLSL.
13467ec681f3Smrg             */
13477ec681f3Smrg            if (op == nir_intrinsic_image_deref_size)
13487ec681f3Smrg               instr->src[1] = nir_src_for_ssa(nir_imm_int(&b, 0));
134901e04c3fSmrg            nir_builder_instr_insert(&b, &instr->instr);
135001e04c3fSmrg            break;
135101e04c3fSmrg         }
135201e04c3fSmrg
135301e04c3fSmrg         /* Set the address argument, extending the coordinate vector to four
135401e04c3fSmrg          * components.
135501e04c3fSmrg          */
135601e04c3fSmrg         nir_ssa_def *src_addr =
135701e04c3fSmrg            evaluate_rvalue((ir_dereference *)param);
135801e04c3fSmrg         nir_ssa_def *srcs[4];
135901e04c3fSmrg
136001e04c3fSmrg         for (int i = 0; i < 4; i++) {
136101e04c3fSmrg            if (i < type->coordinate_components())
136201e04c3fSmrg               srcs[i] = nir_channel(&b, src_addr, i);
136301e04c3fSmrg            else
13647ec681f3Smrg               srcs[i] = nir_ssa_undef(&b, 1, 32);
136501e04c3fSmrg         }
136601e04c3fSmrg
136701e04c3fSmrg         instr->src[1] = nir_src_for_ssa(nir_vec(&b, srcs, 4));
136801e04c3fSmrg         param = param->get_next();
136901e04c3fSmrg
137001e04c3fSmrg         /* Set the sample argument, which is undefined for single-sample
137101e04c3fSmrg          * images.
137201e04c3fSmrg          */
137301e04c3fSmrg         if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
137401e04c3fSmrg            instr->src[2] =
137501e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
137601e04c3fSmrg            param = param->get_next();
137701e04c3fSmrg         } else {
13787ec681f3Smrg            instr->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
137901e04c3fSmrg         }
138001e04c3fSmrg
138101e04c3fSmrg         /* Set the intrinsic parameters. */
138201e04c3fSmrg         if (!param->is_tail_sentinel()) {
138301e04c3fSmrg            instr->src[3] =
138401e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
138501e04c3fSmrg            param = param->get_next();
13867ec681f3Smrg         } else if (op == nir_intrinsic_image_deref_load) {
13877ec681f3Smrg            instr->src[3] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */
138801e04c3fSmrg         }
138901e04c3fSmrg
139001e04c3fSmrg         if (!param->is_tail_sentinel()) {
139101e04c3fSmrg            instr->src[4] =
139201e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
139301e04c3fSmrg            param = param->get_next();
13947ec681f3Smrg         } else if (op == nir_intrinsic_image_deref_store) {
13957ec681f3Smrg            instr->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */
139601e04c3fSmrg         }
13977ec681f3Smrg
139801e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
139901e04c3fSmrg         break;
140001e04c3fSmrg      }
140101e04c3fSmrg      case nir_intrinsic_memory_barrier:
140201e04c3fSmrg      case nir_intrinsic_group_memory_barrier:
140301e04c3fSmrg      case nir_intrinsic_memory_barrier_atomic_counter:
140401e04c3fSmrg      case nir_intrinsic_memory_barrier_buffer:
140501e04c3fSmrg      case nir_intrinsic_memory_barrier_image:
140601e04c3fSmrg      case nir_intrinsic_memory_barrier_shared:
140701e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
140801e04c3fSmrg         break;
140901e04c3fSmrg      case nir_intrinsic_shader_clock:
141001e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest, 2, 32, NULL);
14117ec681f3Smrg         nir_intrinsic_set_memory_scope(instr, NIR_SCOPE_SUBGROUP);
141201e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
141301e04c3fSmrg         break;
141401e04c3fSmrg      case nir_intrinsic_begin_invocation_interlock:
141501e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
141601e04c3fSmrg         break;
141701e04c3fSmrg      case nir_intrinsic_end_invocation_interlock:
141801e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
141901e04c3fSmrg         break;
142001e04c3fSmrg      case nir_intrinsic_store_ssbo: {
142101e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
142201e04c3fSmrg         ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();
142301e04c3fSmrg
142401e04c3fSmrg         param = param->get_next();
142501e04c3fSmrg         ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
142601e04c3fSmrg
142701e04c3fSmrg         param = param->get_next();
142801e04c3fSmrg         ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
142901e04c3fSmrg
143001e04c3fSmrg         param = param->get_next();
143101e04c3fSmrg         ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
143201e04c3fSmrg         assert(write_mask);
143301e04c3fSmrg
14347e102996Smaya         nir_ssa_def *nir_val = evaluate_rvalue(val);
14357e102996Smaya         if (val->type->is_boolean())
14367e102996Smaya            nir_val = nir_b2i32(&b, nir_val);
14377e102996Smaya
14387e102996Smaya         instr->src[0] = nir_src_for_ssa(nir_val);
143901e04c3fSmrg         instr->src[1] = nir_src_for_ssa(evaluate_rvalue(block));
144001e04c3fSmrg         instr->src[2] = nir_src_for_ssa(evaluate_rvalue(offset));
14417e102996Smaya         intrinsic_set_std430_align(instr, val->type);
144201e04c3fSmrg         nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]);
144301e04c3fSmrg         instr->num_components = val->type->vector_elements;
144401e04c3fSmrg
144501e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
144601e04c3fSmrg         break;
144701e04c3fSmrg      }
144801e04c3fSmrg      case nir_intrinsic_load_shared: {
144901e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
145001e04c3fSmrg         ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
145101e04c3fSmrg
145201e04c3fSmrg         nir_intrinsic_set_base(instr, 0);
145301e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(offset));
145401e04c3fSmrg
145501e04c3fSmrg         const glsl_type *type = ir->return_deref->var->type;
145601e04c3fSmrg         instr->num_components = type->vector_elements;
14577e102996Smaya         intrinsic_set_std430_align(instr, type);
145801e04c3fSmrg
145901e04c3fSmrg         /* Setup destination register */
14607e102996Smaya         unsigned bit_size = type->is_boolean() ? 32 : glsl_get_bit_size(type);
146101e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest,
146201e04c3fSmrg                           type->vector_elements, bit_size, NULL);
146301e04c3fSmrg
146401e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
14657e102996Smaya
14667e102996Smaya         /* The value in shared memory is a 32-bit value */
14677e102996Smaya         if (type->is_boolean())
14687ec681f3Smrg            ret = nir_b2b1(&b, &instr->dest.ssa);
146901e04c3fSmrg         break;
147001e04c3fSmrg      }
147101e04c3fSmrg      case nir_intrinsic_store_shared: {
147201e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
147301e04c3fSmrg         ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
147401e04c3fSmrg
147501e04c3fSmrg         param = param->get_next();
147601e04c3fSmrg         ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
147701e04c3fSmrg
147801e04c3fSmrg         param = param->get_next();
147901e04c3fSmrg         ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
148001e04c3fSmrg         assert(write_mask);
148101e04c3fSmrg
148201e04c3fSmrg         nir_intrinsic_set_base(instr, 0);
148301e04c3fSmrg         instr->src[1] = nir_src_for_ssa(evaluate_rvalue(offset));
148401e04c3fSmrg
148501e04c3fSmrg         nir_intrinsic_set_write_mask(instr, write_mask->value.u[0]);
148601e04c3fSmrg
14877e102996Smaya         nir_ssa_def *nir_val = evaluate_rvalue(val);
14887e102996Smaya         /* The value in shared memory is a 32-bit value */
14897e102996Smaya         if (val->type->is_boolean())
14907ec681f3Smrg            nir_val = nir_b2b32(&b, nir_val);
14917e102996Smaya
14927e102996Smaya         instr->src[0] = nir_src_for_ssa(nir_val);
149301e04c3fSmrg         instr->num_components = val->type->vector_elements;
14947e102996Smaya         intrinsic_set_std430_align(instr, val->type);
149501e04c3fSmrg
149601e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
149701e04c3fSmrg         break;
149801e04c3fSmrg      }
149901e04c3fSmrg      case nir_intrinsic_shared_atomic_add:
150001e04c3fSmrg      case nir_intrinsic_shared_atomic_imin:
150101e04c3fSmrg      case nir_intrinsic_shared_atomic_umin:
150201e04c3fSmrg      case nir_intrinsic_shared_atomic_imax:
150301e04c3fSmrg      case nir_intrinsic_shared_atomic_umax:
150401e04c3fSmrg      case nir_intrinsic_shared_atomic_and:
150501e04c3fSmrg      case nir_intrinsic_shared_atomic_or:
150601e04c3fSmrg      case nir_intrinsic_shared_atomic_xor:
150701e04c3fSmrg      case nir_intrinsic_shared_atomic_exchange:
150801e04c3fSmrg      case nir_intrinsic_shared_atomic_comp_swap:
150901e04c3fSmrg      case nir_intrinsic_shared_atomic_fadd:
151001e04c3fSmrg      case nir_intrinsic_shared_atomic_fmin:
151101e04c3fSmrg      case nir_intrinsic_shared_atomic_fmax:
151201e04c3fSmrg      case nir_intrinsic_shared_atomic_fcomp_swap:  {
151301e04c3fSmrg         int param_count = ir->actual_parameters.length();
151401e04c3fSmrg         assert(param_count == 2 || param_count == 3);
151501e04c3fSmrg
151601e04c3fSmrg         /* Offset */
151701e04c3fSmrg         exec_node *param = ir->actual_parameters.get_head();
151801e04c3fSmrg         ir_instruction *inst = (ir_instruction *) param;
151901e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
152001e04c3fSmrg
152101e04c3fSmrg         /* data1 parameter (this is always present) */
152201e04c3fSmrg         param = param->get_next();
152301e04c3fSmrg         inst = (ir_instruction *) param;
152401e04c3fSmrg         instr->src[1] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
152501e04c3fSmrg
152601e04c3fSmrg         /* data2 parameter (only with atomic_comp_swap) */
152701e04c3fSmrg         if (param_count == 3) {
152801e04c3fSmrg            assert(op == nir_intrinsic_shared_atomic_comp_swap ||
152901e04c3fSmrg                   op == nir_intrinsic_shared_atomic_fcomp_swap);
153001e04c3fSmrg            param = param->get_next();
153101e04c3fSmrg            inst = (ir_instruction *) param;
153201e04c3fSmrg            instr->src[2] =
153301e04c3fSmrg               nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
153401e04c3fSmrg         }
153501e04c3fSmrg
153601e04c3fSmrg         /* Atomic result */
153701e04c3fSmrg         assert(ir->return_deref);
153801e04c3fSmrg         unsigned bit_size = glsl_get_bit_size(ir->return_deref->type);
153901e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest,
154001e04c3fSmrg                           ir->return_deref->type->vector_elements,
154101e04c3fSmrg                           bit_size, NULL);
154201e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
154301e04c3fSmrg         break;
154401e04c3fSmrg      }
15457ec681f3Smrg      case nir_intrinsic_vote_ieq:
15467ec681f3Smrg         instr->num_components = 1;
15477ec681f3Smrg         FALLTHROUGH;
154801e04c3fSmrg      case nir_intrinsic_vote_any:
15497ec681f3Smrg      case nir_intrinsic_vote_all: {
15507e102996Smaya         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL);
155101e04c3fSmrg
155201e04c3fSmrg         ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
155301e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
155401e04c3fSmrg
155501e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
155601e04c3fSmrg         break;
155701e04c3fSmrg      }
155801e04c3fSmrg
155901e04c3fSmrg      case nir_intrinsic_ballot: {
156001e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest,
156101e04c3fSmrg                           ir->return_deref->type->vector_elements, 64, NULL);
156201e04c3fSmrg         instr->num_components = ir->return_deref->type->vector_elements;
156301e04c3fSmrg
156401e04c3fSmrg         ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
156501e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
156601e04c3fSmrg
156701e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
156801e04c3fSmrg         break;
156901e04c3fSmrg      }
157001e04c3fSmrg      case nir_intrinsic_read_invocation: {
157101e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest,
157201e04c3fSmrg                           ir->return_deref->type->vector_elements, 32, NULL);
157301e04c3fSmrg         instr->num_components = ir->return_deref->type->vector_elements;
157401e04c3fSmrg
157501e04c3fSmrg         ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
157601e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
157701e04c3fSmrg
157801e04c3fSmrg         ir_rvalue *invocation = (ir_rvalue *) ir->actual_parameters.get_head()->next;
157901e04c3fSmrg         instr->src[1] = nir_src_for_ssa(evaluate_rvalue(invocation));
158001e04c3fSmrg
158101e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
158201e04c3fSmrg         break;
158301e04c3fSmrg      }
158401e04c3fSmrg      case nir_intrinsic_read_first_invocation: {
158501e04c3fSmrg         nir_ssa_dest_init(&instr->instr, &instr->dest,
158601e04c3fSmrg                           ir->return_deref->type->vector_elements, 32, NULL);
158701e04c3fSmrg         instr->num_components = ir->return_deref->type->vector_elements;
158801e04c3fSmrg
158901e04c3fSmrg         ir_rvalue *value = (ir_rvalue *) ir->actual_parameters.get_head();
159001e04c3fSmrg         instr->src[0] = nir_src_for_ssa(evaluate_rvalue(value));
159101e04c3fSmrg
159201e04c3fSmrg         nir_builder_instr_insert(&b, &instr->instr);
159301e04c3fSmrg         break;
159401e04c3fSmrg      }
15957ec681f3Smrg      case nir_intrinsic_is_helper_invocation: {
15967ec681f3Smrg         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 1, NULL);
15977ec681f3Smrg         nir_builder_instr_insert(&b, &instr->instr);
15987ec681f3Smrg         break;
15997ec681f3Smrg      }
160001e04c3fSmrg      default:
160101e04c3fSmrg         unreachable("not reached");
160201e04c3fSmrg      }
160301e04c3fSmrg
160401e04c3fSmrg      if (ir->return_deref)
160501e04c3fSmrg         nir_store_deref(&b, evaluate_deref(ir->return_deref), ret, ~0);
160601e04c3fSmrg
160701e04c3fSmrg      return;
160801e04c3fSmrg   }
160901e04c3fSmrg
16107e102996Smaya   struct hash_entry *entry =
16117e102996Smaya      _mesa_hash_table_search(this->overload_table, ir->callee);
16127e102996Smaya   assert(entry);
16137e102996Smaya   nir_function *callee = (nir_function *) entry->data;
16147e102996Smaya
16157e102996Smaya   nir_call_instr *call = nir_call_instr_create(this->shader, callee);
16167e102996Smaya
16177e102996Smaya   unsigned i = 0;
16187e102996Smaya   nir_deref_instr *ret_deref = NULL;
16197e102996Smaya   if (ir->return_deref) {
16207e102996Smaya      nir_variable *ret_tmp =
16217e102996Smaya         nir_local_variable_create(this->impl, ir->return_deref->type,
16227e102996Smaya                                   "return_tmp");
16237e102996Smaya      ret_deref = nir_build_deref_var(&b, ret_tmp);
16247e102996Smaya      call->params[i++] = nir_src_for_ssa(&ret_deref->dest.ssa);
16257e102996Smaya   }
16267e102996Smaya
16277e102996Smaya   foreach_two_lists(formal_node, &ir->callee->parameters,
16287e102996Smaya                     actual_node, &ir->actual_parameters) {
16297e102996Smaya      ir_rvalue *param_rvalue = (ir_rvalue *) actual_node;
16307e102996Smaya      ir_variable *sig_param = (ir_variable *) formal_node;
16317e102996Smaya
16327e102996Smaya      if (sig_param->data.mode == ir_var_function_out) {
16337e102996Smaya         nir_deref_instr *out_deref = evaluate_deref(param_rvalue);
16347e102996Smaya         call->params[i] = nir_src_for_ssa(&out_deref->dest.ssa);
16357e102996Smaya      } else if (sig_param->data.mode == ir_var_function_in) {
16367e102996Smaya         nir_ssa_def *val = evaluate_rvalue(param_rvalue);
16377e102996Smaya         nir_src src = nir_src_for_ssa(val);
16387e102996Smaya
16397ec681f3Smrg         nir_src_copy(&call->params[i], &src);
16407e102996Smaya      } else if (sig_param->data.mode == ir_var_function_inout) {
16417e102996Smaya         unreachable("unimplemented: inout parameters");
16427e102996Smaya      }
16437e102996Smaya
16447e102996Smaya      i++;
16457e102996Smaya   }
16467e102996Smaya
16477e102996Smaya   nir_builder_instr_insert(&b, &call->instr);
16487e102996Smaya
16497e102996Smaya   if (ir->return_deref)
16507e102996Smaya      nir_store_deref(&b, evaluate_deref(ir->return_deref), nir_load_deref(&b, ret_deref), ~0);
165101e04c3fSmrg}
165201e04c3fSmrg
165301e04c3fSmrgvoid
165401e04c3fSmrgnir_visitor::visit(ir_assignment *ir)
165501e04c3fSmrg{
165601e04c3fSmrg   unsigned num_components = ir->lhs->type->vector_elements;
165701e04c3fSmrg
165801e04c3fSmrg   b.exact = ir->lhs->variable_referenced()->data.invariant ||
165901e04c3fSmrg             ir->lhs->variable_referenced()->data.precise;
166001e04c3fSmrg
166101e04c3fSmrg   if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) &&
166201e04c3fSmrg       (ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) {
16637ec681f3Smrg      nir_deref_instr *lhs = evaluate_deref(ir->lhs);
16647ec681f3Smrg      nir_deref_instr *rhs = evaluate_deref(ir->rhs);
16657ec681f3Smrg      enum gl_access_qualifier lhs_qualifiers = deref_get_qualifier(lhs);
16667ec681f3Smrg      enum gl_access_qualifier rhs_qualifiers = deref_get_qualifier(rhs);
166701e04c3fSmrg      if (ir->condition) {
166801e04c3fSmrg         nir_push_if(&b, evaluate_rvalue(ir->condition));
16697ec681f3Smrg         nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers,
16707ec681f3Smrg                                    rhs_qualifiers);
167101e04c3fSmrg         nir_pop_if(&b, NULL);
167201e04c3fSmrg      } else {
16737ec681f3Smrg         nir_copy_deref_with_access(&b, lhs, rhs, lhs_qualifiers,
16747ec681f3Smrg                                    rhs_qualifiers);
167501e04c3fSmrg      }
167601e04c3fSmrg      return;
167701e04c3fSmrg   }
167801e04c3fSmrg
167901e04c3fSmrg   assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector());
168001e04c3fSmrg
168101e04c3fSmrg   ir->lhs->accept(this);
168201e04c3fSmrg   nir_deref_instr *lhs_deref = this->deref;
168301e04c3fSmrg   nir_ssa_def *src = evaluate_rvalue(ir->rhs);
168401e04c3fSmrg
168501e04c3fSmrg   if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) {
168601e04c3fSmrg      /* GLSL IR will give us the input to the write-masked assignment in a
168701e04c3fSmrg       * single packed vector.  So, for example, if the writemask is xzw, then
168801e04c3fSmrg       * we have to swizzle x -> x, y -> z, and z -> w and get the y component
168901e04c3fSmrg       * from the load.
169001e04c3fSmrg       */
169101e04c3fSmrg      unsigned swiz[4];
169201e04c3fSmrg      unsigned component = 0;
169301e04c3fSmrg      for (unsigned i = 0; i < 4; i++) {
169401e04c3fSmrg         swiz[i] = ir->write_mask & (1 << i) ? component++ : 0;
169501e04c3fSmrg      }
16967ec681f3Smrg      src = nir_swizzle(&b, src, swiz, num_components);
169701e04c3fSmrg   }
169801e04c3fSmrg
16997ec681f3Smrg   enum gl_access_qualifier qualifiers = deref_get_qualifier(lhs_deref);
170001e04c3fSmrg   if (ir->condition) {
170101e04c3fSmrg      nir_push_if(&b, evaluate_rvalue(ir->condition));
17027ec681f3Smrg      nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask,
17037ec681f3Smrg                                  qualifiers);
170401e04c3fSmrg      nir_pop_if(&b, NULL);
170501e04c3fSmrg   } else {
17067ec681f3Smrg      nir_store_deref_with_access(&b, lhs_deref, src, ir->write_mask,
17077ec681f3Smrg                                  qualifiers);
170801e04c3fSmrg   }
170901e04c3fSmrg}
171001e04c3fSmrg
171101e04c3fSmrg/*
171201e04c3fSmrg * Given an instruction, returns a pointer to its destination or NULL if there
171301e04c3fSmrg * is no destination.
171401e04c3fSmrg *
171501e04c3fSmrg * Note that this only handles instructions we generate at this level.
171601e04c3fSmrg */
171701e04c3fSmrgstatic nir_dest *
171801e04c3fSmrgget_instr_dest(nir_instr *instr)
171901e04c3fSmrg{
172001e04c3fSmrg   nir_alu_instr *alu_instr;
172101e04c3fSmrg   nir_intrinsic_instr *intrinsic_instr;
172201e04c3fSmrg   nir_tex_instr *tex_instr;
172301e04c3fSmrg
172401e04c3fSmrg   switch (instr->type) {
172501e04c3fSmrg      case nir_instr_type_alu:
172601e04c3fSmrg         alu_instr = nir_instr_as_alu(instr);
172701e04c3fSmrg         return &alu_instr->dest.dest;
172801e04c3fSmrg
172901e04c3fSmrg      case nir_instr_type_intrinsic:
173001e04c3fSmrg         intrinsic_instr = nir_instr_as_intrinsic(instr);
173101e04c3fSmrg         if (nir_intrinsic_infos[intrinsic_instr->intrinsic].has_dest)
173201e04c3fSmrg            return &intrinsic_instr->dest;
173301e04c3fSmrg         else
173401e04c3fSmrg            return NULL;
173501e04c3fSmrg
173601e04c3fSmrg      case nir_instr_type_tex:
173701e04c3fSmrg         tex_instr = nir_instr_as_tex(instr);
173801e04c3fSmrg         return &tex_instr->dest;
173901e04c3fSmrg
174001e04c3fSmrg      default:
174101e04c3fSmrg         unreachable("not reached");
174201e04c3fSmrg   }
174301e04c3fSmrg
174401e04c3fSmrg   return NULL;
174501e04c3fSmrg}
174601e04c3fSmrg
174701e04c3fSmrgvoid
174801e04c3fSmrgnir_visitor::add_instr(nir_instr *instr, unsigned num_components,
174901e04c3fSmrg                       unsigned bit_size)
175001e04c3fSmrg{
175101e04c3fSmrg   nir_dest *dest = get_instr_dest(instr);
175201e04c3fSmrg
175301e04c3fSmrg   if (dest)
175401e04c3fSmrg      nir_ssa_dest_init(instr, dest, num_components, bit_size, NULL);
175501e04c3fSmrg
175601e04c3fSmrg   nir_builder_instr_insert(&b, instr);
175701e04c3fSmrg
175801e04c3fSmrg   if (dest) {
175901e04c3fSmrg      assert(dest->is_ssa);
176001e04c3fSmrg      this->result = &dest->ssa;
176101e04c3fSmrg   }
176201e04c3fSmrg}
176301e04c3fSmrg
176401e04c3fSmrgnir_ssa_def *
176501e04c3fSmrgnir_visitor::evaluate_rvalue(ir_rvalue* ir)
176601e04c3fSmrg{
176701e04c3fSmrg   ir->accept(this);
176801e04c3fSmrg   if (ir->as_dereference() || ir->as_constant()) {
176901e04c3fSmrg      /*
177001e04c3fSmrg       * A dereference is being used on the right hand side, which means we
177101e04c3fSmrg       * must emit a variable load.
177201e04c3fSmrg       */
177301e04c3fSmrg
17747ec681f3Smrg      enum gl_access_qualifier access = deref_get_qualifier(this->deref);
17757ec681f3Smrg      this->result = nir_load_deref_with_access(&b, this->deref, access);
177601e04c3fSmrg   }
177701e04c3fSmrg
177801e04c3fSmrg   return this->result;
177901e04c3fSmrg}
178001e04c3fSmrg
178101e04c3fSmrgstatic bool
178201e04c3fSmrgtype_is_float(glsl_base_type type)
178301e04c3fSmrg{
178401e04c3fSmrg   return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE ||
178501e04c3fSmrg      type == GLSL_TYPE_FLOAT16;
178601e04c3fSmrg}
178701e04c3fSmrg
178801e04c3fSmrgstatic bool
178901e04c3fSmrgtype_is_signed(glsl_base_type type)
179001e04c3fSmrg{
179101e04c3fSmrg   return type == GLSL_TYPE_INT || type == GLSL_TYPE_INT64 ||
179201e04c3fSmrg      type == GLSL_TYPE_INT16;
179301e04c3fSmrg}
179401e04c3fSmrg
179501e04c3fSmrgvoid
179601e04c3fSmrgnir_visitor::visit(ir_expression *ir)
179701e04c3fSmrg{
179801e04c3fSmrg   /* Some special cases */
179901e04c3fSmrg   switch (ir->operation) {
180001e04c3fSmrg   case ir_unop_interpolate_at_centroid:
180101e04c3fSmrg   case ir_binop_interpolate_at_offset:
180201e04c3fSmrg   case ir_binop_interpolate_at_sample: {
180301e04c3fSmrg      ir_dereference *deref = ir->operands[0]->as_dereference();
180401e04c3fSmrg      ir_swizzle *swizzle = NULL;
180501e04c3fSmrg      if (!deref) {
180601e04c3fSmrg         /* the api does not allow a swizzle here, but the varying packing code
180701e04c3fSmrg          * may have pushed one into here.
180801e04c3fSmrg          */
180901e04c3fSmrg         swizzle = ir->operands[0]->as_swizzle();
181001e04c3fSmrg         assert(swizzle);
181101e04c3fSmrg         deref = swizzle->val->as_dereference();
181201e04c3fSmrg         assert(deref);
181301e04c3fSmrg      }
181401e04c3fSmrg
181501e04c3fSmrg      deref->accept(this);
181601e04c3fSmrg
181701e04c3fSmrg      nir_intrinsic_op op;
18187ec681f3Smrg      if (nir_deref_mode_is(this->deref, nir_var_shader_in)) {
181901e04c3fSmrg         switch (ir->operation) {
182001e04c3fSmrg         case ir_unop_interpolate_at_centroid:
182101e04c3fSmrg            op = nir_intrinsic_interp_deref_at_centroid;
182201e04c3fSmrg            break;
182301e04c3fSmrg         case ir_binop_interpolate_at_offset:
182401e04c3fSmrg            op = nir_intrinsic_interp_deref_at_offset;
182501e04c3fSmrg            break;
182601e04c3fSmrg         case ir_binop_interpolate_at_sample:
182701e04c3fSmrg            op = nir_intrinsic_interp_deref_at_sample;
182801e04c3fSmrg            break;
182901e04c3fSmrg         default:
183001e04c3fSmrg            unreachable("Invalid interpolation intrinsic");
183101e04c3fSmrg         }
183201e04c3fSmrg      } else {
183301e04c3fSmrg         /* This case can happen if the vertex shader does not write the
183401e04c3fSmrg          * given varying.  In this case, the linker will lower it to a
183501e04c3fSmrg          * global variable.  Since interpolating a variable makes no
183601e04c3fSmrg          * sense, we'll just turn it into a load which will probably
183701e04c3fSmrg          * eventually end up as an SSA definition.
183801e04c3fSmrg          */
18397ec681f3Smrg         assert(nir_deref_mode_is(this->deref, nir_var_shader_temp));
184001e04c3fSmrg         op = nir_intrinsic_load_deref;
184101e04c3fSmrg      }
184201e04c3fSmrg
184301e04c3fSmrg      nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(shader, op);
184401e04c3fSmrg      intrin->num_components = deref->type->vector_elements;
184501e04c3fSmrg      intrin->src[0] = nir_src_for_ssa(&this->deref->dest.ssa);
184601e04c3fSmrg
184701e04c3fSmrg      if (intrin->intrinsic == nir_intrinsic_interp_deref_at_offset ||
184801e04c3fSmrg          intrin->intrinsic == nir_intrinsic_interp_deref_at_sample)
184901e04c3fSmrg         intrin->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1]));
185001e04c3fSmrg
185101e04c3fSmrg      unsigned bit_size =  glsl_get_bit_size(deref->type);
185201e04c3fSmrg      add_instr(&intrin->instr, deref->type->vector_elements, bit_size);
185301e04c3fSmrg
185401e04c3fSmrg      if (swizzle) {
185501e04c3fSmrg         unsigned swiz[4] = {
185601e04c3fSmrg            swizzle->mask.x, swizzle->mask.y, swizzle->mask.z, swizzle->mask.w
185701e04c3fSmrg         };
185801e04c3fSmrg
185901e04c3fSmrg         result = nir_swizzle(&b, result, swiz,
18607ec681f3Smrg                              swizzle->type->vector_elements);
186101e04c3fSmrg      }
186201e04c3fSmrg
186301e04c3fSmrg      return;
186401e04c3fSmrg   }
186501e04c3fSmrg
18667e102996Smaya   case ir_unop_ssbo_unsized_array_length: {
18677e102996Smaya      nir_intrinsic_instr *intrin =
18687e102996Smaya         nir_intrinsic_instr_create(b.shader,
18697e102996Smaya                                    nir_intrinsic_deref_buffer_array_length);
18707e102996Smaya
18717e102996Smaya      ir_dereference *deref = ir->operands[0]->as_dereference();
18727e102996Smaya      intrin->src[0] = nir_src_for_ssa(&evaluate_deref(deref)->dest.ssa);
18737e102996Smaya
18747e102996Smaya      add_instr(&intrin->instr, 1, 32);
18757e102996Smaya      return;
18767e102996Smaya   }
18777e102996Smaya
18787ec681f3Smrg   case ir_binop_ubo_load:
18797ec681f3Smrg      /* UBO loads should only have been lowered in GLSL IR for non-nir drivers,
18807ec681f3Smrg       * NIR drivers make use of gl_nir_lower_buffers() instead.
18817ec681f3Smrg       */
18827ec681f3Smrg      unreachable("Invalid operation nir doesn't want lowered ubo loads");
188301e04c3fSmrg   default:
188401e04c3fSmrg      break;
188501e04c3fSmrg   }
188601e04c3fSmrg
188701e04c3fSmrg   nir_ssa_def *srcs[4];
188801e04c3fSmrg   for (unsigned i = 0; i < ir->num_operands; i++)
188901e04c3fSmrg      srcs[i] = evaluate_rvalue(ir->operands[i]);
189001e04c3fSmrg
189101e04c3fSmrg   glsl_base_type types[4];
189201e04c3fSmrg   for (unsigned i = 0; i < ir->num_operands; i++)
18937ec681f3Smrg      types[i] = ir->operands[i]->type->base_type;
189401e04c3fSmrg
18957ec681f3Smrg   glsl_base_type out_type = ir->type->base_type;
189601e04c3fSmrg
189701e04c3fSmrg   switch (ir->operation) {
189801e04c3fSmrg   case ir_unop_bit_not: result = nir_inot(&b, srcs[0]); break;
189901e04c3fSmrg   case ir_unop_logic_not:
19007e102996Smaya      result = nir_inot(&b, srcs[0]);
190101e04c3fSmrg      break;
190201e04c3fSmrg   case ir_unop_neg:
190301e04c3fSmrg      result = type_is_float(types[0]) ? nir_fneg(&b, srcs[0])
190401e04c3fSmrg                                       : nir_ineg(&b, srcs[0]);
190501e04c3fSmrg      break;
190601e04c3fSmrg   case ir_unop_abs:
190701e04c3fSmrg      result = type_is_float(types[0]) ? nir_fabs(&b, srcs[0])
190801e04c3fSmrg                                       : nir_iabs(&b, srcs[0]);
190901e04c3fSmrg      break;
19107ec681f3Smrg   case ir_unop_clz:
19117ec681f3Smrg      result = nir_uclz(&b, srcs[0]);
19127ec681f3Smrg      break;
191301e04c3fSmrg   case ir_unop_saturate:
191401e04c3fSmrg      assert(type_is_float(types[0]));
191501e04c3fSmrg      result = nir_fsat(&b, srcs[0]);
191601e04c3fSmrg      break;
191701e04c3fSmrg   case ir_unop_sign:
191801e04c3fSmrg      result = type_is_float(types[0]) ? nir_fsign(&b, srcs[0])
191901e04c3fSmrg                                       : nir_isign(&b, srcs[0]);
192001e04c3fSmrg      break;
192101e04c3fSmrg   case ir_unop_rcp:  result = nir_frcp(&b, srcs[0]);  break;
192201e04c3fSmrg   case ir_unop_rsq:  result = nir_frsq(&b, srcs[0]);  break;
192301e04c3fSmrg   case ir_unop_sqrt: result = nir_fsqrt(&b, srcs[0]); break;
192401e04c3fSmrg   case ir_unop_exp:  unreachable("ir_unop_exp should have been lowered");
192501e04c3fSmrg   case ir_unop_log:  unreachable("ir_unop_log should have been lowered");
192601e04c3fSmrg   case ir_unop_exp2: result = nir_fexp2(&b, srcs[0]); break;
192701e04c3fSmrg   case ir_unop_log2: result = nir_flog2(&b, srcs[0]); break;
192801e04c3fSmrg   case ir_unop_i2f:
192901e04c3fSmrg   case ir_unop_u2f:
193001e04c3fSmrg   case ir_unop_b2f:
193101e04c3fSmrg   case ir_unop_f2i:
193201e04c3fSmrg   case ir_unop_f2u:
193301e04c3fSmrg   case ir_unop_f2b:
193401e04c3fSmrg   case ir_unop_i2b:
193501e04c3fSmrg   case ir_unop_b2i:
193601e04c3fSmrg   case ir_unop_b2i64:
193701e04c3fSmrg   case ir_unop_d2f:
193801e04c3fSmrg   case ir_unop_f2d:
19397ec681f3Smrg   case ir_unop_f162f:
19407ec681f3Smrg   case ir_unop_f2f16:
19417ec681f3Smrg   case ir_unop_f162b:
19427ec681f3Smrg   case ir_unop_b2f16:
19437ec681f3Smrg   case ir_unop_i2i:
19447ec681f3Smrg   case ir_unop_u2u:
194501e04c3fSmrg   case ir_unop_d2i:
194601e04c3fSmrg   case ir_unop_d2u:
194701e04c3fSmrg   case ir_unop_d2b:
194801e04c3fSmrg   case ir_unop_i2d:
194901e04c3fSmrg   case ir_unop_u2d:
195001e04c3fSmrg   case ir_unop_i642i:
195101e04c3fSmrg   case ir_unop_i642u:
195201e04c3fSmrg   case ir_unop_i642f:
195301e04c3fSmrg   case ir_unop_i642b:
195401e04c3fSmrg   case ir_unop_i642d:
195501e04c3fSmrg   case ir_unop_u642i:
195601e04c3fSmrg   case ir_unop_u642u:
195701e04c3fSmrg   case ir_unop_u642f:
195801e04c3fSmrg   case ir_unop_u642d:
195901e04c3fSmrg   case ir_unop_i2i64:
196001e04c3fSmrg   case ir_unop_u2i64:
196101e04c3fSmrg   case ir_unop_f2i64:
196201e04c3fSmrg   case ir_unop_d2i64:
196301e04c3fSmrg   case ir_unop_i2u64:
196401e04c3fSmrg   case ir_unop_u2u64:
196501e04c3fSmrg   case ir_unop_f2u64:
196601e04c3fSmrg   case ir_unop_d2u64:
196701e04c3fSmrg   case ir_unop_i2u:
196801e04c3fSmrg   case ir_unop_u2i:
196901e04c3fSmrg   case ir_unop_i642u64:
197001e04c3fSmrg   case ir_unop_u642i64: {
197101e04c3fSmrg      nir_alu_type src_type = nir_get_nir_type_for_glsl_base_type(types[0]);
197201e04c3fSmrg      nir_alu_type dst_type = nir_get_nir_type_for_glsl_base_type(out_type);
197301e04c3fSmrg      result = nir_build_alu(&b, nir_type_conversion_op(src_type, dst_type,
197401e04c3fSmrg                                 nir_rounding_mode_undef),
197501e04c3fSmrg                                 srcs[0], NULL, NULL, NULL);
197601e04c3fSmrg      /* b2i and b2f don't have fixed bit-size versions so the builder will
197701e04c3fSmrg       * just assume 32 and we have to fix it up here.
197801e04c3fSmrg       */
197901e04c3fSmrg      result->bit_size = nir_alu_type_get_type_size(dst_type);
198001e04c3fSmrg      break;
198101e04c3fSmrg   }
198201e04c3fSmrg
19837ec681f3Smrg   case ir_unop_f2fmp: {
19847ec681f3Smrg      result = nir_build_alu(&b, nir_op_f2fmp, srcs[0], NULL, NULL, NULL);
19857ec681f3Smrg      break;
19867ec681f3Smrg   }
19877ec681f3Smrg
19887ec681f3Smrg   case ir_unop_i2imp: {
19897ec681f3Smrg      result = nir_build_alu(&b, nir_op_i2imp, srcs[0], NULL, NULL, NULL);
19907ec681f3Smrg      break;
19917ec681f3Smrg   }
19927ec681f3Smrg
19937ec681f3Smrg   case ir_unop_u2ump: {
19947ec681f3Smrg      result = nir_build_alu(&b, nir_op_i2imp, srcs[0], NULL, NULL, NULL);
19957ec681f3Smrg      break;
19967ec681f3Smrg   }
19977ec681f3Smrg
199801e04c3fSmrg   case ir_unop_bitcast_i2f:
199901e04c3fSmrg   case ir_unop_bitcast_f2i:
200001e04c3fSmrg   case ir_unop_bitcast_u2f:
200101e04c3fSmrg   case ir_unop_bitcast_f2u:
200201e04c3fSmrg   case ir_unop_bitcast_i642d:
200301e04c3fSmrg   case ir_unop_bitcast_d2i64:
200401e04c3fSmrg   case ir_unop_bitcast_u642d:
200501e04c3fSmrg   case ir_unop_bitcast_d2u64:
200601e04c3fSmrg   case ir_unop_subroutine_to_int:
200701e04c3fSmrg      /* no-op */
20087ec681f3Smrg      result = nir_mov(&b, srcs[0]);
200901e04c3fSmrg      break;
201001e04c3fSmrg   case ir_unop_trunc: result = nir_ftrunc(&b, srcs[0]); break;
201101e04c3fSmrg   case ir_unop_ceil:  result = nir_fceil(&b, srcs[0]); break;
201201e04c3fSmrg   case ir_unop_floor: result = nir_ffloor(&b, srcs[0]); break;
201301e04c3fSmrg   case ir_unop_fract: result = nir_ffract(&b, srcs[0]); break;
201401e04c3fSmrg   case ir_unop_frexp_exp: result = nir_frexp_exp(&b, srcs[0]); break;
201501e04c3fSmrg   case ir_unop_frexp_sig: result = nir_frexp_sig(&b, srcs[0]); break;
201601e04c3fSmrg   case ir_unop_round_even: result = nir_fround_even(&b, srcs[0]); break;
201701e04c3fSmrg   case ir_unop_sin:   result = nir_fsin(&b, srcs[0]); break;
201801e04c3fSmrg   case ir_unop_cos:   result = nir_fcos(&b, srcs[0]); break;
201901e04c3fSmrg   case ir_unop_dFdx:        result = nir_fddx(&b, srcs[0]); break;
202001e04c3fSmrg   case ir_unop_dFdy:        result = nir_fddy(&b, srcs[0]); break;
202101e04c3fSmrg   case ir_unop_dFdx_fine:   result = nir_fddx_fine(&b, srcs[0]); break;
202201e04c3fSmrg   case ir_unop_dFdy_fine:   result = nir_fddy_fine(&b, srcs[0]); break;
202301e04c3fSmrg   case ir_unop_dFdx_coarse: result = nir_fddx_coarse(&b, srcs[0]); break;
202401e04c3fSmrg   case ir_unop_dFdy_coarse: result = nir_fddy_coarse(&b, srcs[0]); break;
202501e04c3fSmrg   case ir_unop_pack_snorm_2x16:
202601e04c3fSmrg      result = nir_pack_snorm_2x16(&b, srcs[0]);
202701e04c3fSmrg      break;
202801e04c3fSmrg   case ir_unop_pack_snorm_4x8:
202901e04c3fSmrg      result = nir_pack_snorm_4x8(&b, srcs[0]);
203001e04c3fSmrg      break;
203101e04c3fSmrg   case ir_unop_pack_unorm_2x16:
203201e04c3fSmrg      result = nir_pack_unorm_2x16(&b, srcs[0]);
203301e04c3fSmrg      break;
203401e04c3fSmrg   case ir_unop_pack_unorm_4x8:
203501e04c3fSmrg      result = nir_pack_unorm_4x8(&b, srcs[0]);
203601e04c3fSmrg      break;
203701e04c3fSmrg   case ir_unop_pack_half_2x16:
203801e04c3fSmrg      result = nir_pack_half_2x16(&b, srcs[0]);
203901e04c3fSmrg      break;
204001e04c3fSmrg   case ir_unop_unpack_snorm_2x16:
204101e04c3fSmrg      result = nir_unpack_snorm_2x16(&b, srcs[0]);
204201e04c3fSmrg      break;
204301e04c3fSmrg   case ir_unop_unpack_snorm_4x8:
204401e04c3fSmrg      result = nir_unpack_snorm_4x8(&b, srcs[0]);
204501e04c3fSmrg      break;
204601e04c3fSmrg   case ir_unop_unpack_unorm_2x16:
204701e04c3fSmrg      result = nir_unpack_unorm_2x16(&b, srcs[0]);
204801e04c3fSmrg      break;
204901e04c3fSmrg   case ir_unop_unpack_unorm_4x8:
205001e04c3fSmrg      result = nir_unpack_unorm_4x8(&b, srcs[0]);
205101e04c3fSmrg      break;
205201e04c3fSmrg   case ir_unop_unpack_half_2x16:
205301e04c3fSmrg      result = nir_unpack_half_2x16(&b, srcs[0]);
205401e04c3fSmrg      break;
205501e04c3fSmrg   case ir_unop_pack_sampler_2x32:
205601e04c3fSmrg   case ir_unop_pack_image_2x32:
205701e04c3fSmrg   case ir_unop_pack_double_2x32:
205801e04c3fSmrg   case ir_unop_pack_int_2x32:
205901e04c3fSmrg   case ir_unop_pack_uint_2x32:
206001e04c3fSmrg      result = nir_pack_64_2x32(&b, srcs[0]);
206101e04c3fSmrg      break;
206201e04c3fSmrg   case ir_unop_unpack_sampler_2x32:
206301e04c3fSmrg   case ir_unop_unpack_image_2x32:
206401e04c3fSmrg   case ir_unop_unpack_double_2x32:
206501e04c3fSmrg   case ir_unop_unpack_int_2x32:
206601e04c3fSmrg   case ir_unop_unpack_uint_2x32:
206701e04c3fSmrg      result = nir_unpack_64_2x32(&b, srcs[0]);
206801e04c3fSmrg      break;
206901e04c3fSmrg   case ir_unop_bitfield_reverse:
207001e04c3fSmrg      result = nir_bitfield_reverse(&b, srcs[0]);
207101e04c3fSmrg      break;
207201e04c3fSmrg   case ir_unop_bit_count:
207301e04c3fSmrg      result = nir_bit_count(&b, srcs[0]);
207401e04c3fSmrg      break;
207501e04c3fSmrg   case ir_unop_find_msb:
207601e04c3fSmrg      switch (types[0]) {
207701e04c3fSmrg      case GLSL_TYPE_UINT:
207801e04c3fSmrg         result = nir_ufind_msb(&b, srcs[0]);
207901e04c3fSmrg         break;
208001e04c3fSmrg      case GLSL_TYPE_INT:
208101e04c3fSmrg         result = nir_ifind_msb(&b, srcs[0]);
208201e04c3fSmrg         break;
208301e04c3fSmrg      default:
208401e04c3fSmrg         unreachable("Invalid type for findMSB()");
208501e04c3fSmrg      }
208601e04c3fSmrg      break;
208701e04c3fSmrg   case ir_unop_find_lsb:
208801e04c3fSmrg      result = nir_find_lsb(&b, srcs[0]);
208901e04c3fSmrg      break;
209001e04c3fSmrg
209101e04c3fSmrg   case ir_unop_get_buffer_size: {
209201e04c3fSmrg      nir_intrinsic_instr *load = nir_intrinsic_instr_create(
209301e04c3fSmrg         this->shader,
20947ec681f3Smrg         nir_intrinsic_get_ssbo_size);
209501e04c3fSmrg      load->num_components = ir->type->vector_elements;
209601e04c3fSmrg      load->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[0]));
209701e04c3fSmrg      unsigned bit_size = glsl_get_bit_size(ir->type);
209801e04c3fSmrg      add_instr(&load->instr, ir->type->vector_elements, bit_size);
209901e04c3fSmrg      return;
210001e04c3fSmrg   }
210101e04c3fSmrg
21027ec681f3Smrg   case ir_unop_atan:
21037ec681f3Smrg      result = nir_atan(&b, srcs[0]);
21047ec681f3Smrg      break;
21057ec681f3Smrg
210601e04c3fSmrg   case ir_binop_add:
210701e04c3fSmrg      result = type_is_float(out_type) ? nir_fadd(&b, srcs[0], srcs[1])
210801e04c3fSmrg                                       : nir_iadd(&b, srcs[0], srcs[1]);
210901e04c3fSmrg      break;
21107ec681f3Smrg   case ir_binop_add_sat:
21117ec681f3Smrg      result = type_is_signed(out_type) ? nir_iadd_sat(&b, srcs[0], srcs[1])
21127ec681f3Smrg                                        : nir_uadd_sat(&b, srcs[0], srcs[1]);
21137ec681f3Smrg      break;
211401e04c3fSmrg   case ir_binop_sub:
211501e04c3fSmrg      result = type_is_float(out_type) ? nir_fsub(&b, srcs[0], srcs[1])
211601e04c3fSmrg                                       : nir_isub(&b, srcs[0], srcs[1]);
211701e04c3fSmrg      break;
21187ec681f3Smrg   case ir_binop_sub_sat:
21197ec681f3Smrg      result = type_is_signed(out_type) ? nir_isub_sat(&b, srcs[0], srcs[1])
21207ec681f3Smrg                                        : nir_usub_sat(&b, srcs[0], srcs[1]);
21217ec681f3Smrg      break;
21227ec681f3Smrg   case ir_binop_abs_sub:
21237ec681f3Smrg      /* out_type is always unsigned for ir_binop_abs_sub, so we have to key
21247ec681f3Smrg       * on the type of the sources.
21257ec681f3Smrg       */
21267ec681f3Smrg      result = type_is_signed(types[0]) ? nir_uabs_isub(&b, srcs[0], srcs[1])
21277ec681f3Smrg                                        : nir_uabs_usub(&b, srcs[0], srcs[1]);
21287ec681f3Smrg      break;
21297ec681f3Smrg   case ir_binop_avg:
21307ec681f3Smrg      result = type_is_signed(out_type) ? nir_ihadd(&b, srcs[0], srcs[1])
21317ec681f3Smrg                                        : nir_uhadd(&b, srcs[0], srcs[1]);
21327ec681f3Smrg      break;
21337ec681f3Smrg   case ir_binop_avg_round:
21347ec681f3Smrg      result = type_is_signed(out_type) ? nir_irhadd(&b, srcs[0], srcs[1])
21357ec681f3Smrg                                        : nir_urhadd(&b, srcs[0], srcs[1]);
21367ec681f3Smrg      break;
21377ec681f3Smrg   case ir_binop_mul_32x16:
21387ec681f3Smrg      result = type_is_signed(out_type) ? nir_imul_32x16(&b, srcs[0], srcs[1])
21397ec681f3Smrg                                        : nir_umul_32x16(&b, srcs[0], srcs[1]);
21407ec681f3Smrg      break;
214101e04c3fSmrg   case ir_binop_mul:
21427e102996Smaya      if (type_is_float(out_type))
21437e102996Smaya         result = nir_fmul(&b, srcs[0], srcs[1]);
21447e102996Smaya      else if (out_type == GLSL_TYPE_INT64 &&
21457e102996Smaya               (ir->operands[0]->type->base_type == GLSL_TYPE_INT ||
21467e102996Smaya                ir->operands[1]->type->base_type == GLSL_TYPE_INT))
21477e102996Smaya         result = nir_imul_2x32_64(&b, srcs[0], srcs[1]);
21487e102996Smaya      else if (out_type == GLSL_TYPE_UINT64 &&
21497e102996Smaya               (ir->operands[0]->type->base_type == GLSL_TYPE_UINT ||
21507e102996Smaya                ir->operands[1]->type->base_type == GLSL_TYPE_UINT))
21517e102996Smaya         result = nir_umul_2x32_64(&b, srcs[0], srcs[1]);
21527e102996Smaya      else
21537e102996Smaya         result = nir_imul(&b, srcs[0], srcs[1]);
215401e04c3fSmrg      break;
215501e04c3fSmrg   case ir_binop_div:
215601e04c3fSmrg      if (type_is_float(out_type))
215701e04c3fSmrg         result = nir_fdiv(&b, srcs[0], srcs[1]);
215801e04c3fSmrg      else if (type_is_signed(out_type))
215901e04c3fSmrg         result = nir_idiv(&b, srcs[0], srcs[1]);
216001e04c3fSmrg      else
216101e04c3fSmrg         result = nir_udiv(&b, srcs[0], srcs[1]);
216201e04c3fSmrg      break;
216301e04c3fSmrg   case ir_binop_mod:
216401e04c3fSmrg      result = type_is_float(out_type) ? nir_fmod(&b, srcs[0], srcs[1])
216501e04c3fSmrg                                       : nir_umod(&b, srcs[0], srcs[1]);
216601e04c3fSmrg      break;
216701e04c3fSmrg   case ir_binop_min:
216801e04c3fSmrg      if (type_is_float(out_type))
216901e04c3fSmrg         result = nir_fmin(&b, srcs[0], srcs[1]);
217001e04c3fSmrg      else if (type_is_signed(out_type))
217101e04c3fSmrg         result = nir_imin(&b, srcs[0], srcs[1]);
217201e04c3fSmrg      else
217301e04c3fSmrg         result = nir_umin(&b, srcs[0], srcs[1]);
217401e04c3fSmrg      break;
217501e04c3fSmrg   case ir_binop_max:
217601e04c3fSmrg      if (type_is_float(out_type))
217701e04c3fSmrg         result = nir_fmax(&b, srcs[0], srcs[1]);
217801e04c3fSmrg      else if (type_is_signed(out_type))
217901e04c3fSmrg         result = nir_imax(&b, srcs[0], srcs[1]);
218001e04c3fSmrg      else
218101e04c3fSmrg         result = nir_umax(&b, srcs[0], srcs[1]);
218201e04c3fSmrg      break;
218301e04c3fSmrg   case ir_binop_pow: result = nir_fpow(&b, srcs[0], srcs[1]); break;
218401e04c3fSmrg   case ir_binop_bit_and: result = nir_iand(&b, srcs[0], srcs[1]); break;
218501e04c3fSmrg   case ir_binop_bit_or: result = nir_ior(&b, srcs[0], srcs[1]); break;
218601e04c3fSmrg   case ir_binop_bit_xor: result = nir_ixor(&b, srcs[0], srcs[1]); break;
218701e04c3fSmrg   case ir_binop_logic_and:
21887e102996Smaya      result = nir_iand(&b, srcs[0], srcs[1]);
218901e04c3fSmrg      break;
219001e04c3fSmrg   case ir_binop_logic_or:
21917e102996Smaya      result = nir_ior(&b, srcs[0], srcs[1]);
219201e04c3fSmrg      break;
219301e04c3fSmrg   case ir_binop_logic_xor:
21947e102996Smaya      result = nir_ixor(&b, srcs[0], srcs[1]);
219501e04c3fSmrg      break;
21967ec681f3Smrg   case ir_binop_lshift: result = nir_ishl(&b, srcs[0], nir_u2u32(&b, srcs[1])); break;
219701e04c3fSmrg   case ir_binop_rshift:
21987ec681f3Smrg      result = (type_is_signed(out_type)) ? nir_ishr(&b, srcs[0], nir_u2u32(&b, srcs[1]))
21997ec681f3Smrg                                          : nir_ushr(&b, srcs[0], nir_u2u32(&b, srcs[1]));
220001e04c3fSmrg      break;
220101e04c3fSmrg   case ir_binop_imul_high:
220201e04c3fSmrg      result = (out_type == GLSL_TYPE_INT) ? nir_imul_high(&b, srcs[0], srcs[1])
220301e04c3fSmrg                                           : nir_umul_high(&b, srcs[0], srcs[1]);
220401e04c3fSmrg      break;
220501e04c3fSmrg   case ir_binop_carry:  result = nir_uadd_carry(&b, srcs[0], srcs[1]);  break;
220601e04c3fSmrg   case ir_binop_borrow: result = nir_usub_borrow(&b, srcs[0], srcs[1]); break;
220701e04c3fSmrg   case ir_binop_less:
22087e102996Smaya      if (type_is_float(types[0]))
22097e102996Smaya         result = nir_flt(&b, srcs[0], srcs[1]);
22107e102996Smaya      else if (type_is_signed(types[0]))
22117e102996Smaya         result = nir_ilt(&b, srcs[0], srcs[1]);
22127e102996Smaya      else
22137e102996Smaya         result = nir_ult(&b, srcs[0], srcs[1]);
221401e04c3fSmrg      break;
221501e04c3fSmrg   case ir_binop_gequal:
22167e102996Smaya      if (type_is_float(types[0]))
22177e102996Smaya         result = nir_fge(&b, srcs[0], srcs[1]);
22187e102996Smaya      else if (type_is_signed(types[0]))
22197e102996Smaya         result = nir_ige(&b, srcs[0], srcs[1]);
22207e102996Smaya      else
22217e102996Smaya         result = nir_uge(&b, srcs[0], srcs[1]);
222201e04c3fSmrg      break;
222301e04c3fSmrg   case ir_binop_equal:
22247e102996Smaya      if (type_is_float(types[0]))
22257e102996Smaya         result = nir_feq(&b, srcs[0], srcs[1]);
22267e102996Smaya      else
22277e102996Smaya         result = nir_ieq(&b, srcs[0], srcs[1]);
222801e04c3fSmrg      break;
222901e04c3fSmrg   case ir_binop_nequal:
22307e102996Smaya      if (type_is_float(types[0]))
22317ec681f3Smrg         result = nir_fneu(&b, srcs[0], srcs[1]);
22327e102996Smaya      else
22337e102996Smaya         result = nir_ine(&b, srcs[0], srcs[1]);
223401e04c3fSmrg      break;
223501e04c3fSmrg   case ir_binop_all_equal:
22367e102996Smaya      if (type_is_float(types[0])) {
22377e102996Smaya         switch (ir->operands[0]->type->vector_elements) {
22387e102996Smaya            case 1: result = nir_feq(&b, srcs[0], srcs[1]); break;
22397e102996Smaya            case 2: result = nir_ball_fequal2(&b, srcs[0], srcs[1]); break;
22407e102996Smaya            case 3: result = nir_ball_fequal3(&b, srcs[0], srcs[1]); break;
22417e102996Smaya            case 4: result = nir_ball_fequal4(&b, srcs[0], srcs[1]); break;
22427e102996Smaya            default:
22437e102996Smaya               unreachable("not reached");
224401e04c3fSmrg         }
224501e04c3fSmrg      } else {
224601e04c3fSmrg         switch (ir->operands[0]->type->vector_elements) {
22477e102996Smaya            case 1: result = nir_ieq(&b, srcs[0], srcs[1]); break;
22487e102996Smaya            case 2: result = nir_ball_iequal2(&b, srcs[0], srcs[1]); break;
22497e102996Smaya            case 3: result = nir_ball_iequal3(&b, srcs[0], srcs[1]); break;
22507e102996Smaya            case 4: result = nir_ball_iequal4(&b, srcs[0], srcs[1]); break;
225101e04c3fSmrg            default:
225201e04c3fSmrg               unreachable("not reached");
225301e04c3fSmrg         }
225401e04c3fSmrg      }
225501e04c3fSmrg      break;
225601e04c3fSmrg   case ir_binop_any_nequal:
22577e102996Smaya      if (type_is_float(types[0])) {
22587e102996Smaya         switch (ir->operands[0]->type->vector_elements) {
22597ec681f3Smrg            case 1: result = nir_fneu(&b, srcs[0], srcs[1]); break;
22607e102996Smaya            case 2: result = nir_bany_fnequal2(&b, srcs[0], srcs[1]); break;
22617e102996Smaya            case 3: result = nir_bany_fnequal3(&b, srcs[0], srcs[1]); break;
22627e102996Smaya            case 4: result = nir_bany_fnequal4(&b, srcs[0], srcs[1]); break;
22637e102996Smaya            default:
22647e102996Smaya               unreachable("not reached");
226501e04c3fSmrg         }
226601e04c3fSmrg      } else {
226701e04c3fSmrg         switch (ir->operands[0]->type->vector_elements) {
22687e102996Smaya            case 1: result = nir_ine(&b, srcs[0], srcs[1]); break;
22697e102996Smaya            case 2: result = nir_bany_inequal2(&b, srcs[0], srcs[1]); break;
22707e102996Smaya            case 3: result = nir_bany_inequal3(&b, srcs[0], srcs[1]); break;
22717e102996Smaya            case 4: result = nir_bany_inequal4(&b, srcs[0], srcs[1]); break;
227201e04c3fSmrg            default:
227301e04c3fSmrg               unreachable("not reached");
227401e04c3fSmrg         }
227501e04c3fSmrg      }
227601e04c3fSmrg      break;
227701e04c3fSmrg   case ir_binop_dot:
22787ec681f3Smrg      result = nir_fdot(&b, srcs[0], srcs[1]);
227901e04c3fSmrg      break;
228001e04c3fSmrg   case ir_binop_vector_extract: {
228101e04c3fSmrg      result = nir_channel(&b, srcs[0], 0);
228201e04c3fSmrg      for (unsigned i = 1; i < ir->operands[0]->type->vector_elements; i++) {
228301e04c3fSmrg         nir_ssa_def *swizzled = nir_channel(&b, srcs[0], i);
22847ec681f3Smrg         result = nir_bcsel(&b, nir_ieq_imm(&b, srcs[1], i),
228501e04c3fSmrg                            swizzled, result);
228601e04c3fSmrg      }
228701e04c3fSmrg      break;
228801e04c3fSmrg   }
228901e04c3fSmrg
22907ec681f3Smrg   case ir_binop_atan2:
22917ec681f3Smrg      result = nir_atan2(&b, srcs[0], srcs[1]);
22927ec681f3Smrg      break;
22937ec681f3Smrg
229401e04c3fSmrg   case ir_binop_ldexp: result = nir_ldexp(&b, srcs[0], srcs[1]); break;
229501e04c3fSmrg   case ir_triop_fma:
229601e04c3fSmrg      result = nir_ffma(&b, srcs[0], srcs[1], srcs[2]);
229701e04c3fSmrg      break;
229801e04c3fSmrg   case ir_triop_lrp:
229901e04c3fSmrg      result = nir_flrp(&b, srcs[0], srcs[1], srcs[2]);
230001e04c3fSmrg      break;
230101e04c3fSmrg   case ir_triop_csel:
23027e102996Smaya      result = nir_bcsel(&b, srcs[0], srcs[1], srcs[2]);
230301e04c3fSmrg      break;
230401e04c3fSmrg   case ir_triop_bitfield_extract:
23057ec681f3Smrg      result = ir->type->is_int_16_32() ?
23067ec681f3Smrg         nir_ibitfield_extract(&b, nir_i2i32(&b, srcs[0]), nir_i2i32(&b, srcs[1]), nir_i2i32(&b, srcs[2])) :
23077ec681f3Smrg         nir_ubitfield_extract(&b, nir_u2u32(&b, srcs[0]), nir_i2i32(&b, srcs[1]), nir_i2i32(&b, srcs[2]));
230801e04c3fSmrg      break;
230901e04c3fSmrg   case ir_quadop_bitfield_insert:
23107ec681f3Smrg      result = nir_bitfield_insert(&b,
23117ec681f3Smrg                                   nir_u2u32(&b, srcs[0]), nir_u2u32(&b, srcs[1]),
23127ec681f3Smrg                                   nir_i2i32(&b, srcs[2]), nir_i2i32(&b, srcs[3]));
231301e04c3fSmrg      break;
231401e04c3fSmrg   case ir_quadop_vector:
231501e04c3fSmrg      result = nir_vec(&b, srcs, ir->type->vector_elements);
231601e04c3fSmrg      break;
231701e04c3fSmrg
231801e04c3fSmrg   default:
231901e04c3fSmrg      unreachable("not reached");
232001e04c3fSmrg   }
232101e04c3fSmrg}
232201e04c3fSmrg
232301e04c3fSmrgvoid
232401e04c3fSmrgnir_visitor::visit(ir_swizzle *ir)
232501e04c3fSmrg{
232601e04c3fSmrg   unsigned swizzle[4] = { ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w };
232701e04c3fSmrg   result = nir_swizzle(&b, evaluate_rvalue(ir->val), swizzle,
23287ec681f3Smrg                        ir->type->vector_elements);
232901e04c3fSmrg}
233001e04c3fSmrg
233101e04c3fSmrgvoid
233201e04c3fSmrgnir_visitor::visit(ir_texture *ir)
233301e04c3fSmrg{
233401e04c3fSmrg   unsigned num_srcs;
233501e04c3fSmrg   nir_texop op;
233601e04c3fSmrg   switch (ir->op) {
233701e04c3fSmrg   case ir_tex:
233801e04c3fSmrg      op = nir_texop_tex;
233901e04c3fSmrg      num_srcs = 1; /* coordinate */
234001e04c3fSmrg      break;
234101e04c3fSmrg
234201e04c3fSmrg   case ir_txb:
234301e04c3fSmrg   case ir_txl:
234401e04c3fSmrg      op = (ir->op == ir_txb) ? nir_texop_txb : nir_texop_txl;
234501e04c3fSmrg      num_srcs = 2; /* coordinate, bias/lod */
234601e04c3fSmrg      break;
234701e04c3fSmrg
234801e04c3fSmrg   case ir_txd:
234901e04c3fSmrg      op = nir_texop_txd; /* coordinate, dPdx, dPdy */
235001e04c3fSmrg      num_srcs = 3;
235101e04c3fSmrg      break;
235201e04c3fSmrg
235301e04c3fSmrg   case ir_txf:
235401e04c3fSmrg      op = nir_texop_txf;
235501e04c3fSmrg      if (ir->lod_info.lod != NULL)
235601e04c3fSmrg         num_srcs = 2; /* coordinate, lod */
235701e04c3fSmrg      else
235801e04c3fSmrg         num_srcs = 1; /* coordinate */
235901e04c3fSmrg      break;
236001e04c3fSmrg
236101e04c3fSmrg   case ir_txf_ms:
236201e04c3fSmrg      op = nir_texop_txf_ms;
236301e04c3fSmrg      num_srcs = 2; /* coordinate, sample_index */
236401e04c3fSmrg      break;
236501e04c3fSmrg
236601e04c3fSmrg   case ir_txs:
236701e04c3fSmrg      op = nir_texop_txs;
236801e04c3fSmrg      if (ir->lod_info.lod != NULL)
236901e04c3fSmrg         num_srcs = 1; /* lod */
237001e04c3fSmrg      else
237101e04c3fSmrg         num_srcs = 0;
237201e04c3fSmrg      break;
237301e04c3fSmrg
237401e04c3fSmrg   case ir_lod:
237501e04c3fSmrg      op = nir_texop_lod;
237601e04c3fSmrg      num_srcs = 1; /* coordinate */
237701e04c3fSmrg      break;
237801e04c3fSmrg
237901e04c3fSmrg   case ir_tg4:
238001e04c3fSmrg      op = nir_texop_tg4;
238101e04c3fSmrg      num_srcs = 1; /* coordinate */
238201e04c3fSmrg      break;
238301e04c3fSmrg
238401e04c3fSmrg   case ir_query_levels:
238501e04c3fSmrg      op = nir_texop_query_levels;
238601e04c3fSmrg      num_srcs = 0;
238701e04c3fSmrg      break;
238801e04c3fSmrg
238901e04c3fSmrg   case ir_texture_samples:
239001e04c3fSmrg      op = nir_texop_texture_samples;
239101e04c3fSmrg      num_srcs = 0;
239201e04c3fSmrg      break;
239301e04c3fSmrg
239401e04c3fSmrg   case ir_samples_identical:
239501e04c3fSmrg      op = nir_texop_samples_identical;
239601e04c3fSmrg      num_srcs = 1; /* coordinate */
239701e04c3fSmrg      break;
239801e04c3fSmrg
239901e04c3fSmrg   default:
240001e04c3fSmrg      unreachable("not reached");
240101e04c3fSmrg   }
240201e04c3fSmrg
240301e04c3fSmrg   if (ir->projector != NULL)
240401e04c3fSmrg      num_srcs++;
240501e04c3fSmrg   if (ir->shadow_comparator != NULL)
240601e04c3fSmrg      num_srcs++;
24077e102996Smaya   /* offsets are constants we store inside nir_tex_intrs.offsets */
24087e102996Smaya   if (ir->offset != NULL && !ir->offset->type->is_array())
240901e04c3fSmrg      num_srcs++;
241001e04c3fSmrg
241101e04c3fSmrg   /* Add one for the texture deref */
241201e04c3fSmrg   num_srcs += 2;
241301e04c3fSmrg
241401e04c3fSmrg   nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs);
241501e04c3fSmrg
241601e04c3fSmrg   instr->op = op;
241701e04c3fSmrg   instr->sampler_dim =
241801e04c3fSmrg      (glsl_sampler_dim) ir->sampler->type->sampler_dimensionality;
241901e04c3fSmrg   instr->is_array = ir->sampler->type->sampler_array;
242001e04c3fSmrg   instr->is_shadow = ir->sampler->type->sampler_shadow;
242101e04c3fSmrg   if (instr->is_shadow)
242201e04c3fSmrg      instr->is_new_style_shadow = (ir->type->vector_elements == 1);
24237ec681f3Smrg   instr->dest_type = nir_get_nir_type_for_glsl_type(ir->type);
242401e04c3fSmrg
242501e04c3fSmrg   nir_deref_instr *sampler_deref = evaluate_deref(ir->sampler);
24267e102996Smaya
24277e102996Smaya   /* check for bindless handles */
24287ec681f3Smrg   if (!nir_deref_mode_is(sampler_deref, nir_var_uniform) ||
24297e102996Smaya       nir_deref_instr_get_variable(sampler_deref)->data.bindless) {
24307e102996Smaya      nir_ssa_def *load = nir_load_deref(&b, sampler_deref);
24317e102996Smaya      instr->src[0].src = nir_src_for_ssa(load);
24327e102996Smaya      instr->src[0].src_type = nir_tex_src_texture_handle;
24337e102996Smaya      instr->src[1].src = nir_src_for_ssa(load);
24347e102996Smaya      instr->src[1].src_type = nir_tex_src_sampler_handle;
24357e102996Smaya   } else {
24367e102996Smaya      instr->src[0].src = nir_src_for_ssa(&sampler_deref->dest.ssa);
24377e102996Smaya      instr->src[0].src_type = nir_tex_src_texture_deref;
24387e102996Smaya      instr->src[1].src = nir_src_for_ssa(&sampler_deref->dest.ssa);
24397e102996Smaya      instr->src[1].src_type = nir_tex_src_sampler_deref;
24407e102996Smaya   }
244101e04c3fSmrg
244201e04c3fSmrg   unsigned src_number = 2;
244301e04c3fSmrg
244401e04c3fSmrg   if (ir->coordinate != NULL) {
244501e04c3fSmrg      instr->coord_components = ir->coordinate->type->vector_elements;
244601e04c3fSmrg      instr->src[src_number].src =
244701e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->coordinate));
244801e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_coord;
244901e04c3fSmrg      src_number++;
245001e04c3fSmrg   }
245101e04c3fSmrg
245201e04c3fSmrg   if (ir->projector != NULL) {
245301e04c3fSmrg      instr->src[src_number].src =
245401e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->projector));
245501e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_projector;
245601e04c3fSmrg      src_number++;
245701e04c3fSmrg   }
245801e04c3fSmrg
245901e04c3fSmrg   if (ir->shadow_comparator != NULL) {
246001e04c3fSmrg      instr->src[src_number].src =
246101e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->shadow_comparator));
246201e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_comparator;
246301e04c3fSmrg      src_number++;
246401e04c3fSmrg   }
246501e04c3fSmrg
246601e04c3fSmrg   if (ir->offset != NULL) {
24677e102996Smaya      if (ir->offset->type->is_array()) {
24687e102996Smaya         for (int i = 0; i < ir->offset->type->array_size(); i++) {
24697e102996Smaya            const ir_constant *c =
24707e102996Smaya               ir->offset->as_constant()->get_array_element(i);
24717e102996Smaya
24727e102996Smaya            for (unsigned j = 0; j < 2; ++j) {
24737e102996Smaya               int val = c->get_int_component(j);
24747e102996Smaya               assert(val <= 31 && val >= -32);
24757e102996Smaya               instr->tg4_offsets[i][j] = val;
24767e102996Smaya            }
24777e102996Smaya         }
24787e102996Smaya      } else {
24797e102996Smaya         assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar());
248001e04c3fSmrg
24817e102996Smaya         instr->src[src_number].src =
24827e102996Smaya            nir_src_for_ssa(evaluate_rvalue(ir->offset));
24837e102996Smaya         instr->src[src_number].src_type = nir_tex_src_offset;
24847e102996Smaya         src_number++;
24857e102996Smaya      }
248601e04c3fSmrg   }
248701e04c3fSmrg
248801e04c3fSmrg   switch (ir->op) {
248901e04c3fSmrg   case ir_txb:
249001e04c3fSmrg      instr->src[src_number].src =
249101e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->lod_info.bias));
249201e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_bias;
249301e04c3fSmrg      src_number++;
249401e04c3fSmrg      break;
249501e04c3fSmrg
249601e04c3fSmrg   case ir_txl:
249701e04c3fSmrg   case ir_txf:
249801e04c3fSmrg   case ir_txs:
249901e04c3fSmrg      if (ir->lod_info.lod != NULL) {
250001e04c3fSmrg         instr->src[src_number].src =
250101e04c3fSmrg            nir_src_for_ssa(evaluate_rvalue(ir->lod_info.lod));
250201e04c3fSmrg         instr->src[src_number].src_type = nir_tex_src_lod;
250301e04c3fSmrg         src_number++;
250401e04c3fSmrg      }
250501e04c3fSmrg      break;
250601e04c3fSmrg
250701e04c3fSmrg   case ir_txd:
250801e04c3fSmrg      instr->src[src_number].src =
250901e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdx));
251001e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_ddx;
251101e04c3fSmrg      src_number++;
251201e04c3fSmrg      instr->src[src_number].src =
251301e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->lod_info.grad.dPdy));
251401e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_ddy;
251501e04c3fSmrg      src_number++;
251601e04c3fSmrg      break;
251701e04c3fSmrg
251801e04c3fSmrg   case ir_txf_ms:
251901e04c3fSmrg      instr->src[src_number].src =
252001e04c3fSmrg         nir_src_for_ssa(evaluate_rvalue(ir->lod_info.sample_index));
252101e04c3fSmrg      instr->src[src_number].src_type = nir_tex_src_ms_index;
252201e04c3fSmrg      src_number++;
252301e04c3fSmrg      break;
252401e04c3fSmrg
252501e04c3fSmrg   case ir_tg4:
252601e04c3fSmrg      instr->component = ir->lod_info.component->as_constant()->value.u[0];
252701e04c3fSmrg      break;
252801e04c3fSmrg
252901e04c3fSmrg   default:
253001e04c3fSmrg      break;
253101e04c3fSmrg   }
253201e04c3fSmrg
253301e04c3fSmrg   assert(src_number == num_srcs);
253401e04c3fSmrg
253501e04c3fSmrg   unsigned bit_size = glsl_get_bit_size(ir->type);
253601e04c3fSmrg   add_instr(&instr->instr, nir_tex_instr_dest_size(instr), bit_size);
253701e04c3fSmrg}
253801e04c3fSmrg
253901e04c3fSmrgvoid
254001e04c3fSmrgnir_visitor::visit(ir_constant *ir)
254101e04c3fSmrg{
254201e04c3fSmrg   /*
254301e04c3fSmrg    * We don't know if this variable is an array or struct that gets
254401e04c3fSmrg    * dereferenced, so do the safe thing an make it a variable with a
254501e04c3fSmrg    * constant initializer and return a dereference.
254601e04c3fSmrg    */
254701e04c3fSmrg
254801e04c3fSmrg   nir_variable *var =
254901e04c3fSmrg      nir_local_variable_create(this->impl, ir->type, "const_temp");
255001e04c3fSmrg   var->data.read_only = true;
255101e04c3fSmrg   var->constant_initializer = constant_copy(ir, var);
255201e04c3fSmrg
255301e04c3fSmrg   this->deref = nir_build_deref_var(&b, var);
255401e04c3fSmrg}
255501e04c3fSmrg
255601e04c3fSmrgvoid
255701e04c3fSmrgnir_visitor::visit(ir_dereference_variable *ir)
255801e04c3fSmrg{
25597e102996Smaya   if (ir->variable_referenced()->data.mode == ir_var_function_out) {
25607e102996Smaya      unsigned i = (sig->return_type != glsl_type::void_type) ? 1 : 0;
25617e102996Smaya
25627e102996Smaya      foreach_in_list(ir_variable, param, &sig->parameters) {
25637e102996Smaya         if (param == ir->variable_referenced()) {
25647e102996Smaya            break;
25657e102996Smaya         }
25667e102996Smaya         i++;
25677e102996Smaya      }
25687e102996Smaya
25697e102996Smaya      this->deref = nir_build_deref_cast(&b, nir_load_param(&b, i),
25707e102996Smaya                                         nir_var_function_temp, ir->type, 0);
25717e102996Smaya      return;
25727e102996Smaya   }
25737e102996Smaya
25747e102996Smaya   assert(ir->variable_referenced()->data.mode != ir_var_function_inout);
25757e102996Smaya
257601e04c3fSmrg   struct hash_entry *entry =
257701e04c3fSmrg      _mesa_hash_table_search(this->var_table, ir->var);
257801e04c3fSmrg   assert(entry);
257901e04c3fSmrg   nir_variable *var = (nir_variable *) entry->data;
258001e04c3fSmrg
258101e04c3fSmrg   this->deref = nir_build_deref_var(&b, var);
258201e04c3fSmrg}
258301e04c3fSmrg
258401e04c3fSmrgvoid
258501e04c3fSmrgnir_visitor::visit(ir_dereference_record *ir)
258601e04c3fSmrg{
258701e04c3fSmrg   ir->record->accept(this);
258801e04c3fSmrg
258901e04c3fSmrg   int field_index = ir->field_idx;
259001e04c3fSmrg   assert(field_index >= 0);
259101e04c3fSmrg
259201e04c3fSmrg   this->deref = nir_build_deref_struct(&b, this->deref, field_index);
259301e04c3fSmrg}
259401e04c3fSmrg
259501e04c3fSmrgvoid
259601e04c3fSmrgnir_visitor::visit(ir_dereference_array *ir)
259701e04c3fSmrg{
259801e04c3fSmrg   nir_ssa_def *index = evaluate_rvalue(ir->array_index);
259901e04c3fSmrg
260001e04c3fSmrg   ir->array->accept(this);
260101e04c3fSmrg
260201e04c3fSmrg   this->deref = nir_build_deref_array(&b, this->deref, index);
260301e04c3fSmrg}
260401e04c3fSmrg
260501e04c3fSmrgvoid
260601e04c3fSmrgnir_visitor::visit(ir_barrier *)
260701e04c3fSmrg{
26087ec681f3Smrg   if (shader->info.stage == MESA_SHADER_COMPUTE)
26097ec681f3Smrg      nir_memory_barrier_shared(&b);
26107ec681f3Smrg   else if (shader->info.stage == MESA_SHADER_TESS_CTRL)
26117ec681f3Smrg      nir_memory_barrier_tcs_patch(&b);
26127ec681f3Smrg
26137ec681f3Smrg   nir_control_barrier(&b);
261401e04c3fSmrg}
26157e102996Smaya
26167e102996Smayanir_shader *
26177e102996Smayaglsl_float64_funcs_to_nir(struct gl_context *ctx,
26187e102996Smaya                          const nir_shader_compiler_options *options)
26197e102996Smaya{
26207ec681f3Smrg   /* It's not possible to use float64 on GLSL ES, so don't bother trying to
26217ec681f3Smrg    * build the support code.  The support code depends on higher versions of
26227ec681f3Smrg    * desktop GLSL, so it will fail to compile (below) anyway.
26237ec681f3Smrg    */
26247ec681f3Smrg   if (!_mesa_is_desktop_gl(ctx) || ctx->Const.GLSLVersion < 400)
26257ec681f3Smrg      return NULL;
26267ec681f3Smrg
26277e102996Smaya   /* We pretend it's a vertex shader.  Ultimately, the stage shouldn't
26287e102996Smaya    * matter because we're not optimizing anything here.
26297e102996Smaya    */
26307e102996Smaya   struct gl_shader *sh = _mesa_new_shader(-1, MESA_SHADER_VERTEX);
26317e102996Smaya   sh->Source = float64_source;
26327e102996Smaya   sh->CompileStatus = COMPILE_FAILURE;
26337e102996Smaya   _mesa_glsl_compile_shader(ctx, sh, false, false, true);
26347e102996Smaya
26357e102996Smaya   if (!sh->CompileStatus) {
26367e102996Smaya      if (sh->InfoLog) {
26377e102996Smaya         _mesa_problem(ctx,
26387e102996Smaya                       "fp64 software impl compile failed:\n%s\nsource:\n%s\n",
26397e102996Smaya                       sh->InfoLog, float64_source);
26407e102996Smaya      }
26417e102996Smaya      return NULL;
26427e102996Smaya   }
26437e102996Smaya
26447e102996Smaya   nir_shader *nir = nir_shader_create(NULL, MESA_SHADER_VERTEX, options, NULL);
26457e102996Smaya
26467e102996Smaya   nir_visitor v1(ctx, nir);
26477e102996Smaya   nir_function_visitor v2(&v1);
26487e102996Smaya   v2.run(sh->ir);
26497e102996Smaya   visit_exec_list(sh->ir, &v1);
26507e102996Smaya
26517e102996Smaya   /* _mesa_delete_shader will try to free sh->Source but it's static const */
26527e102996Smaya   sh->Source = NULL;
26537e102996Smaya   _mesa_delete_shader(ctx, sh);
26547e102996Smaya
26557e102996Smaya   nir_validate_shader(nir, "float64_funcs_to_nir");
26567e102996Smaya
26577ec681f3Smrg   NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
26587e102996Smaya   NIR_PASS_V(nir, nir_lower_returns);
26597e102996Smaya   NIR_PASS_V(nir, nir_inline_functions);
26607e102996Smaya   NIR_PASS_V(nir, nir_opt_deref);
26617e102996Smaya
26627ec681f3Smrg   /* Do some optimizations to clean up the shader now.  By optimizing the
26637ec681f3Smrg    * functions in the library, we avoid having to re-do that work every
26647ec681f3Smrg    * time we inline a copy of a function.  Reducing basic blocks also helps
26657ec681f3Smrg    * with compile times.
26667ec681f3Smrg    */
26677ec681f3Smrg   NIR_PASS_V(nir, nir_lower_vars_to_ssa);
26687ec681f3Smrg   NIR_PASS_V(nir, nir_copy_prop);
26697ec681f3Smrg   NIR_PASS_V(nir, nir_opt_dce);
26707ec681f3Smrg   NIR_PASS_V(nir, nir_opt_cse);
26717ec681f3Smrg   NIR_PASS_V(nir, nir_opt_gcm, true);
26727ec681f3Smrg   NIR_PASS_V(nir, nir_opt_peephole_select, 1, false, false);
26737ec681f3Smrg   NIR_PASS_V(nir, nir_opt_dce);
26747ec681f3Smrg
26757e102996Smaya   return nir;
26767e102996Smaya}
2677