nir/spirv: don't use bare types, remove assert in split vars for testing
[mesa.git] / src / compiler / spirv / vtn_variables.c
index 9a57438a888364f5a6b4212bfd35284edbca251b..782ad08d321a11cd8eb7e5db61c4a41ea5c6e43c 100644 (file)
@@ -79,9 +79,7 @@ vtn_access_link_as_ssa(struct vtn_builder *b, struct vtn_access_link link,
       nir_ssa_def *ssa = vtn_ssa_value(b, link.id)->def;
       if (ssa->bit_size != bit_size)
          ssa = nir_i2i(&b->nb, ssa, bit_size);
-      if (stride != 1)
-         ssa = nir_imul_imm(&b->nb, ssa, stride);
-      return ssa;
+      return nir_imul_imm(&b->nb, ssa, stride);
    }
 }
 
@@ -98,12 +96,25 @@ vk_desc_type_for_mode(struct vtn_builder *b, enum vtn_variable_mode mode)
    }
 }
 
+static const struct glsl_type *
+vtn_ptr_type_for_mode(struct vtn_builder *b, enum vtn_variable_mode mode)
+{
+   switch (mode) {
+   case vtn_variable_mode_ubo:
+      return b->options->ubo_ptr_type;
+   case vtn_variable_mode_ssbo:
+      return b->options->ssbo_ptr_type;
+   default:
+      vtn_fail("Invalid mode for vulkan_resource_index");
+   }
+}
+
 static nir_ssa_def *
 vtn_variable_resource_index(struct vtn_builder *b, struct vtn_variable *var,
                             nir_ssa_def *desc_array_index)
 {
    if (!desc_array_index) {
-      vtn_assert(glsl_type_is_struct(var->type->type));
+      vtn_assert(glsl_type_is_struct_or_ifc(var->type->type));
       desc_array_index = nir_imm_int(&b->nb, 0);
    }
 
@@ -115,7 +126,13 @@ vtn_variable_resource_index(struct vtn_builder *b, struct vtn_variable *var,
    nir_intrinsic_set_binding(instr, var->binding);
    nir_intrinsic_set_desc_type(instr, vk_desc_type_for_mode(b, var->mode));
 
-   nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+   const struct glsl_type *index_type =
+      b->options->lower_ubo_ssbo_access_to_offsets ?
+      glsl_uint_type() : vtn_ptr_type_for_mode(b, var->mode);
+
+   instr->num_components = glsl_get_vector_elements(index_type);
+   nir_ssa_dest_init(&instr->instr, &instr->dest, instr->num_components,
+                     glsl_get_bit_size(index_type), NULL);
    nir_builder_instr_insert(&b->nb, &instr->instr);
 
    return &instr->dest.ssa;
@@ -132,7 +149,13 @@ vtn_resource_reindex(struct vtn_builder *b, enum vtn_variable_mode mode,
    instr->src[1] = nir_src_for_ssa(offset_index);
    nir_intrinsic_set_desc_type(instr, vk_desc_type_for_mode(b, mode));
 
-   nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+   const struct glsl_type *index_type =
+      b->options->lower_ubo_ssbo_access_to_offsets ?
+      glsl_uint_type() : vtn_ptr_type_for_mode(b, mode);
+
+   instr->num_components = glsl_get_vector_elements(index_type);
+   nir_ssa_dest_init(&instr->instr, &instr->dest, instr->num_components,
+                     glsl_get_bit_size(index_type), NULL);
    nir_builder_instr_insert(&b->nb, &instr->instr);
 
    return &instr->dest.ssa;
@@ -140,17 +163,20 @@ vtn_resource_reindex(struct vtn_builder *b, enum vtn_variable_mode mode,
 
 static nir_ssa_def *
 vtn_descriptor_load(struct vtn_builder *b, enum vtn_variable_mode mode,
-                    const struct glsl_type *desc_type, nir_ssa_def *desc_index)
+                    nir_ssa_def *desc_index)
 {
    nir_intrinsic_instr *desc_load =
       nir_intrinsic_instr_create(b->nb.shader,
                                  nir_intrinsic_load_vulkan_descriptor);
    desc_load->src[0] = nir_src_for_ssa(desc_index);
-   desc_load->num_components = glsl_get_vector_elements(desc_type);
    nir_intrinsic_set_desc_type(desc_load, vk_desc_type_for_mode(b, mode));
+
+   const struct glsl_type *ptr_type = vtn_ptr_type_for_mode(b, mode);
+
+   desc_load->num_components = glsl_get_vector_elements(ptr_type);
    nir_ssa_dest_init(&desc_load->instr, &desc_load->dest,
                      desc_load->num_components,
-                     glsl_get_bit_size(desc_type), NULL);
+                     glsl_get_bit_size(ptr_type), NULL);
    nir_builder_instr_insert(&b->nb, &desc_load->instr);
 
    return &desc_load->dest.ssa;
@@ -254,8 +280,7 @@ vtn_nir_deref_pointer_dereference(struct vtn_builder *b,
        * final block index.  Insert a descriptor load and cast to a deref to
        * start the deref chain.
        */
-      nir_ssa_def *desc =
-         vtn_descriptor_load(b, base->mode, base->ptr_type->type, block_index);
+      nir_ssa_def *desc = vtn_descriptor_load(b, base->mode, block_index);
 
       assert(base->mode == vtn_variable_mode_ssbo ||
              base->mode == vtn_variable_mode_ubo);
@@ -288,7 +313,7 @@ vtn_nir_deref_pointer_dereference(struct vtn_builder *b,
    }
 
    for (; idx < deref_chain->length; idx++) {
-      if (glsl_type_is_struct(type->type)) {
+      if (glsl_type_is_struct_or_ifc(type->type)) {
          vtn_assert(deref_chain->link[idx].mode == vtn_access_mode_literal);
          unsigned field = deref_chain->link[idx].id;
          tail = nir_build_deref_struct(&b->nb, tail, field);
@@ -577,11 +602,11 @@ _vtn_local_load_store(struct vtn_builder *b, bool load, nir_deref_instr *deref,
       unsigned elems = glsl_get_length(deref->type);
       for (unsigned i = 0; i < elems; i++) {
          nir_deref_instr *child =
-            nir_build_deref_array(&b->nb, deref, nir_imm_int(&b->nb, i));
+            nir_build_deref_array_imm(&b->nb, deref, i);
          _vtn_local_load_store(b, load, child, inout->elems[i]);
       }
    } else {
-      vtn_assert(glsl_type_is_struct(deref->type));
+      vtn_assert(glsl_type_is_struct_or_ifc(deref->type));
       unsigned elems = glsl_get_length(deref->type);
       for (unsigned i = 0; i < elems; i++) {
          nir_deref_instr *child = nir_build_deref_struct(&b->nb, deref, i);
@@ -1310,6 +1335,10 @@ vtn_get_builtin_location(struct vtn_builder *b,
       *location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
       set_mode_system_value(b, mode);
       break;
+   case SpvBuiltInGlobalLinearId:
+      *location = SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX;
+      set_mode_system_value(b, mode);
+      break;
    case SpvBuiltInBaseVertex:
       /* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same
        * semantic as SPIR-V BaseVertex (SYSTEM_VALUE_FIRST_VERTEX).
@@ -1765,10 +1794,6 @@ vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
       if (vtn_pointer_is_external_block(b, ptr) &&
           vtn_type_contains_block(b, ptr->type) &&
           ptr->mode != vtn_variable_mode_phys_ssbo) {
-         const unsigned bit_size = glsl_get_bit_size(ptr->ptr_type->type);
-         const unsigned num_components =
-            glsl_get_vector_elements(ptr->ptr_type->type);
-
          /* In this case, we're looking for a block index and not an actual
           * deref.
           *
@@ -1793,13 +1818,7 @@ vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
             ptr = vtn_nir_deref_pointer_dereference(b, ptr, &chain);
          }
 
-         /* A block index is just a 32-bit value but the pointer has some
-          * other dimensionality.  Cram it in there and we'll unpack it later
-          * in vtn_pointer_from_ssa.
-          */
-         const unsigned swiz[4] = { 0, };
-         return nir_swizzle(&b->nb, nir_u2u(&b->nb, ptr->block_index, bit_size),
-                            swiz, num_components, false);
+         return ptr->block_index;
       } else {
          return &vtn_pointer_to_deref(b, ptr)->dest.ssa;
       }
@@ -1853,17 +1872,15 @@ vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
    } else {
       const struct glsl_type *deref_type = ptr_type->deref->type;
       if (!vtn_pointer_is_external_block(b, ptr)) {
-         assert(ssa->bit_size == 32 && ssa->num_components == 1);
          ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
-                                           glsl_get_bare_type(deref_type), 0);
+                                           deref_type, 0);
       } else if (vtn_type_contains_block(b, ptr->type) &&
                  ptr->mode != vtn_variable_mode_phys_ssbo) {
          /* This is a pointer to somewhere in an array of blocks, not a
-          * pointer to somewhere inside the block.  We squashed it into a
-          * random vector type before so just pick off the first channel and
-          * cast it back to 32 bits.
+          * pointer to somewhere inside the block.  Set the block index
+          * instead of making a cast.
           */
-         ptr->block_index = nir_u2u32(&b->nb, nir_channel(&b->nb, ssa, 0));
+         ptr->block_index = ssa;
       } else {
          /* This is a pointer to something internal or a pointer inside a
           * block.  It's just a regular cast.
@@ -2037,7 +2054,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
          /* Private variables don't have any explicit layout but some layouts
           * may have leaked through due to type deduplication in the SPIR-V.
           */
-         var->var->type = glsl_get_bare_type(var->type->type);
+         var->var->type = var->type->type;
       }
       var->var->data.mode = nir_mode;
       var->var->data.location = -1;
@@ -2055,7 +2072,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
           * layouts may have leaked through due to type deduplication in the
           * SPIR-V.
           */
-         var->var->type = glsl_get_bare_type(var->type->type);
+         var->var->type = var->type->type;
          var->var->data.mode = nir_var_mem_shared;
       }
       break;
@@ -2081,7 +2098,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
       var->patch = false;
       vtn_foreach_decoration(b, val, var_is_patch_cb, &var->patch);
       if (glsl_type_is_array(var->type->type) &&
-          glsl_type_is_struct(without_array->type)) {
+          glsl_type_is_struct_or_ifc(without_array->type)) {
          vtn_foreach_decoration(b, vtn_value(b, without_array->id,
                                              vtn_value_type_type),
                                 var_is_patch_cb, &var->patch);
@@ -2113,7 +2130,7 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
        * the SPIR-V.  We do, however, keep the layouts in the variable's
        * interface_type because we need offsets for XFB arrays of blocks.
        */
-      var->var->type = glsl_get_bare_type(var->type->type);
+      var->var->type = var->type->type;
       var->var->data.mode = nir_mode;
       var->var->data.patch = var->patch;
 
@@ -2299,9 +2316,10 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
 
    case SpvOpAccessChain:
    case SpvOpPtrAccessChain:
-   case SpvOpInBoundsAccessChain: {
+   case SpvOpInBoundsAccessChain:
+   case SpvOpInBoundsPtrAccessChain: {
       struct vtn_access_chain *chain = vtn_access_chain_create(b, count - 4);
-      chain->ptr_as_array = (opcode == SpvOpPtrAccessChain);
+      chain->ptr_as_array = (opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
 
       unsigned idx = 0;
       for (int i = 4; i < count; i++) {