2 * Copyright © 2015 Intel Corporation
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:
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
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
24 * Jason Ekstrand (jason@jlekstrand.net)
28 #include "vtn_private.h"
29 #include "spirv_info.h"
30 #include "nir_deref.h"
31 #include <vulkan/vulkan_core.h>
33 static void ptr_decoration_cb(struct vtn_builder
*b
,
34 struct vtn_value
*val
, int member
,
35 const struct vtn_decoration
*dec
,
39 vtn_push_value_pointer(struct vtn_builder
*b
, uint32_t value_id
,
40 struct vtn_pointer
*ptr
)
42 struct vtn_value
*val
= vtn_push_value(b
, value_id
, vtn_value_type_pointer
);
44 vtn_foreach_decoration(b
, val
, ptr_decoration_cb
, ptr
);
49 ssa_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
, int member
,
50 const struct vtn_decoration
*dec
, void *void_ssa
)
52 struct vtn_ssa_value
*ssa
= void_ssa
;
54 switch (dec
->decoration
) {
55 case SpvDecorationNonUniformEXT
:
56 ssa
->access
|= ACCESS_NON_UNIFORM
;
65 vtn_push_ssa(struct vtn_builder
*b
, uint32_t value_id
,
66 struct vtn_type
*type
, struct vtn_ssa_value
*ssa
)
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
));
72 val
= vtn_push_value(b
, value_id
, vtn_value_type_ssa
);
74 vtn_foreach_decoration(b
, val
, ssa_decoration_cb
, val
->ssa
);
79 static struct vtn_access_chain
*
80 vtn_access_chain_create(struct vtn_builder
*b
, unsigned length
)
82 struct vtn_access_chain
*chain
;
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
;
94 vtn_mode_uses_ssa_offset(struct vtn_builder
*b
,
95 enum vtn_variable_mode mode
)
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
;
104 vtn_pointer_is_external_block(struct vtn_builder
*b
,
105 struct vtn_pointer
*ptr
)
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
;
114 vtn_access_link_as_ssa(struct vtn_builder
*b
, struct vtn_access_link link
,
115 unsigned stride
, unsigned bit_size
)
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
);
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
);
128 static VkDescriptorType
129 vk_desc_type_for_mode(struct vtn_builder
*b
, enum vtn_variable_mode 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
;
137 vtn_fail("Invalid mode for vulkan_resource_index");
142 vtn_variable_resource_index(struct vtn_builder
*b
, struct vtn_variable
*var
,
143 nir_ssa_def
*desc_array_index
)
145 vtn_assert(b
->options
->environment
== NIR_SPIRV_VULKAN
);
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);
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
));
160 vtn_fail_if(var
->mode
!= vtn_variable_mode_ubo
&&
161 var
->mode
!= vtn_variable_mode_ssbo
,
162 "Invalid mode for vulkan_resource_index");
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
);
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
);
174 return &instr
->dest
.ssa
;
178 vtn_resource_reindex(struct vtn_builder
*b
, enum vtn_variable_mode mode
,
179 nir_ssa_def
*base_index
, nir_ssa_def
*offset_index
)
181 vtn_assert(b
->options
->environment
== NIR_SPIRV_VULKAN
);
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
));
190 vtn_fail_if(mode
!= vtn_variable_mode_ubo
&& mode
!= vtn_variable_mode_ssbo
,
191 "Invalid mode for vulkan_resource_reindex");
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
);
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
);
203 return &instr
->dest
.ssa
;
207 vtn_descriptor_load(struct vtn_builder
*b
, enum vtn_variable_mode mode
,
208 nir_ssa_def
*desc_index
)
210 vtn_assert(b
->options
->environment
== NIR_SPIRV_VULKAN
);
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
));
218 vtn_fail_if(mode
!= vtn_variable_mode_ubo
&& mode
!= vtn_variable_mode_ssbo
,
219 "Invalid mode for load_vulkan_descriptor");
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
);
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
);
231 return &desc_load
->dest
.ssa
;
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
)
240 struct vtn_type
*type
= base
->type
;
241 enum gl_access_qualifier access
= base
->access
| deref_chain
->access
;
244 nir_deref_instr
*tail
;
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
;
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":
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."
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.
266 /* Figure out the descriptor array index if any
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
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
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);
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
);
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);
299 desc_arr_idx
= nir_iadd(&b
->nb
, desc_arr_idx
, arr_offset
);
301 desc_arr_idx
= arr_offset
;
303 type
= type
->array_element
;
304 access
|= type
->access
;
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
);
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.
321 struct vtn_pointer
*ptr
= rzalloc(b
, struct vtn_pointer
);
322 ptr
->mode
= base
->mode
;
324 ptr
->block_index
= block_index
;
325 ptr
->access
= access
;
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.
333 nir_ssa_def
*desc
= vtn_descriptor_load(b
, base
->mode
, block_index
);
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
;
340 tail
= nir_build_deref_cast(&b
->nb
, desc
, nir_mode
, type
->type
,
341 base
->ptr_type
->stride
);
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
);
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.
356 tail
= nir_build_deref_cast(&b
->nb
, &tail
->dest
.ssa
, tail
->mode
,
357 tail
->type
, base
->ptr_type
->stride
);
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
);
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
];
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
;
379 access
|= type
->access
;
382 struct vtn_pointer
*ptr
= rzalloc(b
, struct vtn_pointer
);
383 ptr
->mode
= base
->mode
;
385 ptr
->var
= base
->var
;
387 ptr
->access
= access
;
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
)
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
;
403 if (base
->mode
== vtn_variable_mode_ubo
||
404 base
->mode
== vtn_variable_mode_ssbo
) {
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) {
411 vtn_access_link_as_ssa(b
, deref_chain
->link
[0], 1, 32);
413 /* This consumes a level of type */
414 type
= type
->array_element
;
415 access
|= type
->access
;
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.
422 desc_arr_idx
= nir_imm_int(&b
->nb
, 0);
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);
429 /* We have a regular non-array SSBO. */
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:
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."
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.
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.
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);
462 block_index
= vtn_resource_reindex(b
, base
->mode
,
463 block_index
, offset_index
);
468 if (base
->mode
== vtn_variable_mode_workgroup
) {
469 /* SLM doesn't need nor have a block index */
470 vtn_assert(!block_index
);
472 /* We need the variable for the base offset */
473 vtn_assert(base
->var
);
475 /* We need ptr_type for size and alignment */
476 vtn_assert(base
->ptr_type
);
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.
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
;
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
);
494 /* Start off with at the start of the push constant block. */
495 offset
= nir_imm_int(&b
->nb
, 0);
497 /* The code above should have ensured a block_index when needed. */
498 vtn_assert(block_index
);
500 /* Start off with at the start of the buffer. */
501 offset
= nir_imm_int(&b
->nb
, 0);
505 if (deref_chain
->ptr_as_array
&& idx
== 0) {
506 /* We need ptr_type for the stride */
507 vtn_assert(base
->ptr_type
);
509 /* We need at least one element in the chain */
510 vtn_assert(deref_chain
->length
>= 1);
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
);
519 for (; idx
< deref_chain
->length
; idx
++) {
520 switch (glsl_get_base_type(type
->type
)) {
523 case GLSL_TYPE_UINT16
:
524 case GLSL_TYPE_INT16
:
525 case GLSL_TYPE_UINT8
:
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
:
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
;
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
;
554 vtn_fail("Invalid type for deref");
558 struct vtn_pointer
*ptr
= rzalloc(b
, struct vtn_pointer
);
559 ptr
->mode
= base
->mode
;
561 ptr
->block_index
= block_index
;
562 ptr
->offset
= offset
;
563 ptr
->access
= access
;
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
)
574 if (vtn_pointer_uses_ssa_offset(b
, base
)) {
575 return vtn_ssa_offset_pointer_dereference(b
, base
, deref_chain
);
577 return vtn_nir_deref_pointer_dereference(b
, base
, deref_chain
);
582 vtn_pointer_for_variable(struct vtn_builder
*b
,
583 struct vtn_variable
*var
, struct vtn_type
*ptr_type
)
585 struct vtn_pointer
*pointer
= rzalloc(b
, struct vtn_pointer
);
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
;
593 pointer
->access
= var
->access
| var
->type
->access
;
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.
602 * Manages uint scalars, arrays, and arrays of arrays of any nested depth.
604 static const struct glsl_type
*
605 repair_atomic_type(const struct glsl_type
*type
)
607 assert(glsl_get_base_type(glsl_without_array(type
)) == GLSL_TYPE_UINT
);
608 assert(glsl_type_is_scalar(glsl_without_array(type
)));
610 if (glsl_type_is_array(type
)) {
611 const struct glsl_type
*atomic
=
612 repair_atomic_type(glsl_get_array_element(type
));
614 return glsl_array_type(atomic
, glsl_get_length(type
),
615 glsl_get_explicit_stride(type
));
617 return glsl_atomic_uint_type();
622 vtn_pointer_to_deref(struct vtn_builder
*b
, struct vtn_pointer
*ptr
)
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
);
630 vtn_assert(!vtn_pointer_uses_ssa_offset(b
, ptr
));
632 struct vtn_access_chain chain
= {
635 ptr
= vtn_nir_deref_pointer_dereference(b
, ptr
, &chain
);
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
)
646 if (glsl_type_is_vector_or_scalar(deref
->type
)) {
648 inout
->def
= nir_load_deref_with_access(&b
->nb
, deref
, access
);
650 nir_store_deref_with_access(&b
->nb
, deref
, inout
->def
, ~0, access
);
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
);
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
);
671 vtn_nir_deref(struct vtn_builder
*b
, uint32_t id
)
673 struct vtn_pointer
*ptr
= vtn_value(b
, id
, vtn_value_type_pointer
)->pointer
;
674 return vtn_pointer_to_deref(b
, ptr
);
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.
682 static nir_deref_instr
*
683 get_deref_tail(nir_deref_instr
*deref
)
685 if (deref
->deref_type
!= nir_deref_type_array
)
688 nir_deref_instr
*parent
=
689 nir_instr_as_deref(deref
->parent
.ssa
->parent_instr
);
691 if (glsl_type_is_vector(parent
->type
))
697 struct vtn_ssa_value
*
698 vtn_local_load(struct vtn_builder
*b
, nir_deref_instr
*src
,
699 enum gl_access_qualifier access
)
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
);
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
));
711 val
->def
= vtn_vector_extract_dynamic(b
, val
->def
, src
->arr
.index
.ssa
);
718 vtn_local_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
719 nir_deref_instr
*dest
, enum gl_access_qualifier access
)
721 nir_deref_instr
*dest_tail
= get_deref_tail(dest
);
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
);
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
));
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
);
735 _vtn_local_load_store(b
, false, dest_tail
, src
, access
);
740 vtn_pointer_to_offset(struct vtn_builder
*b
, struct vtn_pointer
*ptr
,
741 nir_ssa_def
**index_out
)
743 assert(vtn_pointer_uses_ssa_offset(b
, ptr
));
745 struct vtn_access_chain chain
= {
748 ptr
= vtn_ssa_offset_pointer_dereference(b
, ptr
, &chain
);
750 *index_out
= ptr
->block_index
;
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.
758 vtn_type_block_size(struct vtn_builder
*b
, struct vtn_type
*type
)
760 enum glsl_base_type base_type
= glsl_get_base_type(type
->type
);
764 case GLSL_TYPE_UINT16
:
765 case GLSL_TYPE_INT16
:
766 case GLSL_TYPE_UINT8
:
768 case GLSL_TYPE_UINT64
:
769 case GLSL_TYPE_INT64
:
770 case GLSL_TYPE_FLOAT
:
771 case GLSL_TYPE_FLOAT16
:
773 case GLSL_TYPE_DOUBLE
: {
774 unsigned cols
= type
->row_major
? glsl_get_vector_elements(type
->type
) :
775 glsl_get_matrix_columns(type
->type
);
777 vtn_assert(type
->stride
> 0);
778 return type
->stride
* cols
;
780 unsigned type_size
= glsl_get_bit_size(type
->type
) / 8;
781 return glsl_get_vector_elements(type
->type
) * type_size
;
785 case GLSL_TYPE_STRUCT
:
786 case GLSL_TYPE_INTERFACE
: {
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
);
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
);
803 vtn_fail("Invalid block type");
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
)
815 nir_intrinsic_instr
*instr
= nir_intrinsic_instr_create(b
->nb
.shader
, op
);
816 instr
->num_components
= glsl_get_vector_elements(type
);
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.
822 const unsigned data_bit_size
= glsl_type_is_boolean(type
) ? 32 :
823 glsl_get_bit_size(type
);
827 nir_intrinsic_set_write_mask(instr
, (1 << instr
->num_components
) - 1);
828 instr
->src
[src
++] = nir_src_for_ssa((*inout
)->def
);
831 if (op
== nir_intrinsic_load_push_constant
) {
832 nir_intrinsic_set_base(instr
, access_offset
);
833 nir_intrinsic_set_range(instr
, access_size
);
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
);
842 /* With extensions like relaxed_block_layout, we really can't guarantee
843 * much more than scalar alignment.
845 if (op
!= nir_intrinsic_load_push_constant
)
846 nir_intrinsic_set_align(instr
, data_bit_size
/ 8, 0);
849 instr
->src
[src
++] = nir_src_for_ssa(index
);
851 if (op
== nir_intrinsic_load_push_constant
) {
852 /* We need to subtract the offset from where the intrinsic will load the
855 nir_src_for_ssa(nir_isub(&b
->nb
, offset
,
856 nir_imm_int(&b
->nb
, access_offset
)));
858 instr
->src
[src
++] = nir_src_for_ssa(offset
);
862 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
,
863 instr
->num_components
, data_bit_size
, NULL
);
864 (*inout
)->def
= &instr
->dest
.ssa
;
867 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
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));
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
)
880 if (load
&& *inout
== NULL
)
881 *inout
= vtn_create_ssa_value(b
, type
->type
);
883 enum glsl_base_type base_type
= glsl_get_base_type(type
->type
);
887 case GLSL_TYPE_UINT16
:
888 case GLSL_TYPE_INT16
:
889 case GLSL_TYPE_UINT8
:
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
:
897 /* This is where things get interesting. At this point, we've hit
898 * a vector, a scalar, or a matrix.
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
;
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
);
913 transpose
= vtn_ssa_transpose(b
, *inout
);
917 num_ops
= glsl_get_matrix_columns(type
->type
);
918 vec_width
= glsl_get_vector_elements(type
->type
);
919 col_stride
= type
->stride
;
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
,
928 glsl_vector_type(base_type
, vec_width
),
929 type
->access
| access
);
932 if (load
&& type
->row_major
)
933 *inout
= vtn_ssa_transpose(b
, *inout
);
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
,
943 type
->access
| access
);
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.
948 vtn_assert(type
->stride
> type_size
);
949 vtn_assert(type
->stride
% type_size
== 0);
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
;
957 temp_val
.def
= nir_channel(&b
->nb
, (*inout
)->def
, i
);
958 temp_val
.type
= glsl_scalar_type(base_type
);
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
;
970 *inout
= vtn_create_ssa_value(b
, type
->type
);
971 (*inout
)->def
= nir_vec(&b
->nb
, per_comp
, elems
);
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
,
985 type
->array_element
->access
| access
,
986 &(*inout
)->elems
[i
]);
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
,
1000 type
->members
[i
]->access
| access
,
1001 &(*inout
)->elems
[i
]);
1007 vtn_fail("Invalid block member type");
1011 static struct vtn_ssa_value
*
1012 vtn_block_load(struct vtn_builder
*b
, struct vtn_pointer
*src
)
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
;
1020 case vtn_variable_mode_ssbo
:
1021 op
= nir_intrinsic_load_ssbo
;
1023 case vtn_variable_mode_push_constant
:
1024 op
= nir_intrinsic_load_push_constant
;
1025 access_size
= b
->shader
->num_uniforms
;
1027 case vtn_variable_mode_workgroup
:
1028 op
= nir_intrinsic_load_shared
;
1031 vtn_fail("Invalid block variable mode");
1034 nir_ssa_def
*offset
, *index
= NULL
;
1035 offset
= vtn_pointer_to_offset(b
, src
, &index
);
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
);
1045 vtn_block_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1046 struct vtn_pointer
*dst
)
1048 nir_intrinsic_op op
;
1049 switch (dst
->mode
) {
1050 case vtn_variable_mode_ssbo
:
1051 op
= nir_intrinsic_store_ssbo
;
1053 case vtn_variable_mode_workgroup
:
1054 op
= nir_intrinsic_store_shared
;
1057 vtn_fail("Invalid block variable mode");
1060 nir_ssa_def
*offset
, *index
= NULL
;
1061 offset
= vtn_pointer_to_offset(b
, dst
, &index
);
1063 _vtn_block_load_store(b
, op
, false, index
, offset
,
1064 0, 0, dst
->type
, dst
->access
, &src
);
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
)
1073 enum glsl_base_type base_type
= glsl_get_base_type(ptr
->type
->type
);
1074 switch (base_type
) {
1075 case GLSL_TYPE_UINT
:
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
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
);
1105 nir_store_deref_with_access(&b
->nb
, deref
, (*inout
)->def
, ~0,
1106 ptr
->type
->access
| access
);
1110 *inout
= vtn_local_load(b
, deref
, ptr
->type
->access
| access
);
1112 vtn_local_store(b
, *inout
, deref
, ptr
->type
->access
| access
);
1119 case GLSL_TYPE_INTERFACE
:
1120 case GLSL_TYPE_ARRAY
:
1121 case GLSL_TYPE_STRUCT
: {
1122 unsigned elems
= glsl_get_length(ptr
->type
->type
);
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
);
1130 struct vtn_access_chain chain
= {
1133 { .mode
= vtn_access_mode_literal
, },
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
]);
1146 vtn_fail("Invalid access chain type");
1150 struct vtn_ssa_value
*
1151 vtn_variable_load(struct vtn_builder
*b
, struct vtn_pointer
*src
)
1153 if (vtn_pointer_uses_ssa_offset(b
, src
)) {
1154 return vtn_block_load(b
, src
);
1156 struct vtn_ssa_value
*val
= NULL
;
1157 _vtn_variable_load_store(b
, true, src
, src
->access
, &val
);
1163 vtn_variable_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1164 struct vtn_pointer
*dest
)
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
);
1171 _vtn_variable_load_store(b
, false, dest
, dest
->access
, &src
);
1176 _vtn_variable_copy(struct vtn_builder
*b
, struct vtn_pointer
*dest
,
1177 struct vtn_pointer
*src
)
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
:
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.
1200 vtn_variable_store(b
, vtn_variable_load(b
, src
), dest
);
1203 case GLSL_TYPE_INTERFACE
:
1204 case GLSL_TYPE_ARRAY
:
1205 case GLSL_TYPE_STRUCT
: {
1206 struct vtn_access_chain chain
= {
1209 { .mode
= vtn_access_mode_literal
, },
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
);
1220 _vtn_variable_copy(b
, dest_elem
, src_elem
);
1226 vtn_fail("Invalid access chain type");
1231 vtn_variable_copy(struct vtn_builder
*b
, struct vtn_pointer
*dest
,
1232 struct vtn_pointer
*src
)
1234 /* TODO: At some point, we should add a special-case for when we can
1235 * just emit a copy_var intrinsic.
1237 _vtn_variable_copy(b
, dest
, src
);
1241 set_mode_system_value(struct vtn_builder
*b
, nir_variable_mode
*mode
)
1243 vtn_assert(*mode
== nir_var_system_value
|| *mode
== nir_var_shader_in
);
1244 *mode
= nir_var_system_value
;
1248 vtn_get_builtin_location(struct vtn_builder
*b
,
1249 SpvBuiltIn builtin
, int *location
,
1250 nir_variable_mode
*mode
)
1253 case SpvBuiltInPosition
:
1254 *location
= VARYING_SLOT_POS
;
1256 case SpvBuiltInPointSize
:
1257 *location
= VARYING_SLOT_PSIZ
;
1259 case SpvBuiltInClipDistance
:
1260 *location
= VARYING_SLOT_CLIP_DIST0
; /* XXX CLIP_DIST1? */
1262 case SpvBuiltInCullDistance
:
1263 *location
= VARYING_SLOT_CULL_DIST0
;
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.
1273 *location
= SYSTEM_VALUE_VERTEX_ID
;
1274 set_mode_system_value(b
, mode
);
1276 case SpvBuiltInInstanceIndex
:
1277 *location
= SYSTEM_VALUE_INSTANCE_INDEX
;
1278 set_mode_system_value(b
, mode
);
1280 case SpvBuiltInInstanceId
:
1281 *location
= SYSTEM_VALUE_INSTANCE_ID
;
1282 set_mode_system_value(b
, mode
);
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
;
1291 *location
= SYSTEM_VALUE_PRIMITIVE_ID
;
1292 set_mode_system_value(b
, mode
);
1295 case SpvBuiltInInvocationId
:
1296 *location
= SYSTEM_VALUE_INVOCATION_ID
;
1297 set_mode_system_value(b
, mode
);
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
;
1310 vtn_fail("invalid stage for SpvBuiltInLayer");
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
;
1323 vtn_fail("invalid stage for SpvBuiltInViewportIndex");
1325 case SpvBuiltInTessLevelOuter
:
1326 *location
= VARYING_SLOT_TESS_LEVEL_OUTER
;
1328 case SpvBuiltInTessLevelInner
:
1329 *location
= VARYING_SLOT_TESS_LEVEL_INNER
;
1331 case SpvBuiltInTessCoord
:
1332 *location
= SYSTEM_VALUE_TESS_COORD
;
1333 set_mode_system_value(b
, mode
);
1335 case SpvBuiltInPatchVertices
:
1336 *location
= SYSTEM_VALUE_VERTICES_IN
;
1337 set_mode_system_value(b
, mode
);
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
;
1345 *location
= VARYING_SLOT_POS
;
1348 case SpvBuiltInPointCoord
:
1349 *location
= VARYING_SLOT_PNTC
;
1350 vtn_assert(*mode
== nir_var_shader_in
);
1352 case SpvBuiltInFrontFacing
:
1353 *location
= SYSTEM_VALUE_FRONT_FACE
;
1354 set_mode_system_value(b
, mode
);
1356 case SpvBuiltInSampleId
:
1357 *location
= SYSTEM_VALUE_SAMPLE_ID
;
1358 set_mode_system_value(b
, mode
);
1360 case SpvBuiltInSamplePosition
:
1361 *location
= SYSTEM_VALUE_SAMPLE_POS
;
1362 set_mode_system_value(b
, mode
);
1364 case SpvBuiltInSampleMask
:
1365 if (*mode
== nir_var_shader_out
) {
1366 *location
= FRAG_RESULT_SAMPLE_MASK
;
1368 *location
= SYSTEM_VALUE_SAMPLE_MASK_IN
;
1369 set_mode_system_value(b
, mode
);
1372 case SpvBuiltInFragDepth
:
1373 *location
= FRAG_RESULT_DEPTH
;
1374 vtn_assert(*mode
== nir_var_shader_out
);
1376 case SpvBuiltInHelperInvocation
:
1377 *location
= SYSTEM_VALUE_HELPER_INVOCATION
;
1378 set_mode_system_value(b
, mode
);
1380 case SpvBuiltInNumWorkgroups
:
1381 *location
= SYSTEM_VALUE_NUM_WORK_GROUPS
;
1382 set_mode_system_value(b
, mode
);
1384 case SpvBuiltInWorkgroupSize
:
1385 *location
= SYSTEM_VALUE_LOCAL_GROUP_SIZE
;
1386 set_mode_system_value(b
, mode
);
1388 case SpvBuiltInWorkgroupId
:
1389 *location
= SYSTEM_VALUE_WORK_GROUP_ID
;
1390 set_mode_system_value(b
, mode
);
1392 case SpvBuiltInLocalInvocationId
:
1393 *location
= SYSTEM_VALUE_LOCAL_INVOCATION_ID
;
1394 set_mode_system_value(b
, mode
);
1396 case SpvBuiltInLocalInvocationIndex
:
1397 *location
= SYSTEM_VALUE_LOCAL_INVOCATION_INDEX
;
1398 set_mode_system_value(b
, mode
);
1400 case SpvBuiltInGlobalInvocationId
:
1401 *location
= SYSTEM_VALUE_GLOBAL_INVOCATION_ID
;
1402 set_mode_system_value(b
, mode
);
1404 case SpvBuiltInGlobalLinearId
:
1405 *location
= SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX
;
1406 set_mode_system_value(b
, mode
);
1408 case SpvBuiltInBaseVertex
:
1409 /* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same
1410 * semantic as Vulkan BaseVertex (SYSTEM_VALUE_FIRST_VERTEX).
1412 if (b
->options
->environment
== NIR_SPIRV_OPENGL
)
1413 *location
= SYSTEM_VALUE_BASE_VERTEX
;
1415 *location
= SYSTEM_VALUE_FIRST_VERTEX
;
1416 set_mode_system_value(b
, mode
);
1418 case SpvBuiltInBaseInstance
:
1419 *location
= SYSTEM_VALUE_BASE_INSTANCE
;
1420 set_mode_system_value(b
, mode
);
1422 case SpvBuiltInDrawIndex
:
1423 *location
= SYSTEM_VALUE_DRAW_ID
;
1424 set_mode_system_value(b
, mode
);
1426 case SpvBuiltInSubgroupSize
:
1427 *location
= SYSTEM_VALUE_SUBGROUP_SIZE
;
1428 set_mode_system_value(b
, mode
);
1430 case SpvBuiltInSubgroupId
:
1431 *location
= SYSTEM_VALUE_SUBGROUP_ID
;
1432 set_mode_system_value(b
, mode
);
1434 case SpvBuiltInSubgroupLocalInvocationId
:
1435 *location
= SYSTEM_VALUE_SUBGROUP_INVOCATION
;
1436 set_mode_system_value(b
, mode
);
1438 case SpvBuiltInNumSubgroups
:
1439 *location
= SYSTEM_VALUE_NUM_SUBGROUPS
;
1440 set_mode_system_value(b
, mode
);
1442 case SpvBuiltInDeviceIndex
:
1443 *location
= SYSTEM_VALUE_DEVICE_INDEX
;
1444 set_mode_system_value(b
, mode
);
1446 case SpvBuiltInViewIndex
:
1447 *location
= SYSTEM_VALUE_VIEW_INDEX
;
1448 set_mode_system_value(b
, mode
);
1450 case SpvBuiltInSubgroupEqMask
:
1451 *location
= SYSTEM_VALUE_SUBGROUP_EQ_MASK
,
1452 set_mode_system_value(b
, mode
);
1454 case SpvBuiltInSubgroupGeMask
:
1455 *location
= SYSTEM_VALUE_SUBGROUP_GE_MASK
,
1456 set_mode_system_value(b
, mode
);
1458 case SpvBuiltInSubgroupGtMask
:
1459 *location
= SYSTEM_VALUE_SUBGROUP_GT_MASK
,
1460 set_mode_system_value(b
, mode
);
1462 case SpvBuiltInSubgroupLeMask
:
1463 *location
= SYSTEM_VALUE_SUBGROUP_LE_MASK
,
1464 set_mode_system_value(b
, mode
);
1466 case SpvBuiltInSubgroupLtMask
:
1467 *location
= SYSTEM_VALUE_SUBGROUP_LT_MASK
,
1468 set_mode_system_value(b
, mode
);
1470 case SpvBuiltInFragStencilRefEXT
:
1471 *location
= FRAG_RESULT_STENCIL
;
1472 vtn_assert(*mode
== nir_var_shader_out
);
1474 case SpvBuiltInWorkDim
:
1475 *location
= SYSTEM_VALUE_WORK_DIM
;
1476 set_mode_system_value(b
, mode
);
1478 case SpvBuiltInGlobalSize
:
1479 *location
= SYSTEM_VALUE_GLOBAL_GROUP_SIZE
;
1480 set_mode_system_value(b
, mode
);
1483 vtn_fail("Unsupported builtin: %s (%u)",
1484 spirv_builtin_to_string(builtin
), builtin
);
1489 apply_var_decoration(struct vtn_builder
*b
,
1490 struct nir_variable_data
*var_data
,
1491 const struct vtn_decoration
*dec
)
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
;
1499 case SpvDecorationFlat
:
1500 var_data
->interpolation
= INTERP_MODE_FLAT
;
1502 case SpvDecorationCentroid
:
1503 var_data
->centroid
= true;
1505 case SpvDecorationSample
:
1506 var_data
->sample
= true;
1508 case SpvDecorationInvariant
:
1509 var_data
->invariant
= true;
1511 case SpvDecorationConstant
:
1512 var_data
->read_only
= true;
1514 case SpvDecorationNonReadable
:
1515 var_data
->image
.access
|= ACCESS_NON_READABLE
;
1517 case SpvDecorationNonWritable
:
1518 var_data
->read_only
= true;
1519 var_data
->image
.access
|= ACCESS_NON_WRITEABLE
;
1521 case SpvDecorationRestrict
:
1522 var_data
->image
.access
|= ACCESS_RESTRICT
;
1524 case SpvDecorationVolatile
:
1525 var_data
->image
.access
|= ACCESS_VOLATILE
;
1527 case SpvDecorationCoherent
:
1528 var_data
->image
.access
|= ACCESS_COHERENT
;
1530 case SpvDecorationComponent
:
1531 var_data
->location_frac
= dec
->operands
[0];
1533 case SpvDecorationIndex
:
1534 var_data
->index
= dec
->operands
[0];
1536 case SpvDecorationBuiltIn
: {
1537 SpvBuiltIn builtin
= dec
->operands
[0];
1539 nir_variable_mode mode
= var_data
->mode
;
1540 vtn_get_builtin_location(b
, builtin
, &var_data
->location
, &mode
);
1541 var_data
->mode
= mode
;
1544 case SpvBuiltInTessLevelOuter
:
1545 case SpvBuiltInTessLevelInner
:
1546 case SpvBuiltInClipDistance
:
1547 case SpvBuiltInCullDistance
:
1548 var_data
->compact
= true;
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 */
1565 case SpvDecorationPatch
:
1566 var_data
->patch
= true;
1569 case SpvDecorationLocation
:
1570 vtn_fail("Handled above");
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 */
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
));
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;
1592 case SpvDecorationXfbStride
:
1593 var_data
->explicit_xfb_stride
= true;
1594 var_data
->xfb_stride
= dec
->operands
[0];
1596 case SpvDecorationOffset
:
1597 var_data
->explicit_offset
= true;
1598 var_data
->offset
= dec
->operands
[0];
1601 case SpvDecorationStream
:
1602 var_data
->stream
= dec
->operands
[0];
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
));
1617 case SpvDecorationUserSemantic
:
1618 /* User semantic decorations can safely be ignored by the driver. */
1621 case SpvDecorationRestrictPointerEXT
:
1622 case SpvDecorationAliasedPointerEXT
:
1623 /* TODO: We should actually plumb alias information through NIR. */
1627 vtn_fail_with_decoration("Unhandled decoration", dec
->decoration
);
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
)
1635 if (dec
->decoration
== SpvDecorationPatch
) {
1636 *((bool *) out_is_patch
) = true;
1641 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
, int member
,
1642 const struct vtn_decoration
*dec
, void *void_var
)
1644 struct vtn_variable
*vtn_var
= void_var
;
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;
1652 case SpvDecorationDescriptorSet
:
1653 vtn_var
->descriptor_set
= dec
->operands
[0];
1655 case SpvDecorationInputAttachmentIndex
:
1656 vtn_var
->input_attachment_index
= dec
->operands
[0];
1658 case SpvDecorationPatch
:
1659 vtn_var
->patch
= true;
1661 case SpvDecorationOffset
:
1662 vtn_var
->offset
= dec
->operands
[0];
1664 case SpvDecorationNonWritable
:
1665 vtn_var
->access
|= ACCESS_NON_WRITEABLE
;
1667 case SpvDecorationNonReadable
:
1668 vtn_var
->access
|= ACCESS_NON_READABLE
;
1670 case SpvDecorationVolatile
:
1671 vtn_var
->access
|= ACCESS_VOLATILE
;
1673 case SpvDecorationCoherent
:
1674 vtn_var
->access
|= ACCESS_COHERENT
;
1676 case SpvDecorationCounterBuffer
:
1677 /* Counter buffer decorations can safely be ignored by the driver. */
1683 if (val
->value_type
== vtn_value_type_pointer
) {
1684 assert(val
->pointer
->var
== void_var
);
1685 assert(member
== -1);
1687 assert(val
->value_type
== vtn_value_type_type
);
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
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 "
1711 if (vtn_var
->var
->num_members
== 0) {
1712 /* This handles the member and lone variable cases */
1713 vtn_var
->var
->data
.location
= location
;
1715 /* This handles the structure member case */
1716 assert(vtn_var
->var
->members
);
1719 vtn_var
->base_location
= location
;
1721 vtn_var
->var
->members
[member
].location
= location
;
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.
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
);
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
);
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.
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
);
1757 ptr_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
, int member
,
1758 const struct vtn_decoration
*dec
, void *void_ptr
)
1760 struct vtn_pointer
*ptr
= void_ptr
;
1762 switch (dec
->decoration
) {
1763 case SpvDecorationNonUniformEXT
:
1764 ptr
->access
|= ACCESS_NON_UNIFORM
;
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
)
1778 enum vtn_variable_mode mode
;
1779 nir_variable_mode nir_mode
;
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
;
1790 /* Default-block uniforms, coming from gl_spirv */
1791 mode
= vtn_variable_mode_uniform
;
1792 nir_mode
= nir_var_uniform
;
1795 case SpvStorageClassStorageBuffer
:
1796 mode
= vtn_variable_mode_ssbo
;
1797 nir_mode
= nir_var_mem_ssbo
;
1799 case SpvStorageClassPhysicalStorageBufferEXT
:
1800 mode
= vtn_variable_mode_phys_ssbo
;
1801 nir_mode
= nir_var_mem_global
;
1803 case SpvStorageClassUniformConstant
:
1804 mode
= vtn_variable_mode_uniform
;
1805 nir_mode
= nir_var_uniform
;
1807 case SpvStorageClassPushConstant
:
1808 mode
= vtn_variable_mode_push_constant
;
1809 nir_mode
= nir_var_uniform
;
1811 case SpvStorageClassInput
:
1812 mode
= vtn_variable_mode_input
;
1813 nir_mode
= nir_var_shader_in
;
1815 case SpvStorageClassOutput
:
1816 mode
= vtn_variable_mode_output
;
1817 nir_mode
= nir_var_shader_out
;
1819 case SpvStorageClassPrivate
:
1820 mode
= vtn_variable_mode_private
;
1821 nir_mode
= nir_var_shader_temp
;
1823 case SpvStorageClassFunction
:
1824 mode
= vtn_variable_mode_function
;
1825 nir_mode
= nir_var_function_temp
;
1827 case SpvStorageClassWorkgroup
:
1828 mode
= vtn_variable_mode_workgroup
;
1829 nir_mode
= nir_var_mem_shared
;
1831 case SpvStorageClassAtomicCounter
:
1832 mode
= vtn_variable_mode_uniform
;
1833 nir_mode
= nir_var_uniform
;
1835 case SpvStorageClassCrossWorkgroup
:
1836 mode
= vtn_variable_mode_cross_workgroup
;
1837 nir_mode
= nir_var_mem_global
;
1839 case SpvStorageClassImage
:
1840 mode
= vtn_variable_mode_image
;
1841 nir_mode
= nir_var_mem_ubo
;
1843 case SpvStorageClassGeneric
:
1845 vtn_fail("Unhandled variable storage class: %s (%u)",
1846 spirv_storageclass_to_string(class), class);
1850 *nir_mode_out
= nir_mode
;
1856 vtn_mode_to_address_format(struct vtn_builder
*b
, enum vtn_variable_mode mode
)
1859 case vtn_variable_mode_ubo
:
1860 return b
->options
->ubo_addr_format
;
1862 case vtn_variable_mode_ssbo
:
1863 return b
->options
->ssbo_addr_format
;
1865 case vtn_variable_mode_phys_ssbo
:
1866 return b
->options
->phys_ssbo_addr_format
;
1868 case vtn_variable_mode_push_constant
:
1869 return b
->options
->push_const_addr_format
;
1871 case vtn_variable_mode_workgroup
:
1872 return b
->options
->shared_addr_format
;
1874 case vtn_variable_mode_cross_workgroup
:
1875 return b
->options
->global_addr_format
;
1877 case vtn_variable_mode_function
:
1878 if (b
->physical_ptrs
)
1879 return b
->options
->temp_addr_format
;
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
;
1890 unreachable("Invalid variable mode");
1894 vtn_pointer_to_ssa(struct vtn_builder
*b
, struct vtn_pointer
*ptr
)
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
);
1902 /* If we don't have an offset then we must be a pointer to the variable
1905 vtn_assert(!ptr
->offset
&& !ptr
->block_index
);
1907 struct vtn_access_chain chain
= {
1910 ptr
= vtn_ssa_offset_pointer_dereference(b
, ptr
, &chain
);
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
);
1919 vtn_assert(ptr
->mode
== vtn_variable_mode_workgroup
);
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
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.
1938 if (!ptr
->block_index
) {
1939 /* If we don't have a block_index then we must be a pointer to the
1942 vtn_assert(!ptr
->deref
);
1944 struct vtn_access_chain chain
= {
1947 ptr
= vtn_nir_deref_pointer_dereference(b
, ptr
, &chain
);
1950 return ptr
->block_index
;
1952 return &vtn_pointer_to_deref(b
, ptr
)->dest
.ssa
;
1957 struct vtn_pointer
*
1958 vtn_pointer_from_ssa(struct vtn_builder
*b
, nir_ssa_def
*ssa
,
1959 struct vtn_type
*ptr_type
)
1961 vtn_assert(ptr_type
->base_type
== vtn_base_type_pointer
);
1963 struct vtn_pointer
*ptr
= rzalloc(b
, struct vtn_pointer
);
1964 struct vtn_type
*without_array
=
1965 vtn_type_without_array(ptr_type
->deref
);
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
;
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.
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
;
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);
1996 vtn_assert(ssa
->num_components
== 1);
1997 ptr
->block_index
= NULL
;
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.
2011 ptr
->block_index
= ssa
;
2013 /* This is a pointer to something internal or a pointer inside a
2014 * block. It's just a regular cast.
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.
2025 ptr
->deref
= nir_build_deref_cast(&b
->nb
, ssa
, nir_mode
,
2026 ptr_type
->deref
->type
,
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
);
2038 is_per_vertex_inout(const struct vtn_variable
*var
, gl_shader_stage stage
)
2040 if (var
->patch
|| !glsl_type_is_array(var
->type
->type
))
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
;
2049 if (var
->mode
== vtn_variable_mode_output
)
2050 return stage
== MESA_SHADER_TESS_CTRL
;
2056 assign_missing_member_locations(struct vtn_variable
*var
)
2059 glsl_get_length(glsl_without_array(var
->type
->type
));
2060 int location
= var
->base_location
;
2062 for (unsigned i
= 0; i
< length
; i
++) {
2063 /* From the Vulkan spec:
2065 * “If the structure type is a Block but without a Location, then each
2066 * of its members must have a Location decoration.”
2069 if (var
->type
->block
) {
2070 assert(var
->base_location
!= -1 ||
2071 var
->var
->members
[i
].location
!= -1);
2074 /* From the Vulkan spec:
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.”
2080 if (var
->var
->members
[i
].location
!= -1)
2081 location
= var
->var
->members
[i
].location
;
2083 var
->var
->members
[i
].location
= location
;
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
2089 const struct glsl_type
*member_type
=
2090 glsl_get_struct_field(glsl_without_array(var
->type
->type
), i
);
2093 glsl_count_attribute_slots(member_type
,
2094 false /* is_gl_vertex_input */);
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
)
2104 vtn_assert(ptr_type
->base_type
== vtn_base_type_pointer
);
2105 struct vtn_type
*type
= ptr_type
->deref
;
2107 struct vtn_type
*without_array
= vtn_type_without_array(ptr_type
->deref
);
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
);
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
++;
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");
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.
2131 vtn_warn("Variables in the StorageBuffer storage class must "
2132 "have a struct type with the Block decoration");
2135 b
->shader
->info
.num_ssbos
++;
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
++;
2143 case vtn_variable_mode_push_constant
:
2144 b
->shader
->num_uniforms
= vtn_type_block_size(b
, type
);
2147 case vtn_variable_mode_image
:
2148 vtn_fail("Cannot create a variable with the Image storage class");
2151 case vtn_variable_mode_phys_ssbo
:
2152 vtn_fail("Cannot create a variable with the "
2153 "PhysicalStorageBufferEXT storage class");
2157 /* No tallying is needed */
2161 struct vtn_variable
*var
= rzalloc(b
, struct vtn_variable
);
2164 var
->base_location
= -1;
2166 vtn_assert(val
->value_type
== vtn_value_type_pointer
);
2167 val
->pointer
= vtn_pointer_for_variable(b
, var
, ptr_type
);
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
);
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.
2182 var
->var
->type
= repair_atomic_type(var
->type
->type
);
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.
2187 var
->var
->type
= var
->type
->type
;
2189 var
->var
->data
.mode
= nir_mode
;
2190 var
->var
->data
.location
= -1;
2191 var
->var
->interface_type
= NULL
;
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
);
2199 var
->var
->type
= var
->type
->type
;
2200 var
->var
->interface_type
= var
->type
->type
;
2202 var
->var
->data
.mode
= nir_mode
;
2203 var
->var
->data
.location
= -1;
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
2215 var
->var
->type
= var
->type
->type
;
2216 var
->var
->data
.mode
= nir_var_mem_shared
;
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.
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.
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.
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
);
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.
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.
2262 per_vertex_type
= var
->type
->array_element
;
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.
2272 var
->var
->type
= var
->type
->type
;
2273 var
->var
->data
.mode
= nir_mode
;
2274 var
->var
->data
.patch
= var
->patch
;
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.
2286 while (iface_type
->base_type
== vtn_base_type_array
)
2287 iface_type
= iface_type
->array_element
;
2289 if (iface_type
->base_type
== vtn_base_type_struct
&& iface_type
->block
)
2290 var
->var
->interface_type
= iface_type
->type
;
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
);
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;
2306 /* For inputs and outputs, we need to grab locations and builtin
2307 * information from the per-vertex type.
2309 vtn_foreach_decoration(b
, vtn_value(b
, per_vertex_type
->id
,
2310 vtn_value_type_type
),
2311 var_decoration_cb
, var
);
2315 case vtn_variable_mode_push_constant
:
2316 case vtn_variable_mode_cross_workgroup
:
2317 /* These don't need actual variables. */
2320 case vtn_variable_mode_image
:
2321 case vtn_variable_mode_phys_ssbo
:
2322 unreachable("Should have been caught before");
2326 var
->var
->constant_initializer
=
2327 nir_constant_clone(initializer
, var
->var
);
2330 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
2331 vtn_foreach_decoration(b
, val
, ptr_decoration_cb
, val
->pointer
);
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
);
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.
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
;
2351 if (glsl_type_is_image(without_array
->type
))
2352 var
->var
->data
.image
.format
= without_array
->image_format
;
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
);
2361 vtn_assert(vtn_pointer_is_external_block(b
, val
->pointer
));
2366 vtn_assert_types_equal(struct vtn_builder
*b
, SpvOp opcode
,
2367 struct vtn_type
*dst_type
,
2368 struct vtn_type
*src_type
)
2370 if (dst_type
->id
== src_type
->id
)
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.
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
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
);
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
));
2395 static nir_ssa_def
*
2396 nir_shrink_zero_pad_vec(nir_builder
*b
, nir_ssa_def
*val
,
2397 unsigned num_components
)
2399 if (val
->num_components
== num_components
)
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
);
2407 comps
[i
] = nir_imm_intN_t(b
, 0, val
->bit_size
);
2409 return nir_vec(b
, comps
, num_components
);
2412 static nir_ssa_def
*
2413 nir_sloppy_bitcast(nir_builder
*b
, nir_ssa_def
*val
,
2414 const struct glsl_type
*type
)
2416 const unsigned num_components
= glsl_get_vector_elements(type
);
2417 const unsigned bit_size
= glsl_get_bit_size(type
);
2419 /* First, zero-pad to ensure that the value is big enough that when we
2420 * bit-cast it, we don't loose anything.
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
);
2428 val
= nir_bitcast_vector(b
, val
, bit_size
);
2430 return nir_shrink_zero_pad_vec(b
, val
, num_components
);
2434 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
2435 const uint32_t *w
, unsigned count
)
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
;
2444 case SpvOpVariable
: {
2445 struct vtn_type
*ptr_type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
2447 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_pointer
);
2449 SpvStorageClass storage_class
= w
[3];
2450 nir_constant
*initializer
= NULL
;
2452 initializer
= vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
2454 vtn_create_variable(b
, val
, ptr_type
, storage_class
, initializer
);
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
);
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
]);
2473 chain
->link
[idx
].mode
= vtn_access_mode_id
;
2474 chain
->link
[idx
].id
= w
[i
];
2476 access
|= vtn_value_access(link_val
);
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.
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
);
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
);
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
);
2516 vtn_assert_types_equal(b
, opcode
, dest
->type
->deref
, src
->type
->deref
);
2518 vtn_variable_copy(b
, dest
->pointer
, src
->pointer
);
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
;
2528 vtn_assert_types_equal(b
, opcode
, res_type
, src_val
->type
->deref
);
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
);
2536 vtn_push_ssa(b
, w
[2], res_type
, vtn_variable_load(b
, src
));
2541 struct vtn_value
*dest_val
= vtn_value(b
, w
[1], vtn_value_type_pointer
);
2542 struct vtn_pointer
*dest
= dest_val
->pointer
;
2543 struct vtn_value
*src_val
= vtn_untyped_value(b
, w
[2]);
2545 /* OpStore requires us to actually have a storage type */
2546 vtn_fail_if(dest
->type
->type
== NULL
,
2547 "Invalid destination type for OpStore");
2549 if (glsl_get_base_type(dest
->type
->type
) == GLSL_TYPE_BOOL
&&
2550 glsl_get_base_type(src_val
->type
->type
) == GLSL_TYPE_UINT
) {
2551 /* Early versions of GLSLang would use uint types for UBOs/SSBOs but
2552 * would then store them to a local variable as bool. Work around
2553 * the issue by doing an implicit conversion.
2555 * https://github.com/KhronosGroup/glslang/issues/170
2556 * https://bugs.freedesktop.org/show_bug.cgi?id=104424
2558 vtn_warn("OpStore of value of type OpTypeInt to a pointer to type "
2559 "OpTypeBool. Doing an implicit conversion to work around "
2561 struct vtn_ssa_value
*bool_ssa
=
2562 vtn_create_ssa_value(b
, dest
->type
->type
);
2563 bool_ssa
->def
= nir_i2b(&b
->nb
, vtn_ssa_value(b
, w
[2])->def
);
2564 vtn_variable_store(b
, bool_ssa
, dest
);
2568 vtn_assert_types_equal(b
, opcode
, dest_val
->type
->deref
, src_val
->type
);
2570 if (glsl_type_is_sampler(dest
->type
->type
)) {
2571 if (b
->wa_glslang_179
) {
2572 vtn_warn("OpStore of a sampler detected. Doing on-the-fly copy "
2573 "propagation to workaround the problem.");
2574 vtn_assert(dest
->var
->copy_prop_sampler
== NULL
);
2575 dest
->var
->copy_prop_sampler
=
2576 vtn_value(b
, w
[2], vtn_value_type_pointer
)->pointer
;
2578 vtn_fail("Vulkan does not allow OpStore of a sampler or image.");
2583 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[2]);
2584 vtn_variable_store(b
, src
, dest
);
2588 case SpvOpArrayLength
: {
2589 struct vtn_pointer
*ptr
=
2590 vtn_value(b
, w
[3], vtn_value_type_pointer
)->pointer
;
2591 const uint32_t field
= w
[4];
2593 vtn_fail_if(ptr
->type
->base_type
!= vtn_base_type_struct
,
2594 "OpArrayLength must take a pointer to a structure type");
2595 vtn_fail_if(field
!= ptr
->type
->length
- 1 ||
2596 ptr
->type
->members
[field
]->base_type
!= vtn_base_type_array
,
2597 "OpArrayLength must reference the last memeber of the "
2598 "structure and that must be an array");
2600 const uint32_t offset
= ptr
->type
->offsets
[field
];
2601 const uint32_t stride
= ptr
->type
->members
[field
]->stride
;
2603 if (!ptr
->block_index
) {
2604 struct vtn_access_chain chain
= {
2607 ptr
= vtn_pointer_dereference(b
, ptr
, &chain
);
2608 vtn_assert(ptr
->block_index
);
2611 nir_intrinsic_instr
*instr
=
2612 nir_intrinsic_instr_create(b
->nb
.shader
,
2613 nir_intrinsic_get_buffer_size
);
2614 instr
->src
[0] = nir_src_for_ssa(ptr
->block_index
);
2615 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 1, 32, NULL
);
2616 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
2617 nir_ssa_def
*buf_size
= &instr
->dest
.ssa
;
2619 /* array_length = max(buffer_size - offset, 0) / stride */
2620 nir_ssa_def
*array_length
=
2625 nir_imm_int(&b
->nb
, offset
)),
2626 nir_imm_int(&b
->nb
, 0u)),
2627 nir_imm_int(&b
->nb
, stride
));
2629 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2630 val
->ssa
= vtn_create_ssa_value(b
, glsl_uint_type());
2631 val
->ssa
->def
= array_length
;
2635 case SpvOpConvertPtrToU
: {
2636 struct vtn_value
*u_val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2638 vtn_fail_if(u_val
->type
->base_type
!= vtn_base_type_vector
&&
2639 u_val
->type
->base_type
!= vtn_base_type_scalar
,
2640 "OpConvertPtrToU can only be used to cast to a vector or "
2643 /* The pointer will be converted to an SSA value automatically */
2644 struct vtn_ssa_value
*ptr_ssa
= vtn_ssa_value(b
, w
[3]);
2646 u_val
->ssa
= vtn_create_ssa_value(b
, u_val
->type
->type
);
2647 u_val
->ssa
->def
= nir_sloppy_bitcast(&b
->nb
, ptr_ssa
->def
, u_val
->type
->type
);
2648 u_val
->ssa
->access
|= ptr_ssa
->access
;
2652 case SpvOpConvertUToPtr
: {
2653 struct vtn_value
*ptr_val
=
2654 vtn_push_value(b
, w
[2], vtn_value_type_pointer
);
2655 struct vtn_value
*u_val
= vtn_value(b
, w
[3], vtn_value_type_ssa
);
2657 vtn_fail_if(ptr_val
->type
->type
== NULL
,
2658 "OpConvertUToPtr can only be used on physical pointers");
2660 vtn_fail_if(u_val
->type
->base_type
!= vtn_base_type_vector
&&
2661 u_val
->type
->base_type
!= vtn_base_type_scalar
,
2662 "OpConvertUToPtr can only be used to cast from a vector or "
2665 nir_ssa_def
*ptr_ssa
= nir_sloppy_bitcast(&b
->nb
, u_val
->ssa
->def
,
2666 ptr_val
->type
->type
);
2667 ptr_val
->pointer
= vtn_pointer_from_ssa(b
, ptr_ssa
, ptr_val
->type
);
2668 vtn_foreach_decoration(b
, ptr_val
, ptr_decoration_cb
, ptr_val
->pointer
);
2669 ptr_val
->pointer
->access
|= u_val
->ssa
->access
;
2673 case SpvOpCopyMemorySized
:
2675 vtn_fail_with_opcode("Unhandled opcode", opcode
);