Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/compiler/spirv/spirv_to_nir.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 "nir/nir_vla.h"
30
#include "nir/nir_control_flow.h"
31
#include "nir/nir_constant_expressions.h"
32
#include "nir/nir_deref.h"
33
#include "spirv_info.h"
34
35
#include "util/format/u_format.h"
36
#include "util/u_math.h"
37
#include "util/u_string.h"
38
39
#include <stdio.h>
40
41
#ifndef NDEBUG
42
static enum nir_spirv_debug_level
43
vtn_default_log_level(void)
44
{
45
enum nir_spirv_debug_level level = NIR_SPIRV_DEBUG_LEVEL_WARNING;
46
const char *vtn_log_level_strings[] = {
47
[NIR_SPIRV_DEBUG_LEVEL_WARNING] = "warning",
48
[NIR_SPIRV_DEBUG_LEVEL_INFO] = "info",
49
[NIR_SPIRV_DEBUG_LEVEL_ERROR] = "error",
50
};
51
const char *str = getenv("MESA_SPIRV_LOG_LEVEL");
52
53
if (str == NULL)
54
return NIR_SPIRV_DEBUG_LEVEL_WARNING;
55
56
for (int i = 0; i < ARRAY_SIZE(vtn_log_level_strings); i++) {
57
if (strcasecmp(str, vtn_log_level_strings[i]) == 0) {
58
level = i;
59
break;
60
}
61
}
62
63
return level;
64
}
65
#endif
66
67
void
68
vtn_log(struct vtn_builder *b, enum nir_spirv_debug_level level,
69
size_t spirv_offset, const char *message)
70
{
71
if (b->options->debug.func) {
72
b->options->debug.func(b->options->debug.private_data,
73
level, spirv_offset, message);
74
}
75
76
#ifndef NDEBUG
77
static enum nir_spirv_debug_level default_level =
78
NIR_SPIRV_DEBUG_LEVEL_INVALID;
79
80
if (default_level == NIR_SPIRV_DEBUG_LEVEL_INVALID)
81
default_level = vtn_default_log_level();
82
83
if (level >= default_level)
84
fprintf(stderr, "%s\n", message);
85
#endif
86
}
87
88
void
89
vtn_logf(struct vtn_builder *b, enum nir_spirv_debug_level level,
90
size_t spirv_offset, const char *fmt, ...)
91
{
92
va_list args;
93
char *msg;
94
95
va_start(args, fmt);
96
msg = ralloc_vasprintf(NULL, fmt, args);
97
va_end(args);
98
99
vtn_log(b, level, spirv_offset, msg);
100
101
ralloc_free(msg);
102
}
103
104
static void
105
vtn_log_err(struct vtn_builder *b,
106
enum nir_spirv_debug_level level, const char *prefix,
107
const char *file, unsigned line,
108
const char *fmt, va_list args)
109
{
110
char *msg;
111
112
msg = ralloc_strdup(NULL, prefix);
113
114
#ifndef NDEBUG
115
ralloc_asprintf_append(&msg, " In file %s:%u\n", file, line);
116
#endif
117
118
ralloc_asprintf_append(&msg, " ");
119
120
ralloc_vasprintf_append(&msg, fmt, args);
121
122
ralloc_asprintf_append(&msg, "\n %zu bytes into the SPIR-V binary",
123
b->spirv_offset);
124
125
if (b->file) {
126
ralloc_asprintf_append(&msg,
127
"\n in SPIR-V source file %s, line %d, col %d",
128
b->file, b->line, b->col);
129
}
130
131
vtn_log(b, level, b->spirv_offset, msg);
132
133
ralloc_free(msg);
134
}
135
136
static void
137
vtn_dump_shader(struct vtn_builder *b, const char *path, const char *prefix)
138
{
139
static int idx = 0;
140
141
char filename[1024];
142
int len = snprintf(filename, sizeof(filename), "%s/%s-%d.spirv",
143
path, prefix, idx++);
144
if (len < 0 || len >= sizeof(filename))
145
return;
146
147
FILE *f = fopen(filename, "w");
148
if (f == NULL)
149
return;
150
151
fwrite(b->spirv, sizeof(*b->spirv), b->spirv_word_count, f);
152
fclose(f);
153
154
vtn_info("SPIR-V shader dumped to %s", filename);
155
}
156
157
void
158
_vtn_warn(struct vtn_builder *b, const char *file, unsigned line,
159
const char *fmt, ...)
160
{
161
va_list args;
162
163
va_start(args, fmt);
164
vtn_log_err(b, NIR_SPIRV_DEBUG_LEVEL_WARNING, "SPIR-V WARNING:\n",
165
file, line, fmt, args);
166
va_end(args);
167
}
168
169
void
170
_vtn_err(struct vtn_builder *b, const char *file, unsigned line,
171
const char *fmt, ...)
172
{
173
va_list args;
174
175
va_start(args, fmt);
176
vtn_log_err(b, NIR_SPIRV_DEBUG_LEVEL_ERROR, "SPIR-V ERROR:\n",
177
file, line, fmt, args);
178
va_end(args);
179
}
180
181
void
182
_vtn_fail(struct vtn_builder *b, const char *file, unsigned line,
183
const char *fmt, ...)
184
{
185
va_list args;
186
187
va_start(args, fmt);
188
vtn_log_err(b, NIR_SPIRV_DEBUG_LEVEL_ERROR, "SPIR-V parsing FAILED:\n",
189
file, line, fmt, args);
190
va_end(args);
191
192
const char *dump_path = getenv("MESA_SPIRV_FAIL_DUMP_PATH");
193
if (dump_path)
194
vtn_dump_shader(b, dump_path, "fail");
195
196
vtn_longjmp(b->fail_jump, 1);
197
}
198
199
static struct vtn_ssa_value *
200
vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
201
{
202
struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
203
val->type = glsl_get_bare_type(type);
204
205
if (glsl_type_is_vector_or_scalar(type)) {
206
unsigned num_components = glsl_get_vector_elements(val->type);
207
unsigned bit_size = glsl_get_bit_size(val->type);
208
val->def = nir_ssa_undef(&b->nb, num_components, bit_size);
209
} else {
210
unsigned elems = glsl_get_length(val->type);
211
val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
212
if (glsl_type_is_array_or_matrix(type)) {
213
const struct glsl_type *elem_type = glsl_get_array_element(type);
214
for (unsigned i = 0; i < elems; i++)
215
val->elems[i] = vtn_undef_ssa_value(b, elem_type);
216
} else {
217
vtn_assert(glsl_type_is_struct_or_ifc(type));
218
for (unsigned i = 0; i < elems; i++) {
219
const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
220
val->elems[i] = vtn_undef_ssa_value(b, elem_type);
221
}
222
}
223
}
224
225
return val;
226
}
227
228
static struct vtn_ssa_value *
229
vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
230
const struct glsl_type *type)
231
{
232
struct hash_entry *entry = _mesa_hash_table_search(b->const_table, constant);
233
234
if (entry)
235
return entry->data;
236
237
struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
238
val->type = glsl_get_bare_type(type);
239
240
if (glsl_type_is_vector_or_scalar(type)) {
241
unsigned num_components = glsl_get_vector_elements(val->type);
242
unsigned bit_size = glsl_get_bit_size(type);
243
nir_load_const_instr *load =
244
nir_load_const_instr_create(b->shader, num_components, bit_size);
245
246
memcpy(load->value, constant->values,
247
sizeof(nir_const_value) * num_components);
248
249
nir_instr_insert_before_cf_list(&b->nb.impl->body, &load->instr);
250
val->def = &load->def;
251
} else {
252
unsigned elems = glsl_get_length(val->type);
253
val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
254
if (glsl_type_is_array_or_matrix(type)) {
255
const struct glsl_type *elem_type = glsl_get_array_element(type);
256
for (unsigned i = 0; i < elems; i++) {
257
val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
258
elem_type);
259
}
260
} else {
261
vtn_assert(glsl_type_is_struct_or_ifc(type));
262
for (unsigned i = 0; i < elems; i++) {
263
const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
264
val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
265
elem_type);
266
}
267
}
268
}
269
270
return val;
271
}
272
273
struct vtn_ssa_value *
274
vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
275
{
276
struct vtn_value *val = vtn_untyped_value(b, value_id);
277
switch (val->value_type) {
278
case vtn_value_type_undef:
279
return vtn_undef_ssa_value(b, val->type->type);
280
281
case vtn_value_type_constant:
282
return vtn_const_ssa_value(b, val->constant, val->type->type);
283
284
case vtn_value_type_ssa:
285
return val->ssa;
286
287
case vtn_value_type_pointer:
288
vtn_assert(val->pointer->ptr_type && val->pointer->ptr_type->type);
289
struct vtn_ssa_value *ssa =
290
vtn_create_ssa_value(b, val->pointer->ptr_type->type);
291
ssa->def = vtn_pointer_to_ssa(b, val->pointer);
292
return ssa;
293
294
default:
295
vtn_fail("Invalid type for an SSA value");
296
}
297
}
298
299
struct vtn_value *
300
vtn_push_ssa_value(struct vtn_builder *b, uint32_t value_id,
301
struct vtn_ssa_value *ssa)
302
{
303
struct vtn_type *type = vtn_get_value_type(b, value_id);
304
305
/* See vtn_create_ssa_value */
306
vtn_fail_if(ssa->type != glsl_get_bare_type(type->type),
307
"Type mismatch for SPIR-V SSA value");
308
309
struct vtn_value *val;
310
if (type->base_type == vtn_base_type_pointer) {
311
val = vtn_push_pointer(b, value_id, vtn_pointer_from_ssa(b, ssa->def, type));
312
} else {
313
/* Don't trip the value_type_ssa check in vtn_push_value */
314
val = vtn_push_value(b, value_id, vtn_value_type_invalid);
315
val->value_type = vtn_value_type_ssa;
316
val->ssa = ssa;
317
}
318
319
return val;
320
}
321
322
nir_ssa_def *
323
vtn_get_nir_ssa(struct vtn_builder *b, uint32_t value_id)
324
{
325
struct vtn_ssa_value *ssa = vtn_ssa_value(b, value_id);
326
vtn_fail_if(!glsl_type_is_vector_or_scalar(ssa->type),
327
"Expected a vector or scalar type");
328
return ssa->def;
329
}
330
331
struct vtn_value *
332
vtn_push_nir_ssa(struct vtn_builder *b, uint32_t value_id, nir_ssa_def *def)
333
{
334
/* Types for all SPIR-V SSA values are set as part of a pre-pass so the
335
* type will be valid by the time we get here.
336
*/
337
struct vtn_type *type = vtn_get_value_type(b, value_id);
338
vtn_fail_if(def->num_components != glsl_get_vector_elements(type->type) ||
339
def->bit_size != glsl_get_bit_size(type->type),
340
"Mismatch between NIR and SPIR-V type.");
341
struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, type->type);
342
ssa->def = def;
343
return vtn_push_ssa_value(b, value_id, ssa);
344
}
345
346
static enum gl_access_qualifier
347
spirv_to_gl_access_qualifier(struct vtn_builder *b,
348
SpvAccessQualifier access_qualifier)
349
{
350
switch (access_qualifier) {
351
case SpvAccessQualifierReadOnly:
352
return ACCESS_NON_WRITEABLE;
353
case SpvAccessQualifierWriteOnly:
354
return ACCESS_NON_READABLE;
355
case SpvAccessQualifierReadWrite:
356
return 0;
357
default:
358
vtn_fail("Invalid image access qualifier");
359
}
360
}
361
362
static nir_deref_instr *
363
vtn_get_image(struct vtn_builder *b, uint32_t value_id,
364
enum gl_access_qualifier *access)
365
{
366
struct vtn_type *type = vtn_get_value_type(b, value_id);
367
vtn_assert(type->base_type == vtn_base_type_image);
368
if (access)
369
*access |= spirv_to_gl_access_qualifier(b, type->access_qualifier);
370
return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
371
nir_var_uniform, type->glsl_image, 0);
372
}
373
374
static void
375
vtn_push_image(struct vtn_builder *b, uint32_t value_id,
376
nir_deref_instr *deref, bool propagate_non_uniform)
377
{
378
struct vtn_type *type = vtn_get_value_type(b, value_id);
379
vtn_assert(type->base_type == vtn_base_type_image);
380
struct vtn_value *value = vtn_push_nir_ssa(b, value_id, &deref->dest.ssa);
381
value->propagated_non_uniform = propagate_non_uniform;
382
}
383
384
static nir_deref_instr *
385
vtn_get_sampler(struct vtn_builder *b, uint32_t value_id)
386
{
387
struct vtn_type *type = vtn_get_value_type(b, value_id);
388
vtn_assert(type->base_type == vtn_base_type_sampler);
389
return nir_build_deref_cast(&b->nb, vtn_get_nir_ssa(b, value_id),
390
nir_var_uniform, glsl_bare_sampler_type(), 0);
391
}
392
393
nir_ssa_def *
394
vtn_sampled_image_to_nir_ssa(struct vtn_builder *b,
395
struct vtn_sampled_image si)
396
{
397
return nir_vec2(&b->nb, &si.image->dest.ssa, &si.sampler->dest.ssa);
398
}
399
400
static void
401
vtn_push_sampled_image(struct vtn_builder *b, uint32_t value_id,
402
struct vtn_sampled_image si, bool propagate_non_uniform)
403
{
404
struct vtn_type *type = vtn_get_value_type(b, value_id);
405
vtn_assert(type->base_type == vtn_base_type_sampled_image);
406
struct vtn_value *value = vtn_push_nir_ssa(b, value_id,
407
vtn_sampled_image_to_nir_ssa(b, si));
408
value->propagated_non_uniform = propagate_non_uniform;
409
}
410
411
static struct vtn_sampled_image
412
vtn_get_sampled_image(struct vtn_builder *b, uint32_t value_id)
413
{
414
struct vtn_type *type = vtn_get_value_type(b, value_id);
415
vtn_assert(type->base_type == vtn_base_type_sampled_image);
416
nir_ssa_def *si_vec2 = vtn_get_nir_ssa(b, value_id);
417
418
struct vtn_sampled_image si = { NULL, };
419
si.image = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 0),
420
nir_var_uniform,
421
type->image->glsl_image, 0);
422
si.sampler = nir_build_deref_cast(&b->nb, nir_channel(&b->nb, si_vec2, 1),
423
nir_var_uniform,
424
glsl_bare_sampler_type(), 0);
425
return si;
426
}
427
428
static const char *
429
vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
430
unsigned word_count, unsigned *words_used)
431
{
432
/* From the SPIR-V spec:
433
*
434
* "A string is interpreted as a nul-terminated stream of characters.
435
* The character set is Unicode in the UTF-8 encoding scheme. The UTF-8
436
* octets (8-bit bytes) are packed four per word, following the
437
* little-endian convention (i.e., the first octet is in the
438
* lowest-order 8 bits of the word). The final word contains the
439
* string’s nul-termination character (0), and all contents past the
440
* end of the string in the final word are padded with 0."
441
*
442
* On big-endian, we need to byte-swap.
443
*/
444
#if UTIL_ARCH_BIG_ENDIAN
445
{
446
uint32_t *copy = ralloc_array(b, uint32_t, word_count);
447
for (unsigned i = 0; i < word_count; i++)
448
copy[i] = util_bswap32(words[i]);
449
words = copy;
450
}
451
#endif
452
453
const char *str = (char *)words;
454
const char *end = memchr(str, 0, word_count * 4);
455
vtn_fail_if(end == NULL, "String is not null-terminated");
456
457
if (words_used)
458
*words_used = DIV_ROUND_UP(end - str + 1, sizeof(*words));
459
460
return str;
461
}
462
463
const uint32_t *
464
vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
465
const uint32_t *end, vtn_instruction_handler handler)
466
{
467
b->file = NULL;
468
b->line = -1;
469
b->col = -1;
470
471
const uint32_t *w = start;
472
while (w < end) {
473
SpvOp opcode = w[0] & SpvOpCodeMask;
474
unsigned count = w[0] >> SpvWordCountShift;
475
vtn_assert(count >= 1 && w + count <= end);
476
477
b->spirv_offset = (uint8_t *)w - (uint8_t *)b->spirv;
478
479
switch (opcode) {
480
case SpvOpNop:
481
break; /* Do nothing */
482
483
case SpvOpLine:
484
b->file = vtn_value(b, w[1], vtn_value_type_string)->str;
485
b->line = w[2];
486
b->col = w[3];
487
break;
488
489
case SpvOpNoLine:
490
b->file = NULL;
491
b->line = -1;
492
b->col = -1;
493
break;
494
495
default:
496
if (!handler(b, opcode, w, count))
497
return w;
498
break;
499
}
500
501
w += count;
502
}
503
504
b->spirv_offset = 0;
505
b->file = NULL;
506
b->line = -1;
507
b->col = -1;
508
509
assert(w == end);
510
return w;
511
}
512
513
static bool
514
vtn_handle_non_semantic_instruction(struct vtn_builder *b, SpvOp ext_opcode,
515
const uint32_t *w, unsigned count)
516
{
517
/* Do nothing. */
518
return true;
519
}
520
521
static void
522
vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
523
const uint32_t *w, unsigned count)
524
{
525
switch (opcode) {
526
case SpvOpExtInstImport: {
527
struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
528
const char *ext = vtn_string_literal(b, &w[2], count - 2, NULL);
529
if (strcmp(ext, "GLSL.std.450") == 0) {
530
val->ext_handler = vtn_handle_glsl450_instruction;
531
} else if ((strcmp(ext, "SPV_AMD_gcn_shader") == 0)
532
&& (b->options && b->options->caps.amd_gcn_shader)) {
533
val->ext_handler = vtn_handle_amd_gcn_shader_instruction;
534
} else if ((strcmp(ext, "SPV_AMD_shader_ballot") == 0)
535
&& (b->options && b->options->caps.amd_shader_ballot)) {
536
val->ext_handler = vtn_handle_amd_shader_ballot_instruction;
537
} else if ((strcmp(ext, "SPV_AMD_shader_trinary_minmax") == 0)
538
&& (b->options && b->options->caps.amd_trinary_minmax)) {
539
val->ext_handler = vtn_handle_amd_shader_trinary_minmax_instruction;
540
} else if ((strcmp(ext, "SPV_AMD_shader_explicit_vertex_parameter") == 0)
541
&& (b->options && b->options->caps.amd_shader_explicit_vertex_parameter)) {
542
val->ext_handler = vtn_handle_amd_shader_explicit_vertex_parameter_instruction;
543
} else if (strcmp(ext, "OpenCL.std") == 0) {
544
val->ext_handler = vtn_handle_opencl_instruction;
545
} else if (strstr(ext, "NonSemantic.") == ext) {
546
val->ext_handler = vtn_handle_non_semantic_instruction;
547
} else {
548
vtn_fail("Unsupported extension: %s", ext);
549
}
550
break;
551
}
552
553
case SpvOpExtInst: {
554
struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
555
bool handled = val->ext_handler(b, w[4], w, count);
556
vtn_assert(handled);
557
break;
558
}
559
560
default:
561
vtn_fail_with_opcode("Unhandled opcode", opcode);
562
}
563
}
564
565
static void
566
_foreach_decoration_helper(struct vtn_builder *b,
567
struct vtn_value *base_value,
568
int parent_member,
569
struct vtn_value *value,
570
vtn_decoration_foreach_cb cb, void *data)
571
{
572
for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
573
int member;
574
if (dec->scope == VTN_DEC_DECORATION) {
575
member = parent_member;
576
} else if (dec->scope >= VTN_DEC_STRUCT_MEMBER0) {
577
vtn_fail_if(value->value_type != vtn_value_type_type ||
578
value->type->base_type != vtn_base_type_struct,
579
"OpMemberDecorate and OpGroupMemberDecorate are only "
580
"allowed on OpTypeStruct");
581
/* This means we haven't recursed yet */
582
assert(value == base_value);
583
584
member = dec->scope - VTN_DEC_STRUCT_MEMBER0;
585
586
vtn_fail_if(member >= base_value->type->length,
587
"OpMemberDecorate specifies member %d but the "
588
"OpTypeStruct has only %u members",
589
member, base_value->type->length);
590
} else {
591
/* Not a decoration */
592
assert(dec->scope == VTN_DEC_EXECUTION_MODE);
593
continue;
594
}
595
596
if (dec->group) {
597
assert(dec->group->value_type == vtn_value_type_decoration_group);
598
_foreach_decoration_helper(b, base_value, member, dec->group,
599
cb, data);
600
} else {
601
cb(b, base_value, member, dec, data);
602
}
603
}
604
}
605
606
/** Iterates (recursively if needed) over all of the decorations on a value
607
*
608
* This function iterates over all of the decorations applied to a given
609
* value. If it encounters a decoration group, it recurses into the group
610
* and iterates over all of those decorations as well.
611
*/
612
void
613
vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
614
vtn_decoration_foreach_cb cb, void *data)
615
{
616
_foreach_decoration_helper(b, value, -1, value, cb, data);
617
}
618
619
void
620
vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,
621
vtn_execution_mode_foreach_cb cb, void *data)
622
{
623
for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
624
if (dec->scope != VTN_DEC_EXECUTION_MODE)
625
continue;
626
627
assert(dec->group == NULL);
628
cb(b, value, dec, data);
629
}
630
}
631
632
void
633
vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
634
const uint32_t *w, unsigned count)
635
{
636
const uint32_t *w_end = w + count;
637
const uint32_t target = w[1];
638
w += 2;
639
640
switch (opcode) {
641
case SpvOpDecorationGroup:
642
vtn_push_value(b, target, vtn_value_type_decoration_group);
643
break;
644
645
case SpvOpDecorate:
646
case SpvOpDecorateId:
647
case SpvOpMemberDecorate:
648
case SpvOpDecorateString:
649
case SpvOpMemberDecorateString:
650
case SpvOpExecutionMode:
651
case SpvOpExecutionModeId: {
652
struct vtn_value *val = vtn_untyped_value(b, target);
653
654
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
655
switch (opcode) {
656
case SpvOpDecorate:
657
case SpvOpDecorateId:
658
case SpvOpDecorateString:
659
dec->scope = VTN_DEC_DECORATION;
660
break;
661
case SpvOpMemberDecorate:
662
case SpvOpMemberDecorateString:
663
dec->scope = VTN_DEC_STRUCT_MEMBER0 + *(w++);
664
vtn_fail_if(dec->scope < VTN_DEC_STRUCT_MEMBER0, /* overflow */
665
"Member argument of OpMemberDecorate too large");
666
break;
667
case SpvOpExecutionMode:
668
case SpvOpExecutionModeId:
669
dec->scope = VTN_DEC_EXECUTION_MODE;
670
break;
671
default:
672
unreachable("Invalid decoration opcode");
673
}
674
dec->decoration = *(w++);
675
dec->operands = w;
676
677
/* Link into the list */
678
dec->next = val->decoration;
679
val->decoration = dec;
680
break;
681
}
682
683
case SpvOpGroupMemberDecorate:
684
case SpvOpGroupDecorate: {
685
struct vtn_value *group =
686
vtn_value(b, target, vtn_value_type_decoration_group);
687
688
for (; w < w_end; w++) {
689
struct vtn_value *val = vtn_untyped_value(b, *w);
690
struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
691
692
dec->group = group;
693
if (opcode == SpvOpGroupDecorate) {
694
dec->scope = VTN_DEC_DECORATION;
695
} else {
696
dec->scope = VTN_DEC_STRUCT_MEMBER0 + *(++w);
697
vtn_fail_if(dec->scope < 0, /* Check for overflow */
698
"Member argument of OpGroupMemberDecorate too large");
699
}
700
701
/* Link into the list */
702
dec->next = val->decoration;
703
val->decoration = dec;
704
}
705
break;
706
}
707
708
default:
709
unreachable("Unhandled opcode");
710
}
711
}
712
713
struct member_decoration_ctx {
714
unsigned num_fields;
715
struct glsl_struct_field *fields;
716
struct vtn_type *type;
717
};
718
719
/**
720
* Returns true if the given type contains a struct decorated Block or
721
* BufferBlock
722
*/
723
bool
724
vtn_type_contains_block(struct vtn_builder *b, struct vtn_type *type)
725
{
726
switch (type->base_type) {
727
case vtn_base_type_array:
728
return vtn_type_contains_block(b, type->array_element);
729
case vtn_base_type_struct:
730
if (type->block || type->buffer_block)
731
return true;
732
for (unsigned i = 0; i < type->length; i++) {
733
if (vtn_type_contains_block(b, type->members[i]))
734
return true;
735
}
736
return false;
737
default:
738
return false;
739
}
740
}
741
742
/** Returns true if two types are "compatible", i.e. you can do an OpLoad,
743
* OpStore, or OpCopyMemory between them without breaking anything.
744
* Technically, the SPIR-V rules require the exact same type ID but this lets
745
* us internally be a bit looser.
746
*/
747
bool
748
vtn_types_compatible(struct vtn_builder *b,
749
struct vtn_type *t1, struct vtn_type *t2)
750
{
751
if (t1->id == t2->id)
752
return true;
753
754
if (t1->base_type != t2->base_type)
755
return false;
756
757
switch (t1->base_type) {
758
case vtn_base_type_void:
759
case vtn_base_type_scalar:
760
case vtn_base_type_vector:
761
case vtn_base_type_matrix:
762
case vtn_base_type_image:
763
case vtn_base_type_sampler:
764
case vtn_base_type_sampled_image:
765
case vtn_base_type_event:
766
return t1->type == t2->type;
767
768
case vtn_base_type_array:
769
return t1->length == t2->length &&
770
vtn_types_compatible(b, t1->array_element, t2->array_element);
771
772
case vtn_base_type_pointer:
773
return vtn_types_compatible(b, t1->deref, t2->deref);
774
775
case vtn_base_type_struct:
776
if (t1->length != t2->length)
777
return false;
778
779
for (unsigned i = 0; i < t1->length; i++) {
780
if (!vtn_types_compatible(b, t1->members[i], t2->members[i]))
781
return false;
782
}
783
return true;
784
785
case vtn_base_type_accel_struct:
786
return true;
787
788
case vtn_base_type_function:
789
/* This case shouldn't get hit since you can't copy around function
790
* types. Just require them to be identical.
791
*/
792
return false;
793
}
794
795
vtn_fail("Invalid base type");
796
}
797
798
struct vtn_type *
799
vtn_type_without_array(struct vtn_type *type)
800
{
801
while (type->base_type == vtn_base_type_array)
802
type = type->array_element;
803
return type;
804
}
805
806
/* does a shallow copy of a vtn_type */
807
808
static struct vtn_type *
809
vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
810
{
811
struct vtn_type *dest = ralloc(b, struct vtn_type);
812
*dest = *src;
813
814
switch (src->base_type) {
815
case vtn_base_type_void:
816
case vtn_base_type_scalar:
817
case vtn_base_type_vector:
818
case vtn_base_type_matrix:
819
case vtn_base_type_array:
820
case vtn_base_type_pointer:
821
case vtn_base_type_image:
822
case vtn_base_type_sampler:
823
case vtn_base_type_sampled_image:
824
case vtn_base_type_event:
825
case vtn_base_type_accel_struct:
826
/* Nothing more to do */
827
break;
828
829
case vtn_base_type_struct:
830
dest->members = ralloc_array(b, struct vtn_type *, src->length);
831
memcpy(dest->members, src->members,
832
src->length * sizeof(src->members[0]));
833
834
dest->offsets = ralloc_array(b, unsigned, src->length);
835
memcpy(dest->offsets, src->offsets,
836
src->length * sizeof(src->offsets[0]));
837
break;
838
839
case vtn_base_type_function:
840
dest->params = ralloc_array(b, struct vtn_type *, src->length);
841
memcpy(dest->params, src->params, src->length * sizeof(src->params[0]));
842
break;
843
}
844
845
return dest;
846
}
847
848
static const struct glsl_type *
849
wrap_type_in_array(const struct glsl_type *type,
850
const struct glsl_type *array_type)
851
{
852
if (!glsl_type_is_array(array_type))
853
return type;
854
855
const struct glsl_type *elem_type =
856
wrap_type_in_array(type, glsl_get_array_element(array_type));
857
return glsl_array_type(elem_type, glsl_get_length(array_type),
858
glsl_get_explicit_stride(array_type));
859
}
860
861
static bool
862
vtn_type_needs_explicit_layout(struct vtn_builder *b, struct vtn_type *type,
863
enum vtn_variable_mode mode)
864
{
865
/* For OpenCL we never want to strip the info from the types, and it makes
866
* type comparisons easier in later stages.
867
*/
868
if (b->options->environment == NIR_SPIRV_OPENCL)
869
return true;
870
871
switch (mode) {
872
case vtn_variable_mode_input:
873
case vtn_variable_mode_output:
874
/* Layout decorations kept because we need offsets for XFB arrays of
875
* blocks.
876
*/
877
return b->shader->info.has_transform_feedback_varyings;
878
879
case vtn_variable_mode_ssbo:
880
case vtn_variable_mode_phys_ssbo:
881
case vtn_variable_mode_ubo:
882
case vtn_variable_mode_push_constant:
883
case vtn_variable_mode_shader_record:
884
return true;
885
886
case vtn_variable_mode_workgroup:
887
return b->options->caps.workgroup_memory_explicit_layout;
888
889
default:
890
return false;
891
}
892
}
893
894
const struct glsl_type *
895
vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type,
896
enum vtn_variable_mode mode)
897
{
898
if (mode == vtn_variable_mode_atomic_counter) {
899
vtn_fail_if(glsl_without_array(type->type) != glsl_uint_type(),
900
"Variables in the AtomicCounter storage class should be "
901
"(possibly arrays of arrays of) uint.");
902
return wrap_type_in_array(glsl_atomic_uint_type(), type->type);
903
}
904
905
if (mode == vtn_variable_mode_uniform) {
906
switch (type->base_type) {
907
case vtn_base_type_array: {
908
const struct glsl_type *elem_type =
909
vtn_type_get_nir_type(b, type->array_element, mode);
910
911
return glsl_array_type(elem_type, type->length,
912
glsl_get_explicit_stride(type->type));
913
}
914
915
case vtn_base_type_struct: {
916
bool need_new_struct = false;
917
const uint32_t num_fields = type->length;
918
NIR_VLA(struct glsl_struct_field, fields, num_fields);
919
for (unsigned i = 0; i < num_fields; i++) {
920
fields[i] = *glsl_get_struct_field_data(type->type, i);
921
const struct glsl_type *field_nir_type =
922
vtn_type_get_nir_type(b, type->members[i], mode);
923
if (fields[i].type != field_nir_type) {
924
fields[i].type = field_nir_type;
925
need_new_struct = true;
926
}
927
}
928
if (need_new_struct) {
929
if (glsl_type_is_interface(type->type)) {
930
return glsl_interface_type(fields, num_fields,
931
/* packing */ 0, false,
932
glsl_get_type_name(type->type));
933
} else {
934
return glsl_struct_type(fields, num_fields,
935
glsl_get_type_name(type->type),
936
glsl_struct_type_is_packed(type->type));
937
}
938
} else {
939
/* No changes, just pass it on */
940
return type->type;
941
}
942
}
943
944
case vtn_base_type_image:
945
return type->glsl_image;
946
947
case vtn_base_type_sampler:
948
return glsl_bare_sampler_type();
949
950
case vtn_base_type_sampled_image:
951
return type->image->glsl_image;
952
953
default:
954
return type->type;
955
}
956
}
957
958
/* Layout decorations are allowed but ignored in certain conditions,
959
* to allow SPIR-V generators perform type deduplication. Discard
960
* unnecessary ones when passing to NIR.
961
*/
962
if (!vtn_type_needs_explicit_layout(b, type, mode))
963
return glsl_get_bare_type(type->type);
964
965
return type->type;
966
}
967
968
static struct vtn_type *
969
mutable_matrix_member(struct vtn_builder *b, struct vtn_type *type, int member)
970
{
971
type->members[member] = vtn_type_copy(b, type->members[member]);
972
type = type->members[member];
973
974
/* We may have an array of matrices.... Oh, joy! */
975
while (glsl_type_is_array(type->type)) {
976
type->array_element = vtn_type_copy(b, type->array_element);
977
type = type->array_element;
978
}
979
980
vtn_assert(glsl_type_is_matrix(type->type));
981
982
return type;
983
}
984
985
static void
986
vtn_handle_access_qualifier(struct vtn_builder *b, struct vtn_type *type,
987
int member, enum gl_access_qualifier access)
988
{
989
type->members[member] = vtn_type_copy(b, type->members[member]);
990
type = type->members[member];
991
992
type->access |= access;
993
}
994
995
static void
996
array_stride_decoration_cb(struct vtn_builder *b,
997
struct vtn_value *val, int member,
998
const struct vtn_decoration *dec, void *void_ctx)
999
{
1000
struct vtn_type *type = val->type;
1001
1002
if (dec->decoration == SpvDecorationArrayStride) {
1003
if (vtn_type_contains_block(b, type)) {
1004
vtn_warn("The ArrayStride decoration cannot be applied to an array "
1005
"type which contains a structure type decorated Block "
1006
"or BufferBlock");
1007
/* Ignore the decoration */
1008
} else {
1009
vtn_fail_if(dec->operands[0] == 0, "ArrayStride must be non-zero");
1010
type->stride = dec->operands[0];
1011
}
1012
}
1013
}
1014
1015
static void
1016
struct_member_decoration_cb(struct vtn_builder *b,
1017
UNUSED struct vtn_value *val, int member,
1018
const struct vtn_decoration *dec, void *void_ctx)
1019
{
1020
struct member_decoration_ctx *ctx = void_ctx;
1021
1022
if (member < 0)
1023
return;
1024
1025
assert(member < ctx->num_fields);
1026
1027
switch (dec->decoration) {
1028
case SpvDecorationRelaxedPrecision:
1029
case SpvDecorationUniform:
1030
case SpvDecorationUniformId:
1031
break; /* FIXME: Do nothing with this for now. */
1032
case SpvDecorationNonWritable:
1033
vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_NON_WRITEABLE);
1034
break;
1035
case SpvDecorationNonReadable:
1036
vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_NON_READABLE);
1037
break;
1038
case SpvDecorationVolatile:
1039
vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_VOLATILE);
1040
break;
1041
case SpvDecorationCoherent:
1042
vtn_handle_access_qualifier(b, ctx->type, member, ACCESS_COHERENT);
1043
break;
1044
case SpvDecorationNoPerspective:
1045
ctx->fields[member].interpolation = INTERP_MODE_NOPERSPECTIVE;
1046
break;
1047
case SpvDecorationFlat:
1048
ctx->fields[member].interpolation = INTERP_MODE_FLAT;
1049
break;
1050
case SpvDecorationExplicitInterpAMD:
1051
ctx->fields[member].interpolation = INTERP_MODE_EXPLICIT;
1052
break;
1053
case SpvDecorationCentroid:
1054
ctx->fields[member].centroid = true;
1055
break;
1056
case SpvDecorationSample:
1057
ctx->fields[member].sample = true;
1058
break;
1059
case SpvDecorationStream:
1060
/* This is handled later by var_decoration_cb in vtn_variables.c */
1061
break;
1062
case SpvDecorationLocation:
1063
ctx->fields[member].location = dec->operands[0];
1064
break;
1065
case SpvDecorationComponent:
1066
break; /* FIXME: What should we do with these? */
1067
case SpvDecorationBuiltIn:
1068
ctx->type->members[member] = vtn_type_copy(b, ctx->type->members[member]);
1069
ctx->type->members[member]->is_builtin = true;
1070
ctx->type->members[member]->builtin = dec->operands[0];
1071
ctx->type->builtin_block = true;
1072
break;
1073
case SpvDecorationOffset:
1074
ctx->type->offsets[member] = dec->operands[0];
1075
ctx->fields[member].offset = dec->operands[0];
1076
break;
1077
case SpvDecorationMatrixStride:
1078
/* Handled as a second pass */
1079
break;
1080
case SpvDecorationColMajor:
1081
break; /* Nothing to do here. Column-major is the default. */
1082
case SpvDecorationRowMajor:
1083
mutable_matrix_member(b, ctx->type, member)->row_major = true;
1084
break;
1085
1086
case SpvDecorationPatch:
1087
break;
1088
1089
case SpvDecorationSpecId:
1090
case SpvDecorationBlock:
1091
case SpvDecorationBufferBlock:
1092
case SpvDecorationArrayStride:
1093
case SpvDecorationGLSLShared:
1094
case SpvDecorationGLSLPacked:
1095
case SpvDecorationInvariant:
1096
case SpvDecorationRestrict:
1097
case SpvDecorationAliased:
1098
case SpvDecorationConstant:
1099
case SpvDecorationIndex:
1100
case SpvDecorationBinding:
1101
case SpvDecorationDescriptorSet:
1102
case SpvDecorationLinkageAttributes:
1103
case SpvDecorationNoContraction:
1104
case SpvDecorationInputAttachmentIndex:
1105
case SpvDecorationCPacked:
1106
vtn_warn("Decoration not allowed on struct members: %s",
1107
spirv_decoration_to_string(dec->decoration));
1108
break;
1109
1110
case SpvDecorationXfbBuffer:
1111
case SpvDecorationXfbStride:
1112
/* This is handled later by var_decoration_cb in vtn_variables.c */
1113
break;
1114
1115
case SpvDecorationSaturatedConversion:
1116
case SpvDecorationFuncParamAttr:
1117
case SpvDecorationFPRoundingMode:
1118
case SpvDecorationFPFastMathMode:
1119
case SpvDecorationAlignment:
1120
if (b->shader->info.stage != MESA_SHADER_KERNEL) {
1121
vtn_warn("Decoration only allowed for CL-style kernels: %s",
1122
spirv_decoration_to_string(dec->decoration));
1123
}
1124
break;
1125
1126
case SpvDecorationUserSemantic:
1127
case SpvDecorationUserTypeGOOGLE:
1128
/* User semantic decorations can safely be ignored by the driver. */
1129
break;
1130
1131
default:
1132
vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
1133
}
1134
}
1135
1136
/** Chases the array type all the way down to the tail and rewrites the
1137
* glsl_types to be based off the tail's glsl_type.
1138
*/
1139
static void
1140
vtn_array_type_rewrite_glsl_type(struct vtn_type *type)
1141
{
1142
if (type->base_type != vtn_base_type_array)
1143
return;
1144
1145
vtn_array_type_rewrite_glsl_type(type->array_element);
1146
1147
type->type = glsl_array_type(type->array_element->type,
1148
type->length, type->stride);
1149
}
1150
1151
/* Matrix strides are handled as a separate pass because we need to know
1152
* whether the matrix is row-major or not first.
1153
*/
1154
static void
1155
struct_member_matrix_stride_cb(struct vtn_builder *b,
1156
UNUSED struct vtn_value *val, int member,
1157
const struct vtn_decoration *dec,
1158
void *void_ctx)
1159
{
1160
if (dec->decoration != SpvDecorationMatrixStride)
1161
return;
1162
1163
vtn_fail_if(member < 0,
1164
"The MatrixStride decoration is only allowed on members "
1165
"of OpTypeStruct");
1166
vtn_fail_if(dec->operands[0] == 0, "MatrixStride must be non-zero");
1167
1168
struct member_decoration_ctx *ctx = void_ctx;
1169
1170
struct vtn_type *mat_type = mutable_matrix_member(b, ctx->type, member);
1171
if (mat_type->row_major) {
1172
mat_type->array_element = vtn_type_copy(b, mat_type->array_element);
1173
mat_type->stride = mat_type->array_element->stride;
1174
mat_type->array_element->stride = dec->operands[0];
1175
1176
mat_type->type = glsl_explicit_matrix_type(mat_type->type,
1177
dec->operands[0], true);
1178
mat_type->array_element->type = glsl_get_column_type(mat_type->type);
1179
} else {
1180
vtn_assert(mat_type->array_element->stride > 0);
1181
mat_type->stride = dec->operands[0];
1182
1183
mat_type->type = glsl_explicit_matrix_type(mat_type->type,
1184
dec->operands[0], false);
1185
}
1186
1187
/* Now that we've replaced the glsl_type with a properly strided matrix
1188
* type, rewrite the member type so that it's an array of the proper kind
1189
* of glsl_type.
1190
*/
1191
vtn_array_type_rewrite_glsl_type(ctx->type->members[member]);
1192
ctx->fields[member].type = ctx->type->members[member]->type;
1193
}
1194
1195
static void
1196
struct_packed_decoration_cb(struct vtn_builder *b,
1197
struct vtn_value *val, int member,
1198
const struct vtn_decoration *dec, void *void_ctx)
1199
{
1200
vtn_assert(val->type->base_type == vtn_base_type_struct);
1201
if (dec->decoration == SpvDecorationCPacked) {
1202
if (b->shader->info.stage != MESA_SHADER_KERNEL) {
1203
vtn_warn("Decoration only allowed for CL-style kernels: %s",
1204
spirv_decoration_to_string(dec->decoration));
1205
}
1206
val->type->packed = true;
1207
}
1208
}
1209
1210
static void
1211
struct_block_decoration_cb(struct vtn_builder *b,
1212
struct vtn_value *val, int member,
1213
const struct vtn_decoration *dec, void *ctx)
1214
{
1215
if (member != -1)
1216
return;
1217
1218
struct vtn_type *type = val->type;
1219
if (dec->decoration == SpvDecorationBlock)
1220
type->block = true;
1221
else if (dec->decoration == SpvDecorationBufferBlock)
1222
type->buffer_block = true;
1223
}
1224
1225
static void
1226
type_decoration_cb(struct vtn_builder *b,
1227
struct vtn_value *val, int member,
1228
const struct vtn_decoration *dec, UNUSED void *ctx)
1229
{
1230
struct vtn_type *type = val->type;
1231
1232
if (member != -1) {
1233
/* This should have been handled by OpTypeStruct */
1234
assert(val->type->base_type == vtn_base_type_struct);
1235
assert(member >= 0 && member < val->type->length);
1236
return;
1237
}
1238
1239
switch (dec->decoration) {
1240
case SpvDecorationArrayStride:
1241
vtn_assert(type->base_type == vtn_base_type_array ||
1242
type->base_type == vtn_base_type_pointer);
1243
break;
1244
case SpvDecorationBlock:
1245
vtn_assert(type->base_type == vtn_base_type_struct);
1246
vtn_assert(type->block);
1247
break;
1248
case SpvDecorationBufferBlock:
1249
vtn_assert(type->base_type == vtn_base_type_struct);
1250
vtn_assert(type->buffer_block);
1251
break;
1252
case SpvDecorationGLSLShared:
1253
case SpvDecorationGLSLPacked:
1254
/* Ignore these, since we get explicit offsets anyways */
1255
break;
1256
1257
case SpvDecorationRowMajor:
1258
case SpvDecorationColMajor:
1259
case SpvDecorationMatrixStride:
1260
case SpvDecorationBuiltIn:
1261
case SpvDecorationNoPerspective:
1262
case SpvDecorationFlat:
1263
case SpvDecorationPatch:
1264
case SpvDecorationCentroid:
1265
case SpvDecorationSample:
1266
case SpvDecorationExplicitInterpAMD:
1267
case SpvDecorationVolatile:
1268
case SpvDecorationCoherent:
1269
case SpvDecorationNonWritable:
1270
case SpvDecorationNonReadable:
1271
case SpvDecorationUniform:
1272
case SpvDecorationUniformId:
1273
case SpvDecorationLocation:
1274
case SpvDecorationComponent:
1275
case SpvDecorationOffset:
1276
case SpvDecorationXfbBuffer:
1277
case SpvDecorationXfbStride:
1278
case SpvDecorationUserSemantic:
1279
vtn_warn("Decoration only allowed for struct members: %s",
1280
spirv_decoration_to_string(dec->decoration));
1281
break;
1282
1283
case SpvDecorationStream:
1284
/* We don't need to do anything here, as stream is filled up when
1285
* aplying the decoration to a variable, just check that if it is not a
1286
* struct member, it should be a struct.
1287
*/
1288
vtn_assert(type->base_type == vtn_base_type_struct);
1289
break;
1290
1291
case SpvDecorationRelaxedPrecision:
1292
case SpvDecorationSpecId:
1293
case SpvDecorationInvariant:
1294
case SpvDecorationRestrict:
1295
case SpvDecorationAliased:
1296
case SpvDecorationConstant:
1297
case SpvDecorationIndex:
1298
case SpvDecorationBinding:
1299
case SpvDecorationDescriptorSet:
1300
case SpvDecorationLinkageAttributes:
1301
case SpvDecorationNoContraction:
1302
case SpvDecorationInputAttachmentIndex:
1303
vtn_warn("Decoration not allowed on types: %s",
1304
spirv_decoration_to_string(dec->decoration));
1305
break;
1306
1307
case SpvDecorationCPacked:
1308
/* Handled when parsing a struct type, nothing to do here. */
1309
break;
1310
1311
case SpvDecorationSaturatedConversion:
1312
case SpvDecorationFuncParamAttr:
1313
case SpvDecorationFPRoundingMode:
1314
case SpvDecorationFPFastMathMode:
1315
case SpvDecorationAlignment:
1316
vtn_warn("Decoration only allowed for CL-style kernels: %s",
1317
spirv_decoration_to_string(dec->decoration));
1318
break;
1319
1320
case SpvDecorationUserTypeGOOGLE:
1321
/* User semantic decorations can safely be ignored by the driver. */
1322
break;
1323
1324
default:
1325
vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
1326
}
1327
}
1328
1329
static unsigned
1330
translate_image_format(struct vtn_builder *b, SpvImageFormat format)
1331
{
1332
switch (format) {
1333
case SpvImageFormatUnknown: return PIPE_FORMAT_NONE;
1334
case SpvImageFormatRgba32f: return PIPE_FORMAT_R32G32B32A32_FLOAT;
1335
case SpvImageFormatRgba16f: return PIPE_FORMAT_R16G16B16A16_FLOAT;
1336
case SpvImageFormatR32f: return PIPE_FORMAT_R32_FLOAT;
1337
case SpvImageFormatRgba8: return PIPE_FORMAT_R8G8B8A8_UNORM;
1338
case SpvImageFormatRgba8Snorm: return PIPE_FORMAT_R8G8B8A8_SNORM;
1339
case SpvImageFormatRg32f: return PIPE_FORMAT_R32G32_FLOAT;
1340
case SpvImageFormatRg16f: return PIPE_FORMAT_R16G16_FLOAT;
1341
case SpvImageFormatR11fG11fB10f: return PIPE_FORMAT_R11G11B10_FLOAT;
1342
case SpvImageFormatR16f: return PIPE_FORMAT_R16_FLOAT;
1343
case SpvImageFormatRgba16: return PIPE_FORMAT_R16G16B16A16_UNORM;
1344
case SpvImageFormatRgb10A2: return PIPE_FORMAT_R10G10B10A2_UNORM;
1345
case SpvImageFormatRg16: return PIPE_FORMAT_R16G16_UNORM;
1346
case SpvImageFormatRg8: return PIPE_FORMAT_R8G8_UNORM;
1347
case SpvImageFormatR16: return PIPE_FORMAT_R16_UNORM;
1348
case SpvImageFormatR8: return PIPE_FORMAT_R8_UNORM;
1349
case SpvImageFormatRgba16Snorm: return PIPE_FORMAT_R16G16B16A16_SNORM;
1350
case SpvImageFormatRg16Snorm: return PIPE_FORMAT_R16G16_SNORM;
1351
case SpvImageFormatRg8Snorm: return PIPE_FORMAT_R8G8_SNORM;
1352
case SpvImageFormatR16Snorm: return PIPE_FORMAT_R16_SNORM;
1353
case SpvImageFormatR8Snorm: return PIPE_FORMAT_R8_SNORM;
1354
case SpvImageFormatRgba32i: return PIPE_FORMAT_R32G32B32A32_SINT;
1355
case SpvImageFormatRgba16i: return PIPE_FORMAT_R16G16B16A16_SINT;
1356
case SpvImageFormatRgba8i: return PIPE_FORMAT_R8G8B8A8_SINT;
1357
case SpvImageFormatR32i: return PIPE_FORMAT_R32_SINT;
1358
case SpvImageFormatRg32i: return PIPE_FORMAT_R32G32_SINT;
1359
case SpvImageFormatRg16i: return PIPE_FORMAT_R16G16_SINT;
1360
case SpvImageFormatRg8i: return PIPE_FORMAT_R8G8_SINT;
1361
case SpvImageFormatR16i: return PIPE_FORMAT_R16_SINT;
1362
case SpvImageFormatR8i: return PIPE_FORMAT_R8_SINT;
1363
case SpvImageFormatRgba32ui: return PIPE_FORMAT_R32G32B32A32_UINT;
1364
case SpvImageFormatRgba16ui: return PIPE_FORMAT_R16G16B16A16_UINT;
1365
case SpvImageFormatRgba8ui: return PIPE_FORMAT_R8G8B8A8_UINT;
1366
case SpvImageFormatR32ui: return PIPE_FORMAT_R32_UINT;
1367
case SpvImageFormatRgb10a2ui: return PIPE_FORMAT_R10G10B10A2_UINT;
1368
case SpvImageFormatRg32ui: return PIPE_FORMAT_R32G32_UINT;
1369
case SpvImageFormatRg16ui: return PIPE_FORMAT_R16G16_UINT;
1370
case SpvImageFormatRg8ui: return PIPE_FORMAT_R8G8_UINT;
1371
case SpvImageFormatR16ui: return PIPE_FORMAT_R16_UINT;
1372
case SpvImageFormatR8ui: return PIPE_FORMAT_R8_UINT;
1373
case SpvImageFormatR64ui: return PIPE_FORMAT_R64_UINT;
1374
case SpvImageFormatR64i: return PIPE_FORMAT_R64_SINT;
1375
default:
1376
vtn_fail("Invalid image format: %s (%u)",
1377
spirv_imageformat_to_string(format), format);
1378
}
1379
}
1380
1381
static void
1382
vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
1383
const uint32_t *w, unsigned count)
1384
{
1385
struct vtn_value *val = NULL;
1386
1387
/* In order to properly handle forward declarations, we have to defer
1388
* allocation for pointer types.
1389
*/
1390
if (opcode != SpvOpTypePointer && opcode != SpvOpTypeForwardPointer) {
1391
val = vtn_push_value(b, w[1], vtn_value_type_type);
1392
vtn_fail_if(val->type != NULL,
1393
"Only pointers can have forward declarations");
1394
val->type = rzalloc(b, struct vtn_type);
1395
val->type->id = w[1];
1396
}
1397
1398
switch (opcode) {
1399
case SpvOpTypeVoid:
1400
val->type->base_type = vtn_base_type_void;
1401
val->type->type = glsl_void_type();
1402
break;
1403
case SpvOpTypeBool:
1404
val->type->base_type = vtn_base_type_scalar;
1405
val->type->type = glsl_bool_type();
1406
val->type->length = 1;
1407
break;
1408
case SpvOpTypeInt: {
1409
int bit_size = w[2];
1410
const bool signedness = w[3];
1411
vtn_fail_if(bit_size != 8 && bit_size != 16 &&
1412
bit_size != 32 && bit_size != 64,
1413
"Invalid int bit size: %u", bit_size);
1414
val->type->base_type = vtn_base_type_scalar;
1415
val->type->type = signedness ? glsl_intN_t_type(bit_size) :
1416
glsl_uintN_t_type(bit_size);
1417
val->type->length = 1;
1418
break;
1419
}
1420
1421
case SpvOpTypeFloat: {
1422
int bit_size = w[2];
1423
val->type->base_type = vtn_base_type_scalar;
1424
vtn_fail_if(bit_size != 16 && bit_size != 32 && bit_size != 64,
1425
"Invalid float bit size: %u", bit_size);
1426
val->type->type = glsl_floatN_t_type(bit_size);
1427
val->type->length = 1;
1428
break;
1429
}
1430
1431
case SpvOpTypeVector: {
1432
struct vtn_type *base = vtn_get_type(b, w[2]);
1433
unsigned elems = w[3];
1434
1435
vtn_fail_if(base->base_type != vtn_base_type_scalar,
1436
"Base type for OpTypeVector must be a scalar");
1437
vtn_fail_if((elems < 2 || elems > 4) && (elems != 8) && (elems != 16),
1438
"Invalid component count for OpTypeVector");
1439
1440
val->type->base_type = vtn_base_type_vector;
1441
val->type->type = glsl_vector_type(glsl_get_base_type(base->type), elems);
1442
val->type->length = elems;
1443
val->type->stride = glsl_type_is_boolean(val->type->type)
1444
? 4 : glsl_get_bit_size(base->type) / 8;
1445
val->type->array_element = base;
1446
break;
1447
}
1448
1449
case SpvOpTypeMatrix: {
1450
struct vtn_type *base = vtn_get_type(b, w[2]);
1451
unsigned columns = w[3];
1452
1453
vtn_fail_if(base->base_type != vtn_base_type_vector,
1454
"Base type for OpTypeMatrix must be a vector");
1455
vtn_fail_if(columns < 2 || columns > 4,
1456
"Invalid column count for OpTypeMatrix");
1457
1458
val->type->base_type = vtn_base_type_matrix;
1459
val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
1460
glsl_get_vector_elements(base->type),
1461
columns);
1462
vtn_fail_if(glsl_type_is_error(val->type->type),
1463
"Unsupported base type for OpTypeMatrix");
1464
assert(!glsl_type_is_error(val->type->type));
1465
val->type->length = columns;
1466
val->type->array_element = base;
1467
val->type->row_major = false;
1468
val->type->stride = 0;
1469
break;
1470
}
1471
1472
case SpvOpTypeRuntimeArray:
1473
case SpvOpTypeArray: {
1474
struct vtn_type *array_element = vtn_get_type(b, w[2]);
1475
1476
if (opcode == SpvOpTypeRuntimeArray) {
1477
/* A length of 0 is used to denote unsized arrays */
1478
val->type->length = 0;
1479
} else {
1480
val->type->length = vtn_constant_uint(b, w[3]);
1481
}
1482
1483
val->type->base_type = vtn_base_type_array;
1484
val->type->array_element = array_element;
1485
1486
vtn_foreach_decoration(b, val, array_stride_decoration_cb, NULL);
1487
val->type->type = glsl_array_type(array_element->type, val->type->length,
1488
val->type->stride);
1489
break;
1490
}
1491
1492
case SpvOpTypeStruct: {
1493
unsigned num_fields = count - 2;
1494
val->type->base_type = vtn_base_type_struct;
1495
val->type->length = num_fields;
1496
val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
1497
val->type->offsets = ralloc_array(b, unsigned, num_fields);
1498
val->type->packed = false;
1499
1500
NIR_VLA(struct glsl_struct_field, fields, count);
1501
for (unsigned i = 0; i < num_fields; i++) {
1502
val->type->members[i] = vtn_get_type(b, w[i + 2]);
1503
fields[i] = (struct glsl_struct_field) {
1504
.type = val->type->members[i]->type,
1505
.name = ralloc_asprintf(b, "field%d", i),
1506
.location = -1,
1507
.offset = -1,
1508
};
1509
}
1510
1511
vtn_foreach_decoration(b, val, struct_packed_decoration_cb, NULL);
1512
1513
struct member_decoration_ctx ctx = {
1514
.num_fields = num_fields,
1515
.fields = fields,
1516
.type = val->type
1517
};
1518
1519
vtn_foreach_decoration(b, val, struct_member_decoration_cb, &ctx);
1520
1521
/* Propagate access specifiers that are present on all members to the overall type */
1522
enum gl_access_qualifier overall_access = ACCESS_COHERENT | ACCESS_VOLATILE |
1523
ACCESS_NON_READABLE | ACCESS_NON_WRITEABLE;
1524
for (unsigned i = 0; i < num_fields; ++i)
1525
overall_access &= val->type->members[i]->access;
1526
val->type->access = overall_access;
1527
1528
vtn_foreach_decoration(b, val, struct_member_matrix_stride_cb, &ctx);
1529
1530
vtn_foreach_decoration(b, val, struct_block_decoration_cb, NULL);
1531
1532
const char *name = val->name;
1533
1534
if (val->type->block || val->type->buffer_block) {
1535
/* Packing will be ignored since types coming from SPIR-V are
1536
* explicitly laid out.
1537
*/
1538
val->type->type = glsl_interface_type(fields, num_fields,
1539
/* packing */ 0, false,
1540
name ? name : "block");
1541
} else {
1542
val->type->type = glsl_struct_type(fields, num_fields,
1543
name ? name : "struct",
1544
val->type->packed);
1545
}
1546
break;
1547
}
1548
1549
case SpvOpTypeFunction: {
1550
val->type->base_type = vtn_base_type_function;
1551
val->type->type = NULL;
1552
1553
val->type->return_type = vtn_get_type(b, w[2]);
1554
1555
const unsigned num_params = count - 3;
1556
val->type->length = num_params;
1557
val->type->params = ralloc_array(b, struct vtn_type *, num_params);
1558
for (unsigned i = 0; i < count - 3; i++) {
1559
val->type->params[i] = vtn_get_type(b, w[i + 3]);
1560
}
1561
break;
1562
}
1563
1564
case SpvOpTypePointer:
1565
case SpvOpTypeForwardPointer: {
1566
/* We can't blindly push the value because it might be a forward
1567
* declaration.
1568
*/
1569
val = vtn_untyped_value(b, w[1]);
1570
1571
SpvStorageClass storage_class = w[2];
1572
1573
vtn_fail_if(opcode == SpvOpTypeForwardPointer &&
1574
b->shader->info.stage != MESA_SHADER_KERNEL &&
1575
storage_class != SpvStorageClassPhysicalStorageBuffer,
1576
"OpTypeForwardPointer is only allowed in Vulkan with "
1577
"the PhysicalStorageBuffer storage class");
1578
1579
struct vtn_type *deref_type = NULL;
1580
if (opcode == SpvOpTypePointer)
1581
deref_type = vtn_get_type(b, w[3]);
1582
1583
if (val->value_type == vtn_value_type_invalid) {
1584
val->value_type = vtn_value_type_type;
1585
val->type = rzalloc(b, struct vtn_type);
1586
val->type->id = w[1];
1587
val->type->base_type = vtn_base_type_pointer;
1588
val->type->storage_class = storage_class;
1589
1590
/* These can actually be stored to nir_variables and used as SSA
1591
* values so they need a real glsl_type.
1592
*/
1593
enum vtn_variable_mode mode = vtn_storage_class_to_mode(
1594
b, storage_class, deref_type, NULL);
1595
1596
/* The deref type should only matter for the UniformConstant storage
1597
* class. In particular, it should never matter for any storage
1598
* classes that are allowed in combination with OpTypeForwardPointer.
1599
*/
1600
if (storage_class != SpvStorageClassUniform &&
1601
storage_class != SpvStorageClassUniformConstant) {
1602
assert(mode == vtn_storage_class_to_mode(b, storage_class,
1603
NULL, NULL));
1604
}
1605
1606
val->type->type = nir_address_format_to_glsl_type(
1607
vtn_mode_to_address_format(b, mode));
1608
} else {
1609
vtn_fail_if(val->type->storage_class != storage_class,
1610
"The storage classes of an OpTypePointer and any "
1611
"OpTypeForwardPointers that provide forward "
1612
"declarations of it must match.");
1613
}
1614
1615
if (opcode == SpvOpTypePointer) {
1616
vtn_fail_if(val->type->deref != NULL,
1617
"While OpTypeForwardPointer can be used to provide a "
1618
"forward declaration of a pointer, OpTypePointer can "
1619
"only be used once for a given id.");
1620
1621
val->type->deref = deref_type;
1622
1623
/* Only certain storage classes use ArrayStride. */
1624
switch (storage_class) {
1625
case SpvStorageClassWorkgroup:
1626
if (!b->options->caps.workgroup_memory_explicit_layout)
1627
break;
1628
FALLTHROUGH;
1629
1630
case SpvStorageClassUniform:
1631
case SpvStorageClassPushConstant:
1632
case SpvStorageClassStorageBuffer:
1633
case SpvStorageClassPhysicalStorageBuffer:
1634
vtn_foreach_decoration(b, val, array_stride_decoration_cb, NULL);
1635
break;
1636
1637
default:
1638
/* Nothing to do. */
1639
break;
1640
}
1641
}
1642
break;
1643
}
1644
1645
case SpvOpTypeImage: {
1646
val->type->base_type = vtn_base_type_image;
1647
1648
/* Images are represented in NIR as a scalar SSA value that is the
1649
* result of a deref instruction. An OpLoad on an OpTypeImage pointer
1650
* from UniformConstant memory just takes the NIR deref from the pointer
1651
* and turns it into an SSA value.
1652
*/
1653
val->type->type = nir_address_format_to_glsl_type(
1654
vtn_mode_to_address_format(b, vtn_variable_mode_function));
1655
1656
const struct vtn_type *sampled_type = vtn_get_type(b, w[2]);
1657
if (b->shader->info.stage == MESA_SHADER_KERNEL) {
1658
vtn_fail_if(sampled_type->base_type != vtn_base_type_void,
1659
"Sampled type of OpTypeImage must be void for kernels");
1660
} else {
1661
vtn_fail_if(sampled_type->base_type != vtn_base_type_scalar,
1662
"Sampled type of OpTypeImage must be a scalar");
1663
if (b->options->caps.image_atomic_int64) {
1664
vtn_fail_if(glsl_get_bit_size(sampled_type->type) != 32 &&
1665
glsl_get_bit_size(sampled_type->type) != 64,
1666
"Sampled type of OpTypeImage must be a 32 or 64-bit "
1667
"scalar");
1668
} else {
1669
vtn_fail_if(glsl_get_bit_size(sampled_type->type) != 32,
1670
"Sampled type of OpTypeImage must be a 32-bit scalar");
1671
}
1672
}
1673
1674
enum glsl_sampler_dim dim;
1675
switch ((SpvDim)w[3]) {
1676
case SpvDim1D: dim = GLSL_SAMPLER_DIM_1D; break;
1677
case SpvDim2D: dim = GLSL_SAMPLER_DIM_2D; break;
1678
case SpvDim3D: dim = GLSL_SAMPLER_DIM_3D; break;
1679
case SpvDimCube: dim = GLSL_SAMPLER_DIM_CUBE; break;
1680
case SpvDimRect: dim = GLSL_SAMPLER_DIM_RECT; break;
1681
case SpvDimBuffer: dim = GLSL_SAMPLER_DIM_BUF; break;
1682
case SpvDimSubpassData: dim = GLSL_SAMPLER_DIM_SUBPASS; break;
1683
default:
1684
vtn_fail("Invalid SPIR-V image dimensionality: %s (%u)",
1685
spirv_dim_to_string((SpvDim)w[3]), w[3]);
1686
}
1687
1688
/* w[4]: as per Vulkan spec "Validation Rules within a Module",
1689
* The “Depth” operand of OpTypeImage is ignored.
1690
*/
1691
bool is_array = w[5];
1692
bool multisampled = w[6];
1693
unsigned sampled = w[7];
1694
SpvImageFormat format = w[8];
1695
1696
if (count > 9)
1697
val->type->access_qualifier = w[9];
1698
else if (b->shader->info.stage == MESA_SHADER_KERNEL)
1699
/* Per the CL C spec: If no qualifier is provided, read_only is assumed. */
1700
val->type->access_qualifier = SpvAccessQualifierReadOnly;
1701
else
1702
val->type->access_qualifier = SpvAccessQualifierReadWrite;
1703
1704
if (multisampled) {
1705
if (dim == GLSL_SAMPLER_DIM_2D)
1706
dim = GLSL_SAMPLER_DIM_MS;
1707
else if (dim == GLSL_SAMPLER_DIM_SUBPASS)
1708
dim = GLSL_SAMPLER_DIM_SUBPASS_MS;
1709
else
1710
vtn_fail("Unsupported multisampled image type");
1711
}
1712
1713
val->type->image_format = translate_image_format(b, format);
1714
1715
enum glsl_base_type sampled_base_type =
1716
glsl_get_base_type(sampled_type->type);
1717
if (sampled == 1) {
1718
val->type->glsl_image = glsl_sampler_type(dim, false, is_array,
1719
sampled_base_type);
1720
} else if (sampled == 2) {
1721
val->type->glsl_image = glsl_image_type(dim, is_array,
1722
sampled_base_type);
1723
} else if (b->shader->info.stage == MESA_SHADER_KERNEL) {
1724
val->type->glsl_image = glsl_image_type(dim, is_array,
1725
GLSL_TYPE_VOID);
1726
} else {
1727
vtn_fail("We need to know if the image will be sampled");
1728
}
1729
break;
1730
}
1731
1732
case SpvOpTypeSampledImage: {
1733
val->type->base_type = vtn_base_type_sampled_image;
1734
val->type->image = vtn_get_type(b, w[2]);
1735
1736
/* Sampled images are represented NIR as a vec2 SSA value where each
1737
* component is the result of a deref instruction. The first component
1738
* is the image and the second is the sampler. An OpLoad on an
1739
* OpTypeSampledImage pointer from UniformConstant memory just takes
1740
* the NIR deref from the pointer and duplicates it to both vector
1741
* components.
1742
*/
1743
nir_address_format addr_format =
1744
vtn_mode_to_address_format(b, vtn_variable_mode_function);
1745
assert(nir_address_format_num_components(addr_format) == 1);
1746
unsigned bit_size = nir_address_format_bit_size(addr_format);
1747
assert(bit_size == 32 || bit_size == 64);
1748
1749
enum glsl_base_type base_type =
1750
bit_size == 32 ? GLSL_TYPE_UINT : GLSL_TYPE_UINT64;
1751
val->type->type = glsl_vector_type(base_type, 2);
1752
break;
1753
}
1754
1755
case SpvOpTypeSampler:
1756
val->type->base_type = vtn_base_type_sampler;
1757
1758
/* Samplers are represented in NIR as a scalar SSA value that is the
1759
* result of a deref instruction. An OpLoad on an OpTypeSampler pointer
1760
* from UniformConstant memory just takes the NIR deref from the pointer
1761
* and turns it into an SSA value.
1762
*/
1763
val->type->type = nir_address_format_to_glsl_type(
1764
vtn_mode_to_address_format(b, vtn_variable_mode_function));
1765
break;
1766
1767
case SpvOpTypeAccelerationStructureKHR:
1768
val->type->base_type = vtn_base_type_accel_struct;
1769
val->type->type = glsl_uint64_t_type();
1770
break;
1771
1772
case SpvOpTypeOpaque:
1773
val->type->base_type = vtn_base_type_struct;
1774
const char *name = vtn_string_literal(b, &w[2], count - 2, NULL);
1775
val->type->type = glsl_struct_type(NULL, 0, name, false);
1776
break;
1777
1778
case SpvOpTypeEvent:
1779
val->type->base_type = vtn_base_type_event;
1780
val->type->type = glsl_int_type();
1781
break;
1782
1783
case SpvOpTypeDeviceEvent:
1784
case SpvOpTypeReserveId:
1785
case SpvOpTypeQueue:
1786
case SpvOpTypePipe:
1787
default:
1788
vtn_fail_with_opcode("Unhandled opcode", opcode);
1789
}
1790
1791
vtn_foreach_decoration(b, val, type_decoration_cb, NULL);
1792
1793
if (val->type->base_type == vtn_base_type_struct &&
1794
(val->type->block || val->type->buffer_block)) {
1795
for (unsigned i = 0; i < val->type->length; i++) {
1796
vtn_fail_if(vtn_type_contains_block(b, val->type->members[i]),
1797
"Block and BufferBlock decorations cannot decorate a "
1798
"structure type that is nested at any level inside "
1799
"another structure type decorated with Block or "
1800
"BufferBlock.");
1801
}
1802
}
1803
}
1804
1805
static nir_constant *
1806
vtn_null_constant(struct vtn_builder *b, struct vtn_type *type)
1807
{
1808
nir_constant *c = rzalloc(b, nir_constant);
1809
1810
switch (type->base_type) {
1811
case vtn_base_type_scalar:
1812
case vtn_base_type_vector:
1813
/* Nothing to do here. It's already initialized to zero */
1814
break;
1815
1816
case vtn_base_type_pointer: {
1817
enum vtn_variable_mode mode = vtn_storage_class_to_mode(
1818
b, type->storage_class, type->deref, NULL);
1819
nir_address_format addr_format = vtn_mode_to_address_format(b, mode);
1820
1821
const nir_const_value *null_value = nir_address_format_null_value(addr_format);
1822
memcpy(c->values, null_value,
1823
sizeof(nir_const_value) * nir_address_format_num_components(addr_format));
1824
break;
1825
}
1826
1827
case vtn_base_type_void:
1828
case vtn_base_type_image:
1829
case vtn_base_type_sampler:
1830
case vtn_base_type_sampled_image:
1831
case vtn_base_type_function:
1832
case vtn_base_type_event:
1833
/* For those we have to return something but it doesn't matter what. */
1834
break;
1835
1836
case vtn_base_type_matrix:
1837
case vtn_base_type_array:
1838
vtn_assert(type->length > 0);
1839
c->num_elements = type->length;
1840
c->elements = ralloc_array(b, nir_constant *, c->num_elements);
1841
1842
c->elements[0] = vtn_null_constant(b, type->array_element);
1843
for (unsigned i = 1; i < c->num_elements; i++)
1844
c->elements[i] = c->elements[0];
1845
break;
1846
1847
case vtn_base_type_struct:
1848
c->num_elements = type->length;
1849
c->elements = ralloc_array(b, nir_constant *, c->num_elements);
1850
for (unsigned i = 0; i < c->num_elements; i++)
1851
c->elements[i] = vtn_null_constant(b, type->members[i]);
1852
break;
1853
1854
default:
1855
vtn_fail("Invalid type for null constant");
1856
}
1857
1858
return c;
1859
}
1860
1861
static void
1862
spec_constant_decoration_cb(struct vtn_builder *b, UNUSED struct vtn_value *val,
1863
ASSERTED int member,
1864
const struct vtn_decoration *dec, void *data)
1865
{
1866
vtn_assert(member == -1);
1867
if (dec->decoration != SpvDecorationSpecId)
1868
return;
1869
1870
nir_const_value *value = data;
1871
for (unsigned i = 0; i < b->num_specializations; i++) {
1872
if (b->specializations[i].id == dec->operands[0]) {
1873
*value = b->specializations[i].value;
1874
return;
1875
}
1876
}
1877
}
1878
1879
static void
1880
handle_workgroup_size_decoration_cb(struct vtn_builder *b,
1881
struct vtn_value *val,
1882
ASSERTED int member,
1883
const struct vtn_decoration *dec,
1884
UNUSED void *data)
1885
{
1886
vtn_assert(member == -1);
1887
if (dec->decoration != SpvDecorationBuiltIn ||
1888
dec->operands[0] != SpvBuiltInWorkgroupSize)
1889
return;
1890
1891
vtn_assert(val->type->type == glsl_vector_type(GLSL_TYPE_UINT, 3));
1892
b->workgroup_size_builtin = val;
1893
}
1894
1895
static void
1896
vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
1897
const uint32_t *w, unsigned count)
1898
{
1899
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
1900
val->constant = rzalloc(b, nir_constant);
1901
switch (opcode) {
1902
case SpvOpConstantTrue:
1903
case SpvOpConstantFalse:
1904
case SpvOpSpecConstantTrue:
1905
case SpvOpSpecConstantFalse: {
1906
vtn_fail_if(val->type->type != glsl_bool_type(),
1907
"Result type of %s must be OpTypeBool",
1908
spirv_op_to_string(opcode));
1909
1910
bool bval = (opcode == SpvOpConstantTrue ||
1911
opcode == SpvOpSpecConstantTrue);
1912
1913
nir_const_value u32val = nir_const_value_for_uint(bval, 32);
1914
1915
if (opcode == SpvOpSpecConstantTrue ||
1916
opcode == SpvOpSpecConstantFalse)
1917
vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &u32val);
1918
1919
val->constant->values[0].b = u32val.u32 != 0;
1920
break;
1921
}
1922
1923
case SpvOpConstant:
1924
case SpvOpSpecConstant: {
1925
vtn_fail_if(val->type->base_type != vtn_base_type_scalar,
1926
"Result type of %s must be a scalar",
1927
spirv_op_to_string(opcode));
1928
int bit_size = glsl_get_bit_size(val->type->type);
1929
switch (bit_size) {
1930
case 64:
1931
val->constant->values[0].u64 = vtn_u64_literal(&w[3]);
1932
break;
1933
case 32:
1934
val->constant->values[0].u32 = w[3];
1935
break;
1936
case 16:
1937
val->constant->values[0].u16 = w[3];
1938
break;
1939
case 8:
1940
val->constant->values[0].u8 = w[3];
1941
break;
1942
default:
1943
vtn_fail("Unsupported SpvOpConstant bit size: %u", bit_size);
1944
}
1945
1946
if (opcode == SpvOpSpecConstant)
1947
vtn_foreach_decoration(b, val, spec_constant_decoration_cb,
1948
&val->constant->values[0]);
1949
break;
1950
}
1951
1952
case SpvOpSpecConstantComposite:
1953
case SpvOpConstantComposite: {
1954
unsigned elem_count = count - 3;
1955
vtn_fail_if(elem_count != val->type->length,
1956
"%s has %u constituents, expected %u",
1957
spirv_op_to_string(opcode), elem_count, val->type->length);
1958
1959
nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
1960
for (unsigned i = 0; i < elem_count; i++) {
1961
struct vtn_value *val = vtn_untyped_value(b, w[i + 3]);
1962
1963
if (val->value_type == vtn_value_type_constant) {
1964
elems[i] = val->constant;
1965
} else {
1966
vtn_fail_if(val->value_type != vtn_value_type_undef,
1967
"only constants or undefs allowed for "
1968
"SpvOpConstantComposite");
1969
/* to make it easier, just insert a NULL constant for now */
1970
elems[i] = vtn_null_constant(b, val->type);
1971
}
1972
}
1973
1974
switch (val->type->base_type) {
1975
case vtn_base_type_vector: {
1976
assert(glsl_type_is_vector(val->type->type));
1977
for (unsigned i = 0; i < elem_count; i++)
1978
val->constant->values[i] = elems[i]->values[0];
1979
break;
1980
}
1981
1982
case vtn_base_type_matrix:
1983
case vtn_base_type_struct:
1984
case vtn_base_type_array:
1985
ralloc_steal(val->constant, elems);
1986
val->constant->num_elements = elem_count;
1987
val->constant->elements = elems;
1988
break;
1989
1990
default:
1991
vtn_fail("Result type of %s must be a composite type",
1992
spirv_op_to_string(opcode));
1993
}
1994
break;
1995
}
1996
1997
case SpvOpSpecConstantOp: {
1998
nir_const_value u32op = nir_const_value_for_uint(w[3], 32);
1999
vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &u32op);
2000
SpvOp opcode = u32op.u32;
2001
switch (opcode) {
2002
case SpvOpVectorShuffle: {
2003
struct vtn_value *v0 = &b->values[w[4]];
2004
struct vtn_value *v1 = &b->values[w[5]];
2005
2006
vtn_assert(v0->value_type == vtn_value_type_constant ||
2007
v0->value_type == vtn_value_type_undef);
2008
vtn_assert(v1->value_type == vtn_value_type_constant ||
2009
v1->value_type == vtn_value_type_undef);
2010
2011
unsigned len0 = glsl_get_vector_elements(v0->type->type);
2012
unsigned len1 = glsl_get_vector_elements(v1->type->type);
2013
2014
vtn_assert(len0 + len1 < 16);
2015
2016
unsigned bit_size = glsl_get_bit_size(val->type->type);
2017
unsigned bit_size0 = glsl_get_bit_size(v0->type->type);
2018
unsigned bit_size1 = glsl_get_bit_size(v1->type->type);
2019
2020
vtn_assert(bit_size == bit_size0 && bit_size == bit_size1);
2021
(void)bit_size0; (void)bit_size1;
2022
2023
nir_const_value undef = { .u64 = 0xdeadbeefdeadbeef };
2024
nir_const_value combined[NIR_MAX_VEC_COMPONENTS * 2];
2025
2026
if (v0->value_type == vtn_value_type_constant) {
2027
for (unsigned i = 0; i < len0; i++)
2028
combined[i] = v0->constant->values[i];
2029
}
2030
if (v1->value_type == vtn_value_type_constant) {
2031
for (unsigned i = 0; i < len1; i++)
2032
combined[len0 + i] = v1->constant->values[i];
2033
}
2034
2035
for (unsigned i = 0, j = 0; i < count - 6; i++, j++) {
2036
uint32_t comp = w[i + 6];
2037
if (comp == (uint32_t)-1) {
2038
/* If component is not used, set the value to a known constant
2039
* to detect if it is wrongly used.
2040
*/
2041
val->constant->values[j] = undef;
2042
} else {
2043
vtn_fail_if(comp >= len0 + len1,
2044
"All Component literals must either be FFFFFFFF "
2045
"or in [0, N - 1] (inclusive).");
2046
val->constant->values[j] = combined[comp];
2047
}
2048
}
2049
break;
2050
}
2051
2052
case SpvOpCompositeExtract:
2053
case SpvOpCompositeInsert: {
2054
struct vtn_value *comp;
2055
unsigned deref_start;
2056
struct nir_constant **c;
2057
if (opcode == SpvOpCompositeExtract) {
2058
comp = vtn_value(b, w[4], vtn_value_type_constant);
2059
deref_start = 5;
2060
c = &comp->constant;
2061
} else {
2062
comp = vtn_value(b, w[5], vtn_value_type_constant);
2063
deref_start = 6;
2064
val->constant = nir_constant_clone(comp->constant,
2065
(nir_variable *)b);
2066
c = &val->constant;
2067
}
2068
2069
int elem = -1;
2070
const struct vtn_type *type = comp->type;
2071
for (unsigned i = deref_start; i < count; i++) {
2072
vtn_fail_if(w[i] > type->length,
2073
"%uth index of %s is %u but the type has only "
2074
"%u elements", i - deref_start,
2075
spirv_op_to_string(opcode), w[i], type->length);
2076
2077
switch (type->base_type) {
2078
case vtn_base_type_vector:
2079
elem = w[i];
2080
type = type->array_element;
2081
break;
2082
2083
case vtn_base_type_matrix:
2084
case vtn_base_type_array:
2085
c = &(*c)->elements[w[i]];
2086
type = type->array_element;
2087
break;
2088
2089
case vtn_base_type_struct:
2090
c = &(*c)->elements[w[i]];
2091
type = type->members[w[i]];
2092
break;
2093
2094
default:
2095
vtn_fail("%s must only index into composite types",
2096
spirv_op_to_string(opcode));
2097
}
2098
}
2099
2100
if (opcode == SpvOpCompositeExtract) {
2101
if (elem == -1) {
2102
val->constant = *c;
2103
} else {
2104
unsigned num_components = type->length;
2105
for (unsigned i = 0; i < num_components; i++)
2106
val->constant->values[i] = (*c)->values[elem + i];
2107
}
2108
} else {
2109
struct vtn_value *insert =
2110
vtn_value(b, w[4], vtn_value_type_constant);
2111
vtn_assert(insert->type == type);
2112
if (elem == -1) {
2113
*c = insert->constant;
2114
} else {
2115
unsigned num_components = type->length;
2116
for (unsigned i = 0; i < num_components; i++)
2117
(*c)->values[elem + i] = insert->constant->values[i];
2118
}
2119
}
2120
break;
2121
}
2122
2123
default: {
2124
bool swap;
2125
nir_alu_type dst_alu_type = nir_get_nir_type_for_glsl_type(val->type->type);
2126
nir_alu_type src_alu_type = dst_alu_type;
2127
unsigned num_components = glsl_get_vector_elements(val->type->type);
2128
unsigned bit_size;
2129
2130
vtn_assert(count <= 7);
2131
2132
switch (opcode) {
2133
case SpvOpSConvert:
2134
case SpvOpFConvert:
2135
case SpvOpUConvert:
2136
/* We have a source in a conversion */
2137
src_alu_type =
2138
nir_get_nir_type_for_glsl_type(vtn_get_value_type(b, w[4])->type);
2139
/* We use the bitsize of the conversion source to evaluate the opcode later */
2140
bit_size = glsl_get_bit_size(vtn_get_value_type(b, w[4])->type);
2141
break;
2142
default:
2143
bit_size = glsl_get_bit_size(val->type->type);
2144
};
2145
2146
bool exact;
2147
nir_op op = vtn_nir_alu_op_for_spirv_opcode(b, opcode, &swap, &exact,
2148
nir_alu_type_get_type_size(src_alu_type),
2149
nir_alu_type_get_type_size(dst_alu_type));
2150
2151
/* No SPIR-V opcodes handled through this path should set exact.
2152
* Since it is ignored, assert on it.
2153
*/
2154
assert(!exact);
2155
2156
nir_const_value src[3][NIR_MAX_VEC_COMPONENTS];
2157
2158
for (unsigned i = 0; i < count - 4; i++) {
2159
struct vtn_value *src_val =
2160
vtn_value(b, w[4 + i], vtn_value_type_constant);
2161
2162
/* If this is an unsized source, pull the bit size from the
2163
* source; otherwise, we'll use the bit size from the destination.
2164
*/
2165
if (!nir_alu_type_get_type_size(nir_op_infos[op].input_types[i]))
2166
bit_size = glsl_get_bit_size(src_val->type->type);
2167
2168
unsigned src_comps = nir_op_infos[op].input_sizes[i] ?
2169
nir_op_infos[op].input_sizes[i] :
2170
num_components;
2171
2172
unsigned j = swap ? 1 - i : i;
2173
for (unsigned c = 0; c < src_comps; c++)
2174
src[j][c] = src_val->constant->values[c];
2175
}
2176
2177
/* fix up fixed size sources */
2178
switch (op) {
2179
case nir_op_ishl:
2180
case nir_op_ishr:
2181
case nir_op_ushr: {
2182
if (bit_size == 32)
2183
break;
2184
for (unsigned i = 0; i < num_components; ++i) {
2185
switch (bit_size) {
2186
case 64: src[1][i].u32 = src[1][i].u64; break;
2187
case 16: src[1][i].u32 = src[1][i].u16; break;
2188
case 8: src[1][i].u32 = src[1][i].u8; break;
2189
}
2190
}
2191
break;
2192
}
2193
default:
2194
break;
2195
}
2196
2197
nir_const_value *srcs[3] = {
2198
src[0], src[1], src[2],
2199
};
2200
nir_eval_const_opcode(op, val->constant->values,
2201
num_components, bit_size, srcs,
2202
b->shader->info.float_controls_execution_mode);
2203
break;
2204
} /* default */
2205
}
2206
break;
2207
}
2208
2209
case SpvOpConstantNull:
2210
val->constant = vtn_null_constant(b, val->type);
2211
val->is_null_constant = true;
2212
break;
2213
2214
default:
2215
vtn_fail_with_opcode("Unhandled opcode", opcode);
2216
}
2217
2218
/* Now that we have the value, update the workgroup size if needed */
2219
if (b->entry_point_stage == MESA_SHADER_COMPUTE ||
2220
b->entry_point_stage == MESA_SHADER_KERNEL)
2221
vtn_foreach_decoration(b, val, handle_workgroup_size_decoration_cb,
2222
NULL);
2223
}
2224
2225
static void
2226
vtn_split_barrier_semantics(struct vtn_builder *b,
2227
SpvMemorySemanticsMask semantics,
2228
SpvMemorySemanticsMask *before,
2229
SpvMemorySemanticsMask *after)
2230
{
2231
/* For memory semantics embedded in operations, we split them into up to
2232
* two barriers, to be added before and after the operation. This is less
2233
* strict than if we propagated until the final backend stage, but still
2234
* result in correct execution.
2235
*
2236
* A further improvement could be pipe this information (and use!) into the
2237
* next compiler layers, at the expense of making the handling of barriers
2238
* more complicated.
2239
*/
2240
2241
*before = SpvMemorySemanticsMaskNone;
2242
*after = SpvMemorySemanticsMaskNone;
2243
2244
SpvMemorySemanticsMask order_semantics =
2245
semantics & (SpvMemorySemanticsAcquireMask |
2246
SpvMemorySemanticsReleaseMask |
2247
SpvMemorySemanticsAcquireReleaseMask |
2248
SpvMemorySemanticsSequentiallyConsistentMask);
2249
2250
if (util_bitcount(order_semantics) > 1) {
2251
/* Old GLSLang versions incorrectly set all the ordering bits. This was
2252
* fixed in c51287d744fb6e7e9ccc09f6f8451e6c64b1dad6 of glslang repo,
2253
* and it is in GLSLang since revision "SPIRV99.1321" (from Jul-2016).
2254
*/
2255
vtn_warn("Multiple memory ordering semantics specified, "
2256
"assuming AcquireRelease.");
2257
order_semantics = SpvMemorySemanticsAcquireReleaseMask;
2258
}
2259
2260
const SpvMemorySemanticsMask av_vis_semantics =
2261
semantics & (SpvMemorySemanticsMakeAvailableMask |
2262
SpvMemorySemanticsMakeVisibleMask);
2263
2264
const SpvMemorySemanticsMask storage_semantics =
2265
semantics & (SpvMemorySemanticsUniformMemoryMask |
2266
SpvMemorySemanticsSubgroupMemoryMask |
2267
SpvMemorySemanticsWorkgroupMemoryMask |
2268
SpvMemorySemanticsCrossWorkgroupMemoryMask |
2269
SpvMemorySemanticsAtomicCounterMemoryMask |
2270
SpvMemorySemanticsImageMemoryMask |
2271
SpvMemorySemanticsOutputMemoryMask);
2272
2273
const SpvMemorySemanticsMask other_semantics =
2274
semantics & ~(order_semantics | av_vis_semantics | storage_semantics |
2275
SpvMemorySemanticsVolatileMask);
2276
2277
if (other_semantics)
2278
vtn_warn("Ignoring unhandled memory semantics: %u\n", other_semantics);
2279
2280
/* SequentiallyConsistent is treated as AcquireRelease. */
2281
2282
/* The RELEASE barrier happens BEFORE the operation, and it is usually
2283
* associated with a Store. All the write operations with a matching
2284
* semantics will not be reordered after the Store.
2285
*/
2286
if (order_semantics & (SpvMemorySemanticsReleaseMask |
2287
SpvMemorySemanticsAcquireReleaseMask |
2288
SpvMemorySemanticsSequentiallyConsistentMask)) {
2289
*before |= SpvMemorySemanticsReleaseMask | storage_semantics;
2290
}
2291
2292
/* The ACQUIRE barrier happens AFTER the operation, and it is usually
2293
* associated with a Load. All the operations with a matching semantics
2294
* will not be reordered before the Load.
2295
*/
2296
if (order_semantics & (SpvMemorySemanticsAcquireMask |
2297
SpvMemorySemanticsAcquireReleaseMask |
2298
SpvMemorySemanticsSequentiallyConsistentMask)) {
2299
*after |= SpvMemorySemanticsAcquireMask | storage_semantics;
2300
}
2301
2302
if (av_vis_semantics & SpvMemorySemanticsMakeVisibleMask)
2303
*before |= SpvMemorySemanticsMakeVisibleMask | storage_semantics;
2304
2305
if (av_vis_semantics & SpvMemorySemanticsMakeAvailableMask)
2306
*after |= SpvMemorySemanticsMakeAvailableMask | storage_semantics;
2307
}
2308
2309
static nir_memory_semantics
2310
vtn_mem_semantics_to_nir_mem_semantics(struct vtn_builder *b,
2311
SpvMemorySemanticsMask semantics)
2312
{
2313
nir_memory_semantics nir_semantics = 0;
2314
2315
SpvMemorySemanticsMask order_semantics =
2316
semantics & (SpvMemorySemanticsAcquireMask |
2317
SpvMemorySemanticsReleaseMask |
2318
SpvMemorySemanticsAcquireReleaseMask |
2319
SpvMemorySemanticsSequentiallyConsistentMask);
2320
2321
if (util_bitcount(order_semantics) > 1) {
2322
/* Old GLSLang versions incorrectly set all the ordering bits. This was
2323
* fixed in c51287d744fb6e7e9ccc09f6f8451e6c64b1dad6 of glslang repo,
2324
* and it is in GLSLang since revision "SPIRV99.1321" (from Jul-2016).
2325
*/
2326
vtn_warn("Multiple memory ordering semantics bits specified, "
2327
"assuming AcquireRelease.");
2328
order_semantics = SpvMemorySemanticsAcquireReleaseMask;
2329
}
2330
2331
switch (order_semantics) {
2332
case 0:
2333
/* Not an ordering barrier. */
2334
break;
2335
2336
case SpvMemorySemanticsAcquireMask:
2337
nir_semantics = NIR_MEMORY_ACQUIRE;
2338
break;
2339
2340
case SpvMemorySemanticsReleaseMask:
2341
nir_semantics = NIR_MEMORY_RELEASE;
2342
break;
2343
2344
case SpvMemorySemanticsSequentiallyConsistentMask:
2345
FALLTHROUGH; /* Treated as AcquireRelease in Vulkan. */
2346
case SpvMemorySemanticsAcquireReleaseMask:
2347
nir_semantics = NIR_MEMORY_ACQUIRE | NIR_MEMORY_RELEASE;
2348
break;
2349
2350
default:
2351
unreachable("Invalid memory order semantics");
2352
}
2353
2354
if (semantics & SpvMemorySemanticsMakeAvailableMask) {
2355
vtn_fail_if(!b->options->caps.vk_memory_model,
2356
"To use MakeAvailable memory semantics the VulkanMemoryModel "
2357
"capability must be declared.");
2358
nir_semantics |= NIR_MEMORY_MAKE_AVAILABLE;
2359
}
2360
2361
if (semantics & SpvMemorySemanticsMakeVisibleMask) {
2362
vtn_fail_if(!b->options->caps.vk_memory_model,
2363
"To use MakeVisible memory semantics the VulkanMemoryModel "
2364
"capability must be declared.");
2365
nir_semantics |= NIR_MEMORY_MAKE_VISIBLE;
2366
}
2367
2368
return nir_semantics;
2369
}
2370
2371
static nir_variable_mode
2372
vtn_mem_semantics_to_nir_var_modes(struct vtn_builder *b,
2373
SpvMemorySemanticsMask semantics)
2374
{
2375
/* Vulkan Environment for SPIR-V says "SubgroupMemory, CrossWorkgroupMemory,
2376
* and AtomicCounterMemory are ignored".
2377
*/
2378
if (b->options->environment == NIR_SPIRV_VULKAN) {
2379
semantics &= ~(SpvMemorySemanticsSubgroupMemoryMask |
2380
SpvMemorySemanticsCrossWorkgroupMemoryMask |
2381
SpvMemorySemanticsAtomicCounterMemoryMask);
2382
}
2383
2384
/* TODO: Consider adding nir_var_mem_image mode to NIR so it can be used
2385
* for SpvMemorySemanticsImageMemoryMask.
2386
*/
2387
2388
nir_variable_mode modes = 0;
2389
if (semantics & (SpvMemorySemanticsUniformMemoryMask |
2390
SpvMemorySemanticsImageMemoryMask)) {
2391
modes |= nir_var_uniform |
2392
nir_var_mem_ubo |
2393
nir_var_mem_ssbo |
2394
nir_var_mem_global;
2395
}
2396
if (semantics & SpvMemorySemanticsWorkgroupMemoryMask)
2397
modes |= nir_var_mem_shared;
2398
if (semantics & SpvMemorySemanticsCrossWorkgroupMemoryMask)
2399
modes |= nir_var_mem_global;
2400
if (semantics & SpvMemorySemanticsOutputMemoryMask) {
2401
modes |= nir_var_shader_out;
2402
}
2403
2404
return modes;
2405
}
2406
2407
static nir_scope
2408
vtn_scope_to_nir_scope(struct vtn_builder *b, SpvScope scope)
2409
{
2410
nir_scope nir_scope;
2411
switch (scope) {
2412
case SpvScopeDevice:
2413
vtn_fail_if(b->options->caps.vk_memory_model &&
2414
!b->options->caps.vk_memory_model_device_scope,
2415
"If the Vulkan memory model is declared and any instruction "
2416
"uses Device scope, the VulkanMemoryModelDeviceScope "
2417
"capability must be declared.");
2418
nir_scope = NIR_SCOPE_DEVICE;
2419
break;
2420
2421
case SpvScopeQueueFamily:
2422
vtn_fail_if(!b->options->caps.vk_memory_model,
2423
"To use Queue Family scope, the VulkanMemoryModel capability "
2424
"must be declared.");
2425
nir_scope = NIR_SCOPE_QUEUE_FAMILY;
2426
break;
2427
2428
case SpvScopeWorkgroup:
2429
nir_scope = NIR_SCOPE_WORKGROUP;
2430
break;
2431
2432
case SpvScopeSubgroup:
2433
nir_scope = NIR_SCOPE_SUBGROUP;
2434
break;
2435
2436
case SpvScopeInvocation:
2437
nir_scope = NIR_SCOPE_INVOCATION;
2438
break;
2439
2440
case SpvScopeShaderCallKHR:
2441
nir_scope = NIR_SCOPE_SHADER_CALL;
2442
break;
2443
2444
default:
2445
vtn_fail("Invalid memory scope");
2446
}
2447
2448
return nir_scope;
2449
}
2450
2451
static void
2452
vtn_emit_scoped_control_barrier(struct vtn_builder *b, SpvScope exec_scope,
2453
SpvScope mem_scope,
2454
SpvMemorySemanticsMask semantics)
2455
{
2456
nir_memory_semantics nir_semantics =
2457
vtn_mem_semantics_to_nir_mem_semantics(b, semantics);
2458
nir_variable_mode modes = vtn_mem_semantics_to_nir_var_modes(b, semantics);
2459
nir_scope nir_exec_scope = vtn_scope_to_nir_scope(b, exec_scope);
2460
2461
/* Memory semantics is optional for OpControlBarrier. */
2462
nir_scope nir_mem_scope;
2463
if (nir_semantics == 0 || modes == 0)
2464
nir_mem_scope = NIR_SCOPE_NONE;
2465
else
2466
nir_mem_scope = vtn_scope_to_nir_scope(b, mem_scope);
2467
2468
nir_scoped_barrier(&b->nb, .execution_scope=nir_exec_scope, .memory_scope=nir_mem_scope,
2469
.memory_semantics=nir_semantics, .memory_modes=modes);
2470
}
2471
2472
static void
2473
vtn_emit_scoped_memory_barrier(struct vtn_builder *b, SpvScope scope,
2474
SpvMemorySemanticsMask semantics)
2475
{
2476
nir_variable_mode modes = vtn_mem_semantics_to_nir_var_modes(b, semantics);
2477
nir_memory_semantics nir_semantics =
2478
vtn_mem_semantics_to_nir_mem_semantics(b, semantics);
2479
2480
/* No barrier to add. */
2481
if (nir_semantics == 0 || modes == 0)
2482
return;
2483
2484
nir_scoped_barrier(&b->nb, .memory_scope=vtn_scope_to_nir_scope(b, scope),
2485
.memory_semantics=nir_semantics,
2486
.memory_modes=modes);
2487
}
2488
2489
struct vtn_ssa_value *
2490
vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
2491
{
2492
/* Always use bare types for SSA values for a couple of reasons:
2493
*
2494
* 1. Code which emits deref chains should never listen to the explicit
2495
* layout information on the SSA value if any exists. If we've
2496
* accidentally been relying on this, we want to find those bugs.
2497
*
2498
* 2. We want to be able to quickly check that an SSA value being assigned
2499
* to a SPIR-V value has the right type. Using bare types everywhere
2500
* ensures that we can pointer-compare.
2501
*/
2502
struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
2503
val->type = glsl_get_bare_type(type);
2504
2505
2506
if (!glsl_type_is_vector_or_scalar(type)) {
2507
unsigned elems = glsl_get_length(val->type);
2508
val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
2509
if (glsl_type_is_array_or_matrix(type)) {
2510
const struct glsl_type *elem_type = glsl_get_array_element(type);
2511
for (unsigned i = 0; i < elems; i++)
2512
val->elems[i] = vtn_create_ssa_value(b, elem_type);
2513
} else {
2514
vtn_assert(glsl_type_is_struct_or_ifc(type));
2515
for (unsigned i = 0; i < elems; i++) {
2516
const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
2517
val->elems[i] = vtn_create_ssa_value(b, elem_type);
2518
}
2519
}
2520
}
2521
2522
return val;
2523
}
2524
2525
static nir_tex_src
2526
vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
2527
{
2528
nir_tex_src src;
2529
src.src = nir_src_for_ssa(vtn_get_nir_ssa(b, index));
2530
src.src_type = type;
2531
return src;
2532
}
2533
2534
static uint32_t
2535
image_operand_arg(struct vtn_builder *b, const uint32_t *w, uint32_t count,
2536
uint32_t mask_idx, SpvImageOperandsMask op)
2537
{
2538
static const SpvImageOperandsMask ops_with_arg =
2539
SpvImageOperandsBiasMask |
2540
SpvImageOperandsLodMask |
2541
SpvImageOperandsGradMask |
2542
SpvImageOperandsConstOffsetMask |
2543
SpvImageOperandsOffsetMask |
2544
SpvImageOperandsConstOffsetsMask |
2545
SpvImageOperandsSampleMask |
2546
SpvImageOperandsMinLodMask |
2547
SpvImageOperandsMakeTexelAvailableMask |
2548
SpvImageOperandsMakeTexelVisibleMask;
2549
2550
assert(util_bitcount(op) == 1);
2551
assert(w[mask_idx] & op);
2552
assert(op & ops_with_arg);
2553
2554
uint32_t idx = util_bitcount(w[mask_idx] & (op - 1) & ops_with_arg) + 1;
2555
2556
/* Adjust indices for operands with two arguments. */
2557
static const SpvImageOperandsMask ops_with_two_args =
2558
SpvImageOperandsGradMask;
2559
idx += util_bitcount(w[mask_idx] & (op - 1) & ops_with_two_args);
2560
2561
idx += mask_idx;
2562
2563
vtn_fail_if(idx + (op & ops_with_two_args ? 1 : 0) >= count,
2564
"Image op claims to have %s but does not enough "
2565
"following operands", spirv_imageoperands_to_string(op));
2566
2567
return idx;
2568
}
2569
2570
static void
2571
non_uniform_decoration_cb(struct vtn_builder *b,
2572
struct vtn_value *val, int member,
2573
const struct vtn_decoration *dec, void *void_ctx)
2574
{
2575
enum gl_access_qualifier *access = void_ctx;
2576
switch (dec->decoration) {
2577
case SpvDecorationNonUniformEXT:
2578
*access |= ACCESS_NON_UNIFORM;
2579
break;
2580
2581
default:
2582
break;
2583
}
2584
}
2585
2586
/* Apply SignExtend/ZeroExtend operands to get the actual result type for
2587
* image read/sample operations and source type for write operations.
2588
*/
2589
static nir_alu_type
2590
get_image_type(struct vtn_builder *b, nir_alu_type type, unsigned operands)
2591
{
2592
unsigned extend_operands =
2593
operands & (SpvImageOperandsSignExtendMask | SpvImageOperandsZeroExtendMask);
2594
vtn_fail_if(nir_alu_type_get_base_type(type) == nir_type_float && extend_operands,
2595
"SignExtend/ZeroExtend used on floating-point texel type");
2596
vtn_fail_if(extend_operands ==
2597
(SpvImageOperandsSignExtendMask | SpvImageOperandsZeroExtendMask),
2598
"SignExtend and ZeroExtend both specified");
2599
2600
if (operands & SpvImageOperandsSignExtendMask)
2601
return nir_type_int | nir_alu_type_get_type_size(type);
2602
if (operands & SpvImageOperandsZeroExtendMask)
2603
return nir_type_uint | nir_alu_type_get_type_size(type);
2604
2605
return type;
2606
}
2607
2608
static void
2609
vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
2610
const uint32_t *w, unsigned count)
2611
{
2612
if (opcode == SpvOpSampledImage) {
2613
struct vtn_sampled_image si = {
2614
.image = vtn_get_image(b, w[3], NULL),
2615
.sampler = vtn_get_sampler(b, w[4]),
2616
};
2617
2618
enum gl_access_qualifier access = 0;
2619
vtn_foreach_decoration(b, vtn_untyped_value(b, w[3]),
2620
non_uniform_decoration_cb, &access);
2621
vtn_foreach_decoration(b, vtn_untyped_value(b, w[4]),
2622
non_uniform_decoration_cb, &access);
2623
2624
vtn_push_sampled_image(b, w[2], si, access & ACCESS_NON_UNIFORM);
2625
return;
2626
} else if (opcode == SpvOpImage) {
2627
struct vtn_sampled_image si = vtn_get_sampled_image(b, w[3]);
2628
2629
enum gl_access_qualifier access = 0;
2630
vtn_foreach_decoration(b, vtn_untyped_value(b, w[3]),
2631
non_uniform_decoration_cb, &access);
2632
2633
vtn_push_image(b, w[2], si.image, access & ACCESS_NON_UNIFORM);
2634
return;
2635
} else if (opcode == SpvOpImageSparseTexelsResident) {
2636
nir_ssa_def *code = vtn_get_nir_ssa(b, w[3]);
2637
vtn_push_nir_ssa(b, w[2], nir_is_sparse_texels_resident(&b->nb, code));
2638
return;
2639
}
2640
2641
nir_deref_instr *image = NULL, *sampler = NULL;
2642
struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]);
2643
if (sampled_val->type->base_type == vtn_base_type_sampled_image) {
2644
struct vtn_sampled_image si = vtn_get_sampled_image(b, w[3]);
2645
image = si.image;
2646
sampler = si.sampler;
2647
} else {
2648
image = vtn_get_image(b, w[3], NULL);
2649
}
2650
2651
const enum glsl_sampler_dim sampler_dim = glsl_get_sampler_dim(image->type);
2652
const bool is_array = glsl_sampler_type_is_array(image->type);
2653
nir_alu_type dest_type = nir_type_invalid;
2654
2655
/* Figure out the base texture operation */
2656
nir_texop texop;
2657
switch (opcode) {
2658
case SpvOpImageSampleImplicitLod:
2659
case SpvOpImageSparseSampleImplicitLod:
2660
case SpvOpImageSampleDrefImplicitLod:
2661
case SpvOpImageSparseSampleDrefImplicitLod:
2662
case SpvOpImageSampleProjImplicitLod:
2663
case SpvOpImageSampleProjDrefImplicitLod:
2664
texop = nir_texop_tex;
2665
break;
2666
2667
case SpvOpImageSampleExplicitLod:
2668
case SpvOpImageSparseSampleExplicitLod:
2669
case SpvOpImageSampleDrefExplicitLod:
2670
case SpvOpImageSparseSampleDrefExplicitLod:
2671
case SpvOpImageSampleProjExplicitLod:
2672
case SpvOpImageSampleProjDrefExplicitLod:
2673
texop = nir_texop_txl;
2674
break;
2675
2676
case SpvOpImageFetch:
2677
case SpvOpImageSparseFetch:
2678
if (sampler_dim == GLSL_SAMPLER_DIM_MS) {
2679
texop = nir_texop_txf_ms;
2680
} else {
2681
texop = nir_texop_txf;
2682
}
2683
break;
2684
2685
case SpvOpImageGather:
2686
case SpvOpImageSparseGather:
2687
case SpvOpImageDrefGather:
2688
case SpvOpImageSparseDrefGather:
2689
texop = nir_texop_tg4;
2690
break;
2691
2692
case SpvOpImageQuerySizeLod:
2693
case SpvOpImageQuerySize:
2694
texop = nir_texop_txs;
2695
dest_type = nir_type_int32;
2696
break;
2697
2698
case SpvOpImageQueryLod:
2699
texop = nir_texop_lod;
2700
dest_type = nir_type_float32;
2701
break;
2702
2703
case SpvOpImageQueryLevels:
2704
texop = nir_texop_query_levels;
2705
dest_type = nir_type_int32;
2706
break;
2707
2708
case SpvOpImageQuerySamples:
2709
texop = nir_texop_texture_samples;
2710
dest_type = nir_type_int32;
2711
break;
2712
2713
case SpvOpFragmentFetchAMD:
2714
texop = nir_texop_fragment_fetch;
2715
break;
2716
2717
case SpvOpFragmentMaskFetchAMD:
2718
texop = nir_texop_fragment_mask_fetch;
2719
dest_type = nir_type_uint32;
2720
break;
2721
2722
default:
2723
vtn_fail_with_opcode("Unhandled opcode", opcode);
2724
}
2725
2726
nir_tex_src srcs[10]; /* 10 should be enough */
2727
nir_tex_src *p = srcs;
2728
2729
p->src = nir_src_for_ssa(&image->dest.ssa);
2730
p->src_type = nir_tex_src_texture_deref;
2731
p++;
2732
2733
switch (texop) {
2734
case nir_texop_tex:
2735
case nir_texop_txb:
2736
case nir_texop_txl:
2737
case nir_texop_txd:
2738
case nir_texop_tg4:
2739
case nir_texop_lod:
2740
vtn_fail_if(sampler == NULL,
2741
"%s requires an image of type OpTypeSampledImage",
2742
spirv_op_to_string(opcode));
2743
p->src = nir_src_for_ssa(&sampler->dest.ssa);
2744
p->src_type = nir_tex_src_sampler_deref;
2745
p++;
2746
break;
2747
case nir_texop_txf:
2748
case nir_texop_txf_ms:
2749
case nir_texop_txs:
2750
case nir_texop_query_levels:
2751
case nir_texop_texture_samples:
2752
case nir_texop_samples_identical:
2753
case nir_texop_fragment_fetch:
2754
case nir_texop_fragment_mask_fetch:
2755
/* These don't */
2756
break;
2757
case nir_texop_txf_ms_fb:
2758
vtn_fail("unexpected nir_texop_txf_ms_fb");
2759
break;
2760
case nir_texop_txf_ms_mcs:
2761
vtn_fail("unexpected nir_texop_txf_ms_mcs");
2762
case nir_texop_tex_prefetch:
2763
vtn_fail("unexpected nir_texop_tex_prefetch");
2764
}
2765
2766
unsigned idx = 4;
2767
2768
struct nir_ssa_def *coord;
2769
unsigned coord_components;
2770
switch (opcode) {
2771
case SpvOpImageSampleImplicitLod:
2772
case SpvOpImageSparseSampleImplicitLod:
2773
case SpvOpImageSampleExplicitLod:
2774
case SpvOpImageSparseSampleExplicitLod:
2775
case SpvOpImageSampleDrefImplicitLod:
2776
case SpvOpImageSparseSampleDrefImplicitLod:
2777
case SpvOpImageSampleDrefExplicitLod:
2778
case SpvOpImageSparseSampleDrefExplicitLod:
2779
case SpvOpImageSampleProjImplicitLod:
2780
case SpvOpImageSampleProjExplicitLod:
2781
case SpvOpImageSampleProjDrefImplicitLod:
2782
case SpvOpImageSampleProjDrefExplicitLod:
2783
case SpvOpImageFetch:
2784
case SpvOpImageSparseFetch:
2785
case SpvOpImageGather:
2786
case SpvOpImageSparseGather:
2787
case SpvOpImageDrefGather:
2788
case SpvOpImageSparseDrefGather:
2789
case SpvOpImageQueryLod:
2790
case SpvOpFragmentFetchAMD:
2791
case SpvOpFragmentMaskFetchAMD: {
2792
/* All these types have the coordinate as their first real argument */
2793
coord_components = glsl_get_sampler_dim_coordinate_components(sampler_dim);
2794
2795
if (is_array && texop != nir_texop_lod)
2796
coord_components++;
2797
2798
struct vtn_ssa_value *coord_val = vtn_ssa_value(b, w[idx++]);
2799
coord = coord_val->def;
2800
p->src = nir_src_for_ssa(nir_channels(&b->nb, coord,
2801
(1 << coord_components) - 1));
2802
2803
/* OpenCL allows integer sampling coordinates */
2804
if (glsl_type_is_integer(coord_val->type) &&
2805
opcode == SpvOpImageSampleExplicitLod) {
2806
vtn_fail_if(b->shader->info.stage != MESA_SHADER_KERNEL,
2807
"Unless the Kernel capability is being used, the coordinate parameter "
2808
"OpImageSampleExplicitLod must be floating point.");
2809
2810
p->src = nir_src_for_ssa(
2811
nir_fadd(&b->nb, nir_i2f32(&b->nb, p->src.ssa),
2812
nir_imm_float(&b->nb, 0.5)));
2813
}
2814
2815
p->src_type = nir_tex_src_coord;
2816
p++;
2817
break;
2818
}
2819
2820
default:
2821
coord = NULL;
2822
coord_components = 0;
2823
break;
2824
}
2825
2826
switch (opcode) {
2827
case SpvOpImageSampleProjImplicitLod:
2828
case SpvOpImageSampleProjExplicitLod:
2829
case SpvOpImageSampleProjDrefImplicitLod:
2830
case SpvOpImageSampleProjDrefExplicitLod:
2831
/* These have the projector as the last coordinate component */
2832
p->src = nir_src_for_ssa(nir_channel(&b->nb, coord, coord_components));
2833
p->src_type = nir_tex_src_projector;
2834
p++;
2835
break;
2836
2837
default:
2838
break;
2839
}
2840
2841
bool is_shadow = false;
2842
unsigned gather_component = 0;
2843
switch (opcode) {
2844
case SpvOpImageSampleDrefImplicitLod:
2845
case SpvOpImageSparseSampleDrefImplicitLod:
2846
case SpvOpImageSampleDrefExplicitLod:
2847
case SpvOpImageSparseSampleDrefExplicitLod:
2848
case SpvOpImageSampleProjDrefImplicitLod:
2849
case SpvOpImageSampleProjDrefExplicitLod:
2850
case SpvOpImageDrefGather:
2851
case SpvOpImageSparseDrefGather:
2852
/* These all have an explicit depth value as their next source */
2853
is_shadow = true;
2854
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_comparator);
2855
break;
2856
2857
case SpvOpImageGather:
2858
case SpvOpImageSparseGather:
2859
/* This has a component as its next source */
2860
gather_component = vtn_constant_uint(b, w[idx++]);
2861
break;
2862
2863
default:
2864
break;
2865
}
2866
2867
bool is_sparse = false;
2868
switch (opcode) {
2869
case SpvOpImageSparseSampleImplicitLod:
2870
case SpvOpImageSparseSampleExplicitLod:
2871
case SpvOpImageSparseSampleDrefImplicitLod:
2872
case SpvOpImageSparseSampleDrefExplicitLod:
2873
case SpvOpImageSparseFetch:
2874
case SpvOpImageSparseGather:
2875
case SpvOpImageSparseDrefGather:
2876
is_sparse = true;
2877
break;
2878
default:
2879
break;
2880
}
2881
2882
/* For OpImageQuerySizeLod, we always have an LOD */
2883
if (opcode == SpvOpImageQuerySizeLod)
2884
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
2885
2886
/* For OpFragmentFetchAMD, we always have a multisample index */
2887
if (opcode == SpvOpFragmentFetchAMD)
2888
(*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
2889
2890
/* Now we need to handle some number of optional arguments */
2891
struct vtn_value *gather_offsets = NULL;
2892
uint32_t operands = SpvImageOperandsMaskNone;
2893
if (idx < count) {
2894
operands = w[idx];
2895
2896
if (operands & SpvImageOperandsBiasMask) {
2897
vtn_assert(texop == nir_texop_tex ||
2898
texop == nir_texop_tg4);
2899
if (texop == nir_texop_tex)
2900
texop = nir_texop_txb;
2901
uint32_t arg = image_operand_arg(b, w, count, idx,
2902
SpvImageOperandsBiasMask);
2903
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_bias);
2904
}
2905
2906
if (operands & SpvImageOperandsLodMask) {
2907
vtn_assert(texop == nir_texop_txl || texop == nir_texop_txf ||
2908
texop == nir_texop_txs || texop == nir_texop_tg4);
2909
uint32_t arg = image_operand_arg(b, w, count, idx,
2910
SpvImageOperandsLodMask);
2911
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_lod);
2912
}
2913
2914
if (operands & SpvImageOperandsGradMask) {
2915
vtn_assert(texop == nir_texop_txl);
2916
texop = nir_texop_txd;
2917
uint32_t arg = image_operand_arg(b, w, count, idx,
2918
SpvImageOperandsGradMask);
2919
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_ddx);
2920
(*p++) = vtn_tex_src(b, w[arg + 1], nir_tex_src_ddy);
2921
}
2922
2923
vtn_fail_if(util_bitcount(operands & (SpvImageOperandsConstOffsetsMask |
2924
SpvImageOperandsOffsetMask |
2925
SpvImageOperandsConstOffsetMask)) > 1,
2926
"At most one of the ConstOffset, Offset, and ConstOffsets "
2927
"image operands can be used on a given instruction.");
2928
2929
if (operands & SpvImageOperandsOffsetMask) {
2930
uint32_t arg = image_operand_arg(b, w, count, idx,
2931
SpvImageOperandsOffsetMask);
2932
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_offset);
2933
}
2934
2935
if (operands & SpvImageOperandsConstOffsetMask) {
2936
uint32_t arg = image_operand_arg(b, w, count, idx,
2937
SpvImageOperandsConstOffsetMask);
2938
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_offset);
2939
}
2940
2941
if (operands & SpvImageOperandsConstOffsetsMask) {
2942
vtn_assert(texop == nir_texop_tg4);
2943
uint32_t arg = image_operand_arg(b, w, count, idx,
2944
SpvImageOperandsConstOffsetsMask);
2945
gather_offsets = vtn_value(b, w[arg], vtn_value_type_constant);
2946
}
2947
2948
if (operands & SpvImageOperandsSampleMask) {
2949
vtn_assert(texop == nir_texop_txf_ms);
2950
uint32_t arg = image_operand_arg(b, w, count, idx,
2951
SpvImageOperandsSampleMask);
2952
texop = nir_texop_txf_ms;
2953
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_ms_index);
2954
}
2955
2956
if (operands & SpvImageOperandsMinLodMask) {
2957
vtn_assert(texop == nir_texop_tex ||
2958
texop == nir_texop_txb ||
2959
texop == nir_texop_txd);
2960
uint32_t arg = image_operand_arg(b, w, count, idx,
2961
SpvImageOperandsMinLodMask);
2962
(*p++) = vtn_tex_src(b, w[arg], nir_tex_src_min_lod);
2963
}
2964
}
2965
2966
struct vtn_type *ret_type = vtn_get_type(b, w[1]);
2967
struct vtn_type *struct_type = NULL;
2968
if (is_sparse) {
2969
vtn_assert(glsl_type_is_struct_or_ifc(ret_type->type));
2970
struct_type = ret_type;
2971
ret_type = struct_type->members[1];
2972
}
2973
2974
nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
2975
instr->op = texop;
2976
2977
memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
2978
2979
instr->coord_components = coord_components;
2980
instr->sampler_dim = sampler_dim;
2981
instr->is_array = is_array;
2982
instr->is_shadow = is_shadow;
2983
instr->is_sparse = is_sparse;
2984
instr->is_new_style_shadow =
2985
is_shadow && glsl_get_components(ret_type->type) == 1;
2986
instr->component = gather_component;
2987
2988
/* The Vulkan spec says:
2989
*
2990
* "If an instruction loads from or stores to a resource (including
2991
* atomics and image instructions) and the resource descriptor being
2992
* accessed is not dynamically uniform, then the operand corresponding
2993
* to that resource (e.g. the pointer or sampled image operand) must be
2994
* decorated with NonUniform."
2995
*
2996
* It's very careful to specify that the exact operand must be decorated
2997
* NonUniform. The SPIR-V parser is not expected to chase through long
2998
* chains to find the NonUniform decoration. It's either right there or we
2999
* can assume it doesn't exist.
3000
*/
3001
enum gl_access_qualifier access = 0;
3002
vtn_foreach_decoration(b, sampled_val, non_uniform_decoration_cb, &access);
3003
3004
if (sampled_val->propagated_non_uniform)
3005
access |= ACCESS_NON_UNIFORM;
3006
3007
if (image && (access & ACCESS_NON_UNIFORM))
3008
instr->texture_non_uniform = true;
3009
3010
if (sampler && (access & ACCESS_NON_UNIFORM))
3011
instr->sampler_non_uniform = true;
3012
3013
/* for non-query ops, get dest_type from SPIR-V return type */
3014
if (dest_type == nir_type_invalid) {
3015
/* the return type should match the image type, unless the image type is
3016
* VOID (CL image), in which case the return type dictates the sampler
3017
*/
3018
enum glsl_base_type sampler_base =
3019
glsl_get_sampler_result_type(image->type);
3020
enum glsl_base_type ret_base = glsl_get_base_type(ret_type->type);
3021
vtn_fail_if(sampler_base != ret_base && sampler_base != GLSL_TYPE_VOID,
3022
"SPIR-V return type mismatches image type. This is only valid "
3023
"for untyped images (OpenCL).");
3024
dest_type = nir_get_nir_type_for_glsl_base_type(ret_base);
3025
dest_type = get_image_type(b, dest_type, operands);
3026
}
3027
3028
instr->dest_type = dest_type;
3029
3030
nir_ssa_dest_init(&instr->instr, &instr->dest,
3031
nir_tex_instr_dest_size(instr), 32, NULL);
3032
3033
vtn_assert(glsl_get_vector_elements(ret_type->type) ==
3034
nir_tex_instr_result_size(instr));
3035
3036
if (gather_offsets) {
3037
vtn_fail_if(gather_offsets->type->base_type != vtn_base_type_array ||
3038
gather_offsets->type->length != 4,
3039
"ConstOffsets must be an array of size four of vectors "
3040
"of two integer components");
3041
3042
struct vtn_type *vec_type = gather_offsets->type->array_element;
3043
vtn_fail_if(vec_type->base_type != vtn_base_type_vector ||
3044
vec_type->length != 2 ||
3045
!glsl_type_is_integer(vec_type->type),
3046
"ConstOffsets must be an array of size four of vectors "
3047
"of two integer components");
3048
3049
unsigned bit_size = glsl_get_bit_size(vec_type->type);
3050
for (uint32_t i = 0; i < 4; i++) {
3051
const nir_const_value *cvec =
3052
gather_offsets->constant->elements[i]->values;
3053
for (uint32_t j = 0; j < 2; j++) {
3054
switch (bit_size) {
3055
case 8: instr->tg4_offsets[i][j] = cvec[j].i8; break;
3056
case 16: instr->tg4_offsets[i][j] = cvec[j].i16; break;
3057
case 32: instr->tg4_offsets[i][j] = cvec[j].i32; break;
3058
case 64: instr->tg4_offsets[i][j] = cvec[j].i64; break;
3059
default:
3060
vtn_fail("Unsupported bit size: %u", bit_size);
3061
}
3062
}
3063
}
3064
}
3065
3066
nir_builder_instr_insert(&b->nb, &instr->instr);
3067
3068
if (is_sparse) {
3069
struct vtn_ssa_value *dest = vtn_create_ssa_value(b, struct_type->type);
3070
unsigned result_size = glsl_get_vector_elements(ret_type->type);
3071
dest->elems[0]->def = nir_channel(&b->nb, &instr->dest.ssa, result_size);
3072
dest->elems[1]->def = nir_channels(&b->nb, &instr->dest.ssa,
3073
BITFIELD_MASK(result_size));
3074
vtn_push_ssa_value(b, w[2], dest);
3075
} else {
3076
vtn_push_nir_ssa(b, w[2], &instr->dest.ssa);
3077
}
3078
}
3079
3080
static void
3081
fill_common_atomic_sources(struct vtn_builder *b, SpvOp opcode,
3082
const uint32_t *w, nir_src *src)
3083
{
3084
const struct glsl_type *type = vtn_get_type(b, w[1])->type;
3085
unsigned bit_size = glsl_get_bit_size(type);
3086
3087
switch (opcode) {
3088
case SpvOpAtomicIIncrement:
3089
src[0] = nir_src_for_ssa(nir_imm_intN_t(&b->nb, 1, bit_size));
3090
break;
3091
3092
case SpvOpAtomicIDecrement:
3093
src[0] = nir_src_for_ssa(nir_imm_intN_t(&b->nb, -1, bit_size));
3094
break;
3095
3096
case SpvOpAtomicISub:
3097
src[0] =
3098
nir_src_for_ssa(nir_ineg(&b->nb, vtn_get_nir_ssa(b, w[6])));
3099
break;
3100
3101
case SpvOpAtomicCompareExchange:
3102
case SpvOpAtomicCompareExchangeWeak:
3103
src[0] = nir_src_for_ssa(vtn_get_nir_ssa(b, w[8]));
3104
src[1] = nir_src_for_ssa(vtn_get_nir_ssa(b, w[7]));
3105
break;
3106
3107
case SpvOpAtomicExchange:
3108
case SpvOpAtomicIAdd:
3109
case SpvOpAtomicSMin:
3110
case SpvOpAtomicUMin:
3111
case SpvOpAtomicSMax:
3112
case SpvOpAtomicUMax:
3113
case SpvOpAtomicAnd:
3114
case SpvOpAtomicOr:
3115
case SpvOpAtomicXor:
3116
case SpvOpAtomicFAddEXT:
3117
case SpvOpAtomicFMinEXT:
3118
case SpvOpAtomicFMaxEXT:
3119
src[0] = nir_src_for_ssa(vtn_get_nir_ssa(b, w[6]));
3120
break;
3121
3122
default:
3123
vtn_fail_with_opcode("Invalid SPIR-V atomic", opcode);
3124
}
3125
}
3126
3127
static nir_ssa_def *
3128
get_image_coord(struct vtn_builder *b, uint32_t value)
3129
{
3130
nir_ssa_def *coord = vtn_get_nir_ssa(b, value);
3131
/* The image_load_store intrinsics assume a 4-dim coordinate */
3132
return nir_pad_vec4(&b->nb, coord);
3133
}
3134
3135
static void
3136
vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
3137
const uint32_t *w, unsigned count)
3138
{
3139
/* Just get this one out of the way */
3140
if (opcode == SpvOpImageTexelPointer) {
3141
struct vtn_value *val =
3142
vtn_push_value(b, w[2], vtn_value_type_image_pointer);
3143
val->image = ralloc(b, struct vtn_image_pointer);
3144
3145
val->image->image = vtn_nir_deref(b, w[3]);
3146
val->image->coord = get_image_coord(b, w[4]);
3147
val->image->sample = vtn_get_nir_ssa(b, w[5]);
3148
val->image->lod = nir_imm_int(&b->nb, 0);
3149
return;
3150
}
3151
3152
struct vtn_image_pointer image;
3153
SpvScope scope = SpvScopeInvocation;
3154
SpvMemorySemanticsMask semantics = 0;
3155
SpvImageOperandsMask operands = SpvImageOperandsMaskNone;
3156
3157
enum gl_access_qualifier access = 0;
3158
3159
struct vtn_value *res_val;
3160
switch (opcode) {
3161
case SpvOpAtomicExchange:
3162
case SpvOpAtomicCompareExchange:
3163
case SpvOpAtomicCompareExchangeWeak:
3164
case SpvOpAtomicIIncrement:
3165
case SpvOpAtomicIDecrement:
3166
case SpvOpAtomicIAdd:
3167
case SpvOpAtomicISub:
3168
case SpvOpAtomicLoad:
3169
case SpvOpAtomicSMin:
3170
case SpvOpAtomicUMin:
3171
case SpvOpAtomicSMax:
3172
case SpvOpAtomicUMax:
3173
case SpvOpAtomicAnd:
3174
case SpvOpAtomicOr:
3175
case SpvOpAtomicXor:
3176
case SpvOpAtomicFAddEXT:
3177
case SpvOpAtomicFMinEXT:
3178
case SpvOpAtomicFMaxEXT:
3179
res_val = vtn_value(b, w[3], vtn_value_type_image_pointer);
3180
image = *res_val->image;
3181
scope = vtn_constant_uint(b, w[4]);
3182
semantics = vtn_constant_uint(b, w[5]);
3183
access |= ACCESS_COHERENT;
3184
break;
3185
3186
case SpvOpAtomicStore:
3187
res_val = vtn_value(b, w[1], vtn_value_type_image_pointer);
3188
image = *res_val->image;
3189
scope = vtn_constant_uint(b, w[2]);
3190
semantics = vtn_constant_uint(b, w[3]);
3191
access |= ACCESS_COHERENT;
3192
break;
3193
3194
case SpvOpImageQuerySizeLod:
3195
res_val = vtn_untyped_value(b, w[3]);
3196
image.image = vtn_get_image(b, w[3], &access);
3197
image.coord = NULL;
3198
image.sample = NULL;
3199
image.lod = vtn_ssa_value(b, w[4])->def;
3200
break;
3201
3202
case SpvOpImageQuerySize:
3203
case SpvOpImageQuerySamples:
3204
res_val = vtn_untyped_value(b, w[3]);
3205
image.image = vtn_get_image(b, w[3], &access);
3206
image.coord = NULL;
3207
image.sample = NULL;
3208
image.lod = NULL;
3209
break;
3210
3211
case SpvOpImageQueryFormat:
3212
case SpvOpImageQueryOrder:
3213
res_val = vtn_untyped_value(b, w[3]);
3214
image.image = vtn_get_image(b, w[3], &access);
3215
image.coord = NULL;
3216
image.sample = NULL;
3217
image.lod = NULL;
3218
break;
3219
3220
case SpvOpImageRead:
3221
case SpvOpImageSparseRead: {
3222
res_val = vtn_untyped_value(b, w[3]);
3223
image.image = vtn_get_image(b, w[3], &access);
3224
image.coord = get_image_coord(b, w[4]);
3225
3226
operands = count > 5 ? w[5] : SpvImageOperandsMaskNone;
3227
3228
if (operands & SpvImageOperandsSampleMask) {
3229
uint32_t arg = image_operand_arg(b, w, count, 5,
3230
SpvImageOperandsSampleMask);
3231
image.sample = vtn_get_nir_ssa(b, w[arg]);
3232
} else {
3233
image.sample = nir_ssa_undef(&b->nb, 1, 32);
3234
}
3235
3236
if (operands & SpvImageOperandsMakeTexelVisibleMask) {
3237
vtn_fail_if((operands & SpvImageOperandsNonPrivateTexelMask) == 0,
3238
"MakeTexelVisible requires NonPrivateTexel to also be set.");
3239
uint32_t arg = image_operand_arg(b, w, count, 5,
3240
SpvImageOperandsMakeTexelVisibleMask);
3241
semantics = SpvMemorySemanticsMakeVisibleMask;
3242
scope = vtn_constant_uint(b, w[arg]);
3243
}
3244
3245
if (operands & SpvImageOperandsLodMask) {
3246
uint32_t arg = image_operand_arg(b, w, count, 5,
3247
SpvImageOperandsLodMask);
3248
image.lod = vtn_get_nir_ssa(b, w[arg]);
3249
} else {
3250
image.lod = nir_imm_int(&b->nb, 0);
3251
}
3252
3253
if (operands & SpvImageOperandsVolatileTexelMask)
3254
access |= ACCESS_VOLATILE;
3255
3256
break;
3257
}
3258
3259
case SpvOpImageWrite: {
3260
res_val = vtn_untyped_value(b, w[1]);
3261
image.image = vtn_get_image(b, w[1], &access);
3262
image.coord = get_image_coord(b, w[2]);
3263
3264
/* texel = w[3] */
3265
3266
operands = count > 4 ? w[4] : SpvImageOperandsMaskNone;
3267
3268
if (operands & SpvImageOperandsSampleMask) {
3269
uint32_t arg = image_operand_arg(b, w, count, 4,
3270
SpvImageOperandsSampleMask);
3271
image.sample = vtn_get_nir_ssa(b, w[arg]);
3272
} else {
3273
image.sample = nir_ssa_undef(&b->nb, 1, 32);
3274
}
3275
3276
if (operands & SpvImageOperandsMakeTexelAvailableMask) {
3277
vtn_fail_if((operands & SpvImageOperandsNonPrivateTexelMask) == 0,
3278
"MakeTexelAvailable requires NonPrivateTexel to also be set.");
3279
uint32_t arg = image_operand_arg(b, w, count, 4,
3280
SpvImageOperandsMakeTexelAvailableMask);
3281
semantics = SpvMemorySemanticsMakeAvailableMask;
3282
scope = vtn_constant_uint(b, w[arg]);
3283
}
3284
3285
if (operands & SpvImageOperandsLodMask) {
3286
uint32_t arg = image_operand_arg(b, w, count, 4,
3287
SpvImageOperandsLodMask);
3288
image.lod = vtn_get_nir_ssa(b, w[arg]);
3289
} else {
3290
image.lod = nir_imm_int(&b->nb, 0);
3291
}
3292
3293
if (operands & SpvImageOperandsVolatileTexelMask)
3294
access |= ACCESS_VOLATILE;
3295
3296
break;
3297
}
3298
3299
default:
3300
vtn_fail_with_opcode("Invalid image opcode", opcode);
3301
}
3302
3303
if (semantics & SpvMemorySemanticsVolatileMask)
3304
access |= ACCESS_VOLATILE;
3305
3306
nir_intrinsic_op op;
3307
switch (opcode) {
3308
#define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_deref_##N; break;
3309
OP(ImageQuerySize, size)
3310
OP(ImageQuerySizeLod, size)
3311
OP(ImageRead, load)
3312
OP(ImageSparseRead, sparse_load)
3313
OP(ImageWrite, store)
3314
OP(AtomicLoad, load)
3315
OP(AtomicStore, store)
3316
OP(AtomicExchange, atomic_exchange)
3317
OP(AtomicCompareExchange, atomic_comp_swap)
3318
OP(AtomicCompareExchangeWeak, atomic_comp_swap)
3319
OP(AtomicIIncrement, atomic_add)
3320
OP(AtomicIDecrement, atomic_add)
3321
OP(AtomicIAdd, atomic_add)
3322
OP(AtomicISub, atomic_add)
3323
OP(AtomicSMin, atomic_imin)
3324
OP(AtomicUMin, atomic_umin)
3325
OP(AtomicSMax, atomic_imax)
3326
OP(AtomicUMax, atomic_umax)
3327
OP(AtomicAnd, atomic_and)
3328
OP(AtomicOr, atomic_or)
3329
OP(AtomicXor, atomic_xor)
3330
OP(AtomicFAddEXT, atomic_fadd)
3331
OP(AtomicFMinEXT, atomic_fmin)
3332
OP(AtomicFMaxEXT, atomic_fmax)
3333
OP(ImageQueryFormat, format)
3334
OP(ImageQueryOrder, order)
3335
OP(ImageQuerySamples, samples)
3336
#undef OP
3337
default:
3338
vtn_fail_with_opcode("Invalid image opcode", opcode);
3339
}
3340
3341
nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
3342
3343
intrin->src[0] = nir_src_for_ssa(&image.image->dest.ssa);
3344
3345
switch (opcode) {
3346
case SpvOpImageQuerySamples:
3347
case SpvOpImageQuerySize:
3348
case SpvOpImageQuerySizeLod:
3349
case SpvOpImageQueryFormat:
3350
case SpvOpImageQueryOrder:
3351
break;
3352
default:
3353
/* The image coordinate is always 4 components but we may not have that
3354
* many. Swizzle to compensate.
3355
*/
3356
intrin->src[1] = nir_src_for_ssa(nir_pad_vec4(&b->nb, image.coord));
3357
intrin->src[2] = nir_src_for_ssa(image.sample);
3358
break;
3359
}
3360
3361
/* The Vulkan spec says:
3362
*
3363
* "If an instruction loads from or stores to a resource (including
3364
* atomics and image instructions) and the resource descriptor being
3365
* accessed is not dynamically uniform, then the operand corresponding
3366
* to that resource (e.g. the pointer or sampled image operand) must be
3367
* decorated with NonUniform."
3368
*
3369
* It's very careful to specify that the exact operand must be decorated
3370
* NonUniform. The SPIR-V parser is not expected to chase through long
3371
* chains to find the NonUniform decoration. It's either right there or we
3372
* can assume it doesn't exist.
3373
*/
3374
vtn_foreach_decoration(b, res_val, non_uniform_decoration_cb, &access);
3375
nir_intrinsic_set_access(intrin, access);
3376
3377
switch (opcode) {
3378
case SpvOpImageQuerySamples:
3379
case SpvOpImageQueryFormat:
3380
case SpvOpImageQueryOrder:
3381
/* No additional sources */
3382
break;
3383
case SpvOpImageQuerySize:
3384
intrin->src[1] = nir_src_for_ssa(nir_imm_int(&b->nb, 0));
3385
break;
3386
case SpvOpImageQuerySizeLod:
3387
intrin->src[1] = nir_src_for_ssa(image.lod);
3388
break;
3389
case SpvOpAtomicLoad:
3390
case SpvOpImageRead:
3391
case SpvOpImageSparseRead:
3392
/* Only OpImageRead can support a lod parameter if
3393
* SPV_AMD_shader_image_load_store_lod is used but the current NIR
3394
* intrinsics definition for atomics requires us to set it for
3395
* OpAtomicLoad.
3396
*/
3397
intrin->src[3] = nir_src_for_ssa(image.lod);
3398
break;
3399
case SpvOpAtomicStore:
3400
case SpvOpImageWrite: {
3401
const uint32_t value_id = opcode == SpvOpAtomicStore ? w[4] : w[3];
3402
struct vtn_ssa_value *value = vtn_ssa_value(b, value_id);
3403
/* nir_intrinsic_image_deref_store always takes a vec4 value */
3404
assert(op == nir_intrinsic_image_deref_store);
3405
intrin->num_components = 4;
3406
intrin->src[3] = nir_src_for_ssa(nir_pad_vec4(&b->nb, value->def));
3407
/* Only OpImageWrite can support a lod parameter if
3408
* SPV_AMD_shader_image_load_store_lod is used but the current NIR
3409
* intrinsics definition for atomics requires us to set it for
3410
* OpAtomicStore.
3411
*/
3412
intrin->src[4] = nir_src_for_ssa(image.lod);
3413
3414
if (opcode == SpvOpImageWrite) {
3415
nir_alu_type src_type =
3416
get_image_type(b, nir_get_nir_type_for_glsl_type(value->type), operands);
3417
nir_intrinsic_set_src_type(intrin, src_type);
3418
}
3419
break;
3420
}
3421
3422
case SpvOpAtomicCompareExchange:
3423
case SpvOpAtomicCompareExchangeWeak:
3424
case SpvOpAtomicIIncrement:
3425
case SpvOpAtomicIDecrement:
3426
case SpvOpAtomicExchange:
3427
case SpvOpAtomicIAdd:
3428
case SpvOpAtomicISub:
3429
case SpvOpAtomicSMin:
3430
case SpvOpAtomicUMin:
3431
case SpvOpAtomicSMax:
3432
case SpvOpAtomicUMax:
3433
case SpvOpAtomicAnd:
3434
case SpvOpAtomicOr:
3435
case SpvOpAtomicXor:
3436
case SpvOpAtomicFAddEXT:
3437
case SpvOpAtomicFMinEXT:
3438
case SpvOpAtomicFMaxEXT:
3439
fill_common_atomic_sources(b, opcode, w, &intrin->src[3]);
3440
break;
3441
3442
default:
3443
vtn_fail_with_opcode("Invalid image opcode", opcode);
3444
}
3445
3446
/* Image operations implicitly have the Image storage memory semantics. */
3447
semantics |= SpvMemorySemanticsImageMemoryMask;
3448
3449
SpvMemorySemanticsMask before_semantics;
3450
SpvMemorySemanticsMask after_semantics;
3451
vtn_split_barrier_semantics(b, semantics, &before_semantics, &after_semantics);
3452
3453
if (before_semantics)
3454
vtn_emit_memory_barrier(b, scope, before_semantics);
3455
3456
if (opcode != SpvOpImageWrite && opcode != SpvOpAtomicStore) {
3457
struct vtn_type *type = vtn_get_type(b, w[1]);
3458
struct vtn_type *struct_type = NULL;
3459
if (opcode == SpvOpImageSparseRead) {
3460
vtn_assert(glsl_type_is_struct_or_ifc(type->type));
3461
struct_type = type;
3462
type = struct_type->members[1];
3463
}
3464
3465
unsigned dest_components = glsl_get_vector_elements(type->type);
3466
if (opcode == SpvOpImageSparseRead)
3467
dest_components++;
3468
3469
if (nir_intrinsic_infos[op].dest_components == 0)
3470
intrin->num_components = dest_components;
3471
3472
nir_ssa_dest_init(&intrin->instr, &intrin->dest,
3473
nir_intrinsic_dest_components(intrin),
3474
glsl_get_bit_size(type->type), NULL);
3475
3476
nir_builder_instr_insert(&b->nb, &intrin->instr);
3477
3478
nir_ssa_def *result = &intrin->dest.ssa;
3479
if (nir_intrinsic_dest_components(intrin) != dest_components)
3480
result = nir_channels(&b->nb, result, (1 << dest_components) - 1);
3481
3482
if (opcode == SpvOpImageSparseRead) {
3483
struct vtn_ssa_value *dest = vtn_create_ssa_value(b, struct_type->type);
3484
unsigned res_type_size = glsl_get_vector_elements(type->type);
3485
dest->elems[0]->def = nir_channel(&b->nb, result, res_type_size);
3486
if (intrin->dest.ssa.bit_size != 32)
3487
dest->elems[0]->def = nir_u2u32(&b->nb, dest->elems[0]->def);
3488
dest->elems[1]->def = nir_channels(&b->nb, result,
3489
BITFIELD_MASK(res_type_size));
3490
vtn_push_ssa_value(b, w[2], dest);
3491
} else {
3492
vtn_push_nir_ssa(b, w[2], result);
3493
}
3494
3495
if (opcode == SpvOpImageRead || opcode == SpvOpImageSparseRead) {
3496
nir_alu_type dest_type =
3497
get_image_type(b, nir_get_nir_type_for_glsl_type(type->type), operands);
3498
nir_intrinsic_set_dest_type(intrin, dest_type);
3499
}
3500
} else {
3501
nir_builder_instr_insert(&b->nb, &intrin->instr);
3502
}
3503
3504
if (after_semantics)
3505
vtn_emit_memory_barrier(b, scope, after_semantics);
3506
}
3507
3508
static nir_intrinsic_op
3509
get_uniform_nir_atomic_op(struct vtn_builder *b, SpvOp opcode)
3510
{
3511
switch (opcode) {
3512
#define OP(S, N) case SpvOp##S: return nir_intrinsic_atomic_counter_ ##N;
3513
OP(AtomicLoad, read_deref)
3514
OP(AtomicExchange, exchange)
3515
OP(AtomicCompareExchange, comp_swap)
3516
OP(AtomicCompareExchangeWeak, comp_swap)
3517
OP(AtomicIIncrement, inc_deref)
3518
OP(AtomicIDecrement, post_dec_deref)
3519
OP(AtomicIAdd, add_deref)
3520
OP(AtomicISub, add_deref)
3521
OP(AtomicUMin, min_deref)
3522
OP(AtomicUMax, max_deref)
3523
OP(AtomicAnd, and_deref)
3524
OP(AtomicOr, or_deref)
3525
OP(AtomicXor, xor_deref)
3526
#undef OP
3527
default:
3528
/* We left the following out: AtomicStore, AtomicSMin and
3529
* AtomicSmax. Right now there are not nir intrinsics for them. At this
3530
* moment Atomic Counter support is needed for ARB_spirv support, so is
3531
* only need to support GLSL Atomic Counters that are uints and don't
3532
* allow direct storage.
3533
*/
3534
vtn_fail("Invalid uniform atomic");
3535
}
3536
}
3537
3538
static nir_intrinsic_op
3539
get_deref_nir_atomic_op(struct vtn_builder *b, SpvOp opcode)
3540
{
3541
switch (opcode) {
3542
case SpvOpAtomicLoad: return nir_intrinsic_load_deref;
3543
case SpvOpAtomicStore: return nir_intrinsic_store_deref;
3544
#define OP(S, N) case SpvOp##S: return nir_intrinsic_deref_##N;
3545
OP(AtomicExchange, atomic_exchange)
3546
OP(AtomicCompareExchange, atomic_comp_swap)
3547
OP(AtomicCompareExchangeWeak, atomic_comp_swap)
3548
OP(AtomicIIncrement, atomic_add)
3549
OP(AtomicIDecrement, atomic_add)
3550
OP(AtomicIAdd, atomic_add)
3551
OP(AtomicISub, atomic_add)
3552
OP(AtomicSMin, atomic_imin)
3553
OP(AtomicUMin, atomic_umin)
3554
OP(AtomicSMax, atomic_imax)
3555
OP(AtomicUMax, atomic_umax)
3556
OP(AtomicAnd, atomic_and)
3557
OP(AtomicOr, atomic_or)
3558
OP(AtomicXor, atomic_xor)
3559
OP(AtomicFAddEXT, atomic_fadd)
3560
OP(AtomicFMinEXT, atomic_fmin)
3561
OP(AtomicFMaxEXT, atomic_fmax)
3562
#undef OP
3563
default:
3564
vtn_fail_with_opcode("Invalid shared atomic", opcode);
3565
}
3566
}
3567
3568
/*
3569
* Handles shared atomics, ssbo atomics and atomic counters.
3570
*/
3571
static void
3572
vtn_handle_atomics(struct vtn_builder *b, SpvOp opcode,
3573
const uint32_t *w, UNUSED unsigned count)
3574
{
3575
struct vtn_pointer *ptr;
3576
nir_intrinsic_instr *atomic;
3577
3578
SpvScope scope = SpvScopeInvocation;
3579
SpvMemorySemanticsMask semantics = 0;
3580
enum gl_access_qualifier access = 0;
3581
3582
switch (opcode) {
3583
case SpvOpAtomicLoad:
3584
case SpvOpAtomicExchange:
3585
case SpvOpAtomicCompareExchange:
3586
case SpvOpAtomicCompareExchangeWeak:
3587
case SpvOpAtomicIIncrement:
3588
case SpvOpAtomicIDecrement:
3589
case SpvOpAtomicIAdd:
3590
case SpvOpAtomicISub:
3591
case SpvOpAtomicSMin:
3592
case SpvOpAtomicUMin:
3593
case SpvOpAtomicSMax:
3594
case SpvOpAtomicUMax:
3595
case SpvOpAtomicAnd:
3596
case SpvOpAtomicOr:
3597
case SpvOpAtomicXor:
3598
case SpvOpAtomicFAddEXT:
3599
case SpvOpAtomicFMinEXT:
3600
case SpvOpAtomicFMaxEXT:
3601
ptr = vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
3602
scope = vtn_constant_uint(b, w[4]);
3603
semantics = vtn_constant_uint(b, w[5]);
3604
break;
3605
3606
case SpvOpAtomicStore:
3607
ptr = vtn_value(b, w[1], vtn_value_type_pointer)->pointer;
3608
scope = vtn_constant_uint(b, w[2]);
3609
semantics = vtn_constant_uint(b, w[3]);
3610
break;
3611
3612
default:
3613
vtn_fail_with_opcode("Invalid SPIR-V atomic", opcode);
3614
}
3615
3616
if (semantics & SpvMemorySemanticsVolatileMask)
3617
access |= ACCESS_VOLATILE;
3618
3619
/* uniform as "atomic counter uniform" */
3620
if (ptr->mode == vtn_variable_mode_atomic_counter) {
3621
nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
3622
nir_intrinsic_op op = get_uniform_nir_atomic_op(b, opcode);
3623
atomic = nir_intrinsic_instr_create(b->nb.shader, op);
3624
atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa);
3625
3626
/* SSBO needs to initialize index/offset. In this case we don't need to,
3627
* as that info is already stored on the ptr->var->var nir_variable (see
3628
* vtn_create_variable)
3629
*/
3630
3631
switch (opcode) {
3632
case SpvOpAtomicLoad:
3633
case SpvOpAtomicExchange:
3634
case SpvOpAtomicCompareExchange:
3635
case SpvOpAtomicCompareExchangeWeak:
3636
case SpvOpAtomicIIncrement:
3637
case SpvOpAtomicIDecrement:
3638
case SpvOpAtomicIAdd:
3639
case SpvOpAtomicISub:
3640
case SpvOpAtomicSMin:
3641
case SpvOpAtomicUMin:
3642
case SpvOpAtomicSMax:
3643
case SpvOpAtomicUMax:
3644
case SpvOpAtomicAnd:
3645
case SpvOpAtomicOr:
3646
case SpvOpAtomicXor:
3647
/* Nothing: we don't need to call fill_common_atomic_sources here, as
3648
* atomic counter uniforms doesn't have sources
3649
*/
3650
break;
3651
3652
default:
3653
unreachable("Invalid SPIR-V atomic");
3654
3655
}
3656
} else {
3657
nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
3658
const struct glsl_type *deref_type = deref->type;
3659
nir_intrinsic_op op = get_deref_nir_atomic_op(b, opcode);
3660
atomic = nir_intrinsic_instr_create(b->nb.shader, op);
3661
atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa);
3662
3663
if (ptr->mode != vtn_variable_mode_workgroup)
3664
access |= ACCESS_COHERENT;
3665
3666
nir_intrinsic_set_access(atomic, access);
3667
3668
switch (opcode) {
3669
case SpvOpAtomicLoad:
3670
atomic->num_components = glsl_get_vector_elements(deref_type);
3671
break;
3672
3673
case SpvOpAtomicStore:
3674
atomic->num_components = glsl_get_vector_elements(deref_type);
3675
nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1);
3676
atomic->src[1] = nir_src_for_ssa(vtn_get_nir_ssa(b, w[4]));
3677
break;
3678
3679
case SpvOpAtomicExchange:
3680
case SpvOpAtomicCompareExchange:
3681
case SpvOpAtomicCompareExchangeWeak:
3682
case SpvOpAtomicIIncrement:
3683
case SpvOpAtomicIDecrement:
3684
case SpvOpAtomicIAdd:
3685
case SpvOpAtomicISub:
3686
case SpvOpAtomicSMin:
3687
case SpvOpAtomicUMin:
3688
case SpvOpAtomicSMax:
3689
case SpvOpAtomicUMax:
3690
case SpvOpAtomicAnd:
3691
case SpvOpAtomicOr:
3692
case SpvOpAtomicXor:
3693
case SpvOpAtomicFAddEXT:
3694
case SpvOpAtomicFMinEXT:
3695
case SpvOpAtomicFMaxEXT:
3696
fill_common_atomic_sources(b, opcode, w, &atomic->src[1]);
3697
break;
3698
3699
default:
3700
vtn_fail_with_opcode("Invalid SPIR-V atomic", opcode);
3701
}
3702
}
3703
3704
/* Atomic ordering operations will implicitly apply to the atomic operation
3705
* storage class, so include that too.
3706
*/
3707
semantics |= vtn_mode_to_memory_semantics(ptr->mode);
3708
3709
SpvMemorySemanticsMask before_semantics;
3710
SpvMemorySemanticsMask after_semantics;
3711
vtn_split_barrier_semantics(b, semantics, &before_semantics, &after_semantics);
3712
3713
if (before_semantics)
3714
vtn_emit_memory_barrier(b, scope, before_semantics);
3715
3716
if (opcode != SpvOpAtomicStore) {
3717
struct vtn_type *type = vtn_get_type(b, w[1]);
3718
3719
nir_ssa_dest_init(&atomic->instr, &atomic->dest,
3720
glsl_get_vector_elements(type->type),
3721
glsl_get_bit_size(type->type), NULL);
3722
3723
vtn_push_nir_ssa(b, w[2], &atomic->dest.ssa);
3724
}
3725
3726
nir_builder_instr_insert(&b->nb, &atomic->instr);
3727
3728
if (after_semantics)
3729
vtn_emit_memory_barrier(b, scope, after_semantics);
3730
}
3731
3732
static nir_alu_instr *
3733
create_vec(struct vtn_builder *b, unsigned num_components, unsigned bit_size)
3734
{
3735
nir_op op = nir_op_vec(num_components);
3736
nir_alu_instr *vec = nir_alu_instr_create(b->shader, op);
3737
nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components,
3738
bit_size, NULL);
3739
vec->dest.write_mask = (1 << num_components) - 1;
3740
3741
return vec;
3742
}
3743
3744
struct vtn_ssa_value *
3745
vtn_ssa_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
3746
{
3747
if (src->transposed)
3748
return src->transposed;
3749
3750
struct vtn_ssa_value *dest =
3751
vtn_create_ssa_value(b, glsl_transposed_type(src->type));
3752
3753
for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
3754
nir_alu_instr *vec = create_vec(b, glsl_get_matrix_columns(src->type),
3755
glsl_get_bit_size(src->type));
3756
if (glsl_type_is_vector_or_scalar(src->type)) {
3757
vec->src[0].src = nir_src_for_ssa(src->def);
3758
vec->src[0].swizzle[0] = i;
3759
} else {
3760
for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
3761
vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
3762
vec->src[j].swizzle[0] = i;
3763
}
3764
}
3765
nir_builder_instr_insert(&b->nb, &vec->instr);
3766
dest->elems[i]->def = &vec->dest.dest.ssa;
3767
}
3768
3769
dest->transposed = src;
3770
3771
return dest;
3772
}
3773
3774
static nir_ssa_def *
3775
vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
3776
nir_ssa_def *src0, nir_ssa_def *src1,
3777
const uint32_t *indices)
3778
{
3779
nir_alu_instr *vec = create_vec(b, num_components, src0->bit_size);
3780
3781
for (unsigned i = 0; i < num_components; i++) {
3782
uint32_t index = indices[i];
3783
if (index == 0xffffffff) {
3784
vec->src[i].src =
3785
nir_src_for_ssa(nir_ssa_undef(&b->nb, 1, src0->bit_size));
3786
} else if (index < src0->num_components) {
3787
vec->src[i].src = nir_src_for_ssa(src0);
3788
vec->src[i].swizzle[0] = index;
3789
} else {
3790
vec->src[i].src = nir_src_for_ssa(src1);
3791
vec->src[i].swizzle[0] = index - src0->num_components;
3792
}
3793
}
3794
3795
nir_builder_instr_insert(&b->nb, &vec->instr);
3796
3797
return &vec->dest.dest.ssa;
3798
}
3799
3800
/*
3801
* Concatentates a number of vectors/scalars together to produce a vector
3802
*/
3803
static nir_ssa_def *
3804
vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
3805
unsigned num_srcs, nir_ssa_def **srcs)
3806
{
3807
nir_alu_instr *vec = create_vec(b, num_components, srcs[0]->bit_size);
3808
3809
/* From the SPIR-V 1.1 spec for OpCompositeConstruct:
3810
*
3811
* "When constructing a vector, there must be at least two Constituent
3812
* operands."
3813
*/
3814
vtn_assert(num_srcs >= 2);
3815
3816
unsigned dest_idx = 0;
3817
for (unsigned i = 0; i < num_srcs; i++) {
3818
nir_ssa_def *src = srcs[i];
3819
vtn_assert(dest_idx + src->num_components <= num_components);
3820
for (unsigned j = 0; j < src->num_components; j++) {
3821
vec->src[dest_idx].src = nir_src_for_ssa(src);
3822
vec->src[dest_idx].swizzle[0] = j;
3823
dest_idx++;
3824
}
3825
}
3826
3827
/* From the SPIR-V 1.1 spec for OpCompositeConstruct:
3828
*
3829
* "When constructing a vector, the total number of components in all
3830
* the operands must equal the number of components in Result Type."
3831
*/
3832
vtn_assert(dest_idx == num_components);
3833
3834
nir_builder_instr_insert(&b->nb, &vec->instr);
3835
3836
return &vec->dest.dest.ssa;
3837
}
3838
3839
static struct vtn_ssa_value *
3840
vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
3841
{
3842
struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
3843
dest->type = src->type;
3844
3845
if (glsl_type_is_vector_or_scalar(src->type)) {
3846
dest->def = src->def;
3847
} else {
3848
unsigned elems = glsl_get_length(src->type);
3849
3850
dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
3851
for (unsigned i = 0; i < elems; i++)
3852
dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
3853
}
3854
3855
return dest;
3856
}
3857
3858
static struct vtn_ssa_value *
3859
vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
3860
struct vtn_ssa_value *insert, const uint32_t *indices,
3861
unsigned num_indices)
3862
{
3863
struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
3864
3865
struct vtn_ssa_value *cur = dest;
3866
unsigned i;
3867
for (i = 0; i < num_indices - 1; i++) {
3868
/* If we got a vector here, that means the next index will be trying to
3869
* dereference a scalar.
3870
*/
3871
vtn_fail_if(glsl_type_is_vector_or_scalar(cur->type),
3872
"OpCompositeInsert has too many indices.");
3873
vtn_fail_if(indices[i] >= glsl_get_length(cur->type),
3874
"All indices in an OpCompositeInsert must be in-bounds");
3875
cur = cur->elems[indices[i]];
3876
}
3877
3878
if (glsl_type_is_vector_or_scalar(cur->type)) {
3879
vtn_fail_if(indices[i] >= glsl_get_vector_elements(cur->type),
3880
"All indices in an OpCompositeInsert must be in-bounds");
3881
3882
/* According to the SPIR-V spec, OpCompositeInsert may work down to
3883
* the component granularity. In that case, the last index will be
3884
* the index to insert the scalar into the vector.
3885
*/
3886
3887
cur->def = nir_vector_insert_imm(&b->nb, cur->def, insert->def, indices[i]);
3888
} else {
3889
vtn_fail_if(indices[i] >= glsl_get_length(cur->type),
3890
"All indices in an OpCompositeInsert must be in-bounds");
3891
cur->elems[indices[i]] = insert;
3892
}
3893
3894
return dest;
3895
}
3896
3897
static struct vtn_ssa_value *
3898
vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
3899
const uint32_t *indices, unsigned num_indices)
3900
{
3901
struct vtn_ssa_value *cur = src;
3902
for (unsigned i = 0; i < num_indices; i++) {
3903
if (glsl_type_is_vector_or_scalar(cur->type)) {
3904
vtn_assert(i == num_indices - 1);
3905
vtn_fail_if(indices[i] >= glsl_get_vector_elements(cur->type),
3906
"All indices in an OpCompositeExtract must be in-bounds");
3907
3908
/* According to the SPIR-V spec, OpCompositeExtract may work down to
3909
* the component granularity. The last index will be the index of the
3910
* vector to extract.
3911
*/
3912
3913
const struct glsl_type *scalar_type =
3914
glsl_scalar_type(glsl_get_base_type(cur->type));
3915
struct vtn_ssa_value *ret = vtn_create_ssa_value(b, scalar_type);
3916
ret->def = nir_channel(&b->nb, cur->def, indices[i]);
3917
return ret;
3918
} else {
3919
vtn_fail_if(indices[i] >= glsl_get_length(cur->type),
3920
"All indices in an OpCompositeExtract must be in-bounds");
3921
cur = cur->elems[indices[i]];
3922
}
3923
}
3924
3925
return cur;
3926
}
3927
3928
static void
3929
vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
3930
const uint32_t *w, unsigned count)
3931
{
3932
struct vtn_type *type = vtn_get_type(b, w[1]);
3933
struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, type->type);
3934
3935
switch (opcode) {
3936
case SpvOpVectorExtractDynamic:
3937
ssa->def = nir_vector_extract(&b->nb, vtn_get_nir_ssa(b, w[3]),
3938
vtn_get_nir_ssa(b, w[4]));
3939
break;
3940
3941
case SpvOpVectorInsertDynamic:
3942
ssa->def = nir_vector_insert(&b->nb, vtn_get_nir_ssa(b, w[3]),
3943
vtn_get_nir_ssa(b, w[4]),
3944
vtn_get_nir_ssa(b, w[5]));
3945
break;
3946
3947
case SpvOpVectorShuffle:
3948
ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type->type),
3949
vtn_get_nir_ssa(b, w[3]),
3950
vtn_get_nir_ssa(b, w[4]),
3951
w + 5);
3952
break;
3953
3954
case SpvOpCompositeConstruct: {
3955
unsigned elems = count - 3;
3956
assume(elems >= 1);
3957
if (glsl_type_is_vector_or_scalar(type->type)) {
3958
nir_ssa_def *srcs[NIR_MAX_VEC_COMPONENTS];
3959
for (unsigned i = 0; i < elems; i++)
3960
srcs[i] = vtn_get_nir_ssa(b, w[3 + i]);
3961
ssa->def =
3962
vtn_vector_construct(b, glsl_get_vector_elements(type->type),
3963
elems, srcs);
3964
} else {
3965
ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
3966
for (unsigned i = 0; i < elems; i++)
3967
ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
3968
}
3969
break;
3970
}
3971
case SpvOpCompositeExtract:
3972
ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
3973
w + 4, count - 4);
3974
break;
3975
3976
case SpvOpCompositeInsert:
3977
ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
3978
vtn_ssa_value(b, w[3]),
3979
w + 5, count - 5);
3980
break;
3981
3982
case SpvOpCopyLogical:
3983
ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
3984
break;
3985
case SpvOpCopyObject:
3986
vtn_copy_value(b, w[3], w[2]);
3987
return;
3988
3989
default:
3990
vtn_fail_with_opcode("unknown composite operation", opcode);
3991
}
3992
3993
vtn_push_ssa_value(b, w[2], ssa);
3994
}
3995
3996
void
3997
vtn_emit_memory_barrier(struct vtn_builder *b, SpvScope scope,
3998
SpvMemorySemanticsMask semantics)
3999
{
4000
if (b->shader->options->use_scoped_barrier) {
4001
vtn_emit_scoped_memory_barrier(b, scope, semantics);
4002
return;
4003
}
4004
4005
static const SpvMemorySemanticsMask all_memory_semantics =
4006
SpvMemorySemanticsUniformMemoryMask |
4007
SpvMemorySemanticsWorkgroupMemoryMask |
4008
SpvMemorySemanticsAtomicCounterMemoryMask |
4009
SpvMemorySemanticsImageMemoryMask |
4010
SpvMemorySemanticsOutputMemoryMask;
4011
4012
/* If we're not actually doing a memory barrier, bail */
4013
if (!(semantics & all_memory_semantics))
4014
return;
4015
4016
/* GL and Vulkan don't have these */
4017
vtn_assert(scope != SpvScopeCrossDevice);
4018
4019
if (scope == SpvScopeSubgroup)
4020
return; /* Nothing to do here */
4021
4022
if (scope == SpvScopeWorkgroup) {
4023
nir_group_memory_barrier(&b->nb);
4024
return;
4025
}
4026
4027
/* There's only two scopes thing left */
4028
vtn_assert(scope == SpvScopeInvocation || scope == SpvScopeDevice);
4029
4030
/* Map the GLSL memoryBarrier() construct and any barriers with more than one
4031
* semantic to the corresponding NIR one.
4032
*/
4033
if (util_bitcount(semantics & all_memory_semantics) > 1) {
4034
nir_memory_barrier(&b->nb);
4035
if (semantics & SpvMemorySemanticsOutputMemoryMask) {
4036
/* GLSL memoryBarrier() (and the corresponding NIR one) doesn't include
4037
* TCS outputs, so we have to emit it's own intrinsic for that. We
4038
* then need to emit another memory_barrier to prevent moving
4039
* non-output operations to before the tcs_patch barrier.
4040
*/
4041
nir_memory_barrier_tcs_patch(&b->nb);
4042
nir_memory_barrier(&b->nb);
4043
}
4044
return;
4045
}
4046
4047
/* Issue a more specific barrier */
4048
switch (semantics & all_memory_semantics) {
4049
case SpvMemorySemanticsUniformMemoryMask:
4050
nir_memory_barrier_buffer(&b->nb);
4051
break;
4052
case SpvMemorySemanticsWorkgroupMemoryMask:
4053
nir_memory_barrier_shared(&b->nb);
4054
break;
4055
case SpvMemorySemanticsAtomicCounterMemoryMask:
4056
nir_memory_barrier_atomic_counter(&b->nb);
4057
break;
4058
case SpvMemorySemanticsImageMemoryMask:
4059
nir_memory_barrier_image(&b->nb);
4060
break;
4061
case SpvMemorySemanticsOutputMemoryMask:
4062
if (b->nb.shader->info.stage == MESA_SHADER_TESS_CTRL)
4063
nir_memory_barrier_tcs_patch(&b->nb);
4064
break;
4065
default:
4066
break;
4067
}
4068
}
4069
4070
static void
4071
vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
4072
const uint32_t *w, UNUSED unsigned count)
4073
{
4074
switch (opcode) {
4075
case SpvOpEmitVertex:
4076
case SpvOpEmitStreamVertex:
4077
case SpvOpEndPrimitive:
4078
case SpvOpEndStreamPrimitive: {
4079
unsigned stream = 0;
4080
if (opcode == SpvOpEmitStreamVertex || opcode == SpvOpEndStreamPrimitive)
4081
stream = vtn_constant_uint(b, w[1]);
4082
4083
switch (opcode) {
4084
case SpvOpEmitStreamVertex:
4085
case SpvOpEmitVertex:
4086
nir_emit_vertex(&b->nb, stream);
4087
break;
4088
case SpvOpEndPrimitive:
4089
case SpvOpEndStreamPrimitive:
4090
nir_end_primitive(&b->nb, stream);
4091
break;
4092
default:
4093
unreachable("Invalid opcode");
4094
}
4095
break;
4096
}
4097
4098
case SpvOpMemoryBarrier: {
4099
SpvScope scope = vtn_constant_uint(b, w[1]);
4100
SpvMemorySemanticsMask semantics = vtn_constant_uint(b, w[2]);
4101
vtn_emit_memory_barrier(b, scope, semantics);
4102
return;
4103
}
4104
4105
case SpvOpControlBarrier: {
4106
SpvScope execution_scope = vtn_constant_uint(b, w[1]);
4107
SpvScope memory_scope = vtn_constant_uint(b, w[2]);
4108
SpvMemorySemanticsMask memory_semantics = vtn_constant_uint(b, w[3]);
4109
4110
/* GLSLang, prior to commit 8297936dd6eb3, emitted OpControlBarrier with
4111
* memory semantics of None for GLSL barrier().
4112
* And before that, prior to c3f1cdfa, emitted the OpControlBarrier with
4113
* Device instead of Workgroup for execution scope.
4114
*/
4115
if (b->wa_glslang_cs_barrier &&
4116
b->nb.shader->info.stage == MESA_SHADER_COMPUTE &&
4117
(execution_scope == SpvScopeWorkgroup ||
4118
execution_scope == SpvScopeDevice) &&
4119
memory_semantics == SpvMemorySemanticsMaskNone) {
4120
execution_scope = SpvScopeWorkgroup;
4121
memory_scope = SpvScopeWorkgroup;
4122
memory_semantics = SpvMemorySemanticsAcquireReleaseMask |
4123
SpvMemorySemanticsWorkgroupMemoryMask;
4124
}
4125
4126
/* From the SPIR-V spec:
4127
*
4128
* "When used with the TessellationControl execution model, it also
4129
* implicitly synchronizes the Output Storage Class: Writes to Output
4130
* variables performed by any invocation executed prior to a
4131
* OpControlBarrier will be visible to any other invocation after
4132
* return from that OpControlBarrier."
4133
*/
4134
if (b->nb.shader->info.stage == MESA_SHADER_TESS_CTRL) {
4135
memory_semantics &= ~(SpvMemorySemanticsAcquireMask |
4136
SpvMemorySemanticsReleaseMask |
4137
SpvMemorySemanticsAcquireReleaseMask |
4138
SpvMemorySemanticsSequentiallyConsistentMask);
4139
memory_semantics |= SpvMemorySemanticsAcquireReleaseMask |
4140
SpvMemorySemanticsOutputMemoryMask;
4141
}
4142
4143
if (b->shader->options->use_scoped_barrier) {
4144
vtn_emit_scoped_control_barrier(b, execution_scope, memory_scope,
4145
memory_semantics);
4146
} else {
4147
vtn_emit_memory_barrier(b, memory_scope, memory_semantics);
4148
4149
if (execution_scope == SpvScopeWorkgroup)
4150
nir_control_barrier(&b->nb);
4151
}
4152
break;
4153
}
4154
4155
default:
4156
unreachable("unknown barrier instruction");
4157
}
4158
}
4159
4160
static unsigned
4161
gl_primitive_from_spv_execution_mode(struct vtn_builder *b,
4162
SpvExecutionMode mode)
4163
{
4164
switch (mode) {
4165
case SpvExecutionModeInputPoints:
4166
case SpvExecutionModeOutputPoints:
4167
return 0; /* GL_POINTS */
4168
case SpvExecutionModeInputLines:
4169
return 1; /* GL_LINES */
4170
case SpvExecutionModeInputLinesAdjacency:
4171
return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
4172
case SpvExecutionModeTriangles:
4173
return 4; /* GL_TRIANGLES */
4174
case SpvExecutionModeInputTrianglesAdjacency:
4175
return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
4176
case SpvExecutionModeQuads:
4177
return 7; /* GL_QUADS */
4178
case SpvExecutionModeIsolines:
4179
return 0x8E7A; /* GL_ISOLINES */
4180
case SpvExecutionModeOutputLineStrip:
4181
return 3; /* GL_LINE_STRIP */
4182
case SpvExecutionModeOutputTriangleStrip:
4183
return 5; /* GL_TRIANGLE_STRIP */
4184
default:
4185
vtn_fail("Invalid primitive type: %s (%u)",
4186
spirv_executionmode_to_string(mode), mode);
4187
}
4188
}
4189
4190
static unsigned
4191
vertices_in_from_spv_execution_mode(struct vtn_builder *b,
4192
SpvExecutionMode mode)
4193
{
4194
switch (mode) {
4195
case SpvExecutionModeInputPoints:
4196
return 1;
4197
case SpvExecutionModeInputLines:
4198
return 2;
4199
case SpvExecutionModeInputLinesAdjacency:
4200
return 4;
4201
case SpvExecutionModeTriangles:
4202
return 3;
4203
case SpvExecutionModeInputTrianglesAdjacency:
4204
return 6;
4205
default:
4206
vtn_fail("Invalid GS input mode: %s (%u)",
4207
spirv_executionmode_to_string(mode), mode);
4208
}
4209
}
4210
4211
static gl_shader_stage
4212
stage_for_execution_model(struct vtn_builder *b, SpvExecutionModel model)
4213
{
4214
switch (model) {
4215
case SpvExecutionModelVertex:
4216
return MESA_SHADER_VERTEX;
4217
case SpvExecutionModelTessellationControl:
4218
return MESA_SHADER_TESS_CTRL;
4219
case SpvExecutionModelTessellationEvaluation:
4220
return MESA_SHADER_TESS_EVAL;
4221
case SpvExecutionModelGeometry:
4222
return MESA_SHADER_GEOMETRY;
4223
case SpvExecutionModelFragment:
4224
return MESA_SHADER_FRAGMENT;
4225
case SpvExecutionModelGLCompute:
4226
return MESA_SHADER_COMPUTE;
4227
case SpvExecutionModelKernel:
4228
return MESA_SHADER_KERNEL;
4229
case SpvExecutionModelRayGenerationKHR:
4230
return MESA_SHADER_RAYGEN;
4231
case SpvExecutionModelAnyHitKHR:
4232
return MESA_SHADER_ANY_HIT;
4233
case SpvExecutionModelClosestHitKHR:
4234
return MESA_SHADER_CLOSEST_HIT;
4235
case SpvExecutionModelMissKHR:
4236
return MESA_SHADER_MISS;
4237
case SpvExecutionModelIntersectionKHR:
4238
return MESA_SHADER_INTERSECTION;
4239
case SpvExecutionModelCallableKHR:
4240
return MESA_SHADER_CALLABLE;
4241
default:
4242
vtn_fail("Unsupported execution model: %s (%u)",
4243
spirv_executionmodel_to_string(model), model);
4244
}
4245
}
4246
4247
#define spv_check_supported(name, cap) do { \
4248
if (!(b->options && b->options->caps.name)) \
4249
vtn_warn("Unsupported SPIR-V capability: %s (%u)", \
4250
spirv_capability_to_string(cap), cap); \
4251
} while(0)
4252
4253
4254
void
4255
vtn_handle_entry_point(struct vtn_builder *b, const uint32_t *w,
4256
unsigned count)
4257
{
4258
struct vtn_value *entry_point = &b->values[w[2]];
4259
/* Let this be a name label regardless */
4260
unsigned name_words;
4261
entry_point->name = vtn_string_literal(b, &w[3], count - 3, &name_words);
4262
4263
if (strcmp(entry_point->name, b->entry_point_name) != 0 ||
4264
stage_for_execution_model(b, w[1]) != b->entry_point_stage)
4265
return;
4266
4267
vtn_assert(b->entry_point == NULL);
4268
b->entry_point = entry_point;
4269
4270
/* Entry points enumerate which global variables are used. */
4271
size_t start = 3 + name_words;
4272
b->interface_ids_count = count - start;
4273
b->interface_ids = ralloc_array(b, uint32_t, b->interface_ids_count);
4274
memcpy(b->interface_ids, &w[start], b->interface_ids_count * 4);
4275
qsort(b->interface_ids, b->interface_ids_count, 4, cmp_uint32_t);
4276
}
4277
4278
static bool
4279
vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
4280
const uint32_t *w, unsigned count)
4281
{
4282
switch (opcode) {
4283
case SpvOpSource: {
4284
const char *lang;
4285
switch (w[1]) {
4286
default:
4287
case SpvSourceLanguageUnknown: lang = "unknown"; break;
4288
case SpvSourceLanguageESSL: lang = "ESSL"; break;
4289
case SpvSourceLanguageGLSL: lang = "GLSL"; break;
4290
case SpvSourceLanguageOpenCL_C: lang = "OpenCL C"; break;
4291
case SpvSourceLanguageOpenCL_CPP: lang = "OpenCL C++"; break;
4292
case SpvSourceLanguageHLSL: lang = "HLSL"; break;
4293
}
4294
4295
uint32_t version = w[2];
4296
4297
const char *file =
4298
(count > 3) ? vtn_value(b, w[3], vtn_value_type_string)->str : "";
4299
4300
vtn_info("Parsing SPIR-V from %s %u source file %s", lang, version, file);
4301
4302
b->source_lang = w[1];
4303
break;
4304
}
4305
4306
case SpvOpSourceExtension:
4307
case SpvOpSourceContinued:
4308
case SpvOpExtension:
4309
case SpvOpModuleProcessed:
4310
/* Unhandled, but these are for debug so that's ok. */
4311
break;
4312
4313
case SpvOpCapability: {
4314
SpvCapability cap = w[1];
4315
switch (cap) {
4316
case SpvCapabilityMatrix:
4317
case SpvCapabilityShader:
4318
case SpvCapabilityGeometry:
4319
case SpvCapabilityGeometryPointSize:
4320
case SpvCapabilityUniformBufferArrayDynamicIndexing:
4321
case SpvCapabilitySampledImageArrayDynamicIndexing:
4322
case SpvCapabilityStorageBufferArrayDynamicIndexing:
4323
case SpvCapabilityStorageImageArrayDynamicIndexing:
4324
case SpvCapabilityImageRect:
4325
case SpvCapabilitySampledRect:
4326
case SpvCapabilitySampled1D:
4327
case SpvCapabilityImage1D:
4328
case SpvCapabilitySampledCubeArray:
4329
case SpvCapabilityImageCubeArray:
4330
case SpvCapabilitySampledBuffer:
4331
case SpvCapabilityImageBuffer:
4332
case SpvCapabilityImageQuery:
4333
case SpvCapabilityDerivativeControl:
4334
case SpvCapabilityInterpolationFunction:
4335
case SpvCapabilityMultiViewport:
4336
case SpvCapabilitySampleRateShading:
4337
case SpvCapabilityClipDistance:
4338
case SpvCapabilityCullDistance:
4339
case SpvCapabilityInputAttachment:
4340
case SpvCapabilityImageGatherExtended:
4341
case SpvCapabilityStorageImageExtendedFormats:
4342
case SpvCapabilityVector16:
4343
break;
4344
4345
case SpvCapabilityLinkage:
4346
if (!b->options->create_library)
4347
vtn_warn("Unsupported SPIR-V capability: %s",
4348
spirv_capability_to_string(cap));
4349
break;
4350
4351
case SpvCapabilitySparseResidency:
4352
spv_check_supported(sparse_residency, cap);
4353
break;
4354
4355
case SpvCapabilityMinLod:
4356
spv_check_supported(min_lod, cap);
4357
break;
4358
4359
case SpvCapabilityAtomicStorage:
4360
spv_check_supported(atomic_storage, cap);
4361
break;
4362
4363
case SpvCapabilityFloat64:
4364
spv_check_supported(float64, cap);
4365
break;
4366
case SpvCapabilityInt64:
4367
spv_check_supported(int64, cap);
4368
break;
4369
case SpvCapabilityInt16:
4370
spv_check_supported(int16, cap);
4371
break;
4372
case SpvCapabilityInt8:
4373
spv_check_supported(int8, cap);
4374
break;
4375
4376
case SpvCapabilityTransformFeedback:
4377
spv_check_supported(transform_feedback, cap);
4378
break;
4379
4380
case SpvCapabilityGeometryStreams:
4381
spv_check_supported(geometry_streams, cap);
4382
break;
4383
4384
case SpvCapabilityInt64Atomics:
4385
spv_check_supported(int64_atomics, cap);
4386
break;
4387
4388
case SpvCapabilityStorageImageMultisample:
4389
spv_check_supported(storage_image_ms, cap);
4390
break;
4391
4392
case SpvCapabilityAddresses:
4393
spv_check_supported(address, cap);
4394
break;
4395
4396
case SpvCapabilityKernel:
4397
case SpvCapabilityFloat16Buffer:
4398
spv_check_supported(kernel, cap);
4399
break;
4400
4401
case SpvCapabilityGenericPointer:
4402
spv_check_supported(generic_pointers, cap);
4403
break;
4404
4405
case SpvCapabilityImageBasic:
4406
spv_check_supported(kernel_image, cap);
4407
break;
4408
4409
case SpvCapabilityImageReadWrite:
4410
spv_check_supported(kernel_image_read_write, cap);
4411
break;
4412
4413
case SpvCapabilityLiteralSampler:
4414
spv_check_supported(literal_sampler, cap);
4415
break;
4416
4417
case SpvCapabilityImageMipmap:
4418
case SpvCapabilityPipes:
4419
case SpvCapabilityDeviceEnqueue:
4420
vtn_warn("Unsupported OpenCL-style SPIR-V capability: %s",
4421
spirv_capability_to_string(cap));
4422
break;
4423
4424
case SpvCapabilityImageMSArray:
4425
spv_check_supported(image_ms_array, cap);
4426
break;
4427
4428
case SpvCapabilityTessellation:
4429
case SpvCapabilityTessellationPointSize:
4430
spv_check_supported(tessellation, cap);
4431
break;
4432
4433
case SpvCapabilityDrawParameters:
4434
spv_check_supported(draw_parameters, cap);
4435
break;
4436
4437
case SpvCapabilityStorageImageReadWithoutFormat:
4438
spv_check_supported(image_read_without_format, cap);
4439
break;
4440
4441
case SpvCapabilityStorageImageWriteWithoutFormat:
4442
spv_check_supported(image_write_without_format, cap);
4443
break;
4444
4445
case SpvCapabilityDeviceGroup:
4446
spv_check_supported(device_group, cap);
4447
break;
4448
4449
case SpvCapabilityMultiView:
4450
spv_check_supported(multiview, cap);
4451
break;
4452
4453
case SpvCapabilityGroupNonUniform:
4454
spv_check_supported(subgroup_basic, cap);
4455
break;
4456
4457
case SpvCapabilitySubgroupVoteKHR:
4458
case SpvCapabilityGroupNonUniformVote:
4459
spv_check_supported(subgroup_vote, cap);
4460
break;
4461
4462
case SpvCapabilitySubgroupBallotKHR:
4463
case SpvCapabilityGroupNonUniformBallot:
4464
spv_check_supported(subgroup_ballot, cap);
4465
break;
4466
4467
case SpvCapabilityGroupNonUniformShuffle:
4468
case SpvCapabilityGroupNonUniformShuffleRelative:
4469
spv_check_supported(subgroup_shuffle, cap);
4470
break;
4471
4472
case SpvCapabilityGroupNonUniformQuad:
4473
spv_check_supported(subgroup_quad, cap);
4474
break;
4475
4476
case SpvCapabilityGroupNonUniformArithmetic:
4477
case SpvCapabilityGroupNonUniformClustered:
4478
spv_check_supported(subgroup_arithmetic, cap);
4479
break;
4480
4481
case SpvCapabilityGroups:
4482
spv_check_supported(amd_shader_ballot, cap);
4483
break;
4484
4485
case SpvCapabilityVariablePointersStorageBuffer:
4486
case SpvCapabilityVariablePointers:
4487
spv_check_supported(variable_pointers, cap);
4488
b->variable_pointers = true;
4489
break;
4490
4491
case SpvCapabilityStorageUniformBufferBlock16:
4492
case SpvCapabilityStorageUniform16:
4493
case SpvCapabilityStoragePushConstant16:
4494
case SpvCapabilityStorageInputOutput16:
4495
spv_check_supported(storage_16bit, cap);
4496
break;
4497
4498
case SpvCapabilityShaderLayer:
4499
case SpvCapabilityShaderViewportIndex:
4500
case SpvCapabilityShaderViewportIndexLayerEXT:
4501
spv_check_supported(shader_viewport_index_layer, cap);
4502
break;
4503
4504
case SpvCapabilityStorageBuffer8BitAccess:
4505
case SpvCapabilityUniformAndStorageBuffer8BitAccess:
4506
case SpvCapabilityStoragePushConstant8:
4507
spv_check_supported(storage_8bit, cap);
4508
break;
4509
4510
case SpvCapabilityShaderNonUniformEXT:
4511
spv_check_supported(descriptor_indexing, cap);
4512
break;
4513
4514
case SpvCapabilityInputAttachmentArrayDynamicIndexingEXT:
4515
case SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT:
4516
case SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT:
4517
spv_check_supported(descriptor_array_dynamic_indexing, cap);
4518
break;
4519
4520
case SpvCapabilityUniformBufferArrayNonUniformIndexingEXT:
4521
case SpvCapabilitySampledImageArrayNonUniformIndexingEXT:
4522
case SpvCapabilityStorageBufferArrayNonUniformIndexingEXT:
4523
case SpvCapabilityStorageImageArrayNonUniformIndexingEXT:
4524
case SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT:
4525
case SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT:
4526
case SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT:
4527
spv_check_supported(descriptor_array_non_uniform_indexing, cap);
4528
break;
4529
4530
case SpvCapabilityRuntimeDescriptorArrayEXT:
4531
spv_check_supported(runtime_descriptor_array, cap);
4532
break;
4533
4534
case SpvCapabilityStencilExportEXT:
4535
spv_check_supported(stencil_export, cap);
4536
break;
4537
4538
case SpvCapabilitySampleMaskPostDepthCoverage:
4539
spv_check_supported(post_depth_coverage, cap);
4540
break;
4541
4542
case SpvCapabilityDenormFlushToZero:
4543
case SpvCapabilityDenormPreserve:
4544
case SpvCapabilitySignedZeroInfNanPreserve:
4545
case SpvCapabilityRoundingModeRTE:
4546
case SpvCapabilityRoundingModeRTZ:
4547
spv_check_supported(float_controls, cap);
4548
break;
4549
4550
case SpvCapabilityPhysicalStorageBufferAddresses:
4551
spv_check_supported(physical_storage_buffer_address, cap);
4552
break;
4553
4554
case SpvCapabilityComputeDerivativeGroupQuadsNV:
4555
case SpvCapabilityComputeDerivativeGroupLinearNV:
4556
spv_check_supported(derivative_group, cap);
4557
break;
4558
4559
case SpvCapabilityFloat16:
4560
spv_check_supported(float16, cap);
4561
break;
4562
4563
case SpvCapabilityFragmentShaderSampleInterlockEXT:
4564
spv_check_supported(fragment_shader_sample_interlock, cap);
4565
break;
4566
4567
case SpvCapabilityFragmentShaderPixelInterlockEXT:
4568
spv_check_supported(fragment_shader_pixel_interlock, cap);
4569
break;
4570
4571
case SpvCapabilityDemoteToHelperInvocationEXT:
4572
spv_check_supported(demote_to_helper_invocation, cap);
4573
b->uses_demote_to_helper_invocation = true;
4574
break;
4575
4576
case SpvCapabilityShaderClockKHR:
4577
spv_check_supported(shader_clock, cap);
4578
break;
4579
4580
case SpvCapabilityVulkanMemoryModel:
4581
spv_check_supported(vk_memory_model, cap);
4582
break;
4583
4584
case SpvCapabilityVulkanMemoryModelDeviceScope:
4585
spv_check_supported(vk_memory_model_device_scope, cap);
4586
break;
4587
4588
case SpvCapabilityImageReadWriteLodAMD:
4589
spv_check_supported(amd_image_read_write_lod, cap);
4590
break;
4591
4592
case SpvCapabilityIntegerFunctions2INTEL:
4593
spv_check_supported(integer_functions2, cap);
4594
break;
4595
4596
case SpvCapabilityFragmentMaskAMD:
4597
spv_check_supported(amd_fragment_mask, cap);
4598
break;
4599
4600
case SpvCapabilityImageGatherBiasLodAMD:
4601
spv_check_supported(amd_image_gather_bias_lod, cap);
4602
break;
4603
4604
case SpvCapabilityAtomicFloat32AddEXT:
4605
spv_check_supported(float32_atomic_add, cap);
4606
break;
4607
4608
case SpvCapabilityAtomicFloat64AddEXT:
4609
spv_check_supported(float64_atomic_add, cap);
4610
break;
4611
4612
case SpvCapabilitySubgroupShuffleINTEL:
4613
spv_check_supported(intel_subgroup_shuffle, cap);
4614
break;
4615
4616
case SpvCapabilitySubgroupBufferBlockIOINTEL:
4617
spv_check_supported(intel_subgroup_buffer_block_io, cap);
4618
break;
4619
4620
case SpvCapabilityRayTracingKHR:
4621
spv_check_supported(ray_tracing, cap);
4622
break;
4623
4624
case SpvCapabilityRayQueryKHR:
4625
spv_check_supported(ray_query, cap);
4626
break;
4627
4628
case SpvCapabilityRayTraversalPrimitiveCullingKHR:
4629
spv_check_supported(ray_traversal_primitive_culling, cap);
4630
break;
4631
4632
case SpvCapabilityInt64ImageEXT:
4633
spv_check_supported(image_atomic_int64, cap);
4634
break;
4635
4636
case SpvCapabilityFragmentShadingRateKHR:
4637
spv_check_supported(fragment_shading_rate, cap);
4638
break;
4639
4640
case SpvCapabilityWorkgroupMemoryExplicitLayoutKHR:
4641
spv_check_supported(workgroup_memory_explicit_layout, cap);
4642
break;
4643
4644
case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR:
4645
spv_check_supported(workgroup_memory_explicit_layout, cap);
4646
spv_check_supported(storage_8bit, cap);
4647
break;
4648
4649
case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR:
4650
spv_check_supported(workgroup_memory_explicit_layout, cap);
4651
spv_check_supported(storage_16bit, cap);
4652
break;
4653
4654
case SpvCapabilityAtomicFloat16MinMaxEXT:
4655
spv_check_supported(float16_atomic_min_max, cap);
4656
break;
4657
4658
case SpvCapabilityAtomicFloat32MinMaxEXT:
4659
spv_check_supported(float32_atomic_min_max, cap);
4660
break;
4661
4662
case SpvCapabilityAtomicFloat64MinMaxEXT:
4663
spv_check_supported(float64_atomic_min_max, cap);
4664
break;
4665
4666
default:
4667
vtn_fail("Unhandled capability: %s (%u)",
4668
spirv_capability_to_string(cap), cap);
4669
}
4670
break;
4671
}
4672
4673
case SpvOpExtInstImport:
4674
vtn_handle_extension(b, opcode, w, count);
4675
break;
4676
4677
case SpvOpMemoryModel:
4678
switch (w[1]) {
4679
case SpvAddressingModelPhysical32:
4680
vtn_fail_if(b->shader->info.stage != MESA_SHADER_KERNEL,
4681
"AddressingModelPhysical32 only supported for kernels");
4682
b->shader->info.cs.ptr_size = 32;
4683
b->physical_ptrs = true;
4684
assert(nir_address_format_bit_size(b->options->global_addr_format) == 32);
4685
assert(nir_address_format_num_components(b->options->global_addr_format) == 1);
4686
assert(nir_address_format_bit_size(b->options->shared_addr_format) == 32);
4687
assert(nir_address_format_num_components(b->options->shared_addr_format) == 1);
4688
assert(nir_address_format_bit_size(b->options->constant_addr_format) == 32);
4689
assert(nir_address_format_num_components(b->options->constant_addr_format) == 1);
4690
break;
4691
case SpvAddressingModelPhysical64:
4692
vtn_fail_if(b->shader->info.stage != MESA_SHADER_KERNEL,
4693
"AddressingModelPhysical64 only supported for kernels");
4694
b->shader->info.cs.ptr_size = 64;
4695
b->physical_ptrs = true;
4696
assert(nir_address_format_bit_size(b->options->global_addr_format) == 64);
4697
assert(nir_address_format_num_components(b->options->global_addr_format) == 1);
4698
assert(nir_address_format_bit_size(b->options->shared_addr_format) == 64);
4699
assert(nir_address_format_num_components(b->options->shared_addr_format) == 1);
4700
assert(nir_address_format_bit_size(b->options->constant_addr_format) == 64);
4701
assert(nir_address_format_num_components(b->options->constant_addr_format) == 1);
4702
break;
4703
case SpvAddressingModelLogical:
4704
vtn_fail_if(b->shader->info.stage == MESA_SHADER_KERNEL,
4705
"AddressingModelLogical only supported for shaders");
4706
b->physical_ptrs = false;
4707
break;
4708
case SpvAddressingModelPhysicalStorageBuffer64:
4709
vtn_fail_if(!b->options ||
4710
!b->options->caps.physical_storage_buffer_address,
4711
"AddressingModelPhysicalStorageBuffer64 not supported");
4712
break;
4713
default:
4714
vtn_fail("Unknown addressing model: %s (%u)",
4715
spirv_addressingmodel_to_string(w[1]), w[1]);
4716
break;
4717
}
4718
4719
b->mem_model = w[2];
4720
switch (w[2]) {
4721
case SpvMemoryModelSimple:
4722
case SpvMemoryModelGLSL450:
4723
case SpvMemoryModelOpenCL:
4724
break;
4725
case SpvMemoryModelVulkan:
4726
vtn_fail_if(!b->options->caps.vk_memory_model,
4727
"Vulkan memory model is unsupported by this driver");
4728
break;
4729
default:
4730
vtn_fail("Unsupported memory model: %s",
4731
spirv_memorymodel_to_string(w[2]));
4732
break;
4733
}
4734
break;
4735
4736
case SpvOpEntryPoint:
4737
vtn_handle_entry_point(b, w, count);
4738
break;
4739
4740
case SpvOpString:
4741
vtn_push_value(b, w[1], vtn_value_type_string)->str =
4742
vtn_string_literal(b, &w[2], count - 2, NULL);
4743
break;
4744
4745
case SpvOpName:
4746
b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2, NULL);
4747
break;
4748
4749
case SpvOpMemberName:
4750
/* TODO */
4751
break;
4752
4753
case SpvOpExecutionMode:
4754
case SpvOpExecutionModeId:
4755
case SpvOpDecorationGroup:
4756
case SpvOpDecorate:
4757
case SpvOpDecorateId:
4758
case SpvOpMemberDecorate:
4759
case SpvOpGroupDecorate:
4760
case SpvOpGroupMemberDecorate:
4761
case SpvOpDecorateString:
4762
case SpvOpMemberDecorateString:
4763
vtn_handle_decoration(b, opcode, w, count);
4764
break;
4765
4766
case SpvOpExtInst: {
4767
struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
4768
if (val->ext_handler == vtn_handle_non_semantic_instruction) {
4769
/* NonSemantic extended instructions are acceptable in preamble. */
4770
vtn_handle_non_semantic_instruction(b, w[4], w, count);
4771
return true;
4772
} else {
4773
return false; /* End of preamble. */
4774
}
4775
}
4776
4777
default:
4778
return false; /* End of preamble */
4779
}
4780
4781
return true;
4782
}
4783
4784
static void
4785
vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
4786
const struct vtn_decoration *mode, UNUSED void *data)
4787
{
4788
vtn_assert(b->entry_point == entry_point);
4789
4790
switch(mode->exec_mode) {
4791
case SpvExecutionModeOriginUpperLeft:
4792
case SpvExecutionModeOriginLowerLeft:
4793
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4794
b->shader->info.fs.origin_upper_left =
4795
(mode->exec_mode == SpvExecutionModeOriginUpperLeft);
4796
break;
4797
4798
case SpvExecutionModeEarlyFragmentTests:
4799
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4800
b->shader->info.fs.early_fragment_tests = true;
4801
break;
4802
4803
case SpvExecutionModePostDepthCoverage:
4804
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4805
b->shader->info.fs.post_depth_coverage = true;
4806
break;
4807
4808
case SpvExecutionModeInvocations:
4809
vtn_assert(b->shader->info.stage == MESA_SHADER_GEOMETRY);
4810
b->shader->info.gs.invocations = MAX2(1, mode->operands[0]);
4811
break;
4812
4813
case SpvExecutionModeDepthReplacing:
4814
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4815
b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
4816
break;
4817
case SpvExecutionModeDepthGreater:
4818
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4819
b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
4820
break;
4821
case SpvExecutionModeDepthLess:
4822
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4823
b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
4824
break;
4825
case SpvExecutionModeDepthUnchanged:
4826
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4827
b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
4828
break;
4829
4830
case SpvExecutionModeLocalSizeHint:
4831
vtn_assert(b->shader->info.stage == MESA_SHADER_KERNEL);
4832
b->shader->info.cs.workgroup_size_hint[0] = mode->operands[0];
4833
b->shader->info.cs.workgroup_size_hint[1] = mode->operands[1];
4834
b->shader->info.cs.workgroup_size_hint[2] = mode->operands[2];
4835
break;
4836
4837
case SpvExecutionModeLocalSize:
4838
vtn_assert(gl_shader_stage_is_compute(b->shader->info.stage));
4839
b->shader->info.workgroup_size[0] = mode->operands[0];
4840
b->shader->info.workgroup_size[1] = mode->operands[1];
4841
b->shader->info.workgroup_size[2] = mode->operands[2];
4842
break;
4843
4844
case SpvExecutionModeOutputVertices:
4845
if (b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4846
b->shader->info.stage == MESA_SHADER_TESS_EVAL) {
4847
b->shader->info.tess.tcs_vertices_out = mode->operands[0];
4848
} else {
4849
vtn_assert(b->shader->info.stage == MESA_SHADER_GEOMETRY);
4850
b->shader->info.gs.vertices_out = mode->operands[0];
4851
}
4852
break;
4853
4854
case SpvExecutionModeInputPoints:
4855
case SpvExecutionModeInputLines:
4856
case SpvExecutionModeInputLinesAdjacency:
4857
case SpvExecutionModeTriangles:
4858
case SpvExecutionModeInputTrianglesAdjacency:
4859
case SpvExecutionModeQuads:
4860
case SpvExecutionModeIsolines:
4861
if (b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4862
b->shader->info.stage == MESA_SHADER_TESS_EVAL) {
4863
b->shader->info.tess.primitive_mode =
4864
gl_primitive_from_spv_execution_mode(b, mode->exec_mode);
4865
} else {
4866
vtn_assert(b->shader->info.stage == MESA_SHADER_GEOMETRY);
4867
b->shader->info.gs.vertices_in =
4868
vertices_in_from_spv_execution_mode(b, mode->exec_mode);
4869
b->shader->info.gs.input_primitive =
4870
gl_primitive_from_spv_execution_mode(b, mode->exec_mode);
4871
}
4872
break;
4873
4874
case SpvExecutionModeOutputPoints:
4875
case SpvExecutionModeOutputLineStrip:
4876
case SpvExecutionModeOutputTriangleStrip:
4877
vtn_assert(b->shader->info.stage == MESA_SHADER_GEOMETRY);
4878
b->shader->info.gs.output_primitive =
4879
gl_primitive_from_spv_execution_mode(b, mode->exec_mode);
4880
break;
4881
4882
case SpvExecutionModeSpacingEqual:
4883
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4884
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4885
b->shader->info.tess.spacing = TESS_SPACING_EQUAL;
4886
break;
4887
case SpvExecutionModeSpacingFractionalEven:
4888
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4889
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4890
b->shader->info.tess.spacing = TESS_SPACING_FRACTIONAL_EVEN;
4891
break;
4892
case SpvExecutionModeSpacingFractionalOdd:
4893
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4894
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4895
b->shader->info.tess.spacing = TESS_SPACING_FRACTIONAL_ODD;
4896
break;
4897
case SpvExecutionModeVertexOrderCw:
4898
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4899
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4900
b->shader->info.tess.ccw = false;
4901
break;
4902
case SpvExecutionModeVertexOrderCcw:
4903
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4904
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4905
b->shader->info.tess.ccw = true;
4906
break;
4907
case SpvExecutionModePointMode:
4908
vtn_assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL ||
4909
b->shader->info.stage == MESA_SHADER_TESS_EVAL);
4910
b->shader->info.tess.point_mode = true;
4911
break;
4912
4913
case SpvExecutionModePixelCenterInteger:
4914
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4915
b->shader->info.fs.pixel_center_integer = true;
4916
break;
4917
4918
case SpvExecutionModeXfb:
4919
b->shader->info.has_transform_feedback_varyings = true;
4920
break;
4921
4922
case SpvExecutionModeVecTypeHint:
4923
break; /* OpenCL */
4924
4925
case SpvExecutionModeContractionOff:
4926
if (b->shader->info.stage != MESA_SHADER_KERNEL)
4927
vtn_warn("ExectionMode only allowed for CL-style kernels: %s",
4928
spirv_executionmode_to_string(mode->exec_mode));
4929
else
4930
b->exact = true;
4931
break;
4932
4933
case SpvExecutionModeStencilRefReplacingEXT:
4934
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4935
break;
4936
4937
case SpvExecutionModeDerivativeGroupQuadsNV:
4938
vtn_assert(b->shader->info.stage == MESA_SHADER_COMPUTE);
4939
b->shader->info.cs.derivative_group = DERIVATIVE_GROUP_QUADS;
4940
break;
4941
4942
case SpvExecutionModeDerivativeGroupLinearNV:
4943
vtn_assert(b->shader->info.stage == MESA_SHADER_COMPUTE);
4944
b->shader->info.cs.derivative_group = DERIVATIVE_GROUP_LINEAR;
4945
break;
4946
4947
case SpvExecutionModePixelInterlockOrderedEXT:
4948
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4949
b->shader->info.fs.pixel_interlock_ordered = true;
4950
break;
4951
4952
case SpvExecutionModePixelInterlockUnorderedEXT:
4953
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4954
b->shader->info.fs.pixel_interlock_unordered = true;
4955
break;
4956
4957
case SpvExecutionModeSampleInterlockOrderedEXT:
4958
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4959
b->shader->info.fs.sample_interlock_ordered = true;
4960
break;
4961
4962
case SpvExecutionModeSampleInterlockUnorderedEXT:
4963
vtn_assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
4964
b->shader->info.fs.sample_interlock_unordered = true;
4965
break;
4966
4967
case SpvExecutionModeDenormPreserve:
4968
case SpvExecutionModeDenormFlushToZero:
4969
case SpvExecutionModeSignedZeroInfNanPreserve:
4970
case SpvExecutionModeRoundingModeRTE:
4971
case SpvExecutionModeRoundingModeRTZ: {
4972
unsigned execution_mode = 0;
4973
switch (mode->exec_mode) {
4974
case SpvExecutionModeDenormPreserve:
4975
switch (mode->operands[0]) {
4976
case 16: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP16; break;
4977
case 32: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP32; break;
4978
case 64: execution_mode = FLOAT_CONTROLS_DENORM_PRESERVE_FP64; break;
4979
default: vtn_fail("Floating point type not supported");
4980
}
4981
break;
4982
case SpvExecutionModeDenormFlushToZero:
4983
switch (mode->operands[0]) {
4984
case 16: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16; break;
4985
case 32: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32; break;
4986
case 64: execution_mode = FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64; break;
4987
default: vtn_fail("Floating point type not supported");
4988
}
4989
break;
4990
case SpvExecutionModeSignedZeroInfNanPreserve:
4991
switch (mode->operands[0]) {
4992
case 16: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP16; break;
4993
case 32: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP32; break;
4994
case 64: execution_mode = FLOAT_CONTROLS_SIGNED_ZERO_INF_NAN_PRESERVE_FP64; break;
4995
default: vtn_fail("Floating point type not supported");
4996
}
4997
break;
4998
case SpvExecutionModeRoundingModeRTE:
4999
switch (mode->operands[0]) {
5000
case 16: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16; break;
5001
case 32: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32; break;
5002
case 64: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64; break;
5003
default: vtn_fail("Floating point type not supported");
5004
}
5005
break;
5006
case SpvExecutionModeRoundingModeRTZ:
5007
switch (mode->operands[0]) {
5008
case 16: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16; break;
5009
case 32: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32; break;
5010
case 64: execution_mode = FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64; break;
5011
default: vtn_fail("Floating point type not supported");
5012
}
5013
break;
5014
default:
5015
break;
5016
}
5017
5018
b->shader->info.float_controls_execution_mode |= execution_mode;
5019
5020
for (unsigned bit_size = 16; bit_size <= 64; bit_size *= 2) {
5021
vtn_fail_if(nir_is_denorm_flush_to_zero(b->shader->info.float_controls_execution_mode, bit_size) &&
5022
nir_is_denorm_preserve(b->shader->info.float_controls_execution_mode, bit_size),
5023
"Cannot flush to zero and preserve denorms for the same bit size.");
5024
vtn_fail_if(nir_is_rounding_mode_rtne(b->shader->info.float_controls_execution_mode, bit_size) &&
5025
nir_is_rounding_mode_rtz(b->shader->info.float_controls_execution_mode, bit_size),
5026
"Cannot set rounding mode to RTNE and RTZ for the same bit size.");
5027
}
5028
break;
5029
}
5030
5031
case SpvExecutionModeLocalSizeId:
5032
case SpvExecutionModeLocalSizeHintId:
5033
/* Handled later by vtn_handle_execution_mode_id(). */
5034
break;
5035
5036
case SpvExecutionModeSubgroupUniformControlFlowKHR:
5037
/* There's no corresponding SPIR-V capability, so check here. */
5038
vtn_fail_if(!b->options->caps.subgroup_uniform_control_flow,
5039
"SpvExecutionModeSubgroupUniformControlFlowKHR not supported.");
5040
break;
5041
5042
default:
5043
vtn_fail("Unhandled execution mode: %s (%u)",
5044
spirv_executionmode_to_string(mode->exec_mode),
5045
mode->exec_mode);
5046
}
5047
}
5048
5049
static void
5050
vtn_handle_execution_mode_id(struct vtn_builder *b, struct vtn_value *entry_point,
5051
const struct vtn_decoration *mode, UNUSED void *data)
5052
{
5053
5054
vtn_assert(b->entry_point == entry_point);
5055
5056
switch (mode->exec_mode) {
5057
case SpvExecutionModeLocalSizeId:
5058
b->shader->info.workgroup_size[0] = vtn_constant_uint(b, mode->operands[0]);
5059
b->shader->info.workgroup_size[1] = vtn_constant_uint(b, mode->operands[1]);
5060
b->shader->info.workgroup_size[2] = vtn_constant_uint(b, mode->operands[2]);
5061
break;
5062
5063
case SpvExecutionModeLocalSizeHintId:
5064
vtn_assert(b->shader->info.stage == MESA_SHADER_KERNEL);
5065
b->shader->info.cs.workgroup_size_hint[0] = vtn_constant_uint(b, mode->operands[0]);
5066
b->shader->info.cs.workgroup_size_hint[1] = vtn_constant_uint(b, mode->operands[1]);
5067
b->shader->info.cs.workgroup_size_hint[2] = vtn_constant_uint(b, mode->operands[2]);
5068
break;
5069
5070
default:
5071
/* Nothing to do. Literal execution modes already handled by
5072
* vtn_handle_execution_mode(). */
5073
break;
5074
}
5075
}
5076
5077
static bool
5078
vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
5079
const uint32_t *w, unsigned count)
5080
{
5081
vtn_set_instruction_result_type(b, opcode, w, count);
5082
5083
switch (opcode) {
5084
case SpvOpSource:
5085
case SpvOpSourceContinued:
5086
case SpvOpSourceExtension:
5087
case SpvOpExtension:
5088
case SpvOpCapability:
5089
case SpvOpExtInstImport:
5090
case SpvOpMemoryModel:
5091
case SpvOpEntryPoint:
5092
case SpvOpExecutionMode:
5093
case SpvOpString:
5094
case SpvOpName:
5095
case SpvOpMemberName:
5096
case SpvOpDecorationGroup:
5097
case SpvOpDecorate:
5098
case SpvOpDecorateId:
5099
case SpvOpMemberDecorate:
5100
case SpvOpGroupDecorate:
5101
case SpvOpGroupMemberDecorate:
5102
case SpvOpDecorateString:
5103
case SpvOpMemberDecorateString:
5104
vtn_fail("Invalid opcode types and variables section");
5105
break;
5106
5107
case SpvOpTypeVoid:
5108
case SpvOpTypeBool:
5109
case SpvOpTypeInt:
5110
case SpvOpTypeFloat:
5111
case SpvOpTypeVector:
5112
case SpvOpTypeMatrix:
5113
case SpvOpTypeImage:
5114
case SpvOpTypeSampler:
5115
case SpvOpTypeSampledImage:
5116
case SpvOpTypeArray:
5117
case SpvOpTypeRuntimeArray:
5118
case SpvOpTypeStruct:
5119
case SpvOpTypeOpaque:
5120
case SpvOpTypePointer:
5121
case SpvOpTypeForwardPointer:
5122
case SpvOpTypeFunction:
5123
case SpvOpTypeEvent:
5124
case SpvOpTypeDeviceEvent:
5125
case SpvOpTypeReserveId:
5126
case SpvOpTypeQueue:
5127
case SpvOpTypePipe:
5128
case SpvOpTypeAccelerationStructureKHR:
5129
vtn_handle_type(b, opcode, w, count);
5130
break;
5131
5132
case SpvOpConstantTrue:
5133
case SpvOpConstantFalse:
5134
case SpvOpConstant:
5135
case SpvOpConstantComposite:
5136
case SpvOpConstantNull:
5137
case SpvOpSpecConstantTrue:
5138
case SpvOpSpecConstantFalse:
5139
case SpvOpSpecConstant:
5140
case SpvOpSpecConstantComposite:
5141
case SpvOpSpecConstantOp:
5142
vtn_handle_constant(b, opcode, w, count);
5143
break;
5144
5145
case SpvOpUndef:
5146
case SpvOpVariable:
5147
case SpvOpConstantSampler:
5148
vtn_handle_variables(b, opcode, w, count);
5149
break;
5150
5151
case SpvOpExtInst: {
5152
struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
5153
/* NonSemantic extended instructions are acceptable in preamble, others
5154
* will indicate the end of preamble.
5155
*/
5156
return val->ext_handler == vtn_handle_non_semantic_instruction;
5157
}
5158
5159
default:
5160
return false; /* End of preamble */
5161
}
5162
5163
return true;
5164
}
5165
5166
static struct vtn_ssa_value *
5167
vtn_nir_select(struct vtn_builder *b, struct vtn_ssa_value *src0,
5168
struct vtn_ssa_value *src1, struct vtn_ssa_value *src2)
5169
{
5170
struct vtn_ssa_value *dest = rzalloc(b, struct vtn_ssa_value);
5171
dest->type = src1->type;
5172
5173
if (glsl_type_is_vector_or_scalar(src1->type)) {
5174
dest->def = nir_bcsel(&b->nb, src0->def, src1->def, src2->def);
5175
} else {
5176
unsigned elems = glsl_get_length(src1->type);
5177
5178
dest->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
5179
for (unsigned i = 0; i < elems; i++) {
5180
dest->elems[i] = vtn_nir_select(b, src0,
5181
src1->elems[i], src2->elems[i]);
5182
}
5183
}
5184
5185
return dest;
5186
}
5187
5188
static void
5189
vtn_handle_select(struct vtn_builder *b, SpvOp opcode,
5190
const uint32_t *w, unsigned count)
5191
{
5192
/* Handle OpSelect up-front here because it needs to be able to handle
5193
* pointers and not just regular vectors and scalars.
5194
*/
5195
struct vtn_value *res_val = vtn_untyped_value(b, w[2]);
5196
struct vtn_value *cond_val = vtn_untyped_value(b, w[3]);
5197
struct vtn_value *obj1_val = vtn_untyped_value(b, w[4]);
5198
struct vtn_value *obj2_val = vtn_untyped_value(b, w[5]);
5199
5200
vtn_fail_if(obj1_val->type != res_val->type ||
5201
obj2_val->type != res_val->type,
5202
"Object types must match the result type in OpSelect");
5203
5204
vtn_fail_if((cond_val->type->base_type != vtn_base_type_scalar &&
5205
cond_val->type->base_type != vtn_base_type_vector) ||
5206
!glsl_type_is_boolean(cond_val->type->type),
5207
"OpSelect must have either a vector of booleans or "
5208
"a boolean as Condition type");
5209
5210
vtn_fail_if(cond_val->type->base_type == vtn_base_type_vector &&
5211
(res_val->type->base_type != vtn_base_type_vector ||
5212
res_val->type->length != cond_val->type->length),
5213
"When Condition type in OpSelect is a vector, the Result "
5214
"type must be a vector of the same length");
5215
5216
switch (res_val->type->base_type) {
5217
case vtn_base_type_scalar:
5218
case vtn_base_type_vector:
5219
case vtn_base_type_matrix:
5220
case vtn_base_type_array:
5221
case vtn_base_type_struct:
5222
/* OK. */
5223
break;
5224
case vtn_base_type_pointer:
5225
/* We need to have actual storage for pointer types. */
5226
vtn_fail_if(res_val->type->type == NULL,
5227
"Invalid pointer result type for OpSelect");
5228
break;
5229
default:
5230
vtn_fail("Result type of OpSelect must be a scalar, composite, or pointer");
5231
}
5232
5233
vtn_push_ssa_value(b, w[2],
5234
vtn_nir_select(b, vtn_ssa_value(b, w[3]),
5235
vtn_ssa_value(b, w[4]),
5236
vtn_ssa_value(b, w[5])));
5237
}
5238
5239
static void
5240
vtn_handle_ptr(struct vtn_builder *b, SpvOp opcode,
5241
const uint32_t *w, unsigned count)
5242
{
5243
struct vtn_type *type1 = vtn_get_value_type(b, w[3]);
5244
struct vtn_type *type2 = vtn_get_value_type(b, w[4]);
5245
vtn_fail_if(type1->base_type != vtn_base_type_pointer ||
5246
type2->base_type != vtn_base_type_pointer,
5247
"%s operands must have pointer types",
5248
spirv_op_to_string(opcode));
5249
vtn_fail_if(type1->storage_class != type2->storage_class,
5250
"%s operands must have the same storage class",
5251
spirv_op_to_string(opcode));
5252
5253
struct vtn_type *vtn_type = vtn_get_type(b, w[1]);
5254
const struct glsl_type *type = vtn_type->type;
5255
5256
nir_address_format addr_format = vtn_mode_to_address_format(
5257
b, vtn_storage_class_to_mode(b, type1->storage_class, NULL, NULL));
5258
5259
nir_ssa_def *def;
5260
5261
switch (opcode) {
5262
case SpvOpPtrDiff: {
5263
/* OpPtrDiff returns the difference in number of elements (not byte offset). */
5264
unsigned elem_size, elem_align;
5265
glsl_get_natural_size_align_bytes(type1->deref->type,
5266
&elem_size, &elem_align);
5267
5268
def = nir_build_addr_isub(&b->nb,
5269
vtn_get_nir_ssa(b, w[3]),
5270
vtn_get_nir_ssa(b, w[4]),
5271
addr_format);
5272
def = nir_idiv(&b->nb, def, nir_imm_intN_t(&b->nb, elem_size, def->bit_size));
5273
def = nir_i2i(&b->nb, def, glsl_get_bit_size(type));
5274
break;
5275
}
5276
5277
case SpvOpPtrEqual:
5278
case SpvOpPtrNotEqual: {
5279
def = nir_build_addr_ieq(&b->nb,
5280
vtn_get_nir_ssa(b, w[3]),
5281
vtn_get_nir_ssa(b, w[4]),
5282
addr_format);
5283
if (opcode == SpvOpPtrNotEqual)
5284
def = nir_inot(&b->nb, def);
5285
break;
5286
}
5287
5288
default:
5289
unreachable("Invalid ptr operation");
5290
}
5291
5292
vtn_push_nir_ssa(b, w[2], def);
5293
}
5294
5295
static void
5296
vtn_handle_ray_intrinsic(struct vtn_builder *b, SpvOp opcode,
5297
const uint32_t *w, unsigned count)
5298
{
5299
nir_intrinsic_instr *intrin;
5300
5301
switch (opcode) {
5302
case SpvOpTraceNV:
5303
case SpvOpTraceRayKHR: {
5304
intrin = nir_intrinsic_instr_create(b->nb.shader,
5305
nir_intrinsic_trace_ray);
5306
5307
/* The sources are in the same order in the NIR intrinsic */
5308
for (unsigned i = 0; i < 10; i++)
5309
intrin->src[i] = nir_src_for_ssa(vtn_ssa_value(b, w[i + 1])->def);
5310
5311
nir_deref_instr *payload;
5312
if (opcode == SpvOpTraceNV)
5313
payload = vtn_get_call_payload_for_location(b, w[11]);
5314
else
5315
payload = vtn_nir_deref(b, w[11]);
5316
intrin->src[10] = nir_src_for_ssa(&payload->dest.ssa);
5317
nir_builder_instr_insert(&b->nb, &intrin->instr);
5318
break;
5319
}
5320
5321
case SpvOpReportIntersectionKHR: {
5322
intrin = nir_intrinsic_instr_create(b->nb.shader,
5323
nir_intrinsic_report_ray_intersection);
5324
intrin->src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
5325
intrin->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
5326
nir_ssa_dest_init(&intrin->instr, &intrin->dest, 1, 1, NULL);
5327
nir_builder_instr_insert(&b->nb, &intrin->instr);
5328
vtn_push_nir_ssa(b, w[2], &intrin->dest.ssa);
5329
break;
5330
}
5331
5332
case SpvOpIgnoreIntersectionNV:
5333
intrin = nir_intrinsic_instr_create(b->nb.shader,
5334
nir_intrinsic_ignore_ray_intersection);
5335
nir_builder_instr_insert(&b->nb, &intrin->instr);
5336
break;
5337
5338
case SpvOpTerminateRayNV:
5339
intrin = nir_intrinsic_instr_create(b->nb.shader,
5340
nir_intrinsic_terminate_ray);
5341
nir_builder_instr_insert(&b->nb, &intrin->instr);
5342
break;
5343
5344
case SpvOpExecuteCallableNV:
5345
case SpvOpExecuteCallableKHR: {
5346
intrin = nir_intrinsic_instr_create(b->nb.shader,
5347
nir_intrinsic_execute_callable);
5348
intrin->src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[1])->def);
5349
nir_deref_instr *payload;
5350
if (opcode == SpvOpExecuteCallableNV)
5351
payload = vtn_get_call_payload_for_location(b, w[2]);
5352
else
5353
payload = vtn_nir_deref(b, w[2]);
5354
intrin->src[1] = nir_src_for_ssa(&payload->dest.ssa);
5355
nir_builder_instr_insert(&b->nb, &intrin->instr);
5356
break;
5357
}
5358
5359
default:
5360
vtn_fail_with_opcode("Unhandled opcode", opcode);
5361
}
5362
}
5363
5364
static bool
5365
vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
5366
const uint32_t *w, unsigned count)
5367
{
5368
switch (opcode) {
5369
case SpvOpLabel:
5370
break;
5371
5372
case SpvOpLoopMerge:
5373
case SpvOpSelectionMerge:
5374
/* This is handled by cfg pre-pass and walk_blocks */
5375
break;
5376
5377
case SpvOpUndef: {
5378
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
5379
val->type = vtn_get_type(b, w[1]);
5380
break;
5381
}
5382
5383
case SpvOpExtInst:
5384
vtn_handle_extension(b, opcode, w, count);
5385
break;
5386
5387
case SpvOpVariable:
5388
case SpvOpLoad:
5389
case SpvOpStore:
5390
case SpvOpCopyMemory:
5391
case SpvOpCopyMemorySized:
5392
case SpvOpAccessChain:
5393
case SpvOpPtrAccessChain:
5394
case SpvOpInBoundsAccessChain:
5395
case SpvOpInBoundsPtrAccessChain:
5396
case SpvOpArrayLength:
5397
case SpvOpConvertPtrToU:
5398
case SpvOpConvertUToPtr:
5399
case SpvOpGenericCastToPtrExplicit:
5400
case SpvOpGenericPtrMemSemantics:
5401
case SpvOpSubgroupBlockReadINTEL:
5402
case SpvOpSubgroupBlockWriteINTEL:
5403
case SpvOpConvertUToAccelerationStructureKHR:
5404
vtn_handle_variables(b, opcode, w, count);
5405
break;
5406
5407
case SpvOpFunctionCall:
5408
vtn_handle_function_call(b, opcode, w, count);
5409
break;
5410
5411
case SpvOpSampledImage:
5412
case SpvOpImage:
5413
case SpvOpImageSparseTexelsResident:
5414
case SpvOpImageSampleImplicitLod:
5415
case SpvOpImageSparseSampleImplicitLod:
5416
case SpvOpImageSampleExplicitLod:
5417
case SpvOpImageSparseSampleExplicitLod:
5418
case SpvOpImageSampleDrefImplicitLod:
5419
case SpvOpImageSparseSampleDrefImplicitLod:
5420
case SpvOpImageSampleDrefExplicitLod:
5421
case SpvOpImageSparseSampleDrefExplicitLod:
5422
case SpvOpImageSampleProjImplicitLod:
5423
case SpvOpImageSampleProjExplicitLod:
5424
case SpvOpImageSampleProjDrefImplicitLod:
5425
case SpvOpImageSampleProjDrefExplicitLod:
5426
case SpvOpImageFetch:
5427
case SpvOpImageSparseFetch:
5428
case SpvOpImageGather:
5429
case SpvOpImageSparseGather:
5430
case SpvOpImageDrefGather:
5431
case SpvOpImageSparseDrefGather:
5432
case SpvOpImageQueryLod:
5433
case SpvOpImageQueryLevels:
5434
vtn_handle_texture(b, opcode, w, count);
5435
break;
5436
5437
case SpvOpImageRead:
5438
case SpvOpImageSparseRead:
5439
case SpvOpImageWrite:
5440
case SpvOpImageTexelPointer:
5441
case SpvOpImageQueryFormat:
5442
case SpvOpImageQueryOrder:
5443
vtn_handle_image(b, opcode, w, count);
5444
break;
5445
5446
case SpvOpImageQuerySamples:
5447
case SpvOpImageQuerySizeLod:
5448
case SpvOpImageQuerySize: {
5449
struct vtn_type *image_type = vtn_get_value_type(b, w[3]);
5450
vtn_assert(image_type->base_type == vtn_base_type_image);
5451
if (glsl_type_is_image(image_type->glsl_image)) {
5452
vtn_handle_image(b, opcode, w, count);
5453
} else {
5454
vtn_assert(glsl_type_is_sampler(image_type->glsl_image));
5455
vtn_handle_texture(b, opcode, w, count);
5456
}
5457
break;
5458
}
5459
5460
case SpvOpFragmentMaskFetchAMD:
5461
case SpvOpFragmentFetchAMD:
5462
vtn_handle_texture(b, opcode, w, count);
5463
break;
5464
5465
case SpvOpAtomicLoad:
5466
case SpvOpAtomicExchange:
5467
case SpvOpAtomicCompareExchange:
5468
case SpvOpAtomicCompareExchangeWeak:
5469
case SpvOpAtomicIIncrement:
5470
case SpvOpAtomicIDecrement:
5471
case SpvOpAtomicIAdd:
5472
case SpvOpAtomicISub:
5473
case SpvOpAtomicSMin:
5474
case SpvOpAtomicUMin:
5475
case SpvOpAtomicSMax:
5476
case SpvOpAtomicUMax:
5477
case SpvOpAtomicAnd:
5478
case SpvOpAtomicOr:
5479
case SpvOpAtomicXor:
5480
case SpvOpAtomicFAddEXT:
5481
case SpvOpAtomicFMinEXT:
5482
case SpvOpAtomicFMaxEXT: {
5483
struct vtn_value *pointer = vtn_untyped_value(b, w[3]);
5484
if (pointer->value_type == vtn_value_type_image_pointer) {
5485
vtn_handle_image(b, opcode, w, count);
5486
} else {
5487
vtn_assert(pointer->value_type == vtn_value_type_pointer);
5488
vtn_handle_atomics(b, opcode, w, count);
5489
}
5490
break;
5491
}
5492
5493
case SpvOpAtomicStore: {
5494
struct vtn_value *pointer = vtn_untyped_value(b, w[1]);
5495
if (pointer->value_type == vtn_value_type_image_pointer) {
5496
vtn_handle_image(b, opcode, w, count);
5497
} else {
5498
vtn_assert(pointer->value_type == vtn_value_type_pointer);
5499
vtn_handle_atomics(b, opcode, w, count);
5500
}
5501
break;
5502
}
5503
5504
case SpvOpSelect:
5505
vtn_handle_select(b, opcode, w, count);
5506
break;
5507
5508
case SpvOpSNegate:
5509
case SpvOpFNegate:
5510
case SpvOpNot:
5511
case SpvOpAny:
5512
case SpvOpAll:
5513
case SpvOpConvertFToU:
5514
case SpvOpConvertFToS:
5515
case SpvOpConvertSToF:
5516
case SpvOpConvertUToF:
5517
case SpvOpUConvert:
5518
case SpvOpSConvert:
5519
case SpvOpFConvert:
5520
case SpvOpQuantizeToF16:
5521
case SpvOpSatConvertSToU:
5522
case SpvOpSatConvertUToS:
5523
case SpvOpPtrCastToGeneric:
5524
case SpvOpGenericCastToPtr:
5525
case SpvOpIsNan:
5526
case SpvOpIsInf:
5527
case SpvOpIsFinite:
5528
case SpvOpIsNormal:
5529
case SpvOpSignBitSet:
5530
case SpvOpLessOrGreater:
5531
case SpvOpOrdered:
5532
case SpvOpUnordered:
5533
case SpvOpIAdd:
5534
case SpvOpFAdd:
5535
case SpvOpISub:
5536
case SpvOpFSub:
5537
case SpvOpIMul:
5538
case SpvOpFMul:
5539
case SpvOpUDiv:
5540
case SpvOpSDiv:
5541
case SpvOpFDiv:
5542
case SpvOpUMod:
5543
case SpvOpSRem:
5544
case SpvOpSMod:
5545
case SpvOpFRem:
5546
case SpvOpFMod:
5547
case SpvOpVectorTimesScalar:
5548
case SpvOpDot:
5549
case SpvOpIAddCarry:
5550
case SpvOpISubBorrow:
5551
case SpvOpUMulExtended:
5552
case SpvOpSMulExtended:
5553
case SpvOpShiftRightLogical:
5554
case SpvOpShiftRightArithmetic:
5555
case SpvOpShiftLeftLogical:
5556
case SpvOpLogicalEqual:
5557
case SpvOpLogicalNotEqual:
5558
case SpvOpLogicalOr:
5559
case SpvOpLogicalAnd:
5560
case SpvOpLogicalNot:
5561
case SpvOpBitwiseOr:
5562
case SpvOpBitwiseXor:
5563
case SpvOpBitwiseAnd:
5564
case SpvOpIEqual:
5565
case SpvOpFOrdEqual:
5566
case SpvOpFUnordEqual:
5567
case SpvOpINotEqual:
5568
case SpvOpFOrdNotEqual:
5569
case SpvOpFUnordNotEqual:
5570
case SpvOpULessThan:
5571
case SpvOpSLessThan:
5572
case SpvOpFOrdLessThan:
5573
case SpvOpFUnordLessThan:
5574
case SpvOpUGreaterThan:
5575
case SpvOpSGreaterThan:
5576
case SpvOpFOrdGreaterThan:
5577
case SpvOpFUnordGreaterThan:
5578
case SpvOpULessThanEqual:
5579
case SpvOpSLessThanEqual:
5580
case SpvOpFOrdLessThanEqual:
5581
case SpvOpFUnordLessThanEqual:
5582
case SpvOpUGreaterThanEqual:
5583
case SpvOpSGreaterThanEqual:
5584
case SpvOpFOrdGreaterThanEqual:
5585
case SpvOpFUnordGreaterThanEqual:
5586
case SpvOpDPdx:
5587
case SpvOpDPdy:
5588
case SpvOpFwidth:
5589
case SpvOpDPdxFine:
5590
case SpvOpDPdyFine:
5591
case SpvOpFwidthFine:
5592
case SpvOpDPdxCoarse:
5593
case SpvOpDPdyCoarse:
5594
case SpvOpFwidthCoarse:
5595
case SpvOpBitFieldInsert:
5596
case SpvOpBitFieldSExtract:
5597
case SpvOpBitFieldUExtract:
5598
case SpvOpBitReverse:
5599
case SpvOpBitCount:
5600
case SpvOpTranspose:
5601
case SpvOpOuterProduct:
5602
case SpvOpMatrixTimesScalar:
5603
case SpvOpVectorTimesMatrix:
5604
case SpvOpMatrixTimesVector:
5605
case SpvOpMatrixTimesMatrix:
5606
case SpvOpUCountLeadingZerosINTEL:
5607
case SpvOpUCountTrailingZerosINTEL:
5608
case SpvOpAbsISubINTEL:
5609
case SpvOpAbsUSubINTEL:
5610
case SpvOpIAddSatINTEL:
5611
case SpvOpUAddSatINTEL:
5612
case SpvOpIAverageINTEL:
5613
case SpvOpUAverageINTEL:
5614
case SpvOpIAverageRoundedINTEL:
5615
case SpvOpUAverageRoundedINTEL:
5616
case SpvOpISubSatINTEL:
5617
case SpvOpUSubSatINTEL:
5618
case SpvOpIMul32x16INTEL:
5619
case SpvOpUMul32x16INTEL:
5620
vtn_handle_alu(b, opcode, w, count);
5621
break;
5622
5623
case SpvOpBitcast:
5624
vtn_handle_bitcast(b, w, count);
5625
break;
5626
5627
case SpvOpVectorExtractDynamic:
5628
case SpvOpVectorInsertDynamic:
5629
case SpvOpVectorShuffle:
5630
case SpvOpCompositeConstruct:
5631
case SpvOpCompositeExtract:
5632
case SpvOpCompositeInsert:
5633
case SpvOpCopyLogical:
5634
case SpvOpCopyObject:
5635
vtn_handle_composite(b, opcode, w, count);
5636
break;
5637
5638
case SpvOpEmitVertex:
5639
case SpvOpEndPrimitive:
5640
case SpvOpEmitStreamVertex:
5641
case SpvOpEndStreamPrimitive:
5642
case SpvOpControlBarrier:
5643
case SpvOpMemoryBarrier:
5644
vtn_handle_barrier(b, opcode, w, count);
5645
break;
5646
5647
case SpvOpGroupNonUniformElect:
5648
case SpvOpGroupNonUniformAll:
5649
case SpvOpGroupNonUniformAny:
5650
case SpvOpGroupNonUniformAllEqual:
5651
case SpvOpGroupNonUniformBroadcast:
5652
case SpvOpGroupNonUniformBroadcastFirst:
5653
case SpvOpGroupNonUniformBallot:
5654
case SpvOpGroupNonUniformInverseBallot:
5655
case SpvOpGroupNonUniformBallotBitExtract:
5656
case SpvOpGroupNonUniformBallotBitCount:
5657
case SpvOpGroupNonUniformBallotFindLSB:
5658
case SpvOpGroupNonUniformBallotFindMSB:
5659
case SpvOpGroupNonUniformShuffle:
5660
case SpvOpGroupNonUniformShuffleXor:
5661
case SpvOpGroupNonUniformShuffleUp:
5662
case SpvOpGroupNonUniformShuffleDown:
5663
case SpvOpGroupNonUniformIAdd:
5664
case SpvOpGroupNonUniformFAdd:
5665
case SpvOpGroupNonUniformIMul:
5666
case SpvOpGroupNonUniformFMul:
5667
case SpvOpGroupNonUniformSMin:
5668
case SpvOpGroupNonUniformUMin:
5669
case SpvOpGroupNonUniformFMin:
5670
case SpvOpGroupNonUniformSMax:
5671
case SpvOpGroupNonUniformUMax:
5672
case SpvOpGroupNonUniformFMax:
5673
case SpvOpGroupNonUniformBitwiseAnd:
5674
case SpvOpGroupNonUniformBitwiseOr:
5675
case SpvOpGroupNonUniformBitwiseXor:
5676
case SpvOpGroupNonUniformLogicalAnd:
5677
case SpvOpGroupNonUniformLogicalOr:
5678
case SpvOpGroupNonUniformLogicalXor:
5679
case SpvOpGroupNonUniformQuadBroadcast:
5680
case SpvOpGroupNonUniformQuadSwap:
5681
case SpvOpGroupAll:
5682
case SpvOpGroupAny:
5683
case SpvOpGroupBroadcast:
5684
case SpvOpGroupIAdd:
5685
case SpvOpGroupFAdd:
5686
case SpvOpGroupFMin:
5687
case SpvOpGroupUMin:
5688
case SpvOpGroupSMin:
5689
case SpvOpGroupFMax:
5690
case SpvOpGroupUMax:
5691
case SpvOpGroupSMax:
5692
case SpvOpSubgroupBallotKHR:
5693
case SpvOpSubgroupFirstInvocationKHR:
5694
case SpvOpSubgroupReadInvocationKHR:
5695
case SpvOpSubgroupAllKHR:
5696
case SpvOpSubgroupAnyKHR:
5697
case SpvOpSubgroupAllEqualKHR:
5698
case SpvOpGroupIAddNonUniformAMD:
5699
case SpvOpGroupFAddNonUniformAMD:
5700
case SpvOpGroupFMinNonUniformAMD:
5701
case SpvOpGroupUMinNonUniformAMD:
5702
case SpvOpGroupSMinNonUniformAMD:
5703
case SpvOpGroupFMaxNonUniformAMD:
5704
case SpvOpGroupUMaxNonUniformAMD:
5705
case SpvOpGroupSMaxNonUniformAMD:
5706
case SpvOpSubgroupShuffleINTEL:
5707
case SpvOpSubgroupShuffleDownINTEL:
5708
case SpvOpSubgroupShuffleUpINTEL:
5709
case SpvOpSubgroupShuffleXorINTEL:
5710
vtn_handle_subgroup(b, opcode, w, count);
5711
break;
5712
5713
case SpvOpPtrDiff:
5714
case SpvOpPtrEqual:
5715
case SpvOpPtrNotEqual:
5716
vtn_handle_ptr(b, opcode, w, count);
5717
break;
5718
5719
case SpvOpBeginInvocationInterlockEXT:
5720
nir_begin_invocation_interlock(&b->nb);
5721
break;
5722
5723
case SpvOpEndInvocationInterlockEXT:
5724
nir_end_invocation_interlock(&b->nb);
5725
break;
5726
5727
case SpvOpDemoteToHelperInvocationEXT: {
5728
nir_demote(&b->nb);
5729
break;
5730
}
5731
5732
case SpvOpIsHelperInvocationEXT: {
5733
vtn_push_nir_ssa(b, w[2], nir_is_helper_invocation(&b->nb, 1));
5734
break;
5735
}
5736
5737
case SpvOpReadClockKHR: {
5738
SpvScope scope = vtn_constant_uint(b, w[3]);
5739
nir_scope nir_scope;
5740
5741
switch (scope) {
5742
case SpvScopeDevice:
5743
nir_scope = NIR_SCOPE_DEVICE;
5744
break;
5745
case SpvScopeSubgroup:
5746
nir_scope = NIR_SCOPE_SUBGROUP;
5747
break;
5748
default:
5749
vtn_fail("invalid read clock scope");
5750
}
5751
5752
/* Operation supports two result types: uvec2 and uint64_t. The NIR
5753
* intrinsic gives uvec2, so pack the result for the other case.
5754
*/
5755
nir_ssa_def *result = nir_shader_clock(&b->nb, nir_scope);
5756
5757
struct vtn_type *type = vtn_get_type(b, w[1]);
5758
const struct glsl_type *dest_type = type->type;
5759
5760
if (glsl_type_is_vector(dest_type)) {
5761
assert(dest_type == glsl_vector_type(GLSL_TYPE_UINT, 2));
5762
} else {
5763
assert(glsl_type_is_scalar(dest_type));
5764
assert(glsl_get_base_type(dest_type) == GLSL_TYPE_UINT64);
5765
result = nir_pack_64_2x32(&b->nb, result);
5766
}
5767
5768
vtn_push_nir_ssa(b, w[2], result);
5769
break;
5770
}
5771
5772
case SpvOpTraceNV:
5773
case SpvOpTraceRayKHR:
5774
case SpvOpReportIntersectionKHR:
5775
case SpvOpIgnoreIntersectionNV:
5776
case SpvOpTerminateRayNV:
5777
case SpvOpExecuteCallableNV:
5778
case SpvOpExecuteCallableKHR:
5779
vtn_handle_ray_intrinsic(b, opcode, w, count);
5780
break;
5781
5782
case SpvOpLifetimeStart:
5783
case SpvOpLifetimeStop:
5784
break;
5785
5786
case SpvOpGroupAsyncCopy:
5787
case SpvOpGroupWaitEvents:
5788
vtn_handle_opencl_core_instruction(b, opcode, w, count);
5789
break;
5790
5791
default:
5792
vtn_fail_with_opcode("Unhandled opcode", opcode);
5793
}
5794
5795
return true;
5796
}
5797
5798
struct vtn_builder*
5799
vtn_create_builder(const uint32_t *words, size_t word_count,
5800
gl_shader_stage stage, const char *entry_point_name,
5801
const struct spirv_to_nir_options *options)
5802
{
5803
/* Initialize the vtn_builder object */
5804
struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
5805
struct spirv_to_nir_options *dup_options =
5806
ralloc(b, struct spirv_to_nir_options);
5807
*dup_options = *options;
5808
5809
b->spirv = words;
5810
b->spirv_word_count = word_count;
5811
b->file = NULL;
5812
b->line = -1;
5813
b->col = -1;
5814
list_inithead(&b->functions);
5815
b->entry_point_stage = stage;
5816
b->entry_point_name = entry_point_name;
5817
b->options = dup_options;
5818
5819
/*
5820
* Handle the SPIR-V header (first 5 dwords).
5821
* Can't use vtx_assert() as the setjmp(3) target isn't initialized yet.
5822
*/
5823
if (word_count <= 5)
5824
goto fail;
5825
5826
if (words[0] != SpvMagicNumber) {
5827
vtn_err("words[0] was 0x%x, want 0x%x", words[0], SpvMagicNumber);
5828
goto fail;
5829
}
5830
5831
b->version = words[1];
5832
if (b->version < 0x10000) {
5833
vtn_err("version was 0x%x, want >= 0x10000", b->version);
5834
goto fail;
5835
}
5836
5837
b->generator_id = words[2] >> 16;
5838
uint16_t generator_version = words[2];
5839
5840
/* In GLSLang commit 8297936dd6eb3, their handling of barrier() was fixed
5841
* to provide correct memory semantics on compute shader barrier()
5842
* commands. Prior to that, we need to fix them up ourselves. This
5843
* GLSLang fix caused them to bump to generator version 3.
5844
*/
5845
b->wa_glslang_cs_barrier =
5846
(b->generator_id == vtn_generator_glslang_reference_front_end &&
5847
generator_version < 3);
5848
5849
/* words[2] == generator magic */
5850
unsigned value_id_bound = words[3];
5851
if (words[4] != 0) {
5852
vtn_err("words[4] was %u, want 0", words[4]);
5853
goto fail;
5854
}
5855
5856
b->value_id_bound = value_id_bound;
5857
b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
5858
5859
if (b->options->environment == NIR_SPIRV_VULKAN && b->version < 0x10400)
5860
b->vars_used_indirectly = _mesa_pointer_set_create(b);
5861
5862
return b;
5863
fail:
5864
ralloc_free(b);
5865
return NULL;
5866
}
5867
5868
static nir_function *
5869
vtn_emit_kernel_entry_point_wrapper(struct vtn_builder *b,
5870
nir_function *entry_point)
5871
{
5872
vtn_assert(entry_point == b->entry_point->func->nir_func);
5873
vtn_fail_if(!entry_point->name, "entry points are required to have a name");
5874
const char *func_name =
5875
ralloc_asprintf(b->shader, "__wrapped_%s", entry_point->name);
5876
5877
vtn_assert(b->shader->info.stage == MESA_SHADER_KERNEL);
5878
5879
nir_function *main_entry_point = nir_function_create(b->shader, func_name);
5880
main_entry_point->impl = nir_function_impl_create(main_entry_point);
5881
nir_builder_init(&b->nb, main_entry_point->impl);
5882
b->nb.cursor = nir_after_cf_list(&main_entry_point->impl->body);
5883
b->func_param_idx = 0;
5884
5885
nir_call_instr *call = nir_call_instr_create(b->nb.shader, entry_point);
5886
5887
for (unsigned i = 0; i < entry_point->num_params; ++i) {
5888
struct vtn_type *param_type = b->entry_point->func->type->params[i];
5889
5890
/* consider all pointers to function memory to be parameters passed
5891
* by value
5892
*/
5893
bool is_by_val = param_type->base_type == vtn_base_type_pointer &&
5894
param_type->storage_class == SpvStorageClassFunction;
5895
5896
/* input variable */
5897
nir_variable *in_var = rzalloc(b->nb.shader, nir_variable);
5898
in_var->data.mode = nir_var_uniform;
5899
in_var->data.read_only = true;
5900
in_var->data.location = i;
5901
if (param_type->base_type == vtn_base_type_image) {
5902
in_var->data.access =
5903
spirv_to_gl_access_qualifier(b, param_type->access_qualifier);
5904
}
5905
5906
if (is_by_val)
5907
in_var->type = param_type->deref->type;
5908
else if (param_type->base_type == vtn_base_type_image)
5909
in_var->type = param_type->glsl_image;
5910
else if (param_type->base_type == vtn_base_type_sampler)
5911
in_var->type = glsl_bare_sampler_type();
5912
else
5913
in_var->type = param_type->type;
5914
5915
nir_shader_add_variable(b->nb.shader, in_var);
5916
5917
/* we have to copy the entire variable into function memory */
5918
if (is_by_val) {
5919
nir_variable *copy_var =
5920
nir_local_variable_create(main_entry_point->impl, in_var->type,
5921
"copy_in");
5922
nir_copy_var(&b->nb, copy_var, in_var);
5923
call->params[i] =
5924
nir_src_for_ssa(&nir_build_deref_var(&b->nb, copy_var)->dest.ssa);
5925
} else if (param_type->base_type == vtn_base_type_image ||
5926
param_type->base_type == vtn_base_type_sampler) {
5927
/* Don't load the var, just pass a deref of it */
5928
call->params[i] = nir_src_for_ssa(&nir_build_deref_var(&b->nb, in_var)->dest.ssa);
5929
} else {
5930
call->params[i] = nir_src_for_ssa(nir_load_var(&b->nb, in_var));
5931
}
5932
}
5933
5934
nir_builder_instr_insert(&b->nb, &call->instr);
5935
5936
return main_entry_point;
5937
}
5938
5939
static bool
5940
can_remove(nir_variable *var, void *data)
5941
{
5942
const struct set *vars_used_indirectly = data;
5943
return !_mesa_set_search(vars_used_indirectly, var);
5944
}
5945
5946
nir_shader *
5947
spirv_to_nir(const uint32_t *words, size_t word_count,
5948
struct nir_spirv_specialization *spec, unsigned num_spec,
5949
gl_shader_stage stage, const char *entry_point_name,
5950
const struct spirv_to_nir_options *options,
5951
const nir_shader_compiler_options *nir_options)
5952
5953
{
5954
const uint32_t *word_end = words + word_count;
5955
5956
struct vtn_builder *b = vtn_create_builder(words, word_count,
5957
stage, entry_point_name,
5958
options);
5959
5960
if (b == NULL)
5961
return NULL;
5962
5963
/* See also _vtn_fail() */
5964
if (vtn_setjmp(b->fail_jump)) {
5965
ralloc_free(b);
5966
return NULL;
5967
}
5968
5969
/* Skip the SPIR-V header, handled at vtn_create_builder */
5970
words+= 5;
5971
5972
b->shader = nir_shader_create(b, stage, nir_options, NULL);
5973
b->shader->info.float_controls_execution_mode = options->float_controls_execution_mode;
5974
5975
/* Handle all the preamble instructions */
5976
words = vtn_foreach_instruction(b, words, word_end,
5977
vtn_handle_preamble_instruction);
5978
5979
/* DirectXShaderCompiler and glslang/shaderc both create OpKill from HLSL's
5980
* discard/clip, which uses demote semantics. DirectXShaderCompiler will use
5981
* demote if the extension is enabled, so we disable this workaround in that
5982
* case.
5983
*
5984
* Related glslang issue: https://github.com/KhronosGroup/glslang/issues/2416
5985
*/
5986
bool glslang = b->generator_id == vtn_generator_glslang_reference_front_end ||
5987
b->generator_id == vtn_generator_shaderc_over_glslang;
5988
bool dxsc = b->generator_id == vtn_generator_spiregg;
5989
b->convert_discard_to_demote = ((dxsc && !b->uses_demote_to_helper_invocation) ||
5990
(glslang && b->source_lang == SpvSourceLanguageHLSL)) &&
5991
options->caps.demote_to_helper_invocation;
5992
5993
if (!options->create_library && b->entry_point == NULL) {
5994
vtn_fail("Entry point not found for %s shader \"%s\"",
5995
_mesa_shader_stage_to_string(stage), entry_point_name);
5996
ralloc_free(b);
5997
return NULL;
5998
}
5999
6000
/* Ensure a sane address mode is being used for function temps */
6001
assert(nir_address_format_bit_size(b->options->temp_addr_format) == nir_get_ptr_bitsize(b->shader));
6002
assert(nir_address_format_num_components(b->options->temp_addr_format) == 1);
6003
6004
/* Set shader info defaults */
6005
if (stage == MESA_SHADER_GEOMETRY)
6006
b->shader->info.gs.invocations = 1;
6007
6008
/* Parse execution modes. */
6009
if (!options->create_library)
6010
vtn_foreach_execution_mode(b, b->entry_point,
6011
vtn_handle_execution_mode, NULL);
6012
6013
b->specializations = spec;
6014
b->num_specializations = num_spec;
6015
6016
/* Handle all variable, type, and constant instructions */
6017
words = vtn_foreach_instruction(b, words, word_end,
6018
vtn_handle_variable_or_type_instruction);
6019
6020
/* Parse execution modes that depend on IDs. Must happen after we have
6021
* constants parsed.
6022
*/
6023
if (!options->create_library)
6024
vtn_foreach_execution_mode(b, b->entry_point,
6025
vtn_handle_execution_mode_id, NULL);
6026
6027
if (b->workgroup_size_builtin) {
6028
vtn_assert(gl_shader_stage_uses_workgroup(stage));
6029
vtn_assert(b->workgroup_size_builtin->type->type ==
6030
glsl_vector_type(GLSL_TYPE_UINT, 3));
6031
6032
nir_const_value *const_size =
6033
b->workgroup_size_builtin->constant->values;
6034
6035
b->shader->info.workgroup_size[0] = const_size[0].u32;
6036
b->shader->info.workgroup_size[1] = const_size[1].u32;
6037
b->shader->info.workgroup_size[2] = const_size[2].u32;
6038
}
6039
6040
/* Set types on all vtn_values */
6041
vtn_foreach_instruction(b, words, word_end, vtn_set_instruction_result_type);
6042
6043
vtn_build_cfg(b, words, word_end);
6044
6045
if (!options->create_library) {
6046
assert(b->entry_point->value_type == vtn_value_type_function);
6047
b->entry_point->func->referenced = true;
6048
}
6049
6050
bool progress;
6051
do {
6052
progress = false;
6053
vtn_foreach_cf_node(node, &b->functions) {
6054
struct vtn_function *func = vtn_cf_node_as_function(node);
6055
if ((options->create_library || func->referenced) && !func->emitted) {
6056
b->const_table = _mesa_pointer_hash_table_create(b);
6057
6058
vtn_function_emit(b, func, vtn_handle_body_instruction);
6059
progress = true;
6060
}
6061
}
6062
} while (progress);
6063
6064
if (!options->create_library) {
6065
vtn_assert(b->entry_point->value_type == vtn_value_type_function);
6066
nir_function *entry_point = b->entry_point->func->nir_func;
6067
vtn_assert(entry_point);
6068
6069
/* post process entry_points with input params */
6070
if (entry_point->num_params && b->shader->info.stage == MESA_SHADER_KERNEL)
6071
entry_point = vtn_emit_kernel_entry_point_wrapper(b, entry_point);
6072
6073
entry_point->is_entrypoint = true;
6074
}
6075
6076
/* structurize the CFG */
6077
nir_lower_goto_ifs(b->shader);
6078
6079
/* A SPIR-V module can have multiple shaders stages and also multiple
6080
* shaders of the same stage. Global variables are declared per-module.
6081
*
6082
* Starting in SPIR-V 1.4 the list of global variables is part of
6083
* OpEntryPoint, so only valid ones will be created. Previous versions
6084
* only have Input and Output variables listed, so remove dead variables to
6085
* clean up the remaining ones.
6086
*/
6087
if (!options->create_library && b->version < 0x10400) {
6088
const nir_remove_dead_variables_options dead_opts = {
6089
.can_remove_var = can_remove,
6090
.can_remove_var_data = b->vars_used_indirectly,
6091
};
6092
nir_remove_dead_variables(b->shader, ~(nir_var_function_temp |
6093
nir_var_shader_out |
6094
nir_var_shader_in |
6095
nir_var_system_value),
6096
b->vars_used_indirectly ? &dead_opts : NULL);
6097
}
6098
6099
nir_foreach_variable_in_shader(var, b->shader) {
6100
switch (var->data.mode) {
6101
case nir_var_mem_ubo:
6102
b->shader->info.num_ubos++;
6103
break;
6104
case nir_var_mem_ssbo:
6105
b->shader->info.num_ssbos++;
6106
break;
6107
case nir_var_mem_push_const:
6108
vtn_assert(b->shader->num_uniforms == 0);
6109
b->shader->num_uniforms =
6110
glsl_get_explicit_size(glsl_without_array(var->type), false);
6111
break;
6112
}
6113
}
6114
6115
/* We sometimes generate bogus derefs that, while never used, give the
6116
* validator a bit of heartburn. Run dead code to get rid of them.
6117
*/
6118
nir_opt_dce(b->shader);
6119
6120
/* Per SPV_KHR_workgroup_storage_explicit_layout, if one shared variable is
6121
* a Block, all of them will be and Blocks are explicitly laid out.
6122
*/
6123
nir_foreach_variable_with_modes(var, b->shader, nir_var_mem_shared) {
6124
if (glsl_type_is_interface(var->type)) {
6125
assert(b->options->caps.workgroup_memory_explicit_layout);
6126
b->shader->info.shared_memory_explicit_layout = true;
6127
break;
6128
}
6129
}
6130
if (b->shader->info.shared_memory_explicit_layout) {
6131
unsigned size = 0;
6132
nir_foreach_variable_with_modes(var, b->shader, nir_var_mem_shared) {
6133
assert(glsl_type_is_interface(var->type));
6134
const bool align_to_stride = false;
6135
size = MAX2(size, glsl_get_explicit_size(var->type, align_to_stride));
6136
}
6137
b->shader->info.shared_size = size;
6138
}
6139
6140
/* Unparent the shader from the vtn_builder before we delete the builder */
6141
ralloc_steal(NULL, b->shader);
6142
6143
nir_shader *shader = b->shader;
6144
ralloc_free(b);
6145
6146
return shader;
6147
}
6148
6149