vtn_variables.c revision 7ec681f3
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Jason Ekstrand (jason@jlekstrand.net)
25 *
26 */
27
28#include "vtn_private.h"
29#include "spirv_info.h"
30#include "nir_deref.h"
31#include <vulkan/vulkan_core.h>
32
33static struct vtn_pointer*
34vtn_align_pointer(struct vtn_builder *b, struct vtn_pointer *ptr,
35                  unsigned alignment)
36{
37   if (alignment == 0)
38      return ptr;
39
40   if (!util_is_power_of_two_nonzero(alignment)) {
41      vtn_warn("Provided alignment is not a power of two");
42      alignment = 1 << (ffs(alignment) - 1);
43   }
44
45   /* If this pointer doesn't have a deref, bail.  This either means we're
46    * using the old offset+alignment pointers which don't support carrying
47    * alignment information or we're a pointer that is below the block
48    * boundary in our access chain in which case alignment is meaningless.
49    */
50   if (ptr->deref == NULL)
51      return ptr;
52
53   /* Ignore alignment information on logical pointers.  This way, we don't
54    * trip up drivers with unnecessary casts.
55    */
56   nir_address_format addr_format = vtn_mode_to_address_format(b, ptr->mode);
57   if (addr_format == nir_address_format_logical)
58      return ptr;
59
60   struct vtn_pointer *copy = ralloc(b, struct vtn_pointer);
61   *copy = *ptr;
62   copy->deref = nir_alignment_deref_cast(&b->nb, ptr->deref, alignment, 0);
63
64   return copy;
65}
66
67static void
68ptr_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
69                  const struct vtn_decoration *dec, void *void_ptr)
70{
71   struct vtn_pointer *ptr = void_ptr;
72
73   switch (dec->decoration) {
74   case SpvDecorationNonUniformEXT:
75      ptr->access |= ACCESS_NON_UNIFORM;
76      break;
77
78   default:
79      break;
80   }
81}
82
83struct access_align {
84   enum gl_access_qualifier access;
85   uint32_t alignment;
86};
87
88static void
89access_align_cb(struct vtn_builder *b, struct vtn_value *val, int member,
90                const struct vtn_decoration *dec, void *void_ptr)
91{
92   struct access_align *aa = void_ptr;
93
94   switch (dec->decoration) {
95   case SpvDecorationAlignment:
96      aa->alignment = dec->operands[0];
97      break;
98
99   case SpvDecorationNonUniformEXT:
100      aa->access |= ACCESS_NON_UNIFORM;
101      break;
102
103   default:
104      break;
105   }
106}
107
108static struct vtn_pointer*
109vtn_decorate_pointer(struct vtn_builder *b, struct vtn_value *val,
110                     struct vtn_pointer *ptr)
111{
112   struct access_align aa = { 0, };
113   vtn_foreach_decoration(b, val, access_align_cb, &aa);
114
115   ptr = vtn_align_pointer(b, ptr, aa.alignment);
116
117   /* If we're adding access flags, make a copy of the pointer.  We could
118    * probably just OR them in without doing so but this prevents us from
119    * leaking them any further than actually specified in the SPIR-V.
120    */
121   if (aa.access & ~ptr->access) {
122      struct vtn_pointer *copy = ralloc(b, struct vtn_pointer);
123      *copy = *ptr;
124      copy->access |= aa.access;
125      return copy;
126   }
127
128   return ptr;
129}
130
131struct vtn_value *
132vtn_push_pointer(struct vtn_builder *b, uint32_t value_id,
133                 struct vtn_pointer *ptr)
134{
135   struct vtn_value *val = vtn_push_value(b, value_id, vtn_value_type_pointer);
136   val->pointer = vtn_decorate_pointer(b, val, ptr);
137   return val;
138}
139
140void
141vtn_copy_value(struct vtn_builder *b, uint32_t src_value_id,
142               uint32_t dst_value_id)
143{
144   struct vtn_value *src = vtn_untyped_value(b, src_value_id);
145   struct vtn_value *dst = vtn_untyped_value(b, dst_value_id);
146   struct vtn_value src_copy = *src;
147
148   vtn_fail_if(dst->value_type != vtn_value_type_invalid,
149               "SPIR-V id %u has already been written by another instruction",
150               dst_value_id);
151
152   vtn_fail_if(dst->type->id != src->type->id,
153               "Result Type must equal Operand type");
154
155   src_copy.name = dst->name;
156   src_copy.decoration = dst->decoration;
157   src_copy.type = dst->type;
158   *dst = src_copy;
159
160   if (dst->value_type == vtn_value_type_pointer)
161      dst->pointer = vtn_decorate_pointer(b, dst, dst->pointer);
162}
163
164static struct vtn_access_chain *
165vtn_access_chain_create(struct vtn_builder *b, unsigned length)
166{
167   struct vtn_access_chain *chain;
168
169   /* Subtract 1 from the length since there's already one built in */
170   size_t size = sizeof(*chain) +
171                 (MAX2(length, 1) - 1) * sizeof(chain->link[0]);
172   chain = rzalloc_size(b, size);
173   chain->length = length;
174
175   return chain;
176}
177
178static bool
179vtn_mode_is_cross_invocation(struct vtn_builder *b,
180                             enum vtn_variable_mode mode)
181{
182   return mode == vtn_variable_mode_ssbo ||
183          mode == vtn_variable_mode_ubo ||
184          mode == vtn_variable_mode_phys_ssbo ||
185          mode == vtn_variable_mode_push_constant ||
186          mode == vtn_variable_mode_workgroup ||
187          mode == vtn_variable_mode_cross_workgroup;
188}
189
190static bool
191vtn_pointer_is_external_block(struct vtn_builder *b,
192                              struct vtn_pointer *ptr)
193{
194   return ptr->mode == vtn_variable_mode_ssbo ||
195          ptr->mode == vtn_variable_mode_ubo ||
196          ptr->mode == vtn_variable_mode_phys_ssbo;
197}
198
199static nir_ssa_def *
200vtn_access_link_as_ssa(struct vtn_builder *b, struct vtn_access_link link,
201                       unsigned stride, unsigned bit_size)
202{
203   vtn_assert(stride > 0);
204   if (link.mode == vtn_access_mode_literal) {
205      return nir_imm_intN_t(&b->nb, link.id * stride, bit_size);
206   } else {
207      nir_ssa_def *ssa = vtn_ssa_value(b, link.id)->def;
208      if (ssa->bit_size != bit_size)
209         ssa = nir_i2i(&b->nb, ssa, bit_size);
210      return nir_imul_imm(&b->nb, ssa, stride);
211   }
212}
213
214static VkDescriptorType
215vk_desc_type_for_mode(struct vtn_builder *b, enum vtn_variable_mode mode)
216{
217   switch (mode) {
218   case vtn_variable_mode_ubo:
219      return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
220   case vtn_variable_mode_ssbo:
221      return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
222   case vtn_variable_mode_accel_struct:
223      return VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
224   default:
225      vtn_fail("Invalid mode for vulkan_resource_index");
226   }
227}
228
229static nir_ssa_def *
230vtn_variable_resource_index(struct vtn_builder *b, struct vtn_variable *var,
231                            nir_ssa_def *desc_array_index)
232{
233   vtn_assert(b->options->environment == NIR_SPIRV_VULKAN);
234
235   if (!desc_array_index)
236      desc_array_index = nir_imm_int(&b->nb, 0);
237
238   if (b->vars_used_indirectly) {
239      vtn_assert(var->var);
240      _mesa_set_add(b->vars_used_indirectly, var->var);
241   }
242
243   nir_intrinsic_instr *instr =
244      nir_intrinsic_instr_create(b->nb.shader,
245                                 nir_intrinsic_vulkan_resource_index);
246   instr->src[0] = nir_src_for_ssa(desc_array_index);
247   nir_intrinsic_set_desc_set(instr, var->descriptor_set);
248   nir_intrinsic_set_binding(instr, var->binding);
249   nir_intrinsic_set_desc_type(instr, vk_desc_type_for_mode(b, var->mode));
250
251   nir_address_format addr_format = vtn_mode_to_address_format(b, var->mode);
252   nir_ssa_dest_init(&instr->instr, &instr->dest,
253                     nir_address_format_num_components(addr_format),
254                     nir_address_format_bit_size(addr_format), NULL);
255   instr->num_components = instr->dest.ssa.num_components;
256   nir_builder_instr_insert(&b->nb, &instr->instr);
257
258   return &instr->dest.ssa;
259}
260
261static nir_ssa_def *
262vtn_resource_reindex(struct vtn_builder *b, enum vtn_variable_mode mode,
263                     nir_ssa_def *base_index, nir_ssa_def *offset_index)
264{
265   vtn_assert(b->options->environment == NIR_SPIRV_VULKAN);
266
267   nir_intrinsic_instr *instr =
268      nir_intrinsic_instr_create(b->nb.shader,
269                                 nir_intrinsic_vulkan_resource_reindex);
270   instr->src[0] = nir_src_for_ssa(base_index);
271   instr->src[1] = nir_src_for_ssa(offset_index);
272   nir_intrinsic_set_desc_type(instr, vk_desc_type_for_mode(b, mode));
273
274   nir_address_format addr_format = vtn_mode_to_address_format(b, mode);
275   nir_ssa_dest_init(&instr->instr, &instr->dest,
276                     nir_address_format_num_components(addr_format),
277                     nir_address_format_bit_size(addr_format), NULL);
278   instr->num_components = instr->dest.ssa.num_components;
279   nir_builder_instr_insert(&b->nb, &instr->instr);
280
281   return &instr->dest.ssa;
282}
283
284static nir_ssa_def *
285vtn_descriptor_load(struct vtn_builder *b, enum vtn_variable_mode mode,
286                    nir_ssa_def *desc_index)
287{
288   vtn_assert(b->options->environment == NIR_SPIRV_VULKAN);
289
290   nir_intrinsic_instr *desc_load =
291      nir_intrinsic_instr_create(b->nb.shader,
292                                 nir_intrinsic_load_vulkan_descriptor);
293   desc_load->src[0] = nir_src_for_ssa(desc_index);
294   nir_intrinsic_set_desc_type(desc_load, vk_desc_type_for_mode(b, mode));
295
296   nir_address_format addr_format = vtn_mode_to_address_format(b, mode);
297   nir_ssa_dest_init(&desc_load->instr, &desc_load->dest,
298                     nir_address_format_num_components(addr_format),
299                     nir_address_format_bit_size(addr_format), NULL);
300   desc_load->num_components = desc_load->dest.ssa.num_components;
301   nir_builder_instr_insert(&b->nb, &desc_load->instr);
302
303   return &desc_load->dest.ssa;
304}
305
306static struct vtn_pointer *
307vtn_pointer_dereference(struct vtn_builder *b,
308                        struct vtn_pointer *base,
309                        struct vtn_access_chain *deref_chain)
310{
311   struct vtn_type *type = base->type;
312   enum gl_access_qualifier access = base->access | deref_chain->access;
313   unsigned idx = 0;
314
315   nir_deref_instr *tail;
316   if (base->deref) {
317      tail = base->deref;
318   } else if (b->options->environment == NIR_SPIRV_VULKAN &&
319              (vtn_pointer_is_external_block(b, base) ||
320               base->mode == vtn_variable_mode_accel_struct)) {
321      nir_ssa_def *block_index = base->block_index;
322
323      /* We dereferencing an external block pointer.  Correctness of this
324       * operation relies on one particular line in the SPIR-V spec, section
325       * entitled "Validation Rules for Shader Capabilities":
326       *
327       *    "Block and BufferBlock decorations cannot decorate a structure
328       *    type that is nested at any level inside another structure type
329       *    decorated with Block or BufferBlock."
330       *
331       * This means that we can detect the point where we cross over from
332       * descriptor indexing to buffer indexing by looking for the block
333       * decorated struct type.  Anything before the block decorated struct
334       * type is a descriptor indexing operation and anything after the block
335       * decorated struct is a buffer offset operation.
336       */
337
338      /* Figure out the descriptor array index if any
339       *
340       * Some of the Vulkan CTS tests with hand-rolled SPIR-V have been known
341       * to forget the Block or BufferBlock decoration from time to time.
342       * It's more robust if we check for both !block_index and for the type
343       * to contain a block.  This way there's a decent chance that arrays of
344       * UBOs/SSBOs will work correctly even if variable pointers are
345       * completley toast.
346       */
347      nir_ssa_def *desc_arr_idx = NULL;
348      if (!block_index || vtn_type_contains_block(b, type) ||
349          base->mode == vtn_variable_mode_accel_struct) {
350         /* If our type contains a block, then we're still outside the block
351          * and we need to process enough levels of dereferences to get inside
352          * of it.  Same applies to acceleration structures.
353          */
354         if (deref_chain->ptr_as_array) {
355            unsigned aoa_size = glsl_get_aoa_size(type->type);
356            desc_arr_idx = vtn_access_link_as_ssa(b, deref_chain->link[idx],
357                                                  MAX2(aoa_size, 1), 32);
358            idx++;
359         }
360
361         for (; idx < deref_chain->length; idx++) {
362            if (type->base_type != vtn_base_type_array) {
363               vtn_assert(type->base_type == vtn_base_type_struct);
364               break;
365            }
366
367            unsigned aoa_size = glsl_get_aoa_size(type->array_element->type);
368            nir_ssa_def *arr_offset =
369               vtn_access_link_as_ssa(b, deref_chain->link[idx],
370                                      MAX2(aoa_size, 1), 32);
371            if (desc_arr_idx)
372               desc_arr_idx = nir_iadd(&b->nb, desc_arr_idx, arr_offset);
373            else
374               desc_arr_idx = arr_offset;
375
376            type = type->array_element;
377            access |= type->access;
378         }
379      }
380
381      if (!block_index) {
382         vtn_assert(base->var && base->type);
383         block_index = vtn_variable_resource_index(b, base->var, desc_arr_idx);
384      } else if (desc_arr_idx) {
385         block_index = vtn_resource_reindex(b, base->mode,
386                                            block_index, desc_arr_idx);
387      }
388
389      if (idx == deref_chain->length) {
390         /* The entire deref was consumed in finding the block index.  Return
391          * a pointer which just has a block index and a later access chain
392          * will dereference deeper.
393          */
394         struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);
395         ptr->mode = base->mode;
396         ptr->type = type;
397         ptr->block_index = block_index;
398         ptr->access = access;
399         return ptr;
400      }
401
402      /* If we got here, there's more access chain to handle and we have the
403       * final block index.  Insert a descriptor load and cast to a deref to
404       * start the deref chain.
405       */
406      nir_ssa_def *desc = vtn_descriptor_load(b, base->mode, block_index);
407
408      assert(base->mode == vtn_variable_mode_ssbo ||
409             base->mode == vtn_variable_mode_ubo);
410      nir_variable_mode nir_mode =
411         base->mode == vtn_variable_mode_ssbo ? nir_var_mem_ssbo : nir_var_mem_ubo;
412
413      tail = nir_build_deref_cast(&b->nb, desc, nir_mode,
414                                  vtn_type_get_nir_type(b, type, base->mode),
415                                  base->ptr_type->stride);
416   } else if (base->mode == vtn_variable_mode_shader_record) {
417      /* For ShaderRecordBufferKHR variables, we don't have a nir_variable.
418       * It's just a fancy handle around a pointer to the shader record for
419       * the current shader.
420       */
421      tail = nir_build_deref_cast(&b->nb, nir_load_shader_record_ptr(&b->nb),
422                                  nir_var_mem_constant,
423                                  vtn_type_get_nir_type(b, base->type,
424                                                           base->mode),
425                                  0 /* ptr_as_array stride */);
426   } else {
427      assert(base->var && base->var->var);
428      tail = nir_build_deref_var(&b->nb, base->var->var);
429      if (base->ptr_type && base->ptr_type->type) {
430         tail->dest.ssa.num_components =
431            glsl_get_vector_elements(base->ptr_type->type);
432         tail->dest.ssa.bit_size = glsl_get_bit_size(base->ptr_type->type);
433      }
434   }
435
436   if (idx == 0 && deref_chain->ptr_as_array) {
437      /* We start with a deref cast to get the stride.  Hopefully, we'll be
438       * able to delete that cast eventually.
439       */
440      tail = nir_build_deref_cast(&b->nb, &tail->dest.ssa, tail->modes,
441                                  tail->type, base->ptr_type->stride);
442
443      nir_ssa_def *index = vtn_access_link_as_ssa(b, deref_chain->link[0], 1,
444                                                  tail->dest.ssa.bit_size);
445      tail = nir_build_deref_ptr_as_array(&b->nb, tail, index);
446      idx++;
447   }
448
449   for (; idx < deref_chain->length; idx++) {
450      if (glsl_type_is_struct_or_ifc(type->type)) {
451         vtn_assert(deref_chain->link[idx].mode == vtn_access_mode_literal);
452         unsigned field = deref_chain->link[idx].id;
453         tail = nir_build_deref_struct(&b->nb, tail, field);
454         type = type->members[field];
455      } else {
456         nir_ssa_def *arr_index =
457            vtn_access_link_as_ssa(b, deref_chain->link[idx], 1,
458                                   tail->dest.ssa.bit_size);
459         tail = nir_build_deref_array(&b->nb, tail, arr_index);
460         type = type->array_element;
461      }
462
463      access |= type->access;
464   }
465
466   struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);
467   ptr->mode = base->mode;
468   ptr->type = type;
469   ptr->var = base->var;
470   ptr->deref = tail;
471   ptr->access = access;
472
473   return ptr;
474}
475
476nir_deref_instr *
477vtn_pointer_to_deref(struct vtn_builder *b, struct vtn_pointer *ptr)
478{
479   if (!ptr->deref) {
480      struct vtn_access_chain chain = {
481         .length = 0,
482      };
483      ptr = vtn_pointer_dereference(b, ptr, &chain);
484   }
485
486   return ptr->deref;
487}
488
489static void
490_vtn_local_load_store(struct vtn_builder *b, bool load, nir_deref_instr *deref,
491                      struct vtn_ssa_value *inout,
492                      enum gl_access_qualifier access)
493{
494   if (glsl_type_is_vector_or_scalar(deref->type)) {
495      if (load) {
496         inout->def = nir_load_deref_with_access(&b->nb, deref, access);
497      } else {
498         nir_store_deref_with_access(&b->nb, deref, inout->def, ~0, access);
499      }
500   } else if (glsl_type_is_array(deref->type) ||
501              glsl_type_is_matrix(deref->type)) {
502      unsigned elems = glsl_get_length(deref->type);
503      for (unsigned i = 0; i < elems; i++) {
504         nir_deref_instr *child =
505            nir_build_deref_array_imm(&b->nb, deref, i);
506         _vtn_local_load_store(b, load, child, inout->elems[i], access);
507      }
508   } else {
509      vtn_assert(glsl_type_is_struct_or_ifc(deref->type));
510      unsigned elems = glsl_get_length(deref->type);
511      for (unsigned i = 0; i < elems; i++) {
512         nir_deref_instr *child = nir_build_deref_struct(&b->nb, deref, i);
513         _vtn_local_load_store(b, load, child, inout->elems[i], access);
514      }
515   }
516}
517
518nir_deref_instr *
519vtn_nir_deref(struct vtn_builder *b, uint32_t id)
520{
521   struct vtn_pointer *ptr = vtn_pointer(b, id);
522   return vtn_pointer_to_deref(b, ptr);
523}
524
525/*
526 * Gets the NIR-level deref tail, which may have as a child an array deref
527 * selecting which component due to OpAccessChain supporting per-component
528 * indexing in SPIR-V.
529 */
530static nir_deref_instr *
531get_deref_tail(nir_deref_instr *deref)
532{
533   if (deref->deref_type != nir_deref_type_array)
534      return deref;
535
536   nir_deref_instr *parent =
537      nir_instr_as_deref(deref->parent.ssa->parent_instr);
538
539   if (glsl_type_is_vector(parent->type))
540      return parent;
541   else
542      return deref;
543}
544
545struct vtn_ssa_value *
546vtn_local_load(struct vtn_builder *b, nir_deref_instr *src,
547               enum gl_access_qualifier access)
548{
549   nir_deref_instr *src_tail = get_deref_tail(src);
550   struct vtn_ssa_value *val = vtn_create_ssa_value(b, src_tail->type);
551   _vtn_local_load_store(b, true, src_tail, val, access);
552
553   if (src_tail != src) {
554      val->type = src->type;
555      val->def = nir_vector_extract(&b->nb, val->def, src->arr.index.ssa);
556   }
557
558   return val;
559}
560
561void
562vtn_local_store(struct vtn_builder *b, struct vtn_ssa_value *src,
563                nir_deref_instr *dest, enum gl_access_qualifier access)
564{
565   nir_deref_instr *dest_tail = get_deref_tail(dest);
566
567   if (dest_tail != dest) {
568      struct vtn_ssa_value *val = vtn_create_ssa_value(b, dest_tail->type);
569      _vtn_local_load_store(b, true, dest_tail, val, access);
570
571      val->def = nir_vector_insert(&b->nb, val->def, src->def,
572                                   dest->arr.index.ssa);
573      _vtn_local_load_store(b, false, dest_tail, val, access);
574   } else {
575      _vtn_local_load_store(b, false, dest_tail, src, access);
576   }
577}
578
579static nir_ssa_def *
580vtn_pointer_to_descriptor(struct vtn_builder *b, struct vtn_pointer *ptr)
581{
582   assert(ptr->mode == vtn_variable_mode_accel_struct);
583   if (!ptr->block_index) {
584      struct vtn_access_chain chain = {
585         .length = 0,
586      };
587      ptr = vtn_pointer_dereference(b, ptr, &chain);
588   }
589
590   vtn_assert(ptr->deref == NULL && ptr->block_index != NULL);
591   return vtn_descriptor_load(b, ptr->mode, ptr->block_index);
592}
593
594static void
595_vtn_variable_load_store(struct vtn_builder *b, bool load,
596                         struct vtn_pointer *ptr,
597                         enum gl_access_qualifier access,
598                         struct vtn_ssa_value **inout)
599{
600   if (ptr->mode == vtn_variable_mode_uniform) {
601      if (ptr->type->base_type == vtn_base_type_image ||
602          ptr->type->base_type == vtn_base_type_sampler) {
603         /* See also our handling of OpTypeSampler and OpTypeImage */
604         vtn_assert(load);
605         (*inout)->def = vtn_pointer_to_ssa(b, ptr);
606         return;
607      } else if (ptr->type->base_type == vtn_base_type_sampled_image) {
608         /* See also our handling of OpTypeSampledImage */
609         vtn_assert(load);
610         struct vtn_sampled_image si = {
611            .image = vtn_pointer_to_deref(b, ptr),
612            .sampler = vtn_pointer_to_deref(b, ptr),
613         };
614         (*inout)->def = vtn_sampled_image_to_nir_ssa(b, si);
615         return;
616      }
617   } else if (ptr->mode == vtn_variable_mode_accel_struct) {
618      vtn_assert(load);
619      (*inout)->def = vtn_pointer_to_descriptor(b, ptr);
620      return;
621   }
622
623   enum glsl_base_type base_type = glsl_get_base_type(ptr->type->type);
624   switch (base_type) {
625   case GLSL_TYPE_UINT:
626   case GLSL_TYPE_INT:
627   case GLSL_TYPE_UINT16:
628   case GLSL_TYPE_INT16:
629   case GLSL_TYPE_UINT8:
630   case GLSL_TYPE_INT8:
631   case GLSL_TYPE_UINT64:
632   case GLSL_TYPE_INT64:
633   case GLSL_TYPE_FLOAT:
634   case GLSL_TYPE_FLOAT16:
635   case GLSL_TYPE_BOOL:
636   case GLSL_TYPE_DOUBLE:
637      if (glsl_type_is_vector_or_scalar(ptr->type->type)) {
638         /* We hit a vector or scalar; go ahead and emit the load[s] */
639         nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
640         if (vtn_mode_is_cross_invocation(b, ptr->mode)) {
641            /* If it's cross-invocation, we call nir_load/store_deref
642             * directly.  The vtn_local_load/store helpers are too clever and
643             * do magic to avoid array derefs of vectors.  That magic is both
644             * less efficient than the direct load/store and, in the case of
645             * stores, is broken because it creates a race condition if two
646             * threads are writing to different components of the same vector
647             * due to the load+insert+store it uses to emulate the array
648             * deref.
649             */
650            if (load) {
651               (*inout)->def = nir_load_deref_with_access(&b->nb, deref,
652                                                          ptr->type->access | access);
653            } else {
654               nir_store_deref_with_access(&b->nb, deref, (*inout)->def, ~0,
655                                           ptr->type->access | access);
656            }
657         } else {
658            if (load) {
659               *inout = vtn_local_load(b, deref, ptr->type->access | access);
660            } else {
661               vtn_local_store(b, *inout, deref, ptr->type->access | access);
662            }
663         }
664         return;
665      }
666      FALLTHROUGH;
667
668   case GLSL_TYPE_INTERFACE:
669   case GLSL_TYPE_ARRAY:
670   case GLSL_TYPE_STRUCT: {
671      unsigned elems = glsl_get_length(ptr->type->type);
672      struct vtn_access_chain chain = {
673         .length = 1,
674         .link = {
675            { .mode = vtn_access_mode_literal, },
676         }
677      };
678      for (unsigned i = 0; i < elems; i++) {
679         chain.link[0].id = i;
680         struct vtn_pointer *elem = vtn_pointer_dereference(b, ptr, &chain);
681         _vtn_variable_load_store(b, load, elem, ptr->type->access | access,
682                                  &(*inout)->elems[i]);
683      }
684      return;
685   }
686
687   default:
688      vtn_fail("Invalid access chain type");
689   }
690}
691
692struct vtn_ssa_value *
693vtn_variable_load(struct vtn_builder *b, struct vtn_pointer *src,
694                  enum gl_access_qualifier access)
695{
696   struct vtn_ssa_value *val = vtn_create_ssa_value(b, src->type->type);
697   _vtn_variable_load_store(b, true, src, src->access | access, &val);
698   return val;
699}
700
701void
702vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
703                   struct vtn_pointer *dest, enum gl_access_qualifier access)
704{
705   _vtn_variable_load_store(b, false, dest, dest->access | access, &src);
706}
707
708static void
709_vtn_variable_copy(struct vtn_builder *b, struct vtn_pointer *dest,
710                   struct vtn_pointer *src, enum gl_access_qualifier dest_access,
711                   enum gl_access_qualifier src_access)
712{
713   vtn_assert(glsl_get_bare_type(src->type->type) ==
714              glsl_get_bare_type(dest->type->type));
715   enum glsl_base_type base_type = glsl_get_base_type(src->type->type);
716   switch (base_type) {
717   case GLSL_TYPE_UINT:
718   case GLSL_TYPE_INT:
719   case GLSL_TYPE_UINT16:
720   case GLSL_TYPE_INT16:
721   case GLSL_TYPE_UINT8:
722   case GLSL_TYPE_INT8:
723   case GLSL_TYPE_UINT64:
724   case GLSL_TYPE_INT64:
725   case GLSL_TYPE_FLOAT:
726   case GLSL_TYPE_FLOAT16:
727   case GLSL_TYPE_DOUBLE:
728   case GLSL_TYPE_BOOL:
729      /* At this point, we have a scalar, vector, or matrix so we know that
730       * there cannot be any structure splitting still in the way.  By
731       * stopping at the matrix level rather than the vector level, we
732       * ensure that matrices get loaded in the optimal way even if they
733       * are storred row-major in a UBO.
734       */
735      vtn_variable_store(b, vtn_variable_load(b, src, src_access), dest, dest_access);
736      return;
737
738   case GLSL_TYPE_INTERFACE:
739   case GLSL_TYPE_ARRAY:
740   case GLSL_TYPE_STRUCT: {
741      struct vtn_access_chain chain = {
742         .length = 1,
743         .link = {
744            { .mode = vtn_access_mode_literal, },
745         }
746      };
747      unsigned elems = glsl_get_length(src->type->type);
748      for (unsigned i = 0; i < elems; i++) {
749         chain.link[0].id = i;
750         struct vtn_pointer *src_elem =
751            vtn_pointer_dereference(b, src, &chain);
752         struct vtn_pointer *dest_elem =
753            vtn_pointer_dereference(b, dest, &chain);
754
755         _vtn_variable_copy(b, dest_elem, src_elem, dest_access, src_access);
756      }
757      return;
758   }
759
760   default:
761      vtn_fail("Invalid access chain type");
762   }
763}
764
765static void
766vtn_variable_copy(struct vtn_builder *b, struct vtn_pointer *dest,
767                  struct vtn_pointer *src, enum gl_access_qualifier dest_access,
768                  enum gl_access_qualifier src_access)
769{
770   /* TODO: At some point, we should add a special-case for when we can
771    * just emit a copy_var intrinsic.
772    */
773   _vtn_variable_copy(b, dest, src, dest_access, src_access);
774}
775
776static void
777set_mode_system_value(struct vtn_builder *b, nir_variable_mode *mode)
778{
779   vtn_assert(*mode == nir_var_system_value || *mode == nir_var_shader_in);
780   *mode = nir_var_system_value;
781}
782
783static void
784vtn_get_builtin_location(struct vtn_builder *b,
785                         SpvBuiltIn builtin, int *location,
786                         nir_variable_mode *mode)
787{
788   switch (builtin) {
789   case SpvBuiltInPosition:
790   case SpvBuiltInPositionPerViewNV:
791      *location = VARYING_SLOT_POS;
792      break;
793   case SpvBuiltInPointSize:
794      *location = VARYING_SLOT_PSIZ;
795      break;
796   case SpvBuiltInClipDistance:
797   case SpvBuiltInClipDistancePerViewNV:
798      *location = VARYING_SLOT_CLIP_DIST0;
799      break;
800   case SpvBuiltInCullDistance:
801   case SpvBuiltInCullDistancePerViewNV:
802      *location = VARYING_SLOT_CULL_DIST0;
803      break;
804   case SpvBuiltInVertexId:
805   case SpvBuiltInVertexIndex:
806      /* The Vulkan spec defines VertexIndex to be non-zero-based and doesn't
807       * allow VertexId.  The ARB_gl_spirv spec defines VertexId to be the
808       * same as gl_VertexID, which is non-zero-based, and removes
809       * VertexIndex.  Since they're both defined to be non-zero-based, we use
810       * SYSTEM_VALUE_VERTEX_ID for both.
811       */
812      *location = SYSTEM_VALUE_VERTEX_ID;
813      set_mode_system_value(b, mode);
814      break;
815   case SpvBuiltInInstanceIndex:
816      *location = SYSTEM_VALUE_INSTANCE_INDEX;
817      set_mode_system_value(b, mode);
818      break;
819   case SpvBuiltInInstanceId:
820      *location = SYSTEM_VALUE_INSTANCE_ID;
821      set_mode_system_value(b, mode);
822      break;
823   case SpvBuiltInPrimitiveId:
824      if (b->shader->info.stage == MESA_SHADER_FRAGMENT) {
825         vtn_assert(*mode == nir_var_shader_in);
826         *location = VARYING_SLOT_PRIMITIVE_ID;
827      } else if (*mode == nir_var_shader_out) {
828         *location = VARYING_SLOT_PRIMITIVE_ID;
829      } else {
830         *location = SYSTEM_VALUE_PRIMITIVE_ID;
831         set_mode_system_value(b, mode);
832      }
833      break;
834   case SpvBuiltInInvocationId:
835      *location = SYSTEM_VALUE_INVOCATION_ID;
836      set_mode_system_value(b, mode);
837      break;
838   case SpvBuiltInLayer:
839      *location = VARYING_SLOT_LAYER;
840      if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
841         *mode = nir_var_shader_in;
842      else if (b->shader->info.stage == MESA_SHADER_GEOMETRY)
843         *mode = nir_var_shader_out;
844      else if (b->options && b->options->caps.shader_viewport_index_layer &&
845               (b->shader->info.stage == MESA_SHADER_VERTEX ||
846                b->shader->info.stage == MESA_SHADER_TESS_EVAL ||
847                b->shader->info.stage == MESA_SHADER_MESH))
848         *mode = nir_var_shader_out;
849      else
850         vtn_fail("invalid stage for SpvBuiltInLayer");
851      break;
852   case SpvBuiltInViewportIndex:
853      *location = VARYING_SLOT_VIEWPORT;
854      if (b->shader->info.stage == MESA_SHADER_GEOMETRY)
855         *mode = nir_var_shader_out;
856      else if (b->options && b->options->caps.shader_viewport_index_layer &&
857               (b->shader->info.stage == MESA_SHADER_VERTEX ||
858                b->shader->info.stage == MESA_SHADER_TESS_EVAL ||
859                b->shader->info.stage == MESA_SHADER_MESH))
860         *mode = nir_var_shader_out;
861      else if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
862         *mode = nir_var_shader_in;
863      else
864         vtn_fail("invalid stage for SpvBuiltInViewportIndex");
865      break;
866   case SpvBuiltInTessLevelOuter:
867      *location = VARYING_SLOT_TESS_LEVEL_OUTER;
868      break;
869   case SpvBuiltInTessLevelInner:
870      *location = VARYING_SLOT_TESS_LEVEL_INNER;
871      break;
872   case SpvBuiltInTessCoord:
873      *location = SYSTEM_VALUE_TESS_COORD;
874      set_mode_system_value(b, mode);
875      break;
876   case SpvBuiltInPatchVertices:
877      *location = SYSTEM_VALUE_VERTICES_IN;
878      set_mode_system_value(b, mode);
879      break;
880   case SpvBuiltInFragCoord:
881      vtn_assert(*mode == nir_var_shader_in);
882      *mode = nir_var_system_value;
883      *location = SYSTEM_VALUE_FRAG_COORD;
884      break;
885   case SpvBuiltInPointCoord:
886      vtn_assert(*mode == nir_var_shader_in);
887      set_mode_system_value(b, mode);
888      *location = SYSTEM_VALUE_POINT_COORD;
889      break;
890   case SpvBuiltInFrontFacing:
891      *location = SYSTEM_VALUE_FRONT_FACE;
892      set_mode_system_value(b, mode);
893      break;
894   case SpvBuiltInSampleId:
895      *location = SYSTEM_VALUE_SAMPLE_ID;
896      set_mode_system_value(b, mode);
897      break;
898   case SpvBuiltInSamplePosition:
899      *location = SYSTEM_VALUE_SAMPLE_POS;
900      set_mode_system_value(b, mode);
901      break;
902   case SpvBuiltInSampleMask:
903      if (*mode == nir_var_shader_out) {
904         *location = FRAG_RESULT_SAMPLE_MASK;
905      } else {
906         *location = SYSTEM_VALUE_SAMPLE_MASK_IN;
907         set_mode_system_value(b, mode);
908      }
909      break;
910   case SpvBuiltInFragDepth:
911      *location = FRAG_RESULT_DEPTH;
912      vtn_assert(*mode == nir_var_shader_out);
913      break;
914   case SpvBuiltInHelperInvocation:
915      *location = SYSTEM_VALUE_HELPER_INVOCATION;
916      set_mode_system_value(b, mode);
917      break;
918   case SpvBuiltInNumWorkgroups:
919      *location = SYSTEM_VALUE_NUM_WORKGROUPS;
920      set_mode_system_value(b, mode);
921      break;
922   case SpvBuiltInWorkgroupSize:
923   case SpvBuiltInEnqueuedWorkgroupSize:
924      *location = SYSTEM_VALUE_WORKGROUP_SIZE;
925      set_mode_system_value(b, mode);
926      break;
927   case SpvBuiltInWorkgroupId:
928      *location = SYSTEM_VALUE_WORKGROUP_ID;
929      set_mode_system_value(b, mode);
930      break;
931   case SpvBuiltInLocalInvocationId:
932      *location = SYSTEM_VALUE_LOCAL_INVOCATION_ID;
933      set_mode_system_value(b, mode);
934      break;
935   case SpvBuiltInLocalInvocationIndex:
936      *location = SYSTEM_VALUE_LOCAL_INVOCATION_INDEX;
937      set_mode_system_value(b, mode);
938      break;
939   case SpvBuiltInGlobalInvocationId:
940      *location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
941      set_mode_system_value(b, mode);
942      break;
943   case SpvBuiltInGlobalLinearId:
944      *location = SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX;
945      set_mode_system_value(b, mode);
946      break;
947   case SpvBuiltInGlobalOffset:
948      *location = SYSTEM_VALUE_BASE_GLOBAL_INVOCATION_ID;
949      set_mode_system_value(b, mode);
950      break;
951   case SpvBuiltInBaseVertex:
952      /* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same
953       * semantic as Vulkan BaseVertex (SYSTEM_VALUE_FIRST_VERTEX).
954       */
955      if (b->options->environment == NIR_SPIRV_OPENGL)
956         *location = SYSTEM_VALUE_BASE_VERTEX;
957      else
958         *location = SYSTEM_VALUE_FIRST_VERTEX;
959      set_mode_system_value(b, mode);
960      break;
961   case SpvBuiltInBaseInstance:
962      *location = SYSTEM_VALUE_BASE_INSTANCE;
963      set_mode_system_value(b, mode);
964      break;
965   case SpvBuiltInDrawIndex:
966      *location = SYSTEM_VALUE_DRAW_ID;
967      set_mode_system_value(b, mode);
968      break;
969   case SpvBuiltInSubgroupSize:
970      *location = SYSTEM_VALUE_SUBGROUP_SIZE;
971      set_mode_system_value(b, mode);
972      break;
973   case SpvBuiltInSubgroupId:
974      *location = SYSTEM_VALUE_SUBGROUP_ID;
975      set_mode_system_value(b, mode);
976      break;
977   case SpvBuiltInSubgroupLocalInvocationId:
978      *location = SYSTEM_VALUE_SUBGROUP_INVOCATION;
979      set_mode_system_value(b, mode);
980      break;
981   case SpvBuiltInNumSubgroups:
982      *location = SYSTEM_VALUE_NUM_SUBGROUPS;
983      set_mode_system_value(b, mode);
984      break;
985   case SpvBuiltInDeviceIndex:
986      *location = SYSTEM_VALUE_DEVICE_INDEX;
987      set_mode_system_value(b, mode);
988      break;
989   case SpvBuiltInViewIndex:
990      if (b->options && b->options->view_index_is_input) {
991         *location = VARYING_SLOT_VIEW_INDEX;
992         vtn_assert(*mode == nir_var_shader_in);
993      } else {
994         *location = SYSTEM_VALUE_VIEW_INDEX;
995         set_mode_system_value(b, mode);
996      }
997      break;
998   case SpvBuiltInSubgroupEqMask:
999      *location = SYSTEM_VALUE_SUBGROUP_EQ_MASK,
1000      set_mode_system_value(b, mode);
1001      break;
1002   case SpvBuiltInSubgroupGeMask:
1003      *location = SYSTEM_VALUE_SUBGROUP_GE_MASK,
1004      set_mode_system_value(b, mode);
1005      break;
1006   case SpvBuiltInSubgroupGtMask:
1007      *location = SYSTEM_VALUE_SUBGROUP_GT_MASK,
1008      set_mode_system_value(b, mode);
1009      break;
1010   case SpvBuiltInSubgroupLeMask:
1011      *location = SYSTEM_VALUE_SUBGROUP_LE_MASK,
1012      set_mode_system_value(b, mode);
1013      break;
1014   case SpvBuiltInSubgroupLtMask:
1015      *location = SYSTEM_VALUE_SUBGROUP_LT_MASK,
1016      set_mode_system_value(b, mode);
1017      break;
1018   case SpvBuiltInFragStencilRefEXT:
1019      *location = FRAG_RESULT_STENCIL;
1020      vtn_assert(*mode == nir_var_shader_out);
1021      break;
1022   case SpvBuiltInWorkDim:
1023      *location = SYSTEM_VALUE_WORK_DIM;
1024      set_mode_system_value(b, mode);
1025      break;
1026   case SpvBuiltInGlobalSize:
1027      *location = SYSTEM_VALUE_GLOBAL_GROUP_SIZE;
1028      set_mode_system_value(b, mode);
1029      break;
1030   case SpvBuiltInBaryCoordNoPerspAMD:
1031      *location = SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL;
1032      set_mode_system_value(b, mode);
1033      break;
1034   case SpvBuiltInBaryCoordNoPerspCentroidAMD:
1035      *location = SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID;
1036      set_mode_system_value(b, mode);
1037      break;
1038   case SpvBuiltInBaryCoordNoPerspSampleAMD:
1039      *location = SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE;
1040      set_mode_system_value(b, mode);
1041      break;
1042   case SpvBuiltInBaryCoordSmoothAMD:
1043      *location = SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL;
1044      set_mode_system_value(b, mode);
1045      break;
1046   case SpvBuiltInBaryCoordSmoothCentroidAMD:
1047      *location = SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID;
1048      set_mode_system_value(b, mode);
1049      break;
1050   case SpvBuiltInBaryCoordSmoothSampleAMD:
1051      *location = SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE;
1052      set_mode_system_value(b, mode);
1053      break;
1054   case SpvBuiltInBaryCoordPullModelAMD:
1055      *location = SYSTEM_VALUE_BARYCENTRIC_PULL_MODEL;
1056      set_mode_system_value(b, mode);
1057      break;
1058   case SpvBuiltInLaunchIdKHR:
1059      *location = SYSTEM_VALUE_RAY_LAUNCH_ID;
1060      set_mode_system_value(b, mode);
1061      break;
1062   case SpvBuiltInLaunchSizeKHR:
1063      *location = SYSTEM_VALUE_RAY_LAUNCH_SIZE;
1064      set_mode_system_value(b, mode);
1065      break;
1066   case SpvBuiltInWorldRayOriginKHR:
1067      *location = SYSTEM_VALUE_RAY_WORLD_ORIGIN;
1068      set_mode_system_value(b, mode);
1069      break;
1070   case SpvBuiltInWorldRayDirectionKHR:
1071      *location = SYSTEM_VALUE_RAY_WORLD_DIRECTION;
1072      set_mode_system_value(b, mode);
1073      break;
1074   case SpvBuiltInObjectRayOriginKHR:
1075      *location = SYSTEM_VALUE_RAY_OBJECT_ORIGIN;
1076      set_mode_system_value(b, mode);
1077      break;
1078   case SpvBuiltInObjectRayDirectionKHR:
1079      *location = SYSTEM_VALUE_RAY_OBJECT_DIRECTION;
1080      set_mode_system_value(b, mode);
1081      break;
1082   case SpvBuiltInObjectToWorldKHR:
1083      *location = SYSTEM_VALUE_RAY_OBJECT_TO_WORLD;
1084      set_mode_system_value(b, mode);
1085      break;
1086   case SpvBuiltInWorldToObjectKHR:
1087      *location = SYSTEM_VALUE_RAY_WORLD_TO_OBJECT;
1088      set_mode_system_value(b, mode);
1089      break;
1090   case SpvBuiltInRayTminKHR:
1091      *location = SYSTEM_VALUE_RAY_T_MIN;
1092      set_mode_system_value(b, mode);
1093      break;
1094   case SpvBuiltInRayTmaxKHR:
1095   case SpvBuiltInHitTNV:
1096      *location = SYSTEM_VALUE_RAY_T_MAX;
1097      set_mode_system_value(b, mode);
1098      break;
1099   case SpvBuiltInInstanceCustomIndexKHR:
1100      *location = SYSTEM_VALUE_RAY_INSTANCE_CUSTOM_INDEX;
1101      set_mode_system_value(b, mode);
1102      break;
1103   case SpvBuiltInHitKindKHR:
1104      *location = SYSTEM_VALUE_RAY_HIT_KIND;
1105      set_mode_system_value(b, mode);
1106      break;
1107   case SpvBuiltInIncomingRayFlagsKHR:
1108      *location = SYSTEM_VALUE_RAY_FLAGS;
1109      set_mode_system_value(b, mode);
1110      break;
1111   case SpvBuiltInRayGeometryIndexKHR:
1112      *location = SYSTEM_VALUE_RAY_GEOMETRY_INDEX;
1113      set_mode_system_value(b, mode);
1114      break;
1115   case SpvBuiltInShadingRateKHR:
1116      *location = SYSTEM_VALUE_FRAG_SHADING_RATE;
1117      set_mode_system_value(b, mode);
1118      break;
1119   case SpvBuiltInPrimitiveShadingRateKHR:
1120      if (b->shader->info.stage == MESA_SHADER_VERTEX ||
1121          b->shader->info.stage == MESA_SHADER_GEOMETRY) {
1122         *location = VARYING_SLOT_PRIMITIVE_SHADING_RATE;
1123         *mode = nir_var_shader_out;
1124      } else {
1125         vtn_fail("invalid stage for SpvBuiltInPrimitiveShadingRateKHR");
1126      }
1127      break;
1128   case SpvBuiltInPrimitiveCountNV:
1129      *location = VARYING_SLOT_PRIMITIVE_COUNT;
1130      break;
1131   case SpvBuiltInPrimitiveIndicesNV:
1132      *location = VARYING_SLOT_PRIMITIVE_INDICES;
1133      break;
1134   case SpvBuiltInTaskCountNV:
1135      *location = VARYING_SLOT_TASK_COUNT;
1136      break;
1137   default:
1138      vtn_fail("Unsupported builtin: %s (%u)",
1139               spirv_builtin_to_string(builtin), builtin);
1140   }
1141}
1142
1143static void
1144apply_var_decoration(struct vtn_builder *b,
1145                     struct nir_variable_data *var_data,
1146                     const struct vtn_decoration *dec)
1147{
1148   switch (dec->decoration) {
1149   case SpvDecorationRelaxedPrecision:
1150      var_data->precision = GLSL_PRECISION_MEDIUM;
1151      break;
1152   case SpvDecorationNoPerspective:
1153      var_data->interpolation = INTERP_MODE_NOPERSPECTIVE;
1154      break;
1155   case SpvDecorationFlat:
1156      var_data->interpolation = INTERP_MODE_FLAT;
1157      break;
1158   case SpvDecorationExplicitInterpAMD:
1159      var_data->interpolation = INTERP_MODE_EXPLICIT;
1160      break;
1161   case SpvDecorationCentroid:
1162      var_data->centroid = true;
1163      break;
1164   case SpvDecorationSample:
1165      var_data->sample = true;
1166      break;
1167   case SpvDecorationInvariant:
1168      var_data->invariant = true;
1169      break;
1170   case SpvDecorationConstant:
1171      var_data->read_only = true;
1172      break;
1173   case SpvDecorationNonReadable:
1174      var_data->access |= ACCESS_NON_READABLE;
1175      break;
1176   case SpvDecorationNonWritable:
1177      var_data->read_only = true;
1178      var_data->access |= ACCESS_NON_WRITEABLE;
1179      break;
1180   case SpvDecorationRestrict:
1181      var_data->access |= ACCESS_RESTRICT;
1182      break;
1183   case SpvDecorationAliased:
1184      var_data->access &= ~ACCESS_RESTRICT;
1185      break;
1186   case SpvDecorationVolatile:
1187      var_data->access |= ACCESS_VOLATILE;
1188      break;
1189   case SpvDecorationCoherent:
1190      var_data->access |= ACCESS_COHERENT;
1191      break;
1192   case SpvDecorationComponent:
1193      var_data->location_frac = dec->operands[0];
1194      break;
1195   case SpvDecorationIndex:
1196      var_data->index = dec->operands[0];
1197      break;
1198   case SpvDecorationBuiltIn: {
1199      SpvBuiltIn builtin = dec->operands[0];
1200
1201      nir_variable_mode mode = var_data->mode;
1202      vtn_get_builtin_location(b, builtin, &var_data->location, &mode);
1203      var_data->mode = mode;
1204
1205      switch (builtin) {
1206      case SpvBuiltInTessLevelOuter:
1207      case SpvBuiltInTessLevelInner:
1208      case SpvBuiltInClipDistance:
1209      case SpvBuiltInCullDistance:
1210         var_data->compact = true;
1211         break;
1212      default:
1213         break;
1214      }
1215
1216      break;
1217   }
1218
1219   case SpvDecorationSpecId:
1220   case SpvDecorationRowMajor:
1221   case SpvDecorationColMajor:
1222   case SpvDecorationMatrixStride:
1223   case SpvDecorationUniform:
1224   case SpvDecorationUniformId:
1225   case SpvDecorationLinkageAttributes:
1226      break; /* Do nothing with these here */
1227
1228   case SpvDecorationPatch:
1229      var_data->patch = true;
1230      break;
1231
1232   case SpvDecorationLocation:
1233      vtn_fail("Should be handled earlier by var_decoration_cb()");
1234
1235   case SpvDecorationBlock:
1236   case SpvDecorationBufferBlock:
1237   case SpvDecorationArrayStride:
1238   case SpvDecorationGLSLShared:
1239   case SpvDecorationGLSLPacked:
1240      break; /* These can apply to a type but we don't care about them */
1241
1242   case SpvDecorationBinding:
1243   case SpvDecorationDescriptorSet:
1244   case SpvDecorationNoContraction:
1245   case SpvDecorationInputAttachmentIndex:
1246      vtn_warn("Decoration not allowed for variable or structure member: %s",
1247               spirv_decoration_to_string(dec->decoration));
1248      break;
1249
1250   case SpvDecorationXfbBuffer:
1251      var_data->explicit_xfb_buffer = true;
1252      var_data->xfb.buffer = dec->operands[0];
1253      var_data->always_active_io = true;
1254      break;
1255   case SpvDecorationXfbStride:
1256      var_data->explicit_xfb_stride = true;
1257      var_data->xfb.stride = dec->operands[0];
1258      break;
1259   case SpvDecorationOffset:
1260      var_data->explicit_offset = true;
1261      var_data->offset = dec->operands[0];
1262      break;
1263
1264   case SpvDecorationStream:
1265      var_data->stream = dec->operands[0];
1266      break;
1267
1268   case SpvDecorationCPacked:
1269   case SpvDecorationSaturatedConversion:
1270   case SpvDecorationFuncParamAttr:
1271   case SpvDecorationFPRoundingMode:
1272   case SpvDecorationFPFastMathMode:
1273   case SpvDecorationAlignment:
1274      if (b->shader->info.stage != MESA_SHADER_KERNEL) {
1275         vtn_warn("Decoration only allowed for CL-style kernels: %s",
1276                  spirv_decoration_to_string(dec->decoration));
1277      }
1278      break;
1279
1280   case SpvDecorationUserSemantic:
1281   case SpvDecorationUserTypeGOOGLE:
1282      /* User semantic decorations can safely be ignored by the driver. */
1283      break;
1284
1285   case SpvDecorationRestrictPointerEXT:
1286   case SpvDecorationAliasedPointerEXT:
1287      /* TODO: We should actually plumb alias information through NIR. */
1288      break;
1289
1290   case SpvDecorationPerPrimitiveNV:
1291      vtn_fail_if(
1292         !(b->shader->info.stage == MESA_SHADER_MESH && var_data->mode == nir_var_shader_out) &&
1293         !(b->shader->info.stage == MESA_SHADER_FRAGMENT && var_data->mode == nir_var_shader_in),
1294         "PerPrimitiveNV decoration only allowed for Mesh shader outputs or Fragment shader inputs");
1295      var_data->per_primitive = true;
1296      break;
1297
1298   case SpvDecorationPerTaskNV:
1299      vtn_fail_if(
1300         !(b->shader->info.stage == MESA_SHADER_TASK && var_data->mode == nir_var_shader_out) &&
1301         !(b->shader->info.stage == MESA_SHADER_MESH && var_data->mode == nir_var_shader_in),
1302         "PerTaskNV decoration only allowed for Task shader outputs or Mesh shader inputs");
1303      /* Don't set anything, because this decoration is implied by being a
1304       * non-builtin Task Output or Mesh Input.
1305       */
1306      break;
1307
1308   case SpvDecorationPerViewNV:
1309      vtn_fail_if(b->shader->info.stage != MESA_SHADER_MESH,
1310                  "PerViewNV decoration only allowed in Mesh shaders");
1311      var_data->per_view = true;
1312      break;
1313
1314   default:
1315      vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
1316   }
1317}
1318
1319static void
1320gather_var_kind_cb(struct vtn_builder *b, struct vtn_value *val, int member,
1321                   const struct vtn_decoration *dec, void *void_var)
1322{
1323   struct vtn_variable *vtn_var = void_var;
1324   switch (dec->decoration) {
1325   case SpvDecorationPatch:
1326      vtn_var->var->data.patch = true;
1327      break;
1328   case SpvDecorationPerPrimitiveNV:
1329      vtn_var->var->data.per_primitive = true;
1330      break;
1331   case SpvDecorationBuiltIn:
1332      if (b->shader->info.stage == MESA_SHADER_MESH) {
1333         SpvBuiltIn builtin = dec->operands[0];
1334         switch (builtin) {
1335         case SpvBuiltInPrimitiveIndicesNV:
1336            vtn_var->var->data.per_primitive = true;
1337            break;
1338         default:
1339            /* Nothing to do. */
1340            break;
1341         }
1342      }
1343      break;
1344   default:
1345      /* Nothing to do. */
1346      break;
1347   }
1348}
1349
1350static void
1351var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
1352                  const struct vtn_decoration *dec, void *void_var)
1353{
1354   struct vtn_variable *vtn_var = void_var;
1355
1356   /* Handle decorations that apply to a vtn_variable as a whole */
1357   switch (dec->decoration) {
1358   case SpvDecorationBinding:
1359      vtn_var->binding = dec->operands[0];
1360      vtn_var->explicit_binding = true;
1361      return;
1362   case SpvDecorationDescriptorSet:
1363      vtn_var->descriptor_set = dec->operands[0];
1364      return;
1365   case SpvDecorationInputAttachmentIndex:
1366      vtn_var->input_attachment_index = dec->operands[0];
1367      return;
1368   case SpvDecorationPatch:
1369      vtn_var->var->data.patch = true;
1370      break;
1371   case SpvDecorationOffset:
1372      vtn_var->offset = dec->operands[0];
1373      break;
1374   case SpvDecorationNonWritable:
1375      vtn_var->access |= ACCESS_NON_WRITEABLE;
1376      break;
1377   case SpvDecorationNonReadable:
1378      vtn_var->access |= ACCESS_NON_READABLE;
1379      break;
1380   case SpvDecorationVolatile:
1381      vtn_var->access |= ACCESS_VOLATILE;
1382      break;
1383   case SpvDecorationCoherent:
1384      vtn_var->access |= ACCESS_COHERENT;
1385      break;
1386   case SpvDecorationCounterBuffer:
1387      /* Counter buffer decorations can safely be ignored by the driver. */
1388      return;
1389   default:
1390      break;
1391   }
1392
1393   if (val->value_type == vtn_value_type_pointer) {
1394      assert(val->pointer->var == void_var);
1395      assert(member == -1);
1396   } else {
1397      assert(val->value_type == vtn_value_type_type);
1398   }
1399
1400   /* Location is odd.  If applied to a split structure, we have to walk the
1401    * whole thing and accumulate the location.  It's easier to handle as a
1402    * special case.
1403    */
1404   if (dec->decoration == SpvDecorationLocation) {
1405      unsigned location = dec->operands[0];
1406      if (b->shader->info.stage == MESA_SHADER_FRAGMENT &&
1407          vtn_var->mode == vtn_variable_mode_output) {
1408         location += FRAG_RESULT_DATA0;
1409      } else if (b->shader->info.stage == MESA_SHADER_VERTEX &&
1410                 vtn_var->mode == vtn_variable_mode_input) {
1411         location += VERT_ATTRIB_GENERIC0;
1412      } else if (vtn_var->mode == vtn_variable_mode_input ||
1413                 vtn_var->mode == vtn_variable_mode_output) {
1414         location += vtn_var->var->data.patch ? VARYING_SLOT_PATCH0 : VARYING_SLOT_VAR0;
1415      } else if (vtn_var->mode == vtn_variable_mode_call_data ||
1416                 vtn_var->mode == vtn_variable_mode_ray_payload) {
1417         /* This location is fine as-is */
1418      } else if (vtn_var->mode != vtn_variable_mode_uniform) {
1419         vtn_warn("Location must be on input, output, uniform, sampler or "
1420                  "image variable");
1421         return;
1422      }
1423
1424      if (vtn_var->var->num_members == 0) {
1425         /* This handles the member and lone variable cases */
1426         vtn_var->var->data.location = location;
1427      } else {
1428         /* This handles the structure member case */
1429         assert(vtn_var->var->members);
1430
1431         if (member == -1)
1432            vtn_var->base_location = location;
1433         else
1434            vtn_var->var->members[member].location = location;
1435      }
1436
1437      return;
1438   } else {
1439      if (vtn_var->var) {
1440         if (vtn_var->var->num_members == 0) {
1441            /* We call this function on types as well as variables and not all
1442             * struct types get split so we can end up having stray member
1443             * decorations; just ignore them.
1444             */
1445            if (member == -1)
1446               apply_var_decoration(b, &vtn_var->var->data, dec);
1447         } else if (member >= 0) {
1448            /* Member decorations must come from a type */
1449            assert(val->value_type == vtn_value_type_type);
1450            apply_var_decoration(b, &vtn_var->var->members[member], dec);
1451         } else {
1452            unsigned length =
1453               glsl_get_length(glsl_without_array(vtn_var->type->type));
1454            for (unsigned i = 0; i < length; i++)
1455               apply_var_decoration(b, &vtn_var->var->members[i], dec);
1456         }
1457      } else {
1458         /* A few variables, those with external storage, have no actual
1459          * nir_variables associated with them.  Fortunately, all decorations
1460          * we care about for those variables are on the type only.
1461          */
1462         vtn_assert(vtn_var->mode == vtn_variable_mode_ubo ||
1463                    vtn_var->mode == vtn_variable_mode_ssbo ||
1464                    vtn_var->mode == vtn_variable_mode_push_constant);
1465      }
1466   }
1467}
1468
1469enum vtn_variable_mode
1470vtn_storage_class_to_mode(struct vtn_builder *b,
1471                          SpvStorageClass class,
1472                          struct vtn_type *interface_type,
1473                          nir_variable_mode *nir_mode_out)
1474{
1475   enum vtn_variable_mode mode;
1476   nir_variable_mode nir_mode;
1477   switch (class) {
1478   case SpvStorageClassUniform:
1479      /* Assume it's an UBO if we lack the interface_type. */
1480      if (!interface_type || interface_type->block) {
1481         mode = vtn_variable_mode_ubo;
1482         nir_mode = nir_var_mem_ubo;
1483      } else if (interface_type->buffer_block) {
1484         mode = vtn_variable_mode_ssbo;
1485         nir_mode = nir_var_mem_ssbo;
1486      } else {
1487         /* Default-block uniforms, coming from gl_spirv */
1488         mode = vtn_variable_mode_uniform;
1489         nir_mode = nir_var_uniform;
1490      }
1491      break;
1492   case SpvStorageClassStorageBuffer:
1493      mode = vtn_variable_mode_ssbo;
1494      nir_mode = nir_var_mem_ssbo;
1495      break;
1496   case SpvStorageClassPhysicalStorageBuffer:
1497      mode = vtn_variable_mode_phys_ssbo;
1498      nir_mode = nir_var_mem_global;
1499      break;
1500   case SpvStorageClassUniformConstant:
1501      if (b->shader->info.stage == MESA_SHADER_KERNEL) {
1502         mode = vtn_variable_mode_constant;
1503         nir_mode = nir_var_mem_constant;
1504      } else {
1505         /* interface_type is only NULL when OpTypeForwardPointer is used and
1506          * OpTypeForwardPointer cannot be used with the UniformConstant
1507          * storage class.
1508          */
1509         assert(interface_type != NULL);
1510         interface_type = vtn_type_without_array(interface_type);
1511         if (interface_type->base_type == vtn_base_type_accel_struct) {
1512            mode = vtn_variable_mode_accel_struct;
1513            nir_mode = nir_var_uniform;
1514         } else {
1515            mode = vtn_variable_mode_uniform;
1516            nir_mode = nir_var_uniform;
1517         }
1518      }
1519      break;
1520   case SpvStorageClassPushConstant:
1521      mode = vtn_variable_mode_push_constant;
1522      nir_mode = nir_var_mem_push_const;
1523      break;
1524   case SpvStorageClassInput:
1525      mode = vtn_variable_mode_input;
1526      nir_mode = nir_var_shader_in;
1527      break;
1528   case SpvStorageClassOutput:
1529      mode = vtn_variable_mode_output;
1530      nir_mode = nir_var_shader_out;
1531      break;
1532   case SpvStorageClassPrivate:
1533      mode = vtn_variable_mode_private;
1534      nir_mode = nir_var_shader_temp;
1535      break;
1536   case SpvStorageClassFunction:
1537      mode = vtn_variable_mode_function;
1538      nir_mode = nir_var_function_temp;
1539      break;
1540   case SpvStorageClassWorkgroup:
1541      mode = vtn_variable_mode_workgroup;
1542      nir_mode = nir_var_mem_shared;
1543      break;
1544   case SpvStorageClassAtomicCounter:
1545      mode = vtn_variable_mode_atomic_counter;
1546      nir_mode = nir_var_uniform;
1547      break;
1548   case SpvStorageClassCrossWorkgroup:
1549      mode = vtn_variable_mode_cross_workgroup;
1550      nir_mode = nir_var_mem_global;
1551      break;
1552   case SpvStorageClassImage:
1553      mode = vtn_variable_mode_image;
1554      nir_mode = nir_var_mem_ubo;
1555      break;
1556   case SpvStorageClassCallableDataKHR:
1557      mode = vtn_variable_mode_call_data;
1558      nir_mode = nir_var_shader_temp;
1559      break;
1560   case SpvStorageClassIncomingCallableDataKHR:
1561      mode = vtn_variable_mode_call_data_in;
1562      nir_mode = nir_var_shader_call_data;
1563      break;
1564   case SpvStorageClassRayPayloadKHR:
1565      mode = vtn_variable_mode_ray_payload;
1566      nir_mode = nir_var_shader_temp;
1567      break;
1568   case SpvStorageClassIncomingRayPayloadKHR:
1569      mode = vtn_variable_mode_ray_payload_in;
1570      nir_mode = nir_var_shader_call_data;
1571      break;
1572   case SpvStorageClassHitAttributeKHR:
1573      mode = vtn_variable_mode_hit_attrib;
1574      nir_mode = nir_var_ray_hit_attrib;
1575      break;
1576   case SpvStorageClassShaderRecordBufferKHR:
1577      mode = vtn_variable_mode_shader_record;
1578      nir_mode = nir_var_mem_constant;
1579      break;
1580
1581   case SpvStorageClassGeneric:
1582      mode = vtn_variable_mode_generic;
1583      nir_mode = nir_var_mem_generic;
1584      break;
1585   default:
1586      vtn_fail("Unhandled variable storage class: %s (%u)",
1587               spirv_storageclass_to_string(class), class);
1588   }
1589
1590   if (nir_mode_out)
1591      *nir_mode_out = nir_mode;
1592
1593   return mode;
1594}
1595
1596nir_address_format
1597vtn_mode_to_address_format(struct vtn_builder *b, enum vtn_variable_mode mode)
1598{
1599   switch (mode) {
1600   case vtn_variable_mode_ubo:
1601      return b->options->ubo_addr_format;
1602
1603   case vtn_variable_mode_ssbo:
1604      return b->options->ssbo_addr_format;
1605
1606   case vtn_variable_mode_phys_ssbo:
1607      return b->options->phys_ssbo_addr_format;
1608
1609   case vtn_variable_mode_push_constant:
1610      return b->options->push_const_addr_format;
1611
1612   case vtn_variable_mode_workgroup:
1613      return b->options->shared_addr_format;
1614
1615   case vtn_variable_mode_generic:
1616   case vtn_variable_mode_cross_workgroup:
1617      return b->options->global_addr_format;
1618
1619   case vtn_variable_mode_shader_record:
1620   case vtn_variable_mode_constant:
1621      return b->options->constant_addr_format;
1622
1623   case vtn_variable_mode_accel_struct:
1624      return nir_address_format_64bit_global;
1625
1626   case vtn_variable_mode_function:
1627      if (b->physical_ptrs)
1628         return b->options->temp_addr_format;
1629      FALLTHROUGH;
1630
1631   case vtn_variable_mode_private:
1632   case vtn_variable_mode_uniform:
1633   case vtn_variable_mode_atomic_counter:
1634   case vtn_variable_mode_input:
1635   case vtn_variable_mode_output:
1636   case vtn_variable_mode_image:
1637   case vtn_variable_mode_call_data:
1638   case vtn_variable_mode_call_data_in:
1639   case vtn_variable_mode_ray_payload:
1640   case vtn_variable_mode_ray_payload_in:
1641   case vtn_variable_mode_hit_attrib:
1642      return nir_address_format_logical;
1643   }
1644
1645   unreachable("Invalid variable mode");
1646}
1647
1648nir_ssa_def *
1649vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr)
1650{
1651   if ((vtn_pointer_is_external_block(b, ptr) &&
1652        vtn_type_contains_block(b, ptr->type) &&
1653        ptr->mode != vtn_variable_mode_phys_ssbo) ||
1654       ptr->mode == vtn_variable_mode_accel_struct) {
1655      /* In this case, we're looking for a block index and not an actual
1656       * deref.
1657       *
1658       * For PhysicalStorageBuffer pointers, we don't have a block index
1659       * at all because we get the pointer directly from the client.  This
1660       * assumes that there will never be a SSBO binding variable using the
1661       * PhysicalStorageBuffer storage class.  This assumption appears
1662       * to be correct according to the Vulkan spec because the table,
1663       * "Shader Resource and Storage Class Correspondence," the only the
1664       * Uniform storage class with BufferBlock or the StorageBuffer
1665       * storage class with Block can be used.
1666       */
1667      if (!ptr->block_index) {
1668         /* If we don't have a block_index then we must be a pointer to the
1669          * variable itself.
1670          */
1671         vtn_assert(!ptr->deref);
1672
1673         struct vtn_access_chain chain = {
1674            .length = 0,
1675         };
1676         ptr = vtn_pointer_dereference(b, ptr, &chain);
1677      }
1678
1679      return ptr->block_index;
1680   } else {
1681      return &vtn_pointer_to_deref(b, ptr)->dest.ssa;
1682   }
1683}
1684
1685struct vtn_pointer *
1686vtn_pointer_from_ssa(struct vtn_builder *b, nir_ssa_def *ssa,
1687                     struct vtn_type *ptr_type)
1688{
1689   vtn_assert(ptr_type->base_type == vtn_base_type_pointer);
1690
1691   struct vtn_pointer *ptr = rzalloc(b, struct vtn_pointer);
1692   struct vtn_type *without_array =
1693      vtn_type_without_array(ptr_type->deref);
1694
1695   nir_variable_mode nir_mode;
1696   ptr->mode = vtn_storage_class_to_mode(b, ptr_type->storage_class,
1697                                         without_array, &nir_mode);
1698   ptr->type = ptr_type->deref;
1699   ptr->ptr_type = ptr_type;
1700
1701   const struct glsl_type *deref_type =
1702      vtn_type_get_nir_type(b, ptr_type->deref, ptr->mode);
1703   if (!vtn_pointer_is_external_block(b, ptr) &&
1704       ptr->mode != vtn_variable_mode_accel_struct) {
1705      ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
1706                                        deref_type, ptr_type->stride);
1707   } else if ((vtn_type_contains_block(b, ptr->type) &&
1708               ptr->mode != vtn_variable_mode_phys_ssbo) ||
1709              ptr->mode == vtn_variable_mode_accel_struct) {
1710      /* This is a pointer to somewhere in an array of blocks, not a
1711       * pointer to somewhere inside the block.  Set the block index
1712       * instead of making a cast.
1713       */
1714      ptr->block_index = ssa;
1715   } else {
1716      /* This is a pointer to something internal or a pointer inside a
1717       * block.  It's just a regular cast.
1718       *
1719       * For PhysicalStorageBuffer pointers, we don't have a block index
1720       * at all because we get the pointer directly from the client.  This
1721       * assumes that there will never be a SSBO binding variable using the
1722       * PhysicalStorageBuffer storage class.  This assumption appears
1723       * to be correct according to the Vulkan spec because the table,
1724       * "Shader Resource and Storage Class Correspondence," the only the
1725       * Uniform storage class with BufferBlock or the StorageBuffer
1726       * storage class with Block can be used.
1727       */
1728      ptr->deref = nir_build_deref_cast(&b->nb, ssa, nir_mode,
1729                                        deref_type, ptr_type->stride);
1730      ptr->deref->dest.ssa.num_components =
1731         glsl_get_vector_elements(ptr_type->type);
1732      ptr->deref->dest.ssa.bit_size = glsl_get_bit_size(ptr_type->type);
1733   }
1734
1735   return ptr;
1736}
1737
1738static void
1739assign_missing_member_locations(struct vtn_variable *var)
1740{
1741   unsigned length =
1742      glsl_get_length(glsl_without_array(var->type->type));
1743   int location = var->base_location;
1744
1745   for (unsigned i = 0; i < length; i++) {
1746      /* From the Vulkan spec:
1747       *
1748       * “If the structure type is a Block but without a Location, then each
1749       *  of its members must have a Location decoration.”
1750       *
1751       */
1752      if (var->type->block) {
1753         assert(var->base_location != -1 ||
1754                var->var->members[i].location != -1);
1755      }
1756
1757      /* From the Vulkan spec:
1758       *
1759       * “Any member with its own Location decoration is assigned that
1760       *  location. Each remaining member is assigned the location after the
1761       *  immediately preceding member in declaration order.”
1762       */
1763      if (var->var->members[i].location != -1)
1764         location = var->var->members[i].location;
1765      else
1766         var->var->members[i].location = location;
1767
1768      /* Below we use type instead of interface_type, because interface_type
1769       * is only available when it is a Block. This code also supports
1770       * input/outputs that are just structs
1771       */
1772      const struct glsl_type *member_type =
1773         glsl_get_struct_field(glsl_without_array(var->type->type), i);
1774
1775      location +=
1776         glsl_count_attribute_slots(member_type,
1777                                    false /* is_gl_vertex_input */);
1778   }
1779}
1780
1781nir_deref_instr *
1782vtn_get_call_payload_for_location(struct vtn_builder *b, uint32_t location_id)
1783{
1784   uint32_t location = vtn_constant_uint(b, location_id);
1785   nir_foreach_variable_with_modes(var, b->nb.shader, nir_var_shader_temp) {
1786      if (var->data.explicit_location &&
1787          var->data.location == location)
1788         return nir_build_deref_var(&b->nb, var);
1789   }
1790   vtn_fail("Couldn't find variable with a storage class of CallableDataKHR "
1791            "or RayPayloadKHR and location %d", location);
1792}
1793
1794static void
1795vtn_create_variable(struct vtn_builder *b, struct vtn_value *val,
1796                    struct vtn_type *ptr_type, SpvStorageClass storage_class,
1797                    struct vtn_value *initializer)
1798{
1799   vtn_assert(ptr_type->base_type == vtn_base_type_pointer);
1800   struct vtn_type *type = ptr_type->deref;
1801
1802   struct vtn_type *without_array = vtn_type_without_array(ptr_type->deref);
1803
1804   enum vtn_variable_mode mode;
1805   nir_variable_mode nir_mode;
1806   mode = vtn_storage_class_to_mode(b, storage_class, without_array, &nir_mode);
1807
1808   switch (mode) {
1809   case vtn_variable_mode_ubo:
1810      /* There's no other way to get vtn_variable_mode_ubo */
1811      vtn_assert(without_array->block);
1812      break;
1813   case vtn_variable_mode_ssbo:
1814      if (storage_class == SpvStorageClassStorageBuffer &&
1815          !without_array->block) {
1816         if (b->variable_pointers) {
1817            vtn_fail("Variables in the StorageBuffer storage class must "
1818                     "have a struct type with the Block decoration");
1819         } else {
1820            /* If variable pointers are not present, it's still malformed
1821             * SPIR-V but we can parse it and do the right thing anyway.
1822             * Since some of the 8-bit storage tests have bugs in this are,
1823             * just make it a warning for now.
1824             */
1825            vtn_warn("Variables in the StorageBuffer storage class must "
1826                     "have a struct type with the Block decoration");
1827         }
1828      }
1829      break;
1830
1831   case vtn_variable_mode_generic:
1832      vtn_fail("Cannot create a variable with the Generic storage class");
1833      break;
1834
1835   case vtn_variable_mode_image:
1836      vtn_fail("Cannot create a variable with the Image storage class");
1837      break;
1838
1839   case vtn_variable_mode_phys_ssbo:
1840      vtn_fail("Cannot create a variable with the "
1841               "PhysicalStorageBuffer storage class");
1842      break;
1843
1844   default:
1845      /* No tallying is needed */
1846      break;
1847   }
1848
1849   struct vtn_variable *var = rzalloc(b, struct vtn_variable);
1850   var->type = type;
1851   var->mode = mode;
1852   var->base_location = -1;
1853
1854   val->pointer = rzalloc(b, struct vtn_pointer);
1855   val->pointer->mode = var->mode;
1856   val->pointer->type = var->type;
1857   val->pointer->ptr_type = ptr_type;
1858   val->pointer->var = var;
1859   val->pointer->access = var->type->access;
1860
1861   switch (var->mode) {
1862   case vtn_variable_mode_function:
1863   case vtn_variable_mode_private:
1864   case vtn_variable_mode_uniform:
1865   case vtn_variable_mode_atomic_counter:
1866   case vtn_variable_mode_constant:
1867   case vtn_variable_mode_call_data:
1868   case vtn_variable_mode_call_data_in:
1869   case vtn_variable_mode_ray_payload:
1870   case vtn_variable_mode_ray_payload_in:
1871   case vtn_variable_mode_hit_attrib:
1872      /* For these, we create the variable normally */
1873      var->var = rzalloc(b->shader, nir_variable);
1874      var->var->name = ralloc_strdup(var->var, val->name);
1875      var->var->type = vtn_type_get_nir_type(b, var->type, var->mode);
1876
1877      /* This is a total hack but we need some way to flag variables which are
1878       * going to be call payloads.  See get_call_payload_deref.
1879       */
1880      if (storage_class == SpvStorageClassCallableDataKHR ||
1881          storage_class == SpvStorageClassRayPayloadKHR)
1882         var->var->data.explicit_location = true;
1883
1884      var->var->data.mode = nir_mode;
1885      var->var->data.location = -1;
1886      var->var->interface_type = NULL;
1887      break;
1888
1889   case vtn_variable_mode_ubo:
1890   case vtn_variable_mode_ssbo:
1891   case vtn_variable_mode_push_constant:
1892   case vtn_variable_mode_accel_struct:
1893   case vtn_variable_mode_shader_record:
1894      var->var = rzalloc(b->shader, nir_variable);
1895      var->var->name = ralloc_strdup(var->var, val->name);
1896
1897      var->var->type = vtn_type_get_nir_type(b, var->type, var->mode);
1898      var->var->interface_type = var->var->type;
1899
1900      var->var->data.mode = nir_mode;
1901      var->var->data.location = -1;
1902      var->var->data.driver_location = 0;
1903      var->var->data.access = var->type->access;
1904      break;
1905
1906   case vtn_variable_mode_workgroup:
1907   case vtn_variable_mode_cross_workgroup:
1908      /* Create the variable normally */
1909      var->var = rzalloc(b->shader, nir_variable);
1910      var->var->name = ralloc_strdup(var->var, val->name);
1911      var->var->type = vtn_type_get_nir_type(b, var->type, var->mode);
1912      var->var->data.mode = nir_mode;
1913      break;
1914
1915   case vtn_variable_mode_input:
1916   case vtn_variable_mode_output: {
1917      var->var = rzalloc(b->shader, nir_variable);
1918      var->var->name = ralloc_strdup(var->var, val->name);
1919      var->var->type = vtn_type_get_nir_type(b, var->type, var->mode);
1920      var->var->data.mode = nir_mode;
1921
1922      /* In order to know whether or not we're a per-vertex inout, we need
1923       * the patch qualifier.  This means walking the variable decorations
1924       * early before we actually create any variables.  Not a big deal.
1925       *
1926       * GLSLang really likes to place decorations in the most interior
1927       * thing it possibly can.  In particular, if you have a struct, it
1928       * will place the patch decorations on the struct members.  This
1929       * should be handled by the variable splitting below just fine.
1930       *
1931       * If you have an array-of-struct, things get even more weird as it
1932       * will place the patch decorations on the struct even though it's
1933       * inside an array and some of the members being patch and others not
1934       * makes no sense whatsoever.  Since the only sensible thing is for
1935       * it to be all or nothing, we'll call it patch if any of the members
1936       * are declared patch.
1937       */
1938      vtn_foreach_decoration(b, val, gather_var_kind_cb, var);
1939      if (glsl_type_is_array(var->type->type) &&
1940          glsl_type_is_struct_or_ifc(without_array->type)) {
1941         vtn_foreach_decoration(b, vtn_value(b, without_array->id,
1942                                             vtn_value_type_type),
1943                                gather_var_kind_cb, var);
1944      }
1945
1946      struct vtn_type *per_vertex_type = var->type;
1947      if (nir_is_arrayed_io(var->var, b->shader->info.stage))
1948         per_vertex_type = var->type->array_element;
1949
1950      /* Figure out the interface block type. */
1951      struct vtn_type *iface_type = per_vertex_type;
1952      if (var->mode == vtn_variable_mode_output &&
1953          (b->shader->info.stage == MESA_SHADER_VERTEX ||
1954           b->shader->info.stage == MESA_SHADER_TESS_EVAL ||
1955           b->shader->info.stage == MESA_SHADER_GEOMETRY)) {
1956         /* For vertex data outputs, we can end up with arrays of blocks for
1957          * transform feedback where each array element corresponds to a
1958          * different XFB output buffer.
1959          */
1960         while (iface_type->base_type == vtn_base_type_array)
1961            iface_type = iface_type->array_element;
1962      }
1963      if (iface_type->base_type == vtn_base_type_struct && iface_type->block)
1964         var->var->interface_type = vtn_type_get_nir_type(b, iface_type,
1965                                                          var->mode);
1966
1967      /* If it's a block, set it up as per-member so can be splitted later by
1968       * nir_split_per_member_structs.
1969       *
1970       * This is for a couple of reasons.  For one, builtins may all come in a
1971       * block and we really want those split out into separate variables.
1972       * For another, interpolation qualifiers can be applied to members of
1973       * the top-level struct and we need to be able to preserve that
1974       * information.
1975       */
1976      if (per_vertex_type->base_type == vtn_base_type_struct &&
1977          per_vertex_type->block) {
1978         var->var->num_members = glsl_get_length(per_vertex_type->type);
1979         var->var->members = rzalloc_array(var->var, struct nir_variable_data,
1980                                           var->var->num_members);
1981
1982         for (unsigned i = 0; i < var->var->num_members; i++) {
1983            var->var->members[i].mode = nir_mode;
1984            var->var->members[i].patch = var->var->data.patch;
1985            var->var->members[i].location = -1;
1986         }
1987      }
1988
1989      /* For inputs and outputs, we need to grab locations and builtin
1990       * information from the per-vertex type.
1991       */
1992      vtn_foreach_decoration(b, vtn_value(b, per_vertex_type->id,
1993                                          vtn_value_type_type),
1994                             var_decoration_cb, var);
1995
1996      /* PerTask I/O is always a single block without any Location, so
1997       * initialize the base_location of the block and let
1998       * assign_missing_member_locations() do the rest.
1999       */
2000      if ((b->shader->info.stage == MESA_SHADER_TASK && var->mode == vtn_variable_mode_output) ||
2001          (b->shader->info.stage == MESA_SHADER_MESH && var->mode == vtn_variable_mode_input)) {
2002         if (var->type->block)
2003            var->base_location = VARYING_SLOT_VAR0;
2004      }
2005
2006      break;
2007   }
2008
2009   case vtn_variable_mode_image:
2010   case vtn_variable_mode_phys_ssbo:
2011   case vtn_variable_mode_generic:
2012      unreachable("Should have been caught before");
2013   }
2014
2015   /* Ignore incorrectly generated Undef initializers. */
2016   if (b->wa_llvm_spirv_ignore_workgroup_initializer &&
2017       initializer &&
2018       storage_class == SpvStorageClassWorkgroup)
2019      initializer = NULL;
2020
2021   /* Only initialize variable when there is an initializer and it's not
2022    * undef.
2023    */
2024   if (initializer && !initializer->is_undef_constant) {
2025      switch (storage_class) {
2026      case SpvStorageClassWorkgroup:
2027         /* VK_KHR_zero_initialize_workgroup_memory. */
2028         vtn_fail_if(b->options->environment != NIR_SPIRV_VULKAN,
2029                     "Only Vulkan supports variable initializer "
2030                     "for Workgroup variable %u",
2031                     vtn_id_for_value(b, val));
2032         vtn_fail_if(initializer->value_type != vtn_value_type_constant ||
2033                     !initializer->is_null_constant,
2034                     "Workgroup variable %u can only have OpConstantNull "
2035                     "as initializer, but have %u instead",
2036                     vtn_id_for_value(b, val),
2037                     vtn_id_for_value(b, initializer));
2038         b->shader->info.zero_initialize_shared_memory = true;
2039         break;
2040
2041      case SpvStorageClassUniformConstant:
2042         vtn_fail_if(b->options->environment != NIR_SPIRV_OPENGL &&
2043                     b->options->environment != NIR_SPIRV_OPENCL,
2044                     "Only OpenGL and OpenCL support variable initializer "
2045                     "for UniformConstant variable %u\n",
2046                     vtn_id_for_value(b, val));
2047         vtn_fail_if(initializer->value_type != vtn_value_type_constant,
2048                     "UniformConstant variable %u can only have a constant "
2049                     "initializer, but have %u instead",
2050                     vtn_id_for_value(b, val),
2051                     vtn_id_for_value(b, initializer));
2052         break;
2053
2054      case SpvStorageClassOutput:
2055      case SpvStorageClassPrivate:
2056         vtn_assert(b->options->environment != NIR_SPIRV_OPENCL);
2057         /* These can have any initializer. */
2058         break;
2059
2060      case SpvStorageClassFunction:
2061         /* These can have any initializer. */
2062         break;
2063
2064      case SpvStorageClassCrossWorkgroup:
2065         vtn_assert(b->options->environment == NIR_SPIRV_OPENCL);
2066         vtn_fail("Initializer for CrossWorkgroup variable %u "
2067                  "not yet supported in Mesa.",
2068                  vtn_id_for_value(b, val));
2069         break;
2070
2071      default: {
2072         const enum nir_spirv_execution_environment env =
2073            b->options->environment;
2074         const char *env_name =
2075            env == NIR_SPIRV_VULKAN ? "Vulkan" :
2076            env == NIR_SPIRV_OPENCL ? "OpenCL" :
2077            env == NIR_SPIRV_OPENGL ? "OpenGL" :
2078            NULL;
2079         vtn_assert(env_name);
2080         vtn_fail("In %s, any OpVariable with an Initializer operand "
2081                  "must have %s%s%s, or Function as "
2082                  "its Storage Class operand.  Variable %u has an "
2083                  "Initializer but its Storage Class is %s.",
2084                  env_name,
2085                  env == NIR_SPIRV_VULKAN ? "Private, Output, Workgroup" : "",
2086                  env == NIR_SPIRV_OPENCL ? "CrossWorkgroup, UniformConstant" : "",
2087                  env == NIR_SPIRV_OPENGL ? "Private, Output, UniformConstant" : "",
2088                  vtn_id_for_value(b, val),
2089                  spirv_storageclass_to_string(storage_class));
2090         }
2091      }
2092
2093      switch (initializer->value_type) {
2094      case vtn_value_type_constant:
2095         var->var->constant_initializer =
2096            nir_constant_clone(initializer->constant, var->var);
2097         break;
2098      case vtn_value_type_pointer:
2099         var->var->pointer_initializer = initializer->pointer->var->var;
2100         break;
2101      default:
2102         vtn_fail("SPIR-V variable initializer %u must be constant or pointer",
2103                  vtn_id_for_value(b, initializer));
2104      }
2105   }
2106
2107   if (var->mode == vtn_variable_mode_uniform ||
2108       var->mode == vtn_variable_mode_ssbo) {
2109      /* SSBOs and images are assumed to not alias in the Simple, GLSL and Vulkan memory models */
2110      var->var->data.access |= b->mem_model != SpvMemoryModelOpenCL ? ACCESS_RESTRICT : 0;
2111   }
2112
2113   vtn_foreach_decoration(b, val, var_decoration_cb, var);
2114   vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer);
2115
2116   /* Propagate access flags from the OpVariable decorations. */
2117   val->pointer->access |= var->access;
2118
2119   if ((var->mode == vtn_variable_mode_input ||
2120        var->mode == vtn_variable_mode_output) &&
2121       var->var->members) {
2122      assign_missing_member_locations(var);
2123   }
2124
2125   if (var->mode == vtn_variable_mode_uniform ||
2126       var->mode == vtn_variable_mode_ubo ||
2127       var->mode == vtn_variable_mode_ssbo ||
2128       var->mode == vtn_variable_mode_atomic_counter) {
2129      /* XXX: We still need the binding information in the nir_variable
2130       * for these. We should fix that.
2131       */
2132      var->var->data.binding = var->binding;
2133      var->var->data.explicit_binding = var->explicit_binding;
2134      var->var->data.descriptor_set = var->descriptor_set;
2135      var->var->data.index = var->input_attachment_index;
2136      var->var->data.offset = var->offset;
2137
2138      if (glsl_type_is_image(glsl_without_array(var->var->type)))
2139         var->var->data.image.format = without_array->image_format;
2140   }
2141
2142   if (var->mode == vtn_variable_mode_function) {
2143      vtn_assert(var->var != NULL && var->var->members == NULL);
2144      nir_function_impl_add_variable(b->nb.impl, var->var);
2145   } else if (var->var) {
2146      nir_shader_add_variable(b->shader, var->var);
2147   } else {
2148      vtn_assert(vtn_pointer_is_external_block(b, val->pointer) ||
2149                 var->mode == vtn_variable_mode_accel_struct ||
2150                 var->mode == vtn_variable_mode_shader_record);
2151   }
2152}
2153
2154static void
2155vtn_assert_types_equal(struct vtn_builder *b, SpvOp opcode,
2156                       struct vtn_type *dst_type,
2157                       struct vtn_type *src_type)
2158{
2159   if (dst_type->id == src_type->id)
2160      return;
2161
2162   if (vtn_types_compatible(b, dst_type, src_type)) {
2163      /* Early versions of GLSLang would re-emit types unnecessarily and you
2164       * would end up with OpLoad, OpStore, or OpCopyMemory opcodes which have
2165       * mismatched source and destination types.
2166       *
2167       * https://github.com/KhronosGroup/glslang/issues/304
2168       * https://github.com/KhronosGroup/glslang/issues/307
2169       * https://bugs.freedesktop.org/show_bug.cgi?id=104338
2170       * https://bugs.freedesktop.org/show_bug.cgi?id=104424
2171       */
2172      vtn_warn("Source and destination types of %s do not have the same "
2173               "ID (but are compatible): %u vs %u",
2174                spirv_op_to_string(opcode), dst_type->id, src_type->id);
2175      return;
2176   }
2177
2178   vtn_fail("Source and destination types of %s do not match: %s vs. %s",
2179            spirv_op_to_string(opcode),
2180            glsl_get_type_name(dst_type->type),
2181            glsl_get_type_name(src_type->type));
2182}
2183
2184static nir_ssa_def *
2185nir_shrink_zero_pad_vec(nir_builder *b, nir_ssa_def *val,
2186                        unsigned num_components)
2187{
2188   if (val->num_components == num_components)
2189      return val;
2190
2191   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
2192   for (unsigned i = 0; i < num_components; i++) {
2193      if (i < val->num_components)
2194         comps[i] = nir_channel(b, val, i);
2195      else
2196         comps[i] = nir_imm_intN_t(b, 0, val->bit_size);
2197   }
2198   return nir_vec(b, comps, num_components);
2199}
2200
2201static nir_ssa_def *
2202nir_sloppy_bitcast(nir_builder *b, nir_ssa_def *val,
2203                   const struct glsl_type *type)
2204{
2205   const unsigned num_components = glsl_get_vector_elements(type);
2206   const unsigned bit_size = glsl_get_bit_size(type);
2207
2208   /* First, zero-pad to ensure that the value is big enough that when we
2209    * bit-cast it, we don't loose anything.
2210    */
2211   if (val->bit_size < bit_size) {
2212      const unsigned src_num_components_needed =
2213         vtn_align_u32(val->num_components, bit_size / val->bit_size);
2214      val = nir_shrink_zero_pad_vec(b, val, src_num_components_needed);
2215   }
2216
2217   val = nir_bitcast_vector(b, val, bit_size);
2218
2219   return nir_shrink_zero_pad_vec(b, val, num_components);
2220}
2221
2222static bool
2223vtn_get_mem_operands(struct vtn_builder *b, const uint32_t *w, unsigned count,
2224                     unsigned *idx, SpvMemoryAccessMask *access, unsigned *alignment,
2225                     SpvScope *dest_scope, SpvScope *src_scope)
2226{
2227   *access = 0;
2228   *alignment = 0;
2229   if (*idx >= count)
2230      return false;
2231
2232   *access = w[(*idx)++];
2233   if (*access & SpvMemoryAccessAlignedMask) {
2234      vtn_assert(*idx < count);
2235      *alignment = w[(*idx)++];
2236   }
2237
2238   if (*access & SpvMemoryAccessMakePointerAvailableMask) {
2239      vtn_assert(*idx < count);
2240      vtn_assert(dest_scope);
2241      *dest_scope = vtn_constant_uint(b, w[(*idx)++]);
2242   }
2243
2244   if (*access & SpvMemoryAccessMakePointerVisibleMask) {
2245      vtn_assert(*idx < count);
2246      vtn_assert(src_scope);
2247      *src_scope = vtn_constant_uint(b, w[(*idx)++]);
2248   }
2249
2250   return true;
2251}
2252
2253static enum gl_access_qualifier
2254spv_access_to_gl_access(SpvMemoryAccessMask access)
2255{
2256   unsigned result = 0;
2257
2258   if (access & SpvMemoryAccessVolatileMask)
2259      result |= ACCESS_VOLATILE;
2260   if (access & SpvMemoryAccessNontemporalMask)
2261      result |= ACCESS_STREAM_CACHE_POLICY;
2262
2263   return result;
2264}
2265
2266
2267SpvMemorySemanticsMask
2268vtn_mode_to_memory_semantics(enum vtn_variable_mode mode)
2269{
2270   switch (mode) {
2271   case vtn_variable_mode_ssbo:
2272   case vtn_variable_mode_phys_ssbo:
2273      return SpvMemorySemanticsUniformMemoryMask;
2274   case vtn_variable_mode_workgroup:
2275      return SpvMemorySemanticsWorkgroupMemoryMask;
2276   case vtn_variable_mode_cross_workgroup:
2277      return SpvMemorySemanticsCrossWorkgroupMemoryMask;
2278   case vtn_variable_mode_atomic_counter:
2279      return SpvMemorySemanticsAtomicCounterMemoryMask;
2280   case vtn_variable_mode_image:
2281      return SpvMemorySemanticsImageMemoryMask;
2282   case vtn_variable_mode_output:
2283      return SpvMemorySemanticsOutputMemoryMask;
2284   default:
2285      return SpvMemorySemanticsMaskNone;
2286   }
2287}
2288
2289static void
2290vtn_emit_make_visible_barrier(struct vtn_builder *b, SpvMemoryAccessMask access,
2291                              SpvScope scope, enum vtn_variable_mode mode)
2292{
2293   if (!(access & SpvMemoryAccessMakePointerVisibleMask))
2294      return;
2295
2296   vtn_emit_memory_barrier(b, scope, SpvMemorySemanticsMakeVisibleMask |
2297                                     SpvMemorySemanticsAcquireMask |
2298                                     vtn_mode_to_memory_semantics(mode));
2299}
2300
2301static void
2302vtn_emit_make_available_barrier(struct vtn_builder *b, SpvMemoryAccessMask access,
2303                                SpvScope scope, enum vtn_variable_mode mode)
2304{
2305   if (!(access & SpvMemoryAccessMakePointerAvailableMask))
2306      return;
2307
2308   vtn_emit_memory_barrier(b, scope, SpvMemorySemanticsMakeAvailableMask |
2309                                     SpvMemorySemanticsReleaseMask |
2310                                     vtn_mode_to_memory_semantics(mode));
2311}
2312
2313static void
2314ptr_nonuniform_workaround_cb(struct vtn_builder *b, struct vtn_value *val,
2315                  int member, const struct vtn_decoration *dec, void *void_ptr)
2316{
2317   enum gl_access_qualifier *access = void_ptr;
2318
2319   switch (dec->decoration) {
2320   case SpvDecorationNonUniformEXT:
2321      *access |= ACCESS_NON_UNIFORM;
2322      break;
2323
2324   default:
2325      break;
2326   }
2327}
2328
2329void
2330vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
2331                     const uint32_t *w, unsigned count)
2332{
2333   switch (opcode) {
2334   case SpvOpUndef: {
2335      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
2336      val->type = vtn_get_type(b, w[1]);
2337      val->is_undef_constant = true;
2338      break;
2339   }
2340
2341   case SpvOpVariable: {
2342      struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
2343
2344      SpvStorageClass storage_class = w[3];
2345
2346      const bool is_global = storage_class != SpvStorageClassFunction;
2347      const bool is_io = storage_class == SpvStorageClassInput ||
2348                         storage_class == SpvStorageClassOutput;
2349
2350      /* Skip global variables that are not used by the entrypoint.  Before
2351       * SPIR-V 1.4 the interface is only used for I/O variables, so extra
2352       * variables will still need to be removed later.
2353       */
2354      if (!b->options->create_library &&
2355          (is_io || (b->version >= 0x10400 && is_global))) {
2356         if (!bsearch(&w[2], b->interface_ids, b->interface_ids_count, 4, cmp_uint32_t))
2357            break;
2358      }
2359
2360      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer);
2361      struct vtn_value *initializer = count > 4 ? vtn_untyped_value(b, w[4]) : NULL;
2362
2363      vtn_create_variable(b, val, ptr_type, storage_class, initializer);
2364
2365      break;
2366   }
2367
2368   case SpvOpConstantSampler: {
2369      /* Synthesize a pointer-to-sampler type, create a variable of that type,
2370       * and give the variable a constant initializer with the sampler params */
2371      struct vtn_type *sampler_type = vtn_value(b, w[1], vtn_value_type_type)->type;
2372      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer);
2373
2374      struct vtn_type *ptr_type = rzalloc(b, struct vtn_type);
2375      ptr_type = rzalloc(b, struct vtn_type);
2376      ptr_type->base_type = vtn_base_type_pointer;
2377      ptr_type->deref = sampler_type;
2378      ptr_type->storage_class = SpvStorageClassUniform;
2379
2380      ptr_type->type = nir_address_format_to_glsl_type(
2381         vtn_mode_to_address_format(b, vtn_variable_mode_function));
2382
2383      vtn_create_variable(b, val, ptr_type, ptr_type->storage_class, NULL);
2384
2385      nir_variable *nir_var = val->pointer->var->var;
2386      nir_var->data.sampler.is_inline_sampler = true;
2387      nir_var->data.sampler.addressing_mode = w[3];
2388      nir_var->data.sampler.normalized_coordinates = w[4];
2389      nir_var->data.sampler.filter_mode = w[5];
2390
2391      break;
2392   }
2393
2394   case SpvOpAccessChain:
2395   case SpvOpPtrAccessChain:
2396   case SpvOpInBoundsAccessChain:
2397   case SpvOpInBoundsPtrAccessChain: {
2398      struct vtn_access_chain *chain = vtn_access_chain_create(b, count - 4);
2399      enum gl_access_qualifier access = 0;
2400      chain->ptr_as_array = (opcode == SpvOpPtrAccessChain || opcode == SpvOpInBoundsPtrAccessChain);
2401
2402      unsigned idx = 0;
2403      for (int i = 4; i < count; i++) {
2404         struct vtn_value *link_val = vtn_untyped_value(b, w[i]);
2405         if (link_val->value_type == vtn_value_type_constant) {
2406            chain->link[idx].mode = vtn_access_mode_literal;
2407            chain->link[idx].id = vtn_constant_int(b, w[i]);
2408         } else {
2409            chain->link[idx].mode = vtn_access_mode_id;
2410            chain->link[idx].id = w[i];
2411         }
2412
2413         /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
2414         vtn_foreach_decoration(b, link_val, ptr_nonuniform_workaround_cb, &access);
2415
2416         idx++;
2417      }
2418
2419      struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
2420
2421      struct vtn_pointer *base = vtn_pointer(b, w[3]);
2422
2423      /* Workaround for https://gitlab.freedesktop.org/mesa/mesa/-/issues/3406 */
2424      access |= base->access & ACCESS_NON_UNIFORM;
2425
2426      struct vtn_pointer *ptr = vtn_pointer_dereference(b, base, chain);
2427      ptr->ptr_type = ptr_type;
2428      ptr->access |= access;
2429      vtn_push_pointer(b, w[2], ptr);
2430      break;
2431   }
2432
2433   case SpvOpCopyMemory: {
2434      struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
2435      struct vtn_value *src_val = vtn_pointer_value(b, w[2]);
2436      struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
2437      struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
2438
2439      vtn_assert_types_equal(b, opcode, dest_val->type->deref,
2440                                        src_val->type->deref);
2441
2442      unsigned idx = 3, dest_alignment, src_alignment;
2443      SpvMemoryAccessMask dest_access, src_access;
2444      SpvScope dest_scope, src_scope;
2445      vtn_get_mem_operands(b, w, count, &idx, &dest_access, &dest_alignment,
2446                           &dest_scope, &src_scope);
2447      if (!vtn_get_mem_operands(b, w, count, &idx, &src_access, &src_alignment,
2448                                NULL, &src_scope)) {
2449         src_alignment = dest_alignment;
2450         src_access = dest_access;
2451      }
2452      src = vtn_align_pointer(b, src, src_alignment);
2453      dest = vtn_align_pointer(b, dest, dest_alignment);
2454
2455      vtn_emit_make_visible_barrier(b, src_access, src_scope, src->mode);
2456
2457      vtn_variable_copy(b, dest, src,
2458                        spv_access_to_gl_access(dest_access),
2459                        spv_access_to_gl_access(src_access));
2460
2461      vtn_emit_make_available_barrier(b, dest_access, dest_scope, dest->mode);
2462      break;
2463   }
2464
2465   case SpvOpCopyMemorySized: {
2466      struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
2467      struct vtn_value *src_val = vtn_pointer_value(b, w[2]);
2468      nir_ssa_def *size = vtn_get_nir_ssa(b, w[3]);
2469      struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
2470      struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
2471
2472      unsigned idx = 4, dest_alignment, src_alignment;
2473      SpvMemoryAccessMask dest_access, src_access;
2474      SpvScope dest_scope, src_scope;
2475      vtn_get_mem_operands(b, w, count, &idx, &dest_access, &dest_alignment,
2476                           &dest_scope, &src_scope);
2477      if (!vtn_get_mem_operands(b, w, count, &idx, &src_access, &src_alignment,
2478                                NULL, &src_scope)) {
2479         src_alignment = dest_alignment;
2480         src_access = dest_access;
2481      }
2482      src = vtn_align_pointer(b, src, src_alignment);
2483      dest = vtn_align_pointer(b, dest, dest_alignment);
2484
2485      vtn_emit_make_visible_barrier(b, src_access, src_scope, src->mode);
2486
2487      nir_memcpy_deref_with_access(&b->nb,
2488                                   vtn_pointer_to_deref(b, dest),
2489                                   vtn_pointer_to_deref(b, src),
2490                                   size,
2491                                   spv_access_to_gl_access(dest_access),
2492                                   spv_access_to_gl_access(src_access));
2493
2494      vtn_emit_make_available_barrier(b, dest_access, dest_scope, dest->mode);
2495      break;
2496   }
2497
2498   case SpvOpLoad: {
2499      struct vtn_type *res_type = vtn_get_type(b, w[1]);
2500      struct vtn_value *src_val = vtn_value(b, w[3], vtn_value_type_pointer);
2501      struct vtn_pointer *src = vtn_value_to_pointer(b, src_val);
2502
2503      vtn_assert_types_equal(b, opcode, res_type, src_val->type->deref);
2504
2505      unsigned idx = 4, alignment;
2506      SpvMemoryAccessMask access;
2507      SpvScope scope;
2508      vtn_get_mem_operands(b, w, count, &idx, &access, &alignment, NULL, &scope);
2509      src = vtn_align_pointer(b, src, alignment);
2510
2511      vtn_emit_make_visible_barrier(b, access, scope, src->mode);
2512
2513      vtn_push_ssa_value(b, w[2], vtn_variable_load(b, src, spv_access_to_gl_access(access)));
2514      break;
2515   }
2516
2517   case SpvOpStore: {
2518      struct vtn_value *dest_val = vtn_pointer_value(b, w[1]);
2519      struct vtn_pointer *dest = vtn_value_to_pointer(b, dest_val);
2520      struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
2521
2522      /* OpStore requires us to actually have a storage type */
2523      vtn_fail_if(dest->type->type == NULL,
2524                  "Invalid destination type for OpStore");
2525
2526      if (glsl_get_base_type(dest->type->type) == GLSL_TYPE_BOOL &&
2527          glsl_get_base_type(src_val->type->type) == GLSL_TYPE_UINT) {
2528         /* Early versions of GLSLang would use uint types for UBOs/SSBOs but
2529          * would then store them to a local variable as bool.  Work around
2530          * the issue by doing an implicit conversion.
2531          *
2532          * https://github.com/KhronosGroup/glslang/issues/170
2533          * https://bugs.freedesktop.org/show_bug.cgi?id=104424
2534          */
2535         vtn_warn("OpStore of value of type OpTypeInt to a pointer to type "
2536                  "OpTypeBool.  Doing an implicit conversion to work around "
2537                  "the problem.");
2538         struct vtn_ssa_value *bool_ssa =
2539            vtn_create_ssa_value(b, dest->type->type);
2540         bool_ssa->def = nir_i2b(&b->nb, vtn_ssa_value(b, w[2])->def);
2541         vtn_variable_store(b, bool_ssa, dest, 0);
2542         break;
2543      }
2544
2545      vtn_assert_types_equal(b, opcode, dest_val->type->deref, src_val->type);
2546
2547      unsigned idx = 3, alignment;
2548      SpvMemoryAccessMask access;
2549      SpvScope scope;
2550      vtn_get_mem_operands(b, w, count, &idx, &access, &alignment, &scope, NULL);
2551      dest = vtn_align_pointer(b, dest, alignment);
2552
2553      struct vtn_ssa_value *src = vtn_ssa_value(b, w[2]);
2554      vtn_variable_store(b, src, dest, spv_access_to_gl_access(access));
2555
2556      vtn_emit_make_available_barrier(b, access, scope, dest->mode);
2557      break;
2558   }
2559
2560   case SpvOpArrayLength: {
2561      struct vtn_pointer *ptr = vtn_pointer(b, w[3]);
2562      const uint32_t field = w[4];
2563
2564      vtn_fail_if(ptr->type->base_type != vtn_base_type_struct,
2565                  "OpArrayLength must take a pointer to a structure type");
2566      vtn_fail_if(field != ptr->type->length - 1 ||
2567                  ptr->type->members[field]->base_type != vtn_base_type_array,
2568                  "OpArrayLength must reference the last memeber of the "
2569                  "structure and that must be an array");
2570
2571      if (b->options->use_deref_buffer_array_length) {
2572         struct vtn_access_chain chain = {
2573            .length = 1,
2574            .link = {
2575               { .mode = vtn_access_mode_literal, .id = field },
2576            }
2577         };
2578         struct vtn_pointer *array = vtn_pointer_dereference(b, ptr, &chain);
2579
2580         nir_ssa_def *array_length =
2581            nir_build_deref_buffer_array_length(&b->nb, 32,
2582                                                vtn_pointer_to_ssa(b, array),
2583                                                .access=ptr->access | ptr->type->access);
2584
2585         vtn_push_nir_ssa(b, w[2], array_length);
2586      } else {
2587         const uint32_t offset = ptr->type->offsets[field];
2588         const uint32_t stride = ptr->type->members[field]->stride;
2589
2590         if (!ptr->block_index) {
2591            struct vtn_access_chain chain = {
2592               .length = 0,
2593            };
2594            ptr = vtn_pointer_dereference(b, ptr, &chain);
2595            vtn_assert(ptr->block_index);
2596         }
2597
2598         nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index,
2599                                                   .access=ptr->access | ptr->type->access);
2600
2601         /* array_length = max(buffer_size - offset, 0) / stride */
2602         nir_ssa_def *array_length =
2603            nir_idiv(&b->nb,
2604                     nir_imax(&b->nb,
2605                              nir_isub(&b->nb,
2606                                       buf_size,
2607                                       nir_imm_int(&b->nb, offset)),
2608                              nir_imm_int(&b->nb, 0u)),
2609                     nir_imm_int(&b->nb, stride));
2610
2611         vtn_push_nir_ssa(b, w[2], array_length);
2612      }
2613      break;
2614   }
2615
2616   case SpvOpConvertPtrToU: {
2617      struct vtn_type *u_type = vtn_get_type(b, w[1]);
2618      struct vtn_type *ptr_type = vtn_get_value_type(b, w[3]);
2619
2620      vtn_fail_if(ptr_type->base_type != vtn_base_type_pointer ||
2621                  ptr_type->type == NULL,
2622                  "OpConvertPtrToU can only be used on physical pointers");
2623
2624      vtn_fail_if(u_type->base_type != vtn_base_type_vector &&
2625                  u_type->base_type != vtn_base_type_scalar,
2626                  "OpConvertPtrToU can only be used to cast to a vector or "
2627                  "scalar type");
2628
2629      /* The pointer will be converted to an SSA value automatically */
2630      nir_ssa_def *ptr = vtn_get_nir_ssa(b, w[3]);
2631      nir_ssa_def *u = nir_sloppy_bitcast(&b->nb, ptr, u_type->type);
2632      vtn_push_nir_ssa(b, w[2], u);
2633      break;
2634   }
2635
2636   case SpvOpConvertUToPtr: {
2637      struct vtn_type *ptr_type = vtn_get_type(b, w[1]);
2638      struct vtn_type *u_type = vtn_get_value_type(b, w[3]);
2639
2640      vtn_fail_if(ptr_type->base_type != vtn_base_type_pointer ||
2641                  ptr_type->type == NULL,
2642                  "OpConvertUToPtr can only be used on physical pointers");
2643
2644      vtn_fail_if(u_type->base_type != vtn_base_type_vector &&
2645                  u_type->base_type != vtn_base_type_scalar,
2646                  "OpConvertUToPtr can only be used to cast from a vector or "
2647                  "scalar type");
2648
2649      nir_ssa_def *u = vtn_get_nir_ssa(b, w[3]);
2650      nir_ssa_def *ptr = nir_sloppy_bitcast(&b->nb, u, ptr_type->type);
2651      vtn_push_pointer(b, w[2], vtn_pointer_from_ssa(b, ptr, ptr_type));
2652      break;
2653   }
2654
2655   case SpvOpGenericCastToPtrExplicit: {
2656      struct vtn_type *dst_type = vtn_get_type(b, w[1]);
2657      struct vtn_type *src_type = vtn_get_value_type(b, w[3]);
2658      SpvStorageClass storage_class = w[4];
2659
2660      vtn_fail_if(dst_type->base_type != vtn_base_type_pointer ||
2661                  dst_type->storage_class != storage_class,
2662                  "Result type of an SpvOpGenericCastToPtrExplicit must be "
2663                  "an OpTypePointer. Its Storage Class must match the "
2664                  "storage class specified in the instruction");
2665
2666      vtn_fail_if(src_type->base_type != vtn_base_type_pointer ||
2667                  src_type->deref->id != dst_type->deref->id,
2668                  "Source pointer of an SpvOpGenericCastToPtrExplicit must "
2669                  "have a type of OpTypePointer whose Type is the same as "
2670                  "the Type of Result Type");
2671
2672      vtn_fail_if(src_type->storage_class != SpvStorageClassGeneric,
2673                  "Source pointer of an SpvOpGenericCastToPtrExplicit must "
2674                  "point to the Generic Storage Class.");
2675
2676      vtn_fail_if(storage_class != SpvStorageClassWorkgroup &&
2677                  storage_class != SpvStorageClassCrossWorkgroup &&
2678                  storage_class != SpvStorageClassFunction,
2679                  "Storage must be one of the following literal values from "
2680                  "Storage Class: Workgroup, CrossWorkgroup, or Function.");
2681
2682      nir_deref_instr *src_deref = vtn_nir_deref(b, w[3]);
2683
2684      nir_variable_mode nir_mode;
2685      enum vtn_variable_mode mode =
2686         vtn_storage_class_to_mode(b, storage_class, dst_type->deref, &nir_mode);
2687      nir_address_format addr_format = vtn_mode_to_address_format(b, mode);
2688
2689      nir_ssa_def *null_value =
2690         nir_build_imm(&b->nb, nir_address_format_num_components(addr_format),
2691                               nir_address_format_bit_size(addr_format),
2692                               nir_address_format_null_value(addr_format));
2693
2694      nir_ssa_def *valid = nir_build_deref_mode_is(&b->nb, 1, &src_deref->dest.ssa, nir_mode);
2695      vtn_push_nir_ssa(b, w[2], nir_bcsel(&b->nb, valid,
2696                                                  &src_deref->dest.ssa,
2697                                                  null_value));
2698      break;
2699   }
2700
2701   case SpvOpGenericPtrMemSemantics: {
2702      struct vtn_type *dst_type = vtn_get_type(b, w[1]);
2703      struct vtn_type *src_type = vtn_get_value_type(b, w[3]);
2704
2705      vtn_fail_if(dst_type->base_type != vtn_base_type_scalar ||
2706                  dst_type->type != glsl_uint_type(),
2707                  "Result type of an SpvOpGenericPtrMemSemantics must be "
2708                  "an OpTypeInt with 32-bit Width and 0 Signedness.");
2709
2710      vtn_fail_if(src_type->base_type != vtn_base_type_pointer ||
2711                  src_type->storage_class != SpvStorageClassGeneric,
2712                  "Source pointer of an SpvOpGenericPtrMemSemantics must "
2713                  "point to the Generic Storage Class");
2714
2715      nir_deref_instr *src_deref = vtn_nir_deref(b, w[3]);
2716
2717      nir_ssa_def *global_bit =
2718         nir_bcsel(&b->nb, nir_build_deref_mode_is(&b->nb, 1, &src_deref->dest.ssa,
2719                                                   nir_var_mem_global),
2720                   nir_imm_int(&b->nb, SpvMemorySemanticsCrossWorkgroupMemoryMask),
2721                   nir_imm_int(&b->nb, 0));
2722
2723      nir_ssa_def *shared_bit =
2724         nir_bcsel(&b->nb, nir_build_deref_mode_is(&b->nb, 1, &src_deref->dest.ssa,
2725                                                   nir_var_mem_shared),
2726                   nir_imm_int(&b->nb, SpvMemorySemanticsWorkgroupMemoryMask),
2727                   nir_imm_int(&b->nb, 0));
2728
2729      vtn_push_nir_ssa(b, w[2], nir_iand(&b->nb, global_bit, shared_bit));
2730      break;
2731   }
2732
2733   case SpvOpSubgroupBlockReadINTEL: {
2734      struct vtn_type *res_type = vtn_get_type(b, w[1]);
2735      nir_deref_instr *src = vtn_nir_deref(b, w[3]);
2736
2737      nir_intrinsic_instr *load =
2738         nir_intrinsic_instr_create(b->nb.shader,
2739                                    nir_intrinsic_load_deref_block_intel);
2740      load->src[0] = nir_src_for_ssa(&src->dest.ssa);
2741      nir_ssa_dest_init_for_type(&load->instr, &load->dest,
2742                                 res_type->type, NULL);
2743      load->num_components = load->dest.ssa.num_components;
2744      nir_builder_instr_insert(&b->nb, &load->instr);
2745
2746      vtn_push_nir_ssa(b, w[2], &load->dest.ssa);
2747      break;
2748   }
2749
2750   case SpvOpSubgroupBlockWriteINTEL: {
2751      nir_deref_instr *dest = vtn_nir_deref(b, w[1]);
2752      nir_ssa_def *data = vtn_ssa_value(b, w[2])->def;
2753
2754      nir_intrinsic_instr *store =
2755         nir_intrinsic_instr_create(b->nb.shader,
2756                                    nir_intrinsic_store_deref_block_intel);
2757      store->src[0] = nir_src_for_ssa(&dest->dest.ssa);
2758      store->src[1] = nir_src_for_ssa(data);
2759      store->num_components = data->num_components;
2760      nir_builder_instr_insert(&b->nb, &store->instr);
2761      break;
2762   }
2763
2764   case SpvOpConvertUToAccelerationStructureKHR: {
2765      struct vtn_type *as_type = vtn_get_type(b, w[1]);
2766      struct vtn_type *u_type = vtn_get_value_type(b, w[3]);
2767      vtn_fail_if(!((u_type->base_type == vtn_base_type_vector &&
2768                     u_type->type == glsl_vector_type(GLSL_TYPE_UINT, 2)) ||
2769                    (u_type->base_type == vtn_base_type_scalar &&
2770                     u_type->type == glsl_uint64_t_type())),
2771                  "OpConvertUToAccelerationStructure may only be used to "
2772                  "cast from a 64-bit scalar integer or a 2-component vector "
2773                  "of 32-bit integers");
2774      vtn_fail_if(as_type->base_type != vtn_base_type_accel_struct,
2775                  "The result type of an OpConvertUToAccelerationStructure "
2776                  "must be OpTypeAccelerationStructure");
2777
2778      nir_ssa_def *u = vtn_get_nir_ssa(b, w[3]);
2779      vtn_push_nir_ssa(b, w[2], nir_sloppy_bitcast(&b->nb, u, as_type->type));
2780      break;
2781   }
2782
2783   default:
2784      vtn_fail_with_opcode("Unhandled opcode", opcode);
2785   }
2786}
2787