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