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