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