/*
 * Copyright © 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Connor Abbott (cwabbott0@gmail.com)
 *    Jason Ekstrand (jason@jlekstrand.net)
 *
 */

/*
 * This lowering pass converts references to input/output variables with
 * loads/stores to actual input/output intrinsics.
 */

#include "nir.h"
#include "nir_builder.h"
#include "nir_deref.h"

#include "util/u_math.h"

struct lower_io_state {
   void *dead_ctx;
   nir_builder builder;
   int (*type_size)(const struct glsl_type *type, bool);
   nir_variable_mode modes;
   nir_lower_io_options options;
};

static nir_intrinsic_op
ssbo_atomic_for_deref(nir_intrinsic_op deref_op)
{
   switch (deref_op) {
#define OP(O) case nir_intrinsic_deref_##O: return nir_intrinsic_ssbo_##O;
   OP(atomic_exchange)
   OP(atomic_comp_swap)
   OP(atomic_add)
   OP(atomic_imin)
   OP(atomic_umin)
   OP(atomic_imax)
   OP(atomic_umax)
   OP(atomic_and)
   OP(atomic_or)
   OP(atomic_xor)
   OP(atomic_fadd)
   OP(atomic_fmin)
   OP(atomic_fmax)
   OP(atomic_fcomp_swap)
#undef OP
   default:
      unreachable("Invalid SSBO atomic");
   }
}

static nir_intrinsic_op
global_atomic_for_deref(nir_intrinsic_op deref_op)
{
   switch (deref_op) {
#define OP(O) case nir_intrinsic_deref_##O: return nir_intrinsic_global_##O;
   OP(atomic_exchange)
   OP(atomic_comp_swap)
   OP(atomic_add)
   OP(atomic_imin)
   OP(atomic_umin)
   OP(atomic_imax)
   OP(atomic_umax)
   OP(atomic_and)
   OP(atomic_or)
   OP(atomic_xor)
   OP(atomic_fadd)
   OP(atomic_fmin)
   OP(atomic_fmax)
   OP(atomic_fcomp_swap)
#undef OP
   default:
      unreachable("Invalid SSBO atomic");
   }
}

static nir_intrinsic_op
shared_atomic_for_deref(nir_intrinsic_op deref_op)
{
   switch (deref_op) {
#define OP(O) case nir_intrinsic_deref_##O: return nir_intrinsic_shared_##O;
   OP(atomic_exchange)
   OP(atomic_comp_swap)
   OP(atomic_add)
   OP(atomic_imin)
   OP(atomic_umin)
   OP(atomic_imax)
   OP(atomic_umax)
   OP(atomic_and)
   OP(atomic_or)
   OP(atomic_xor)
   OP(atomic_fadd)
   OP(atomic_fmin)
   OP(atomic_fmax)
   OP(atomic_fcomp_swap)
#undef OP
   default:
      unreachable("Invalid shared atomic");
   }
}

void
nir_assign_var_locations(nir_shader *shader, nir_variable_mode mode,
                         unsigned *size,
                         int (*type_size)(const struct glsl_type *, bool))
{
   unsigned location = 0;

   nir_foreach_variable_with_modes(var, shader, mode) {
      var->data.driver_location = location;
      bool bindless_type_size = var->data.mode == nir_var_shader_in ||
                                var->data.mode == nir_var_shader_out ||
                                var->data.bindless;
      location += type_size(var->type, bindless_type_size);
   }

   *size = location;
}

/**
 * Return true if the given variable is a per-vertex input/output array.
 * (such as geometry shader inputs).
 */
bool
nir_is_per_vertex_io(const nir_variable *var, gl_shader_stage stage)
{
   if (var->data.patch || !glsl_type_is_array(var->type))
      return false;

   if (var->data.mode == nir_var_shader_in)
      return stage == MESA_SHADER_GEOMETRY ||
             stage == MESA_SHADER_TESS_CTRL ||
             stage == MESA_SHADER_TESS_EVAL;

   if (var->data.mode == nir_var_shader_out)
      return stage == MESA_SHADER_TESS_CTRL;

   return false;
}

static unsigned get_number_of_slots(struct lower_io_state *state,
                                    const nir_variable *var)
{
   const struct glsl_type *type = var->type;

   if (nir_is_per_vertex_io(var, state->builder.shader->info.stage)) {
      assert(glsl_type_is_array(type));
      type = glsl_get_array_element(type);
   }

   return state->type_size(type, var->data.bindless);
}

static nir_ssa_def *
get_io_offset(nir_builder *b, nir_deref_instr *deref,
              nir_ssa_def **vertex_index,
              int (*type_size)(const struct glsl_type *, bool),
              unsigned *component, bool bts)
{
   nir_deref_path path;
   nir_deref_path_init(&path, deref, NULL);

   assert(path.path[0]->deref_type == nir_deref_type_var);
   nir_deref_instr **p = &path.path[1];

   /* For per-vertex input arrays (i.e. geometry shader inputs), keep the
    * outermost array index separate.  Process the rest normally.
    */
   if (vertex_index != NULL) {
      assert((*p)->deref_type == nir_deref_type_array);
      *vertex_index = nir_ssa_for_src(b, (*p)->arr.index, 1);
      p++;
   }

   if (path.path[0]->var->data.compact) {
      assert((*p)->deref_type == nir_deref_type_array);
      assert(glsl_type_is_scalar((*p)->type));

      /* We always lower indirect dereferences for "compact" array vars. */
      const unsigned index = nir_src_as_uint((*p)->arr.index);
      const unsigned total_offset = *component + index;
      const unsigned slot_offset = total_offset / 4;
      *component = total_offset % 4;
      return nir_imm_int(b, type_size(glsl_vec4_type(), bts) * slot_offset);
   }

   /* Just emit code and let constant-folding go to town */
   nir_ssa_def *offset = nir_imm_int(b, 0);

   for (; *p; p++) {
      if ((*p)->deref_type == nir_deref_type_array) {
         unsigned size = type_size((*p)->type, bts);

         nir_ssa_def *mul =
            nir_amul_imm(b, nir_ssa_for_src(b, (*p)->arr.index, 1), size);

         offset = nir_iadd(b, offset, mul);
      } else if ((*p)->deref_type == nir_deref_type_struct) {
         /* p starts at path[1], so this is safe */
         nir_deref_instr *parent = *(p - 1);

         unsigned field_offset = 0;
         for (unsigned i = 0; i < (*p)->strct.index; i++) {
            field_offset += type_size(glsl_get_struct_field(parent->type, i), bts);
         }
         offset = nir_iadd_imm(b, offset, field_offset);
      } else {
         unreachable("Unsupported deref type");
      }
   }

   nir_deref_path_finish(&path);

   return offset;
}

static nir_ssa_def *
emit_load(struct lower_io_state *state,
          nir_ssa_def *vertex_index, nir_variable *var, nir_ssa_def *offset,
          unsigned component, unsigned num_components, unsigned bit_size,
          nir_alu_type type)
{
   nir_builder *b = &state->builder;
   const nir_shader *nir = b->shader;
   nir_variable_mode mode = var->data.mode;
   nir_ssa_def *barycentric = NULL;

   nir_intrinsic_op op;
   switch (mode) {
   case nir_var_shader_in:
      if (nir->info.stage == MESA_SHADER_FRAGMENT &&
          nir->options->use_interpolated_input_intrinsics &&
          var->data.interpolation != INTERP_MODE_FLAT) {
         if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
            assert(vertex_index != NULL);
            op = nir_intrinsic_load_input_vertex;
         } else {
            assert(vertex_index == NULL);

            nir_intrinsic_op bary_op;
            if (var->data.sample ||
                (state->options & nir_lower_io_force_sample_interpolation))
               bary_op = nir_intrinsic_load_barycentric_sample;
            else if (var->data.centroid)
               bary_op = nir_intrinsic_load_barycentric_centroid;
            else
               bary_op = nir_intrinsic_load_barycentric_pixel;

            barycentric = nir_load_barycentric(&state->builder, bary_op,
                                               var->data.interpolation);
            op = nir_intrinsic_load_interpolated_input;
         }
      } else {
         op = vertex_index ? nir_intrinsic_load_per_vertex_input :
                             nir_intrinsic_load_input;
      }
      break;
   case nir_var_shader_out:
      op = vertex_index ? nir_intrinsic_load_per_vertex_output :
                          nir_intrinsic_load_output;
      break;
   case nir_var_uniform:
      op = nir_intrinsic_load_uniform;
      break;
   default:
      unreachable("Unknown variable mode");
   }

   nir_intrinsic_instr *load =
      nir_intrinsic_instr_create(state->builder.shader, op);
   load->num_components = num_components;

   nir_intrinsic_set_base(load, var->data.driver_location);
   if (mode == nir_var_shader_in || mode == nir_var_shader_out)
      nir_intrinsic_set_component(load, component);

   if (load->intrinsic == nir_intrinsic_load_uniform)
      nir_intrinsic_set_range(load,
                              state->type_size(var->type, var->data.bindless));

   if (load->intrinsic == nir_intrinsic_load_input ||
       load->intrinsic == nir_intrinsic_load_input_vertex ||
       load->intrinsic == nir_intrinsic_load_uniform)
      nir_intrinsic_set_type(load, type);

   if (load->intrinsic != nir_intrinsic_load_uniform) {
      nir_io_semantics semantics = {0};
      semantics.location = var->data.location;
      semantics.num_slots = get_number_of_slots(state, var);
      semantics.fb_fetch_output = var->data.fb_fetch_output;
      semantics.medium_precision =
         var->data.precision == GLSL_PRECISION_MEDIUM ||
         var->data.precision == GLSL_PRECISION_LOW;
      nir_intrinsic_set_io_semantics(load, semantics);
   }

   if (vertex_index) {
      load->src[0] = nir_src_for_ssa(vertex_index);
      load->src[1] = nir_src_for_ssa(offset);
   } else if (barycentric) {
      load->src[0] = nir_src_for_ssa(barycentric);
      load->src[1] = nir_src_for_ssa(offset);
   } else {
      load->src[0] = nir_src_for_ssa(offset);
   }

   nir_ssa_dest_init(&load->instr, &load->dest,
                     num_components, bit_size, NULL);
   nir_builder_instr_insert(b, &load->instr);

   return &load->dest.ssa;
}

static nir_ssa_def *
lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
           nir_ssa_def *vertex_index, nir_variable *var, nir_ssa_def *offset,
           unsigned component, const struct glsl_type *type)
{
   assert(intrin->dest.is_ssa);
   if (intrin->dest.ssa.bit_size == 64 &&
       (state->options & nir_lower_io_lower_64bit_to_32)) {
      nir_builder *b = &state->builder;

      const unsigned slot_size = state->type_size(glsl_dvec_type(2), false);

      nir_ssa_def *comp64[4];
      assert(component == 0 || component == 2);
      unsigned dest_comp = 0;
      while (dest_comp < intrin->dest.ssa.num_components) {
         const unsigned num_comps =
            MIN2(intrin->dest.ssa.num_components - dest_comp,
                 (4 - component) / 2);

         nir_ssa_def *data32 =
            emit_load(state, vertex_index, var, offset, component,
                      num_comps * 2, 32, nir_type_uint32);
         for (unsigned i = 0; i < num_comps; i++) {
            comp64[dest_comp + i] =
               nir_pack_64_2x32(b, nir_channels(b, data32, 3 << (i * 2)));
         }

         /* Only the first store has a component offset */
         component = 0;
         dest_comp += num_comps;
         offset = nir_iadd_imm(b, offset, slot_size);
      }

      return nir_vec(b, comp64, intrin->dest.ssa.num_components);
   } else if (intrin->dest.ssa.bit_size == 1) {
      /* Booleans are 32-bit */
      assert(glsl_type_is_boolean(type));
      return nir_b2b1(&state->builder,
                      emit_load(state, vertex_index, var, offset, component,
                                intrin->dest.ssa.num_components, 32,
                                nir_type_bool32));
   } else {
      return emit_load(state, vertex_index, var, offset, component,
                       intrin->dest.ssa.num_components,
                       intrin->dest.ssa.bit_size,
                       nir_get_nir_type_for_glsl_type(type));
   }
}

static void
emit_store(struct lower_io_state *state, nir_ssa_def *data,
           nir_ssa_def *vertex_index, nir_variable *var, nir_ssa_def *offset,
           unsigned component, unsigned num_components,
           nir_component_mask_t write_mask, nir_alu_type type)
{
   nir_builder *b = &state->builder;
   nir_variable_mode mode = var->data.mode;

   assert(mode == nir_var_shader_out);
   nir_intrinsic_op op;
   op = vertex_index ? nir_intrinsic_store_per_vertex_output :
                       nir_intrinsic_store_output;

   nir_intrinsic_instr *store =
      nir_intrinsic_instr_create(state->builder.shader, op);
   store->num_components = num_components;

   store->src[0] = nir_src_for_ssa(data);

   nir_intrinsic_set_base(store, var->data.driver_location);

   if (mode == nir_var_shader_out)
      nir_intrinsic_set_component(store, component);

   if (store->intrinsic == nir_intrinsic_store_output)
      nir_intrinsic_set_type(store, type);

   nir_intrinsic_set_write_mask(store, write_mask);

   if (vertex_index)
      store->src[1] = nir_src_for_ssa(vertex_index);

   store->src[vertex_index ? 2 : 1] = nir_src_for_ssa(offset);

   unsigned gs_streams = 0;
   if (state->builder.shader->info.stage == MESA_SHADER_GEOMETRY) {
      if (var->data.stream & NIR_STREAM_PACKED) {
         gs_streams = var->data.stream & ~NIR_STREAM_PACKED;
      } else {
         assert(var->data.stream < 4);
         gs_streams = 0;
         for (unsigned i = 0; i < num_components; ++i)
            gs_streams |= var->data.stream << (2 * i);
      }
   }

   nir_io_semantics semantics = {0};
   semantics.location = var->data.location;
   semantics.num_slots = get_number_of_slots(state, var);
   semantics.dual_source_blend_index = var->data.index;
   semantics.gs_streams = gs_streams;
   semantics.medium_precision =
      var->data.precision == GLSL_PRECISION_MEDIUM ||
      var->data.precision == GLSL_PRECISION_LOW;
   semantics.per_view = var->data.per_view;
   nir_intrinsic_set_io_semantics(store, semantics);

   nir_builder_instr_insert(b, &store->instr);
}

static void
lower_store(nir_intrinsic_instr *intrin, struct lower_io_state *state,
            nir_ssa_def *vertex_index, nir_variable *var, nir_ssa_def *offset,
            unsigned component, const struct glsl_type *type)
{
   assert(intrin->src[1].is_ssa);
   if (intrin->src[1].ssa->bit_size == 64 &&
       (state->options & nir_lower_io_lower_64bit_to_32)) {
      nir_builder *b = &state->builder;

      const unsigned slot_size = state->type_size(glsl_dvec_type(2), false);

      assert(component == 0 || component == 2);
      unsigned src_comp = 0;
      nir_component_mask_t write_mask = nir_intrinsic_write_mask(intrin);
      while (src_comp < intrin->num_components) {
         const unsigned num_comps =
            MIN2(intrin->num_components - src_comp,
                 (4 - component) / 2);

         if (write_mask & BITFIELD_MASK(num_comps)) {
            nir_ssa_def *data =
               nir_channels(b, intrin->src[1].ssa,
                            BITFIELD_RANGE(src_comp, num_comps));
            nir_ssa_def *data32 = nir_bitcast_vector(b, data, 32);

            nir_component_mask_t write_mask32 = 0;
            for (unsigned i = 0; i < num_comps; i++) {
               if (write_mask & BITFIELD_MASK(num_comps) & (1 << i))
                  write_mask32 |= 3 << (i * 2);
            }

            emit_store(state, data32, vertex_index, var, offset,
                       component, data32->num_components, write_mask32,
                       nir_type_uint32);
         }

         /* Only the first store has a component offset */
         component = 0;
         src_comp += num_comps;
         write_mask >>= num_comps;
         offset = nir_iadd_imm(b, offset, slot_size);
      }
   } else if (intrin->dest.ssa.bit_size == 1) {
      /* Booleans are 32-bit */
      assert(glsl_type_is_boolean(type));
      nir_ssa_def *b32_val = nir_b2b32(&state->builder, intrin->src[1].ssa);
      emit_store(state, b32_val, vertex_index, var, offset,
                 component, intrin->num_components,
                 nir_intrinsic_write_mask(intrin),
                 nir_type_bool32);
   } else {
      emit_store(state, intrin->src[1].ssa, vertex_index, var, offset,
                 component, intrin->num_components,
                 nir_intrinsic_write_mask(intrin),
                 nir_get_nir_type_for_glsl_type(type));
   }
}

static nir_ssa_def *
lower_interpolate_at(nir_intrinsic_instr *intrin, struct lower_io_state *state,
                     nir_variable *var, nir_ssa_def *offset, unsigned component,
                     const struct glsl_type *type)
{
   nir_builder *b = &state->builder;
   assert(var->data.mode == nir_var_shader_in);

   /* Ignore interpolateAt() for flat variables - flat is flat. Lower
    * interpolateAtVertex() for explicit variables.
    */
   if (var->data.interpolation == INTERP_MODE_FLAT ||
       var->data.interpolation == INTERP_MODE_EXPLICIT) {
      nir_ssa_def *vertex_index = NULL;

      if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
         assert(intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex);
         vertex_index = intrin->src[1].ssa;
      }

      return lower_load(intrin, state, vertex_index, var, offset, component, type);
   }

   /* None of the supported APIs allow interpolation on 64-bit things */
   assert(intrin->dest.is_ssa && intrin->dest.ssa.bit_size <= 32);

   nir_intrinsic_op bary_op;
   switch (intrin->intrinsic) {
   case nir_intrinsic_interp_deref_at_centroid:
      bary_op = (state->options & nir_lower_io_force_sample_interpolation) ?
                nir_intrinsic_load_barycentric_sample :
                nir_intrinsic_load_barycentric_centroid;
      break;
   case nir_intrinsic_interp_deref_at_sample:
      bary_op = nir_intrinsic_load_barycentric_at_sample;
      break;
   case nir_intrinsic_interp_deref_at_offset:
      bary_op = nir_intrinsic_load_barycentric_at_offset;
      break;
   default:
      unreachable("Bogus interpolateAt() intrinsic.");
   }

   nir_intrinsic_instr *bary_setup =
      nir_intrinsic_instr_create(state->builder.shader, bary_op);

   nir_ssa_dest_init(&bary_setup->instr, &bary_setup->dest, 2, 32, NULL);
   nir_intrinsic_set_interp_mode(bary_setup, var->data.interpolation);

   if (intrin->intrinsic == nir_intrinsic_interp_deref_at_sample ||
       intrin->intrinsic == nir_intrinsic_interp_deref_at_offset ||
       intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex)
      nir_src_copy(&bary_setup->src[0], &intrin->src[1], bary_setup);

   nir_builder_instr_insert(b, &bary_setup->instr);

   nir_intrinsic_instr *load =
      nir_intrinsic_instr_create(state->builder.shader,
                                 nir_intrinsic_load_interpolated_input);
   load->num_components = intrin->num_components;

   nir_intrinsic_set_base(load, var->data.driver_location);
   nir_intrinsic_set_component(load, component);

   nir_io_semantics semantics = {0};
   semantics.location = var->data.location;
   semantics.num_slots = get_number_of_slots(state, var);
   semantics.medium_precision =
      var->data.precision == GLSL_PRECISION_MEDIUM ||
      var->data.precision == GLSL_PRECISION_LOW;
   nir_intrinsic_set_io_semantics(load, semantics);

   load->src[0] = nir_src_for_ssa(&bary_setup->dest.ssa);
   load->src[1] = nir_src_for_ssa(offset);

   assert(intrin->dest.is_ssa);
   nir_ssa_dest_init(&load->instr, &load->dest,
                     intrin->dest.ssa.num_components,
                     intrin->dest.ssa.bit_size, NULL);
   nir_builder_instr_insert(b, &load->instr);

   return &load->dest.ssa;
}

static bool
nir_lower_io_block(nir_block *block,
                   struct lower_io_state *state)
{
   nir_builder *b = &state->builder;
   const nir_shader_compiler_options *options = b->shader->options;
   bool progress = false;

   nir_foreach_instr_safe(instr, block) {
      if (instr->type != nir_instr_type_intrinsic)
         continue;

      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);

      switch (intrin->intrinsic) {
      case nir_intrinsic_load_deref:
      case nir_intrinsic_store_deref:
         /* We can lower the io for this nir instrinsic */
         break;
      case nir_intrinsic_interp_deref_at_centroid:
      case nir_intrinsic_interp_deref_at_sample:
      case nir_intrinsic_interp_deref_at_offset:
      case nir_intrinsic_interp_deref_at_vertex:
         /* We can optionally lower these to load_interpolated_input */
         if (options->use_interpolated_input_intrinsics)
            break;
      default:
         /* We can't lower the io for this nir instrinsic, so skip it */
         continue;
      }

      nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);

      nir_variable_mode mode = deref->mode;
      assert(util_is_power_of_two_nonzero(mode));
      if ((state->modes & mode) == 0)
         continue;

      nir_variable *var = nir_deref_instr_get_variable(deref);

      b->cursor = nir_before_instr(instr);

      const bool per_vertex = nir_is_per_vertex_io(var, b->shader->info.stage);

      nir_ssa_def *offset;
      nir_ssa_def *vertex_index = NULL;
      unsigned component_offset = var->data.location_frac;
      bool bindless_type_size = mode == nir_var_shader_in ||
                                mode == nir_var_shader_out ||
                                var->data.bindless;

     if (nir_deref_instr_is_known_out_of_bounds(deref)) {
        /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
         *
         *    In the subsections described above for array, vector, matrix and
         *    structure accesses, any out-of-bounds access produced undefined
         *    behavior....
         *    Out-of-bounds reads return undefined values, which
         *    include values from other variables of the active program or zero.
         *    Out-of-bounds writes may be discarded or overwrite
         *    other variables of the active program.
         *
         * GL_KHR_robustness and GL_ARB_robustness encourage us to return zero
         * for reads.
         *
         * Otherwise get_io_offset would return out-of-bound offset which may
         * result in out-of-bound loading/storing of inputs/outputs,
         * that could cause issues in drivers down the line.
         */
         if (intrin->intrinsic != nir_intrinsic_store_deref) {
            nir_ssa_def *zero =
               nir_imm_zero(b, intrin->dest.ssa.num_components,
                             intrin->dest.ssa.bit_size);
            nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
                                  nir_src_for_ssa(zero));
         }

         nir_instr_remove(&intrin->instr);
         progress = true;
         continue;
      }

      offset = get_io_offset(b, deref, per_vertex ? &vertex_index : NULL,
                             state->type_size, &component_offset,
                             bindless_type_size);

      nir_ssa_def *replacement = NULL;

      switch (intrin->intrinsic) {
      case nir_intrinsic_load_deref:
         replacement = lower_load(intrin, state, vertex_index, var, offset,
                                  component_offset, deref->type);
         break;

      case nir_intrinsic_store_deref:
         lower_store(intrin, state, vertex_index, var, offset,
                     component_offset, deref->type);
         break;

      case nir_intrinsic_interp_deref_at_centroid:
      case nir_intrinsic_interp_deref_at_sample:
      case nir_intrinsic_interp_deref_at_offset:
      case nir_intrinsic_interp_deref_at_vertex:
         assert(vertex_index == NULL);
         replacement = lower_interpolate_at(intrin, state, var, offset,
                                            component_offset, deref->type);
         break;

      default:
         continue;
      }

      if (replacement) {
         nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
                                  nir_src_for_ssa(replacement));
      }
      nir_instr_remove(&intrin->instr);
      progress = true;
   }

   return progress;
}

static bool
nir_lower_io_impl(nir_function_impl *impl,
                  nir_variable_mode modes,
                  int (*type_size)(const struct glsl_type *, bool),
                  nir_lower_io_options options)
{
   struct lower_io_state state;
   bool progress = false;

   nir_builder_init(&state.builder, impl);
   state.dead_ctx = ralloc_context(NULL);
   state.modes = modes;
   state.type_size = type_size;
   state.options = options;

   ASSERTED nir_variable_mode supported_modes =
      nir_var_shader_in | nir_var_shader_out | nir_var_uniform;
   assert(!(modes & ~supported_modes));

   nir_foreach_block(block, impl) {
      progress |= nir_lower_io_block(block, &state);
   }

   ralloc_free(state.dead_ctx);

   nir_metadata_preserve(impl, nir_metadata_block_index |
                               nir_metadata_dominance);
   return progress;
}

/** Lower load/store_deref intrinsics on I/O variables to offset-based intrinsics
 *
 * This pass is intended to be used for cross-stage shader I/O and driver-
 * managed uniforms to turn deref-based access into a simpler model using
 * locations or offsets.  For fragment shader inputs, it can optionally turn
 * load_deref into an explicit interpolation using barycentrics coming from
 * one of the load_barycentric_* intrinsics.  This pass requires that all
 * deref chains are complete and contain no casts.
 */
bool
nir_lower_io(nir_shader *shader, nir_variable_mode modes,
             int (*type_size)(const struct glsl_type *, bool),
             nir_lower_io_options options)
{
   bool progress = false;

   nir_foreach_function(function, shader) {
      if (function->impl) {
         progress |= nir_lower_io_impl(function->impl, modes,
                                       type_size, options);
      }
   }

   return progress;
}

static unsigned
type_scalar_size_bytes(const struct glsl_type *type)
{
   assert(glsl_type_is_vector_or_scalar(type) ||
          glsl_type_is_matrix(type));
   return glsl_type_is_boolean(type) ? 4 : glsl_get_bit_size(type) / 8;
}

static nir_ssa_def *
build_addr_iadd(nir_builder *b, nir_ssa_def *addr,
                nir_address_format addr_format, nir_ssa_def *offset)
{
   assert(offset->num_components == 1);

   switch (addr_format) {
   case nir_address_format_32bit_global:
   case nir_address_format_64bit_global:
   case nir_address_format_32bit_offset:
      assert(addr->bit_size == offset->bit_size);
      assert(addr->num_components == 1);
      return nir_iadd(b, addr, offset);

   case nir_address_format_32bit_offset_as_64bit:
      assert(addr->num_components == 1);
      assert(offset->bit_size == 32);
      return nir_u2u64(b, nir_iadd(b, nir_u2u32(b, addr), offset));

   case nir_address_format_64bit_bounded_global:
      assert(addr->num_components == 4);
      assert(addr->bit_size == offset->bit_size);
      return nir_vec4(b, nir_channel(b, addr, 0),
                         nir_channel(b, addr, 1),
                         nir_channel(b, addr, 2),
                         nir_iadd(b, nir_channel(b, addr, 3), offset));

   case nir_address_format_32bit_index_offset:
      assert(addr->num_components == 2);
      assert(addr->bit_size == offset->bit_size);
      return nir_vec2(b, nir_channel(b, addr, 0),
                         nir_iadd(b, nir_channel(b, addr, 1), offset));

   case nir_address_format_32bit_index_offset_pack64:
      assert(addr->num_components == 1);
      assert(offset->bit_size == 32);
      return nir_pack_64_2x32_split(b,
                                    nir_iadd(b, nir_unpack_64_2x32_split_x(b, addr), offset),
                                    nir_unpack_64_2x32_split_y(b, addr));

   case nir_address_format_vec2_index_32bit_offset:
      assert(addr->num_components == 3);
      assert(offset->bit_size == 32);
      return nir_vec3(b, nir_channel(b, addr, 0), nir_channel(b, addr, 1),
                         nir_iadd(b, nir_channel(b, addr, 2), offset));

   case nir_address_format_logical:
      unreachable("Unsupported address format");
   }
   unreachable("Invalid address format");
}

static unsigned
addr_get_offset_bit_size(nir_ssa_def *addr, nir_address_format addr_format)
{
   if (addr_format == nir_address_format_32bit_offset_as_64bit ||
       addr_format == nir_address_format_32bit_index_offset_pack64)
      return 32;
   return addr->bit_size;
}

static nir_ssa_def *
build_addr_iadd_imm(nir_builder *b, nir_ssa_def *addr,
                    nir_address_format addr_format, int64_t offset)
{
   return build_addr_iadd(b, addr, addr_format,
                             nir_imm_intN_t(b, offset,
                                            addr_get_offset_bit_size(addr, addr_format)));
}

static nir_ssa_def *
build_addr_for_var(nir_builder *b, nir_variable *var,
                   nir_address_format addr_format)
{
   assert(var->data.mode & (nir_var_uniform | nir_var_mem_shared |
                            nir_var_shader_temp | nir_var_function_temp |
                            nir_var_mem_constant));

   const unsigned num_comps = nir_address_format_num_components(addr_format);
   const unsigned bit_size = nir_address_format_bit_size(addr_format);

   switch (addr_format) {
   case nir_address_format_32bit_global:
   case nir_address_format_64bit_global: {
      nir_ssa_def *base_addr;
      switch (var->data.mode) {
      case nir_var_shader_temp:
         base_addr = nir_load_scratch_base_ptr(b, 0, num_comps, bit_size);
         break;

      case nir_var_function_temp:
         base_addr = nir_load_scratch_base_ptr(b, 1, num_comps, bit_size);
         break;

      case nir_var_mem_constant:
         base_addr = nir_load_constant_base_ptr(b, num_comps, bit_size);
         break;

      default:
         unreachable("Unsupported variable mode");
      }

      return build_addr_iadd_imm(b, base_addr, addr_format,
                                    var->data.driver_location);
   }

   case nir_address_format_32bit_offset:
      assert(var->data.driver_location <= UINT32_MAX);
      return nir_imm_int(b, var->data.driver_location);

   case nir_address_format_32bit_offset_as_64bit:
      assert(var->data.driver_location <= UINT32_MAX);
      return nir_imm_int64(b, var->data.driver_location);

   default:
      unreachable("Unsupported address format");
   }
}

static nir_ssa_def *
addr_to_index(nir_builder *b, nir_ssa_def *addr,
              nir_address_format addr_format)
{
   switch (addr_format) {
   case nir_address_format_32bit_index_offset:
      assert(addr->num_components == 2);
      return nir_channel(b, addr, 0);
   case nir_address_format_32bit_index_offset_pack64:
      return nir_unpack_64_2x32_split_y(b, addr);
   case nir_address_format_vec2_index_32bit_offset:
      assert(addr->num_components == 3);
      return nir_channels(b, addr, 0x3);
   default: unreachable("Invalid address format");
   }
}

static nir_ssa_def *
addr_to_offset(nir_builder *b, nir_ssa_def *addr,
               nir_address_format addr_format)
{
   switch (addr_format) {
   case nir_address_format_32bit_index_offset:
      assert(addr->num_components == 2);
      return nir_channel(b, addr, 1);
   case nir_address_format_32bit_index_offset_pack64:
      return nir_unpack_64_2x32_split_x(b, addr);
   case nir_address_format_vec2_index_32bit_offset:
      assert(addr->num_components == 3);
      return nir_channel(b, addr, 2);
   case nir_address_format_32bit_offset:
      return addr;
   case nir_address_format_32bit_offset_as_64bit:
      return nir_u2u32(b, addr);
   default:
      unreachable("Invalid address format");
   }
}

/** Returns true if the given address format resolves to a global address */
static bool
addr_format_is_global(nir_address_format addr_format)
{
   return addr_format == nir_address_format_32bit_global ||
          addr_format == nir_address_format_64bit_global ||
          addr_format == nir_address_format_64bit_bounded_global;
}

static bool
addr_format_is_offset(nir_address_format addr_format)
{
   return addr_format == nir_address_format_32bit_offset ||
          addr_format == nir_address_format_32bit_offset_as_64bit;
}

static nir_ssa_def *
addr_to_global(nir_builder *b, nir_ssa_def *addr,
               nir_address_format addr_format)
{
   switch (addr_format) {
   case nir_address_format_32bit_global:
   case nir_address_format_64bit_global:
      assert(addr->num_components == 1);
      return addr;

   case nir_address_format_64bit_bounded_global:
      assert(addr->num_components == 4);
      return nir_iadd(b, nir_pack_64_2x32(b, nir_channels(b, addr, 0x3)),
                         nir_u2u64(b, nir_channel(b, addr, 3)));

   case nir_address_format_32bit_index_offset:
   case nir_address_format_32bit_index_offset_pack64:
   case nir_address_format_vec2_index_32bit_offset:
   case nir_address_format_32bit_offset:
   case nir_address_format_32bit_offset_as_64bit:
   case nir_address_format_logical:
      unreachable("Cannot get a 64-bit address with this address format");
   }

   unreachable("Invalid address format");
}

static bool
addr_format_needs_bounds_check(nir_address_format addr_format)
{
   return addr_format == nir_address_format_64bit_bounded_global;
}

static nir_ssa_def *
addr_is_in_bounds(nir_builder *b, nir_ssa_def *addr,
                  nir_address_format addr_format, unsigned size)
{
   assert(addr_format == nir_address_format_64bit_bounded_global);
   assert(addr->num_components == 4);
   return nir_ige(b, nir_channel(b, addr, 2),
                     nir_iadd_imm(b, nir_channel(b, addr, 3), size));
}

static void
nir_get_explicit_deref_range(nir_deref_instr *deref,
                             nir_address_format addr_format,
                             uint32_t *out_base,
                             uint32_t *out_range)
{
   uint32_t base = 0;
   uint32_t range = glsl_get_explicit_size(deref->type, false);

   while (true) {
      nir_deref_instr *parent = nir_deref_instr_parent(deref);

      switch (deref->deref_type) {
      case nir_deref_type_array:
      case nir_deref_type_array_wildcard:
      case nir_deref_type_ptr_as_array: {
         const unsigned stride = nir_deref_instr_array_stride(deref);
         if (stride == 0)
            goto fail;

         if (!parent)
            goto fail;

         if (deref->deref_type != nir_deref_type_array_wildcard &&
             nir_src_is_const(deref->arr.index)) {
            base += stride * nir_src_as_uint(deref->arr.index);
         } else {
            if (glsl_get_length(parent->type) == 0)
               goto fail;
            range += stride * (glsl_get_length(parent->type) - 1);
         }
         break;
      }

      case nir_deref_type_struct: {
         if (!parent)
            goto fail;

         base += glsl_get_struct_field_offset(parent->type, deref->strct.index);
         break;
      }

      case nir_deref_type_cast: {
         nir_instr *parent_instr = deref->parent.ssa->parent_instr;

         switch (parent_instr->type) {
         case nir_instr_type_load_const: {
            nir_load_const_instr *load = nir_instr_as_load_const(parent_instr);

            switch (addr_format) {
            case nir_address_format_32bit_offset:
               base += load->value[1].u32;
               break;
            case nir_address_format_32bit_index_offset:
               base += load->value[1].u32;
               break;
            case nir_address_format_vec2_index_32bit_offset:
               base += load->value[2].u32;
               break;
            default:
               goto fail;
            }

            *out_base = base;
            *out_range = range;
            return;
         }

         case nir_instr_type_intrinsic: {
            nir_intrinsic_instr *intr = nir_instr_as_intrinsic(parent_instr);
            switch (intr->intrinsic) {
            case nir_intrinsic_load_vulkan_descriptor:
               /* Assume that a load_vulkan_descriptor won't contribute to an
                * offset within the resource.
                */
               break;
            default:
               goto fail;
            }

            *out_base = base;
            *out_range = range;
            return;
         }

         default:
            goto fail;
         }
      }

      default:
         goto fail;
      }

      deref = parent;
   }

fail:
   *out_base = 0;
   *out_range = ~0;
}

static nir_ssa_def *
build_explicit_io_load(nir_builder *b, nir_intrinsic_instr *intrin,
                       nir_ssa_def *addr, nir_address_format addr_format,
                       uint32_t align_mul, uint32_t align_offset,
                       unsigned num_components)
{
   nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
   nir_variable_mode mode = deref->mode;

   nir_intrinsic_op op;
   switch (mode) {
   case nir_var_mem_ubo:
      op = nir_intrinsic_load_ubo;
      break;
   case nir_var_mem_ssbo:
      if (addr_format_is_global(addr_format))
         op = nir_intrinsic_load_global;
      else
         op = nir_intrinsic_load_ssbo;
      break;
   case nir_var_mem_global:
      assert(addr_format_is_global(addr_format));
      op = nir_intrinsic_load_global;
      break;
   case nir_var_uniform:
      assert(addr_format_is_offset(addr_format));
      assert(b->shader->info.stage == MESA_SHADER_KERNEL);
      op = nir_intrinsic_load_kernel_input;
      break;
   case nir_var_mem_shared:
      assert(addr_format_is_offset(addr_format));
      op = nir_intrinsic_load_shared;
      break;
   case nir_var_shader_temp:
   case nir_var_function_temp:
      if (addr_format_is_offset(addr_format)) {
         op = nir_intrinsic_load_scratch;
      } else {
         assert(addr_format_is_global(addr_format));
         op = nir_intrinsic_load_global;
      }
      break;
   case nir_var_mem_constant:
      if (addr_format_is_offset(addr_format)) {
         op = nir_intrinsic_load_constant;
      } else {
         assert(addr_format_is_global(addr_format));
         op = nir_intrinsic_load_global_constant;
      }
      break;
   default:
      unreachable("Unsupported explicit IO variable mode");
   }

   nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);

   if (addr_format_is_global(addr_format)) {
      load->src[0] = nir_src_for_ssa(addr_to_global(b, addr, addr_format));
   } else if (addr_format_is_offset(addr_format)) {
      assert(addr->num_components == 1);
      load->src[0] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   } else {
      load->src[0] = nir_src_for_ssa(addr_to_index(b, addr, addr_format));
      load->src[1] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   }

   if (nir_intrinsic_has_access(load))
      nir_intrinsic_set_access(load, nir_intrinsic_access(intrin));

   if (op == nir_intrinsic_load_constant) {
      nir_intrinsic_set_base(load, 0);
      nir_intrinsic_set_range(load, b->shader->constant_data_size);
   }

   unsigned bit_size = intrin->dest.ssa.bit_size;
   if (bit_size == 1) {
      /* TODO: Make the native bool bit_size an option. */
      bit_size = 32;
   }

   nir_intrinsic_set_align(load, align_mul, align_offset);

   if (nir_intrinsic_has_range_base(load)) {
      unsigned base, range;
      nir_get_explicit_deref_range(deref, addr_format, &base, &range);
      nir_intrinsic_set_range_base(load, base);
      nir_intrinsic_set_range(load, range);
   }

   assert(intrin->dest.is_ssa);
   load->num_components = num_components;
   nir_ssa_dest_init(&load->instr, &load->dest, num_components,
                     bit_size, intrin->dest.ssa.name);

   assert(bit_size % 8 == 0);

   nir_ssa_def *result;
   if (addr_format_needs_bounds_check(addr_format)) {
      /* The Vulkan spec for robustBufferAccess gives us quite a few options
       * as to what we can do with an OOB read.  Unfortunately, returning
       * undefined values isn't one of them so we return an actual zero.
       */
      nir_ssa_def *zero = nir_imm_zero(b, load->num_components, bit_size);

      const unsigned load_size = (bit_size / 8) * load->num_components;
      nir_push_if(b, addr_is_in_bounds(b, addr, addr_format, load_size));

      nir_builder_instr_insert(b, &load->instr);

      nir_pop_if(b, NULL);

      result = nir_if_phi(b, &load->dest.ssa, zero);
   } else {
      nir_builder_instr_insert(b, &load->instr);
      result = &load->dest.ssa;
   }

   if (intrin->dest.ssa.bit_size == 1) {
      /* For shared, we can go ahead and use NIR's and/or the back-end's
       * standard encoding for booleans rather than forcing a 0/1 boolean.
       * This should save an instruction or two.
       */
      if (mode == nir_var_mem_shared ||
          mode == nir_var_shader_temp ||
          mode == nir_var_function_temp)
         result = nir_b2b1(b, result);
      else
         result = nir_i2b(b, result);
   }

   return result;
}

static void
build_explicit_io_store(nir_builder *b, nir_intrinsic_instr *intrin,
                        nir_ssa_def *addr, nir_address_format addr_format,
                        uint32_t align_mul, uint32_t align_offset,
                        nir_ssa_def *value, nir_component_mask_t write_mask)
{
   nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->mode;

   nir_intrinsic_op op;
   switch (mode) {
   case nir_var_mem_ssbo:
      if (addr_format_is_global(addr_format))
         op = nir_intrinsic_store_global;
      else
         op = nir_intrinsic_store_ssbo;
      break;
   case nir_var_mem_global:
      assert(addr_format_is_global(addr_format));
      op = nir_intrinsic_store_global;
      break;
   case nir_var_mem_shared:
      assert(addr_format_is_offset(addr_format));
      op = nir_intrinsic_store_shared;
      break;
   case nir_var_shader_temp:
   case nir_var_function_temp:
      if (addr_format_is_offset(addr_format)) {
         op = nir_intrinsic_store_scratch;
      } else {
         assert(addr_format_is_global(addr_format));
         op = nir_intrinsic_store_global;
      }
      break;
   default:
      unreachable("Unsupported explicit IO variable mode");
   }

   nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, op);

   if (value->bit_size == 1) {
      /* For shared, we can go ahead and use NIR's and/or the back-end's
       * standard encoding for booleans rather than forcing a 0/1 boolean.
       * This should save an instruction or two.
       *
       * TODO: Make the native bool bit_size an option.
       */
      if (mode == nir_var_mem_shared ||
          mode == nir_var_shader_temp ||
          mode == nir_var_function_temp)
         value = nir_b2b32(b, value);
      else
         value = nir_b2i(b, value, 32);
   }

   store->src[0] = nir_src_for_ssa(value);
   if (addr_format_is_global(addr_format)) {
      store->src[1] = nir_src_for_ssa(addr_to_global(b, addr, addr_format));
   } else if (addr_format_is_offset(addr_format)) {
      assert(addr->num_components == 1);
      store->src[1] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   } else {
      store->src[1] = nir_src_for_ssa(addr_to_index(b, addr, addr_format));
      store->src[2] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   }

   nir_intrinsic_set_write_mask(store, write_mask);

   if (nir_intrinsic_has_access(store))
      nir_intrinsic_set_access(store, nir_intrinsic_access(intrin));

   nir_intrinsic_set_align(store, align_mul, align_offset);

   assert(value->num_components == 1 ||
          value->num_components == intrin->num_components);
   store->num_components = value->num_components;

   assert(value->bit_size % 8 == 0);

   if (addr_format_needs_bounds_check(addr_format)) {
      const unsigned store_size = (value->bit_size / 8) * store->num_components;
      nir_push_if(b, addr_is_in_bounds(b, addr, addr_format, store_size));

      nir_builder_instr_insert(b, &store->instr);

      nir_pop_if(b, NULL);
   } else {
      nir_builder_instr_insert(b, &store->instr);
   }
}

static nir_ssa_def *
build_explicit_io_atomic(nir_builder *b, nir_intrinsic_instr *intrin,
                         nir_ssa_def *addr, nir_address_format addr_format)
{
   nir_variable_mode mode = nir_src_as_deref(intrin->src[0])->mode;
   const unsigned num_data_srcs =
      nir_intrinsic_infos[intrin->intrinsic].num_srcs - 1;

   nir_intrinsic_op op;
   switch (mode) {
   case nir_var_mem_ssbo:
      if (addr_format_is_global(addr_format))
         op = global_atomic_for_deref(intrin->intrinsic);
      else
         op = ssbo_atomic_for_deref(intrin->intrinsic);
      break;
   case nir_var_mem_global:
      assert(addr_format_is_global(addr_format));
      op = global_atomic_for_deref(intrin->intrinsic);
      break;
   case nir_var_mem_shared:
      assert(addr_format_is_offset(addr_format));
      op = shared_atomic_for_deref(intrin->intrinsic);
      break;
   default:
      unreachable("Unsupported explicit IO variable mode");
   }

   nir_intrinsic_instr *atomic = nir_intrinsic_instr_create(b->shader, op);

   unsigned src = 0;
   if (addr_format_is_global(addr_format)) {
      atomic->src[src++] = nir_src_for_ssa(addr_to_global(b, addr, addr_format));
   } else if (addr_format_is_offset(addr_format)) {
      assert(addr->num_components == 1);
      atomic->src[src++] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   } else {
      atomic->src[src++] = nir_src_for_ssa(addr_to_index(b, addr, addr_format));
      atomic->src[src++] = nir_src_for_ssa(addr_to_offset(b, addr, addr_format));
   }
   for (unsigned i = 0; i < num_data_srcs; i++) {
      atomic->src[src++] = nir_src_for_ssa(intrin->src[1 + i].ssa);
   }

   /* Global atomics don't have access flags because they assume that the
    * address may be non-uniform.
    */
   if (nir_intrinsic_has_access(atomic))
      nir_intrinsic_set_access(atomic, nir_intrinsic_access(intrin));

   assert(intrin->dest.ssa.num_components == 1);
   nir_ssa_dest_init(&atomic->instr, &atomic->dest,
                     1, intrin->dest.ssa.bit_size, intrin->dest.ssa.name);

   assert(atomic->dest.ssa.bit_size % 8 == 0);

   if (addr_format_needs_bounds_check(addr_format)) {
      const unsigned atomic_size = atomic->dest.ssa.bit_size / 8;
      nir_push_if(b, addr_is_in_bounds(b, addr, addr_format, atomic_size));

      nir_builder_instr_insert(b, &atomic->instr);

      nir_pop_if(b, NULL);
      return nir_if_phi(b, &atomic->dest.ssa,
                           nir_ssa_undef(b, 1, atomic->dest.ssa.bit_size));
   } else {
      nir_builder_instr_insert(b, &atomic->instr);
      return &atomic->dest.ssa;
   }
}

nir_ssa_def *
nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
                                   nir_ssa_def *base_addr,
                                   nir_address_format addr_format)
{
   assert(deref->dest.is_ssa);
   switch (deref->deref_type) {
   case nir_deref_type_var:
      return build_addr_for_var(b, deref->var, addr_format);

   case nir_deref_type_array: {
      unsigned stride = nir_deref_instr_array_stride(deref);
      assert(stride > 0);

      nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
      index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
      return build_addr_iadd(b, base_addr, addr_format,
                                nir_amul_imm(b, index, stride));
   }

   case nir_deref_type_ptr_as_array: {
      nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
      index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
      unsigned stride = nir_deref_instr_array_stride(deref);
      return build_addr_iadd(b, base_addr, addr_format,
                                nir_amul_imm(b, index, stride));
   }

   case nir_deref_type_array_wildcard:
      unreachable("Wildcards should be lowered by now");
      break;

   case nir_deref_type_struct: {
      nir_deref_instr *parent = nir_deref_instr_parent(deref);
      int offset = glsl_get_struct_field_offset(parent->type,
                                                deref->strct.index);
      assert(offset >= 0);
      return build_addr_iadd_imm(b, base_addr, addr_format, offset);
   }

   case nir_deref_type_cast:
      /* Nothing to do here */
      return base_addr;
   }

   unreachable("Invalid NIR deref type");
}

void
nir_lower_explicit_io_instr(nir_builder *b,
                            nir_intrinsic_instr *intrin,
                            nir_ssa_def *addr,
                            nir_address_format addr_format)
{
   b->cursor = nir_after_instr(&intrin->instr);

   nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
   unsigned vec_stride = glsl_get_explicit_stride(deref->type);
   unsigned scalar_size = type_scalar_size_bytes(deref->type);
   assert(vec_stride == 0 || glsl_type_is_vector(deref->type));
   assert(vec_stride == 0 || vec_stride >= scalar_size);

   uint32_t align_mul, align_offset;
   if (!nir_get_explicit_deref_align(deref, true, &align_mul, &align_offset)) {
      /* If we don't have an alignment from the deref, assume scalar */
      align_mul = scalar_size;
      align_offset = 0;
   }

   if (intrin->intrinsic == nir_intrinsic_load_deref) {
      nir_ssa_def *value;
      if (vec_stride > scalar_size) {
         nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS] = { NULL, };
         for (unsigned i = 0; i < intrin->num_components; i++) {
            unsigned comp_offset = i * vec_stride;
            nir_ssa_def *comp_addr = build_addr_iadd_imm(b, addr, addr_format,
                                                         comp_offset);
            comps[i] = build_explicit_io_load(b, intrin, comp_addr,
                                              addr_format, align_mul,
                                              (align_offset + comp_offset) %
                                                 align_mul,
                                              1);
         }
         value = nir_vec(b, comps, intrin->num_components);
      } else {
         value = build_explicit_io_load(b, intrin, addr, addr_format,
                                        align_mul, align_offset,
                                        intrin->num_components);
      }
      nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(value));
   } else if (intrin->intrinsic == nir_intrinsic_store_deref) {
      assert(intrin->src[1].is_ssa);
      nir_ssa_def *value = intrin->src[1].ssa;
      nir_component_mask_t write_mask = nir_intrinsic_write_mask(intrin);
      if (vec_stride > scalar_size) {
         for (unsigned i = 0; i < intrin->num_components; i++) {
            if (!(write_mask & (1 << i)))
               continue;

            unsigned comp_offset = i * vec_stride;
            nir_ssa_def *comp_addr = build_addr_iadd_imm(b, addr, addr_format,
                                                         comp_offset);
            build_explicit_io_store(b, intrin, comp_addr, addr_format,
                                    align_mul,
                                    (align_offset + comp_offset) % align_mul,
                                    nir_channel(b, value, i), 1);
         }
      } else {
         build_explicit_io_store(b, intrin, addr, addr_format,
                                 align_mul, align_offset,
                                 value, write_mask);
      }
   } else {
      nir_ssa_def *value =
         build_explicit_io_atomic(b, intrin, addr, addr_format);
      nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(value));
   }

   nir_instr_remove(&intrin->instr);
}

bool
nir_get_explicit_deref_align(nir_deref_instr *deref,
                             bool default_to_type_align,
                             uint32_t *align_mul,
                             uint32_t *align_offset)
{
   if (deref->deref_type == nir_deref_type_var) {
      /* If we see a variable, align_mul is effectively infinite because we
       * know the offset exactly (up to the offset of the base pointer for the
       * given variable mode).   We have to pick something so we choose 256B
       * as an arbitrary alignment which seems high enough for any reasonable
       * wide-load use-case.  Back-ends should clamp alignments down if 256B
       * is too large for some reason.
       */
      *align_mul = 256;
      *align_offset = deref->var->data.driver_location % 256;
      return true;
   }

   /* If we're a cast deref that has an alignment, use that. */
   if (deref->deref_type == nir_deref_type_cast && deref->cast.align_mul > 0) {
      *align_mul = deref->cast.align_mul;
      *align_offset = deref->cast.align_offset;
      return true;
   }

   /* Otherwise, we need to compute the alignment based on the parent */
   nir_deref_instr *parent = nir_deref_instr_parent(deref);
   if (parent == NULL) {
      assert(deref->deref_type == nir_deref_type_cast);
      if (default_to_type_align) {
         /* If we don't have a parent, assume the type's alignment, if any. */
         unsigned type_align = glsl_get_explicit_alignment(deref->type);
         if (type_align == 0)
            return false;

         *align_mul = type_align;
         *align_offset = 0;
         return true;
      } else {
         return false;
      }
   }

   uint32_t parent_mul, parent_offset;
   if (!nir_get_explicit_deref_align(parent, default_to_type_align,
                                     &parent_mul, &parent_offset))
      return false;

   switch (deref->deref_type) {
   case nir_deref_type_var:
      unreachable("Handled above");

   case nir_deref_type_array:
   case nir_deref_type_array_wildcard:
   case nir_deref_type_ptr_as_array: {
      const unsigned stride = nir_deref_instr_array_stride(deref);
      if (stride == 0)
         return false;

      if (deref->deref_type != nir_deref_type_array_wildcard &&
          nir_src_is_const(deref->arr.index)) {
         unsigned offset = nir_src_as_uint(deref->arr.index) * stride;
         *align_mul = parent_mul;
         *align_offset = (parent_offset + offset) % parent_mul;
      } else {
         /* If this is a wildcard or an indirect deref, we have to go with the
          * power-of-two gcd.
          */
         *align_mul = MIN2(parent_mul, 1 << (ffs(stride) - 1));
         *align_offset = parent_offset % *align_mul;
      }
      return true;
   }

   case nir_deref_type_struct: {
      const int offset = glsl_get_struct_field_offset(parent->type,
                                                      deref->strct.index);
      if (offset < 0)
         return false;

      *align_mul = parent_mul;
      *align_offset = (parent_offset + offset) % parent_mul;
      return true;
   }

   case nir_deref_type_cast:
      /* We handled the explicit alignment case above. */
      assert(deref->cast.align_mul == 0);
      *align_mul = parent_mul;
      *align_offset = parent_offset;
      return true;
   }

   unreachable("Invalid deref_instr_type");
}

static void
lower_explicit_io_deref(nir_builder *b, nir_deref_instr *deref,
                        nir_address_format addr_format)
{
   /* Just delete the deref if it's not used.  We can't use
    * nir_deref_instr_remove_if_unused here because it may remove more than
    * one deref which could break our list walking since we walk the list
    * backwards.
    */
   assert(list_is_empty(&deref->dest.ssa.if_uses));
   if (list_is_empty(&deref->dest.ssa.uses)) {
      nir_instr_remove(&deref->instr);
      return;
   }

   b->cursor = nir_after_instr(&deref->instr);

   nir_ssa_def *base_addr = NULL;
   if (deref->deref_type != nir_deref_type_var) {
      assert(deref->parent.is_ssa);
      base_addr = deref->parent.ssa;
   }

   nir_ssa_def *addr = nir_explicit_io_address_from_deref(b, deref, base_addr,
                                                          addr_format);
   assert(addr->bit_size == deref->dest.ssa.bit_size);
   assert(addr->num_components == deref->dest.ssa.num_components);

   nir_instr_remove(&deref->instr);
   nir_ssa_def_rewrite_uses(&deref->dest.ssa, nir_src_for_ssa(addr));
}

static void
lower_explicit_io_access(nir_builder *b, nir_intrinsic_instr *intrin,
                         nir_address_format addr_format)
{
   assert(intrin->src[0].is_ssa);
   nir_lower_explicit_io_instr(b, intrin, intrin->src[0].ssa, addr_format);
}

static void
lower_explicit_io_array_length(nir_builder *b, nir_intrinsic_instr *intrin,
                               nir_address_format addr_format)
{
   b->cursor = nir_after_instr(&intrin->instr);

   nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);

   assert(glsl_type_is_array(deref->type));
   assert(glsl_get_length(deref->type) == 0);
   assert(deref->mode == nir_var_mem_ssbo);
   unsigned stride = glsl_get_explicit_stride(deref->type);
   assert(stride > 0);

   nir_ssa_def *addr = &deref->dest.ssa;
   nir_ssa_def *index = addr_to_index(b, addr, addr_format);
   nir_ssa_def *offset = addr_to_offset(b, addr, addr_format);

   nir_intrinsic_instr *bsize =
      nir_intrinsic_instr_create(b->shader, nir_intrinsic_get_ssbo_size);
   bsize->src[0] = nir_src_for_ssa(index);
   nir_ssa_dest_init(&bsize->instr, &bsize->dest, 1, 32, NULL);
   nir_builder_instr_insert(b, &bsize->instr);

   nir_ssa_def *arr_size =
      nir_idiv(b, nir_isub(b, &bsize->dest.ssa, offset),
                  nir_imm_int(b, stride));

   nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(arr_size));
   nir_instr_remove(&intrin->instr);
}

static bool
nir_lower_explicit_io_impl(nir_function_impl *impl, nir_variable_mode modes,
                           nir_address_format addr_format)
{
   bool progress = false;

   nir_builder b;
   nir_builder_init(&b, impl);

   /* Walk in reverse order so that we can see the full deref chain when we
    * lower the access operations.  We lower them assuming that the derefs
    * will be turned into address calculations later.
    */
   nir_foreach_block_reverse(block, impl) {
      nir_foreach_instr_reverse_safe(instr, block) {
         switch (instr->type) {
         case nir_instr_type_deref: {
            nir_deref_instr *deref = nir_instr_as_deref(instr);
            if (deref->mode & modes) {
               lower_explicit_io_deref(&b, deref, addr_format);
               progress = true;
            }
            break;
         }

         case nir_instr_type_intrinsic: {
            nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
            switch (intrin->intrinsic) {
            case nir_intrinsic_load_deref:
            case nir_intrinsic_store_deref:
            case nir_intrinsic_deref_atomic_add:
            case nir_intrinsic_deref_atomic_imin:
            case nir_intrinsic_deref_atomic_umin:
            case nir_intrinsic_deref_atomic_imax:
            case nir_intrinsic_deref_atomic_umax:
            case nir_intrinsic_deref_atomic_and:
            case nir_intrinsic_deref_atomic_or:
            case nir_intrinsic_deref_atomic_xor:
            case nir_intrinsic_deref_atomic_exchange:
            case nir_intrinsic_deref_atomic_comp_swap:
            case nir_intrinsic_deref_atomic_fadd:
            case nir_intrinsic_deref_atomic_fmin:
            case nir_intrinsic_deref_atomic_fmax:
            case nir_intrinsic_deref_atomic_fcomp_swap: {
               nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
               if (deref->mode & modes) {
                  lower_explicit_io_access(&b, intrin, addr_format);
                  progress = true;
               }
               break;
            }

            case nir_intrinsic_deref_buffer_array_length: {
               nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
               if (deref->mode & modes) {
                  lower_explicit_io_array_length(&b, intrin, addr_format);
                  progress = true;
               }
               break;
            }

            default:
               break;
            }
            break;
         }

         default:
            /* Nothing to do */
            break;
         }
      }
   }

   if (progress) {
      nir_metadata_preserve(impl, nir_metadata_block_index |
                                  nir_metadata_dominance);
   }

   return progress;
}

/** Lower explicitly laid out I/O access to byte offset/address intrinsics
 *
 * This pass is intended to be used for any I/O which touches memory external
 * to the shader or which is directly visible to the client.  It requires that
 * all data types in the given modes have a explicit stride/offset decorations
 * to tell it exactly how to calculate the offset/address for the given load,
 * store, or atomic operation.  If the offset/stride information does not come
 * from the client explicitly (as with shared variables in GL or Vulkan),
 * nir_lower_vars_to_explicit_types() can be used to add them.
 *
 * Unlike nir_lower_io, this pass is fully capable of handling incomplete
 * pointer chains which may contain cast derefs.  It does so by walking the
 * deref chain backwards and simply replacing each deref, one at a time, with
 * the appropriate address calculation.  The pass takes a nir_address_format
 * parameter which describes how the offset or address is to be represented
 * during calculations.  By ensuring that the address is always in a
 * consistent format, pointers can safely be conjured from thin air by the
 * driver, stored to variables, passed through phis, etc.
 *
 * The one exception to the simple algorithm described above is for handling
 * row-major matrices in which case we may look down one additional level of
 * the deref chain.
 */
bool
nir_lower_explicit_io(nir_shader *shader, nir_variable_mode modes,
                      nir_address_format addr_format)
{
   bool progress = false;

   nir_foreach_function(function, shader) {
      if (function->impl &&
          nir_lower_explicit_io_impl(function->impl, modes, addr_format))
         progress = true;
   }

   return progress;
}

static bool
nir_lower_vars_to_explicit_types_impl(nir_function_impl *impl,
                                      nir_variable_mode modes,
                                      glsl_type_size_align_func type_info)
{
   bool progress = false;

   nir_foreach_block(block, impl) {
      nir_foreach_instr(instr, block) {
         if (instr->type != nir_instr_type_deref)
            continue;

         nir_deref_instr *deref = nir_instr_as_deref(instr);
         if (!(deref->mode & modes))
            continue;

         unsigned size, alignment;
         const struct glsl_type *new_type =
            glsl_get_explicit_type_for_size_align(deref->type, type_info, &size, &alignment);
         if (new_type != deref->type) {
            progress = true;
            deref->type = new_type;
         }
         if (deref->deref_type == nir_deref_type_cast) {
            /* See also glsl_type::get_explicit_type_for_size_align() */
            unsigned new_stride = align(size, alignment);
            if (new_stride != deref->cast.ptr_stride) {
               deref->cast.ptr_stride = new_stride;
               progress = true;
            }
         }
      }
   }

   if (progress) {
      nir_metadata_preserve(impl, nir_metadata_block_index |
                                  nir_metadata_dominance |
                                  nir_metadata_live_ssa_defs |
                                  nir_metadata_loop_analysis);
   }

   return progress;
}

static bool
lower_vars_to_explicit(nir_shader *shader,
                       struct exec_list *vars, nir_variable_mode mode,
                       glsl_type_size_align_func type_info)
{
   bool progress = false;
   unsigned offset;
   switch (mode) {
   case nir_var_uniform:
      assert(shader->info.stage == MESA_SHADER_KERNEL);
      offset = 0;
      break;
   case nir_var_function_temp:
   case nir_var_shader_temp:
      offset = shader->scratch_size;
      break;
   case nir_var_mem_shared:
      offset = 0;
      break;
   case nir_var_mem_constant:
      offset = shader->constant_data_size;
      break;
   default:
      unreachable("Unsupported mode");
   }
   nir_foreach_variable_in_list(var, vars) {
      if (var->data.mode != mode)
         continue;

      unsigned size, align;
      const struct glsl_type *explicit_type =
         glsl_get_explicit_type_for_size_align(var->type, type_info, &size, &align);

      if (explicit_type != var->type)
         var->type = explicit_type;

      var->data.driver_location = ALIGN_POT(offset, align);
      offset = var->data.driver_location + size;
      progress = true;
   }

   switch (mode) {
   case nir_var_uniform:
      assert(shader->info.stage == MESA_SHADER_KERNEL);
      shader->num_uniforms = offset;
      break;
   case nir_var_shader_temp:
   case nir_var_function_temp:
      shader->scratch_size = offset;
      break;
   case nir_var_mem_shared:
      shader->info.cs.shared_size = offset;
      shader->shared_size = offset;
      break;
   case nir_var_mem_constant:
      shader->constant_data_size = offset;
      break;
   default:
      unreachable("Unsupported mode");
   }

   return progress;
}

bool
nir_lower_vars_to_explicit_types(nir_shader *shader,
                                 nir_variable_mode modes,
                                 glsl_type_size_align_func type_info)
{
   /* TODO: Situations which need to be handled to support more modes:
    * - row-major matrices
    * - compact shader inputs/outputs
    * - interface types
    */
   ASSERTED nir_variable_mode supported =
      nir_var_mem_shared | nir_var_mem_global |
      nir_var_shader_temp | nir_var_function_temp | nir_var_uniform;
   assert(!(modes & ~supported) && "unsupported");

   bool progress = false;

   if (modes & nir_var_uniform)
      progress |= lower_vars_to_explicit(shader, &shader->variables, nir_var_uniform, type_info);
   if (modes & nir_var_mem_shared)
      progress |= lower_vars_to_explicit(shader, &shader->variables, nir_var_mem_shared, type_info);
   if (modes & nir_var_shader_temp)
      progress |= lower_vars_to_explicit(shader, &shader->variables, nir_var_shader_temp, type_info);

   nir_foreach_function(function, shader) {
      if (function->impl) {
         if (modes & nir_var_function_temp)
            progress |= lower_vars_to_explicit(shader, &function->impl->locals, nir_var_function_temp, type_info);

         progress |= nir_lower_vars_to_explicit_types_impl(function->impl, modes, type_info);
      }
   }

   return progress;
}

static void
write_constant(void *dst, const nir_constant *c, const struct glsl_type *type)
{
   if (glsl_type_is_vector_or_scalar(type)) {
      const unsigned num_components = glsl_get_vector_elements(type);
      const unsigned bit_size = glsl_get_bit_size(type);
      if (bit_size == 1) {
         /* Booleans are special-cased to be 32-bit
          *
          * TODO: Make the native bool bit_size an option.
          */
         for (unsigned i = 0; i < num_components; i++) {
            int32_t b32 = -(int)c->values[i].b;
            memcpy((char *)dst + i * 4, &b32, 4);
         }
      } else {
         assert(bit_size >= 8 && bit_size % 8 == 0);
         const unsigned byte_size = bit_size / 8;
         for (unsigned i = 0; i < num_components; i++) {
            /* Annoyingly, thanks to packed structs, we can't make any
             * assumptions about the alignment of dst.  To avoid any strange
             * issues with unaligned writes, we always use memcpy.
             */
            memcpy((char *)dst + i * byte_size, &c->values[i], byte_size);
         }
      }
   } else if (glsl_type_is_array_or_matrix(type)) {
      const unsigned array_len = glsl_get_length(type);
      const unsigned stride = glsl_get_explicit_stride(type);
      assert(stride > 0);
      const struct glsl_type *elem_type = glsl_get_array_element(type);
      for (unsigned i = 0; i < array_len; i++)
         write_constant((char *)dst + i * stride, c->elements[i], elem_type);
   } else {
      assert(glsl_type_is_struct_or_ifc(type));
      const unsigned num_fields = glsl_get_length(type);
      for (unsigned i = 0; i < num_fields; i++) {
         const int field_offset = glsl_get_struct_field_offset(type, i);
         assert(field_offset >= 0);
         const struct glsl_type *field_type = glsl_get_struct_field(type, i);
         write_constant((char *)dst + field_offset, c->elements[i], field_type);
      }
   }
}

bool
nir_lower_mem_constant_vars(nir_shader *shader,
                            glsl_type_size_align_func type_info)
{
   bool progress = false;

   unsigned old_constant_data_size = shader->constant_data_size;
   if (lower_vars_to_explicit(shader, &shader->variables,
                              nir_var_mem_constant, type_info)) {
      assert(shader->constant_data_size > old_constant_data_size);
      shader->constant_data = rerzalloc_size(shader, shader->constant_data,
                                             old_constant_data_size,
                                             shader->constant_data_size);

      nir_foreach_variable_with_modes(var, shader, nir_var_mem_constant) {
         write_constant((char *)shader->constant_data +
                           var->data.driver_location,
                        var->constant_initializer, var->type);
      }
      progress = true;
   }

   nir_foreach_function(function, shader) {
      if (!function->impl)
         continue;

      if (nir_lower_vars_to_explicit_types_impl(function->impl,
                                                nir_var_mem_constant,
                                                type_info))
         progress = true;
   }

   return progress;
}

/**
 * Return the offset source for a load/store intrinsic.
 */
nir_src *
nir_get_io_offset_src(nir_intrinsic_instr *instr)
{
   switch (instr->intrinsic) {
   case nir_intrinsic_load_input:
   case nir_intrinsic_load_output:
   case nir_intrinsic_load_shared:
   case nir_intrinsic_load_uniform:
   case nir_intrinsic_load_global:
   case nir_intrinsic_load_global_constant:
   case nir_intrinsic_load_scratch:
   case nir_intrinsic_load_fs_input_interp_deltas:
   case nir_intrinsic_shared_atomic_add:
   case nir_intrinsic_shared_atomic_and:
   case nir_intrinsic_shared_atomic_comp_swap:
   case nir_intrinsic_shared_atomic_exchange:
   case nir_intrinsic_shared_atomic_fadd:
   case nir_intrinsic_shared_atomic_fcomp_swap:
   case nir_intrinsic_shared_atomic_fmax:
   case nir_intrinsic_shared_atomic_fmin:
   case nir_intrinsic_shared_atomic_imax:
   case nir_intrinsic_shared_atomic_imin:
   case nir_intrinsic_shared_atomic_or:
   case nir_intrinsic_shared_atomic_umax:
   case nir_intrinsic_shared_atomic_umin:
   case nir_intrinsic_shared_atomic_xor:
   case nir_intrinsic_global_atomic_add:
   case nir_intrinsic_global_atomic_and:
   case nir_intrinsic_global_atomic_comp_swap:
   case nir_intrinsic_global_atomic_exchange:
   case nir_intrinsic_global_atomic_fadd:
   case nir_intrinsic_global_atomic_fcomp_swap:
   case nir_intrinsic_global_atomic_fmax:
   case nir_intrinsic_global_atomic_fmin:
   case nir_intrinsic_global_atomic_imax:
   case nir_intrinsic_global_atomic_imin:
   case nir_intrinsic_global_atomic_or:
   case nir_intrinsic_global_atomic_umax:
   case nir_intrinsic_global_atomic_umin:
   case nir_intrinsic_global_atomic_xor:
      return &instr->src[0];
   case nir_intrinsic_load_ubo:
   case nir_intrinsic_load_ssbo:
   case nir_intrinsic_load_input_vertex:
   case nir_intrinsic_load_per_vertex_input:
   case nir_intrinsic_load_per_vertex_output:
   case nir_intrinsic_load_interpolated_input:
   case nir_intrinsic_store_output:
   case nir_intrinsic_store_shared:
   case nir_intrinsic_store_global:
   case nir_intrinsic_store_scratch:
   case nir_intrinsic_ssbo_atomic_add:
   case nir_intrinsic_ssbo_atomic_imin:
   case nir_intrinsic_ssbo_atomic_umin:
   case nir_intrinsic_ssbo_atomic_imax:
   case nir_intrinsic_ssbo_atomic_umax:
   case nir_intrinsic_ssbo_atomic_and:
   case nir_intrinsic_ssbo_atomic_or:
   case nir_intrinsic_ssbo_atomic_xor:
   case nir_intrinsic_ssbo_atomic_exchange:
   case nir_intrinsic_ssbo_atomic_comp_swap:
   case nir_intrinsic_ssbo_atomic_fadd:
   case nir_intrinsic_ssbo_atomic_fmin:
   case nir_intrinsic_ssbo_atomic_fmax:
   case nir_intrinsic_ssbo_atomic_fcomp_swap:
      return &instr->src[1];
   case nir_intrinsic_store_ssbo:
   case nir_intrinsic_store_per_vertex_output:
      return &instr->src[2];
   default:
      return NULL;
   }
}

/**
 * Return the vertex index source for a load/store per_vertex intrinsic.
 */
nir_src *
nir_get_io_vertex_index_src(nir_intrinsic_instr *instr)
{
   switch (instr->intrinsic) {
   case nir_intrinsic_load_per_vertex_input:
   case nir_intrinsic_load_per_vertex_output:
      return &instr->src[0];
   case nir_intrinsic_store_per_vertex_output:
      return &instr->src[1];
   default:
      return NULL;
   }
}

/**
 * Return the numeric constant that identify a NULL pointer for each address
 * format.
 */
const nir_const_value *
nir_address_format_null_value(nir_address_format addr_format)
{
   const static nir_const_value null_values[][NIR_MAX_VEC_COMPONENTS] = {
      [nir_address_format_32bit_global] = {{0}},
      [nir_address_format_64bit_global] = {{0}},
      [nir_address_format_64bit_bounded_global] = {{0}},
      [nir_address_format_32bit_index_offset] = {{.u32 = ~0}, {.u32 = ~0}},
      [nir_address_format_32bit_index_offset_pack64] = {{.u64 = ~0ull}},
      [nir_address_format_vec2_index_32bit_offset] = {{.u32 = ~0}, {.u32 = ~0}, {.u32 = ~0}},
      [nir_address_format_32bit_offset] = {{.u32 = ~0}},
      [nir_address_format_32bit_offset_as_64bit] = {{.u64 = ~0ull}},
      [nir_address_format_logical] = {{.u32 = ~0}},
   };

   assert(addr_format < ARRAY_SIZE(null_values));
   return null_values[addr_format];
}

nir_ssa_def *
nir_build_addr_ieq(nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
                   nir_address_format addr_format)
{
   switch (addr_format) {
   case nir_address_format_32bit_global:
   case nir_address_format_64bit_global:
   case nir_address_format_64bit_bounded_global:
   case nir_address_format_32bit_index_offset:
   case nir_address_format_vec2_index_32bit_offset:
   case nir_address_format_32bit_offset:
      return nir_ball_iequal(b, addr0, addr1);

   case nir_address_format_32bit_offset_as_64bit:
      assert(addr0->num_components == 1 && addr1->num_components == 1);
      return nir_ieq(b, nir_u2u32(b, addr0), nir_u2u32(b, addr1));

   case nir_address_format_32bit_index_offset_pack64:
      assert(addr0->num_components == 1 && addr1->num_components == 1);
      return nir_ball_iequal(b, nir_unpack_64_2x32(b, addr0), nir_unpack_64_2x32(b, addr1));

   case nir_address_format_logical:
      unreachable("Unsupported address format");
   }

   unreachable("Invalid address format");
}

nir_ssa_def *
nir_build_addr_isub(nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
                    nir_address_format addr_format)
{
   switch (addr_format) {
   case nir_address_format_32bit_global:
   case nir_address_format_64bit_global:
   case nir_address_format_32bit_offset:
   case nir_address_format_32bit_index_offset_pack64:
      assert(addr0->num_components == 1);
      assert(addr1->num_components == 1);
      return nir_isub(b, addr0, addr1);

   case nir_address_format_32bit_offset_as_64bit:
      assert(addr0->num_components == 1);
      assert(addr1->num_components == 1);
      return nir_u2u64(b, nir_isub(b, nir_u2u32(b, addr0), nir_u2u32(b, addr1)));

   case nir_address_format_64bit_bounded_global:
      return nir_isub(b, addr_to_global(b, addr0, addr_format),
                         addr_to_global(b, addr1, addr_format));

   case nir_address_format_32bit_index_offset:
      assert(addr0->num_components == 2);
      assert(addr1->num_components == 2);
      /* Assume the same buffer index. */
      return nir_isub(b, nir_channel(b, addr0, 1), nir_channel(b, addr1, 1));

   case nir_address_format_vec2_index_32bit_offset:
      assert(addr0->num_components == 3);
      assert(addr1->num_components == 3);
      /* Assume the same buffer index. */
      return nir_isub(b, nir_channel(b, addr0, 2), nir_channel(b, addr1, 2));

   case nir_address_format_logical:
      unreachable("Unsupported address format");
   }

   unreachable("Invalid address format");
}

static bool
is_input(nir_intrinsic_instr *intrin)
{
   return intrin->intrinsic == nir_intrinsic_load_input ||
          intrin->intrinsic == nir_intrinsic_load_per_vertex_input ||
          intrin->intrinsic == nir_intrinsic_load_interpolated_input ||
          intrin->intrinsic == nir_intrinsic_load_fs_input_interp_deltas;
}

static bool
is_output(nir_intrinsic_instr *intrin)
{
   return intrin->intrinsic == nir_intrinsic_load_output ||
          intrin->intrinsic == nir_intrinsic_load_per_vertex_output ||
          intrin->intrinsic == nir_intrinsic_store_output ||
          intrin->intrinsic == nir_intrinsic_store_per_vertex_output;
}

static bool is_dual_slot(nir_intrinsic_instr *intrin)
{
   if (intrin->intrinsic == nir_intrinsic_store_output ||
       intrin->intrinsic == nir_intrinsic_store_per_vertex_output) {
      return nir_src_bit_size(intrin->src[0]) == 64 &&
             nir_src_num_components(intrin->src[0]) >= 3;
   }

   return nir_dest_bit_size(intrin->dest) == 64 &&
          nir_dest_num_components(intrin->dest) >= 3;
}

/**
 * This pass adds constant offsets to instr->const_index[0] for input/output
 * intrinsics, and resets the offset source to 0.  Non-constant offsets remain
 * unchanged - since we don't know what part of a compound variable is
 * accessed, we allocate storage for the entire thing. For drivers that use
 * nir_lower_io_to_temporaries() before nir_lower_io(), this guarantees that
 * the offset source will be 0, so that they don't have to add it in manually.
 */

static bool
add_const_offset_to_base_block(nir_block *block, nir_builder *b,
                               nir_variable_mode modes)
{
   bool progress = false;
   nir_foreach_instr_safe(instr, block) {
      if (instr->type != nir_instr_type_intrinsic)
         continue;

      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);

      if (((modes & nir_var_shader_in) && is_input(intrin)) ||
          ((modes & nir_var_shader_out) && is_output(intrin))) {
         nir_src *offset = nir_get_io_offset_src(intrin);

         if (nir_src_is_const(*offset)) {
            unsigned off = nir_src_as_uint(*offset);

            nir_intrinsic_set_base(intrin, nir_intrinsic_base(intrin) + off);

            nir_io_semantics sem = nir_intrinsic_io_semantics(intrin);
            sem.location += off;
            /* non-indirect indexing should reduce num_slots */
            sem.num_slots = is_dual_slot(intrin) ? 2 : 1;
            nir_intrinsic_set_io_semantics(intrin, sem);

            b->cursor = nir_before_instr(&intrin->instr);
            nir_instr_rewrite_src(&intrin->instr, offset,
                                  nir_src_for_ssa(nir_imm_int(b, 0)));
            progress = true;
         }
      }
   }

   return progress;
}

bool
nir_io_add_const_offset_to_base(nir_shader *nir, nir_variable_mode modes)
{
   bool progress = false;

   nir_foreach_function(f, nir) {
      if (f->impl) {
         nir_builder b;
         nir_builder_init(&b, f->impl);
         nir_foreach_block(block, f->impl) {
            progress |= add_const_offset_to_base_block(block, &b, modes);
         }
      }
   }

   return progress;
}

