nir/spirv: Fix handling of OpGroupMemberDecorate
[mesa.git] / src / compiler / nir / spirv / spirv_to_nir.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jason Ekstrand (jason@jlekstrand.net)
25 *
26 */
27
28 #include "vtn_private.h"
29 #include "nir/nir_vla.h"
30 #include "nir/nir_control_flow.h"
31 #include "nir/nir_constant_expressions.h"
32
33 static struct vtn_ssa_value *
34 vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
35 {
36 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
37 val->type = type;
38
39 if (glsl_type_is_vector_or_scalar(type)) {
40 unsigned num_components = glsl_get_vector_elements(val->type);
41 nir_ssa_undef_instr *undef =
42 nir_ssa_undef_instr_create(b->shader, num_components);
43
44 nir_instr_insert_before_cf_list(&b->impl->body, &undef->instr);
45 val->def = &undef->def;
46 } else {
47 unsigned elems = glsl_get_length(val->type);
48 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
49 if (glsl_type_is_matrix(type)) {
50 const struct glsl_type *elem_type =
51 glsl_vector_type(glsl_get_base_type(type),
52 glsl_get_vector_elements(type));
53
54 for (unsigned i = 0; i < elems; i++)
55 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
56 } else if (glsl_type_is_array(type)) {
57 const struct glsl_type *elem_type = glsl_get_array_element(type);
58 for (unsigned i = 0; i < elems; i++)
59 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
60 } else {
61 for (unsigned i = 0; i < elems; i++) {
62 const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
63 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
64 }
65 }
66 }
67
68 return val;
69 }
70
71 static struct vtn_ssa_value *
72 vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
73 const struct glsl_type *type)
74 {
75 struct hash_entry *entry = _mesa_hash_table_search(b->const_table, constant);
76
77 if (entry)
78 return entry->data;
79
80 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
81 val->type = type;
82
83 switch (glsl_get_base_type(type)) {
84 case GLSL_TYPE_INT:
85 case GLSL_TYPE_UINT:
86 case GLSL_TYPE_BOOL:
87 case GLSL_TYPE_FLOAT:
88 case GLSL_TYPE_DOUBLE:
89 if (glsl_type_is_vector_or_scalar(type)) {
90 unsigned num_components = glsl_get_vector_elements(val->type);
91 nir_load_const_instr *load =
92 nir_load_const_instr_create(b->shader, num_components);
93
94 for (unsigned i = 0; i < num_components; i++)
95 load->value.u[i] = constant->value.u[i];
96
97 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
98 val->def = &load->def;
99 } else {
100 assert(glsl_type_is_matrix(type));
101 unsigned rows = glsl_get_vector_elements(val->type);
102 unsigned columns = glsl_get_matrix_columns(val->type);
103 val->elems = ralloc_array(b, struct vtn_ssa_value *, columns);
104
105 for (unsigned i = 0; i < columns; i++) {
106 struct vtn_ssa_value *col_val = rzalloc(b, struct vtn_ssa_value);
107 col_val->type = glsl_get_column_type(val->type);
108 nir_load_const_instr *load =
109 nir_load_const_instr_create(b->shader, rows);
110
111 for (unsigned j = 0; j < rows; j++)
112 load->value.u[j] = constant->value.u[rows * i + j];
113
114 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
115 col_val->def = &load->def;
116
117 val->elems[i] = col_val;
118 }
119 }
120 break;
121
122 case GLSL_TYPE_ARRAY: {
123 unsigned elems = glsl_get_length(val->type);
124 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
125 const struct glsl_type *elem_type = glsl_get_array_element(val->type);
126 for (unsigned i = 0; i < elems; i++)
127 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
128 elem_type);
129 break;
130 }
131
132 case GLSL_TYPE_STRUCT: {
133 unsigned elems = glsl_get_length(val->type);
134 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
135 for (unsigned i = 0; i < elems; i++) {
136 const struct glsl_type *elem_type =
137 glsl_get_struct_field(val->type, i);
138 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
139 elem_type);
140 }
141 break;
142 }
143
144 default:
145 unreachable("bad constant type");
146 }
147
148 return val;
149 }
150
151 struct vtn_ssa_value *
152 vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
153 {
154 struct vtn_value *val = vtn_untyped_value(b, value_id);
155 switch (val->value_type) {
156 case vtn_value_type_undef:
157 return vtn_undef_ssa_value(b, val->type->type);
158
159 case vtn_value_type_constant:
160 return vtn_const_ssa_value(b, val->constant, val->const_type);
161
162 case vtn_value_type_ssa:
163 return val->ssa;
164
165 case vtn_value_type_access_chain:
166 /* This is needed for function parameters */
167 return vtn_variable_load(b, val->access_chain);
168
169 default:
170 unreachable("Invalid type for an SSA value");
171 }
172 }
173
174 static char *
175 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
176 unsigned word_count, unsigned *words_used)
177 {
178 char *dup = ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
179 if (words_used) {
180 /* Ammount of space taken by the string (including the null) */
181 unsigned len = strlen(dup) + 1;
182 *words_used = DIV_ROUND_UP(len, sizeof(*words));
183 }
184 return dup;
185 }
186
187 const uint32_t *
188 vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
189 const uint32_t *end, vtn_instruction_handler handler)
190 {
191 b->file = NULL;
192 b->line = -1;
193 b->col = -1;
194
195 const uint32_t *w = start;
196 while (w < end) {
197 SpvOp opcode = w[0] & SpvOpCodeMask;
198 unsigned count = w[0] >> SpvWordCountShift;
199 assert(count >= 1 && w + count <= end);
200
201 switch (opcode) {
202 case SpvOpNop:
203 break; /* Do nothing */
204
205 case SpvOpLine:
206 b->file = vtn_value(b, w[1], vtn_value_type_string)->str;
207 b->line = w[2];
208 b->col = w[3];
209 break;
210
211 case SpvOpNoLine:
212 b->file = NULL;
213 b->line = -1;
214 b->col = -1;
215 break;
216
217 default:
218 if (!handler(b, opcode, w, count))
219 return w;
220 break;
221 }
222
223 w += count;
224 }
225 assert(w == end);
226 return w;
227 }
228
229 static void
230 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
231 const uint32_t *w, unsigned count)
232 {
233 switch (opcode) {
234 case SpvOpExtInstImport: {
235 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
236 if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) {
237 val->ext_handler = vtn_handle_glsl450_instruction;
238 } else {
239 assert(!"Unsupported extension");
240 }
241 break;
242 }
243
244 case SpvOpExtInst: {
245 struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
246 bool handled = val->ext_handler(b, w[4], w, count);
247 (void)handled;
248 assert(handled);
249 break;
250 }
251
252 default:
253 unreachable("Unhandled opcode");
254 }
255 }
256
257 static void
258 _foreach_decoration_helper(struct vtn_builder *b,
259 struct vtn_value *base_value,
260 int parent_member,
261 struct vtn_value *value,
262 vtn_decoration_foreach_cb cb, void *data)
263 {
264 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
265 int member;
266 if (dec->scope == VTN_DEC_DECORATION) {
267 member = parent_member;
268 } else if (dec->scope >= VTN_DEC_STRUCT_MEMBER0) {
269 assert(parent_member == -1);
270 member = dec->scope - VTN_DEC_STRUCT_MEMBER0;
271 } else {
272 /* Not a decoration */
273 continue;
274 }
275
276 if (dec->group) {
277 assert(dec->group->value_type == vtn_value_type_decoration_group);
278 _foreach_decoration_helper(b, base_value, member, dec->group,
279 cb, data);
280 } else {
281 cb(b, base_value, member, dec, data);
282 }
283 }
284 }
285
286 /** Iterates (recursively if needed) over all of the decorations on a value
287 *
288 * This function iterates over all of the decorations applied to a given
289 * value. If it encounters a decoration group, it recurses into the group
290 * and iterates over all of those decorations as well.
291 */
292 void
293 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
294 vtn_decoration_foreach_cb cb, void *data)
295 {
296 _foreach_decoration_helper(b, value, -1, value, cb, data);
297 }
298
299 void
300 vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,
301 vtn_execution_mode_foreach_cb cb, void *data)
302 {
303 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
304 if (dec->scope != VTN_DEC_EXECUTION_MODE)
305 continue;
306
307 assert(dec->group == NULL);
308 cb(b, value, dec, data);
309 }
310 }
311
312 static void
313 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
314 const uint32_t *w, unsigned count)
315 {
316 const uint32_t *w_end = w + count;
317 const uint32_t target = w[1];
318 w += 2;
319
320 switch (opcode) {
321 case SpvOpDecorationGroup:
322 vtn_push_value(b, target, vtn_value_type_decoration_group);
323 break;
324
325 case SpvOpDecorate:
326 case SpvOpMemberDecorate:
327 case SpvOpExecutionMode: {
328 struct vtn_value *val = &b->values[target];
329
330 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
331 switch (opcode) {
332 case SpvOpDecorate:
333 dec->scope = VTN_DEC_DECORATION;
334 break;
335 case SpvOpMemberDecorate:
336 dec->scope = VTN_DEC_STRUCT_MEMBER0 + *(w++);
337 break;
338 case SpvOpExecutionMode:
339 dec->scope = VTN_DEC_EXECUTION_MODE;
340 break;
341 default:
342 unreachable("Invalid decoration opcode");
343 }
344 dec->decoration = *(w++);
345 dec->literals = w;
346
347 /* Link into the list */
348 dec->next = val->decoration;
349 val->decoration = dec;
350 break;
351 }
352
353 case SpvOpGroupMemberDecorate:
354 case SpvOpGroupDecorate: {
355 struct vtn_value *group =
356 vtn_value(b, target, vtn_value_type_decoration_group);
357
358 for (; w < w_end; w++) {
359 struct vtn_value *val = vtn_untyped_value(b, *w);
360 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
361
362 dec->group = group;
363 if (opcode == SpvOpGroupDecorate) {
364 dec->scope = VTN_DEC_DECORATION;
365 } else {
366 dec->scope = VTN_DEC_STRUCT_MEMBER0 + *(++w);
367 }
368
369 /* Link into the list */
370 dec->next = val->decoration;
371 val->decoration = dec;
372 }
373 break;
374 }
375
376 default:
377 unreachable("Unhandled opcode");
378 }
379 }
380
381 struct member_decoration_ctx {
382 unsigned num_fields;
383 struct glsl_struct_field *fields;
384 struct vtn_type *type;
385 };
386
387 /* does a shallow copy of a vtn_type */
388
389 static struct vtn_type *
390 vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
391 {
392 struct vtn_type *dest = ralloc(b, struct vtn_type);
393 dest->type = src->type;
394 dest->is_builtin = src->is_builtin;
395 if (src->is_builtin)
396 dest->builtin = src->builtin;
397
398 if (!glsl_type_is_scalar(src->type)) {
399 switch (glsl_get_base_type(src->type)) {
400 case GLSL_TYPE_INT:
401 case GLSL_TYPE_UINT:
402 case GLSL_TYPE_BOOL:
403 case GLSL_TYPE_FLOAT:
404 case GLSL_TYPE_DOUBLE:
405 case GLSL_TYPE_ARRAY:
406 dest->row_major = src->row_major;
407 dest->stride = src->stride;
408 dest->array_element = src->array_element;
409 break;
410
411 case GLSL_TYPE_STRUCT: {
412 unsigned elems = glsl_get_length(src->type);
413
414 dest->members = ralloc_array(b, struct vtn_type *, elems);
415 memcpy(dest->members, src->members, elems * sizeof(struct vtn_type *));
416
417 dest->offsets = ralloc_array(b, unsigned, elems);
418 memcpy(dest->offsets, src->offsets, elems * sizeof(unsigned));
419 break;
420 }
421
422 default:
423 unreachable("unhandled type");
424 }
425 }
426
427 return dest;
428 }
429
430 static struct vtn_type *
431 mutable_matrix_member(struct vtn_builder *b, struct vtn_type *type, int member)
432 {
433 type->members[member] = vtn_type_copy(b, type->members[member]);
434 type = type->members[member];
435
436 /* We may have an array of matrices.... Oh, joy! */
437 while (glsl_type_is_array(type->type)) {
438 type->array_element = vtn_type_copy(b, type->array_element);
439 type = type->array_element;
440 }
441
442 assert(glsl_type_is_matrix(type->type));
443
444 return type;
445 }
446
447 static void
448 struct_member_decoration_cb(struct vtn_builder *b,
449 struct vtn_value *val, int member,
450 const struct vtn_decoration *dec, void *void_ctx)
451 {
452 struct member_decoration_ctx *ctx = void_ctx;
453
454 if (member < 0)
455 return;
456
457 assert(member < ctx->num_fields);
458
459 switch (dec->decoration) {
460 case SpvDecorationRelaxedPrecision:
461 break; /* FIXME: Do nothing with this for now. */
462 case SpvDecorationNoPerspective:
463 ctx->fields[member].interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
464 break;
465 case SpvDecorationFlat:
466 ctx->fields[member].interpolation = INTERP_QUALIFIER_FLAT;
467 break;
468 case SpvDecorationCentroid:
469 ctx->fields[member].centroid = true;
470 break;
471 case SpvDecorationSample:
472 ctx->fields[member].sample = true;
473 break;
474 case SpvDecorationLocation:
475 ctx->fields[member].location = dec->literals[0];
476 break;
477 case SpvDecorationBuiltIn:
478 ctx->type->members[member] = vtn_type_copy(b, ctx->type->members[member]);
479 ctx->type->members[member]->is_builtin = true;
480 ctx->type->members[member]->builtin = dec->literals[0];
481 ctx->type->builtin_block = true;
482 break;
483 case SpvDecorationOffset:
484 ctx->type->offsets[member] = dec->literals[0];
485 break;
486 case SpvDecorationMatrixStride:
487 mutable_matrix_member(b, ctx->type, member)->stride = dec->literals[0];
488 break;
489 case SpvDecorationColMajor:
490 break; /* Nothing to do here. Column-major is the default. */
491 case SpvDecorationRowMajor:
492 mutable_matrix_member(b, ctx->type, member)->row_major = true;
493 break;
494 default:
495 unreachable("Unhandled member decoration");
496 }
497 }
498
499 static void
500 type_decoration_cb(struct vtn_builder *b,
501 struct vtn_value *val, int member,
502 const struct vtn_decoration *dec, void *ctx)
503 {
504 struct vtn_type *type = val->type;
505
506 if (member != -1)
507 return;
508
509 switch (dec->decoration) {
510 case SpvDecorationArrayStride:
511 type->stride = dec->literals[0];
512 break;
513 case SpvDecorationBlock:
514 type->block = true;
515 break;
516 case SpvDecorationBufferBlock:
517 type->buffer_block = true;
518 break;
519 case SpvDecorationGLSLShared:
520 case SpvDecorationGLSLPacked:
521 /* Ignore these, since we get explicit offsets anyways */
522 break;
523
524 case SpvDecorationStream:
525 assert(dec->literals[0] == 0);
526 break;
527
528 default:
529 unreachable("Unhandled type decoration");
530 }
531 }
532
533 static unsigned
534 translate_image_format(SpvImageFormat format)
535 {
536 switch (format) {
537 case SpvImageFormatUnknown: return 0; /* GL_NONE */
538 case SpvImageFormatRgba32f: return 0x8814; /* GL_RGBA32F */
539 case SpvImageFormatRgba16f: return 0x881A; /* GL_RGBA16F */
540 case SpvImageFormatR32f: return 0x822E; /* GL_R32F */
541 case SpvImageFormatRgba8: return 0x8058; /* GL_RGBA8 */
542 case SpvImageFormatRgba8Snorm: return 0x8F97; /* GL_RGBA8_SNORM */
543 case SpvImageFormatRg32f: return 0x8230; /* GL_RG32F */
544 case SpvImageFormatRg16f: return 0x822F; /* GL_RG16F */
545 case SpvImageFormatR11fG11fB10f: return 0x8C3A; /* GL_R11F_G11F_B10F */
546 case SpvImageFormatR16f: return 0x822D; /* GL_R16F */
547 case SpvImageFormatRgba16: return 0x805B; /* GL_RGBA16 */
548 case SpvImageFormatRgb10A2: return 0x8059; /* GL_RGB10_A2 */
549 case SpvImageFormatRg16: return 0x822C; /* GL_RG16 */
550 case SpvImageFormatRg8: return 0x822B; /* GL_RG8 */
551 case SpvImageFormatR16: return 0x822A; /* GL_R16 */
552 case SpvImageFormatR8: return 0x8229; /* GL_R8 */
553 case SpvImageFormatRgba16Snorm: return 0x8F9B; /* GL_RGBA16_SNORM */
554 case SpvImageFormatRg16Snorm: return 0x8F99; /* GL_RG16_SNORM */
555 case SpvImageFormatRg8Snorm: return 0x8F95; /* GL_RG8_SNORM */
556 case SpvImageFormatR16Snorm: return 0x8F98; /* GL_R16_SNORM */
557 case SpvImageFormatR8Snorm: return 0x8F94; /* GL_R8_SNORM */
558 case SpvImageFormatRgba32i: return 0x8D82; /* GL_RGBA32I */
559 case SpvImageFormatRgba16i: return 0x8D88; /* GL_RGBA16I */
560 case SpvImageFormatRgba8i: return 0x8D8E; /* GL_RGBA8I */
561 case SpvImageFormatR32i: return 0x8235; /* GL_R32I */
562 case SpvImageFormatRg32i: return 0x823B; /* GL_RG32I */
563 case SpvImageFormatRg16i: return 0x8239; /* GL_RG16I */
564 case SpvImageFormatRg8i: return 0x8237; /* GL_RG8I */
565 case SpvImageFormatR16i: return 0x8233; /* GL_R16I */
566 case SpvImageFormatR8i: return 0x8231; /* GL_R8I */
567 case SpvImageFormatRgba32ui: return 0x8D70; /* GL_RGBA32UI */
568 case SpvImageFormatRgba16ui: return 0x8D76; /* GL_RGBA16UI */
569 case SpvImageFormatRgba8ui: return 0x8D7C; /* GL_RGBA8UI */
570 case SpvImageFormatR32ui: return 0x8236; /* GL_R32UI */
571 case SpvImageFormatRgb10a2ui: return 0x906F; /* GL_RGB10_A2UI */
572 case SpvImageFormatRg32ui: return 0x823C; /* GL_RG32UI */
573 case SpvImageFormatRg16ui: return 0x823A; /* GL_RG16UI */
574 case SpvImageFormatRg8ui: return 0x8238; /* GL_RG8UI */
575 case SpvImageFormatR16ui: return 0x823A; /* GL_RG16UI */
576 case SpvImageFormatR8ui: return 0x8232; /* GL_R8UI */
577 default:
578 assert(!"Invalid image format");
579 return 0;
580 }
581 }
582
583 static void
584 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
585 const uint32_t *w, unsigned count)
586 {
587 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_type);
588
589 val->type = rzalloc(b, struct vtn_type);
590 val->type->is_builtin = false;
591 val->type->val = val;
592
593 switch (opcode) {
594 case SpvOpTypeVoid:
595 val->type->type = glsl_void_type();
596 break;
597 case SpvOpTypeBool:
598 val->type->type = glsl_bool_type();
599 break;
600 case SpvOpTypeInt: {
601 const bool signedness = w[3];
602 val->type->type = (signedness ? glsl_int_type() : glsl_uint_type());
603 break;
604 }
605 case SpvOpTypeFloat:
606 val->type->type = glsl_float_type();
607 break;
608
609 case SpvOpTypeVector: {
610 struct vtn_type *base = vtn_value(b, w[2], vtn_value_type_type)->type;
611 unsigned elems = w[3];
612
613 assert(glsl_type_is_scalar(base->type));
614 val->type->type = glsl_vector_type(glsl_get_base_type(base->type), elems);
615
616 /* Vectors implicitly have sizeof(base_type) stride. For now, this
617 * is always 4 bytes. This will have to change if we want to start
618 * supporting doubles or half-floats.
619 */
620 val->type->stride = 4;
621 val->type->array_element = base;
622 break;
623 }
624
625 case SpvOpTypeMatrix: {
626 struct vtn_type *base = vtn_value(b, w[2], vtn_value_type_type)->type;
627 unsigned columns = w[3];
628
629 assert(glsl_type_is_vector(base->type));
630 val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
631 glsl_get_vector_elements(base->type),
632 columns);
633 assert(!glsl_type_is_error(val->type->type));
634 val->type->array_element = base;
635 val->type->row_major = false;
636 val->type->stride = 0;
637 break;
638 }
639
640 case SpvOpTypeRuntimeArray:
641 case SpvOpTypeArray: {
642 struct vtn_type *array_element =
643 vtn_value(b, w[2], vtn_value_type_type)->type;
644
645 unsigned length;
646 if (opcode == SpvOpTypeRuntimeArray) {
647 /* A length of 0 is used to denote unsized arrays */
648 length = 0;
649 } else {
650 length =
651 vtn_value(b, w[3], vtn_value_type_constant)->constant->value.u[0];
652 }
653
654 val->type->type = glsl_array_type(array_element->type, length);
655 val->type->array_element = array_element;
656 val->type->stride = 0;
657 break;
658 }
659
660 case SpvOpTypeStruct: {
661 unsigned num_fields = count - 2;
662 val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
663 val->type->offsets = ralloc_array(b, unsigned, num_fields);
664
665 NIR_VLA(struct glsl_struct_field, fields, count);
666 for (unsigned i = 0; i < num_fields; i++) {
667 val->type->members[i] =
668 vtn_value(b, w[i + 2], vtn_value_type_type)->type;
669 fields[i] = (struct glsl_struct_field) {
670 .type = val->type->members[i]->type,
671 .name = ralloc_asprintf(b, "field%d", i),
672 .location = -1,
673 };
674 }
675
676 struct member_decoration_ctx ctx = {
677 .num_fields = num_fields,
678 .fields = fields,
679 .type = val->type
680 };
681
682 vtn_foreach_decoration(b, val, struct_member_decoration_cb, &ctx);
683
684 const char *name = val->name ? val->name : "struct";
685
686 val->type->type = glsl_struct_type(fields, num_fields, name);
687 break;
688 }
689
690 case SpvOpTypeFunction: {
691 const struct glsl_type *return_type =
692 vtn_value(b, w[2], vtn_value_type_type)->type->type;
693 NIR_VLA(struct glsl_function_param, params, count - 3);
694 for (unsigned i = 0; i < count - 3; i++) {
695 params[i].type = vtn_value(b, w[i + 3], vtn_value_type_type)->type->type;
696
697 /* FIXME: */
698 params[i].in = true;
699 params[i].out = true;
700 }
701 val->type->type = glsl_function_type(return_type, params, count - 3);
702 break;
703 }
704
705 case SpvOpTypePointer:
706 /* FIXME: For now, we'll just do the really lame thing and return
707 * the same type. The validator should ensure that the proper number
708 * of dereferences happen
709 */
710 val->type = vtn_value(b, w[3], vtn_value_type_type)->type;
711 break;
712
713 case SpvOpTypeImage: {
714 const struct glsl_type *sampled_type =
715 vtn_value(b, w[2], vtn_value_type_type)->type->type;
716
717 assert(glsl_type_is_vector_or_scalar(sampled_type));
718
719 enum glsl_sampler_dim dim;
720 switch ((SpvDim)w[3]) {
721 case SpvDim1D: dim = GLSL_SAMPLER_DIM_1D; break;
722 case SpvDim2D: dim = GLSL_SAMPLER_DIM_2D; break;
723 case SpvDim3D: dim = GLSL_SAMPLER_DIM_3D; break;
724 case SpvDimCube: dim = GLSL_SAMPLER_DIM_CUBE; break;
725 case SpvDimRect: dim = GLSL_SAMPLER_DIM_RECT; break;
726 case SpvDimBuffer: dim = GLSL_SAMPLER_DIM_BUF; break;
727 default:
728 unreachable("Invalid SPIR-V Sampler dimension");
729 }
730
731 bool is_shadow = w[4];
732 bool is_array = w[5];
733 bool multisampled = w[6];
734 unsigned sampled = w[7];
735 SpvImageFormat format = w[8];
736
737 if (count > 9)
738 val->type->access_qualifier = w[9];
739 else
740 val->type->access_qualifier = SpvAccessQualifierReadWrite;
741
742 assert(!multisampled && "FIXME: Handl multi-sampled textures");
743
744 val->type->image_format = translate_image_format(format);
745
746 if (sampled == 1) {
747 val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
748 glsl_get_base_type(sampled_type));
749 } else if (sampled == 2) {
750 assert(format);
751 assert(!is_shadow);
752 val->type->type = glsl_image_type(dim, is_array,
753 glsl_get_base_type(sampled_type));
754 } else {
755 assert(!"We need to know if the image will be sampled");
756 }
757 break;
758 }
759
760 case SpvOpTypeSampledImage:
761 val->type = vtn_value(b, w[2], vtn_value_type_type)->type;
762 break;
763
764 case SpvOpTypeSampler:
765 /* The actual sampler type here doesn't really matter. It gets
766 * thrown away the moment you combine it with an image. What really
767 * matters is that it's a sampler type as opposed to an integer type
768 * so the backend knows what to do.
769 *
770 * TODO: Eventually we should consider adding a "bare sampler" type
771 * to glsl_types.
772 */
773 val->type->type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false,
774 GLSL_TYPE_FLOAT);
775 break;
776
777 case SpvOpTypeOpaque:
778 case SpvOpTypeEvent:
779 case SpvOpTypeDeviceEvent:
780 case SpvOpTypeReserveId:
781 case SpvOpTypeQueue:
782 case SpvOpTypePipe:
783 default:
784 unreachable("Unhandled opcode");
785 }
786
787 vtn_foreach_decoration(b, val, type_decoration_cb, NULL);
788 }
789
790 static nir_constant *
791 vtn_null_constant(struct vtn_builder *b, const struct glsl_type *type)
792 {
793 nir_constant *c = rzalloc(b, nir_constant);
794
795 switch (glsl_get_base_type(type)) {
796 case GLSL_TYPE_INT:
797 case GLSL_TYPE_UINT:
798 case GLSL_TYPE_BOOL:
799 case GLSL_TYPE_FLOAT:
800 case GLSL_TYPE_DOUBLE:
801 /* Nothing to do here. It's already initialized to zero */
802 break;
803
804 case GLSL_TYPE_ARRAY:
805 assert(glsl_get_length(type) > 0);
806 c->num_elements = glsl_get_length(type);
807 c->elements = ralloc_array(b, nir_constant *, c->num_elements);
808
809 c->elements[0] = vtn_null_constant(b, glsl_get_array_element(type));
810 for (unsigned i = 1; i < c->num_elements; i++)
811 c->elements[i] = c->elements[0];
812 break;
813
814 case GLSL_TYPE_STRUCT:
815 c->num_elements = glsl_get_length(type);
816 c->elements = ralloc_array(b, nir_constant *, c->num_elements);
817
818 for (unsigned i = 0; i < c->num_elements; i++) {
819 c->elements[i] = vtn_null_constant(b, glsl_get_struct_field(type, i));
820 }
821 break;
822
823 default:
824 unreachable("Invalid type for null constant");
825 }
826
827 return c;
828 }
829
830 static void
831 spec_constant_deocoration_cb(struct vtn_builder *b, struct vtn_value *v,
832 int member, const struct vtn_decoration *dec,
833 void *data)
834 {
835 assert(member == -1);
836 if (dec->decoration != SpvDecorationSpecId)
837 return;
838
839 uint32_t *const_value = data;
840
841 for (unsigned i = 0; i < b->num_specializations; i++) {
842 if (b->specializations[i].id == dec->literals[0]) {
843 *const_value = b->specializations[i].data;
844 return;
845 }
846 }
847 }
848
849 static uint32_t
850 get_specialization(struct vtn_builder *b, struct vtn_value *val,
851 uint32_t const_value)
852 {
853 vtn_foreach_decoration(b, val, spec_constant_deocoration_cb, &const_value);
854 return const_value;
855 }
856
857 static void
858 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
859 const uint32_t *w, unsigned count)
860 {
861 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
862 val->const_type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
863 val->constant = rzalloc(b, nir_constant);
864 switch (opcode) {
865 case SpvOpConstantTrue:
866 assert(val->const_type == glsl_bool_type());
867 val->constant->value.u[0] = NIR_TRUE;
868 break;
869 case SpvOpConstantFalse:
870 assert(val->const_type == glsl_bool_type());
871 val->constant->value.u[0] = NIR_FALSE;
872 break;
873
874 case SpvOpSpecConstantTrue:
875 case SpvOpSpecConstantFalse: {
876 assert(val->const_type == glsl_bool_type());
877 uint32_t int_val =
878 get_specialization(b, val, (opcode == SpvOpSpecConstantTrue));
879 val->constant->value.u[0] = int_val ? NIR_TRUE : NIR_FALSE;
880 break;
881 }
882
883 case SpvOpConstant:
884 assert(glsl_type_is_scalar(val->const_type));
885 val->constant->value.u[0] = w[3];
886 break;
887 case SpvOpSpecConstant:
888 assert(glsl_type_is_scalar(val->const_type));
889 val->constant->value.u[0] = get_specialization(b, val, w[3]);
890 break;
891 case SpvOpSpecConstantComposite:
892 case SpvOpConstantComposite: {
893 unsigned elem_count = count - 3;
894 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
895 for (unsigned i = 0; i < elem_count; i++)
896 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
897
898 switch (glsl_get_base_type(val->const_type)) {
899 case GLSL_TYPE_UINT:
900 case GLSL_TYPE_INT:
901 case GLSL_TYPE_FLOAT:
902 case GLSL_TYPE_BOOL:
903 if (glsl_type_is_matrix(val->const_type)) {
904 unsigned rows = glsl_get_vector_elements(val->const_type);
905 assert(glsl_get_matrix_columns(val->const_type) == elem_count);
906 for (unsigned i = 0; i < elem_count; i++)
907 for (unsigned j = 0; j < rows; j++)
908 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
909 } else {
910 assert(glsl_type_is_vector(val->const_type));
911 assert(glsl_get_vector_elements(val->const_type) == elem_count);
912 for (unsigned i = 0; i < elem_count; i++)
913 val->constant->value.u[i] = elems[i]->value.u[0];
914 }
915 ralloc_free(elems);
916 break;
917
918 case GLSL_TYPE_STRUCT:
919 case GLSL_TYPE_ARRAY:
920 ralloc_steal(val->constant, elems);
921 val->constant->num_elements = elem_count;
922 val->constant->elements = elems;
923 break;
924
925 default:
926 unreachable("Unsupported type for constants");
927 }
928 break;
929 }
930
931 case SpvOpSpecConstantOp: {
932 SpvOp opcode = get_specialization(b, val, w[3]);
933 switch (opcode) {
934 case SpvOpVectorShuffle: {
935 struct vtn_value *v0 = vtn_value(b, w[4], vtn_value_type_constant);
936 struct vtn_value *v1 = vtn_value(b, w[5], vtn_value_type_constant);
937 unsigned len0 = glsl_get_vector_elements(v0->const_type);
938 unsigned len1 = glsl_get_vector_elements(v1->const_type);
939
940 uint32_t u[8];
941 for (unsigned i = 0; i < len0; i++)
942 u[i] = v0->constant->value.u[i];
943 for (unsigned i = 0; i < len1; i++)
944 u[len0 + i] = v1->constant->value.u[i];
945
946 for (unsigned i = 0; i < count - 6; i++) {
947 uint32_t comp = w[i + 6];
948 if (comp == (uint32_t)-1) {
949 val->constant->value.u[i] = 0xdeadbeef;
950 } else {
951 val->constant->value.u[i] = u[comp];
952 }
953 }
954 return;
955 }
956
957 case SpvOpCompositeExtract:
958 case SpvOpCompositeInsert: {
959 struct vtn_value *comp;
960 unsigned deref_start;
961 struct nir_constant **c;
962 if (opcode == SpvOpCompositeExtract) {
963 comp = vtn_value(b, w[4], vtn_value_type_constant);
964 deref_start = 5;
965 c = &comp->constant;
966 } else {
967 comp = vtn_value(b, w[5], vtn_value_type_constant);
968 deref_start = 6;
969 val->constant = nir_constant_clone(comp->constant,
970 (nir_variable *)b);
971 c = &val->constant;
972 }
973
974 int elem = -1;
975 const struct glsl_type *type = comp->const_type;
976 for (unsigned i = deref_start; i < count; i++) {
977 switch (glsl_get_base_type(type)) {
978 case GLSL_TYPE_UINT:
979 case GLSL_TYPE_INT:
980 case GLSL_TYPE_FLOAT:
981 case GLSL_TYPE_BOOL:
982 /* If we hit this granularity, we're picking off an element */
983 if (elem < 0)
984 elem = 0;
985
986 if (glsl_type_is_matrix(type)) {
987 elem += w[i] * glsl_get_vector_elements(type);
988 type = glsl_get_column_type(type);
989 } else {
990 assert(glsl_type_is_vector(type));
991 elem += w[i];
992 type = glsl_scalar_type(glsl_get_base_type(type));
993 }
994 continue;
995
996 case GLSL_TYPE_ARRAY:
997 c = &(*c)->elements[w[i]];
998 type = glsl_get_array_element(type);
999 continue;
1000
1001 case GLSL_TYPE_STRUCT:
1002 c = &(*c)->elements[w[i]];
1003 type = glsl_get_struct_field(type, w[i]);
1004 continue;
1005
1006 default:
1007 unreachable("Invalid constant type");
1008 }
1009 }
1010
1011 if (opcode == SpvOpCompositeExtract) {
1012 if (elem == -1) {
1013 val->constant = *c;
1014 } else {
1015 unsigned num_components = glsl_get_vector_elements(type);
1016 for (unsigned i = 0; i < num_components; i++)
1017 val->constant->value.u[i] = (*c)->value.u[elem + i];
1018 }
1019 } else {
1020 struct vtn_value *insert =
1021 vtn_value(b, w[4], vtn_value_type_constant);
1022 assert(insert->const_type == type);
1023 if (elem == -1) {
1024 *c = insert->constant;
1025 } else {
1026 unsigned num_components = glsl_get_vector_elements(type);
1027 for (unsigned i = 0; i < num_components; i++)
1028 (*c)->value.u[elem + i] = insert->constant->value.u[i];
1029 }
1030 }
1031 return;
1032 }
1033
1034 default: {
1035 bool swap;
1036 nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
1037
1038 unsigned num_components = glsl_get_vector_elements(val->const_type);
1039
1040 nir_const_value src[3];
1041 assert(count <= 7);
1042 for (unsigned i = 0; i < count - 4; i++) {
1043 nir_constant *c =
1044 vtn_value(b, w[4 + i], vtn_value_type_constant)->constant;
1045
1046 unsigned j = swap ? 1 - i : i;
1047 for (unsigned k = 0; k < num_components; k++)
1048 src[j].u[k] = c->value.u[k];
1049 }
1050
1051 nir_const_value res = nir_eval_const_opcode(op, num_components, src);
1052
1053 for (unsigned k = 0; k < num_components; k++)
1054 val->constant->value.u[k] = res.u[k];
1055
1056 return;
1057 } /* default */
1058 }
1059 }
1060
1061 case SpvOpConstantNull:
1062 val->constant = vtn_null_constant(b, val->const_type);
1063 break;
1064
1065 case SpvOpConstantSampler:
1066 assert(!"OpConstantSampler requires Kernel Capability");
1067 break;
1068
1069 default:
1070 unreachable("Unhandled opcode");
1071 }
1072 }
1073
1074 static void
1075 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
1076 const uint32_t *w, unsigned count)
1077 {
1078 struct nir_function *callee =
1079 vtn_value(b, w[3], vtn_value_type_function)->func->impl->function;
1080
1081 nir_call_instr *call = nir_call_instr_create(b->nb.shader, callee);
1082 for (unsigned i = 0; i < call->num_params; i++) {
1083 unsigned arg_id = w[4 + i];
1084 struct vtn_value *arg = vtn_untyped_value(b, arg_id);
1085 if (arg->value_type == vtn_value_type_access_chain) {
1086 nir_deref_var *d = vtn_access_chain_to_deref(b, arg->access_chain);
1087 call->params[i] = nir_deref_as_var(nir_copy_deref(call, &d->deref));
1088 } else {
1089 struct vtn_ssa_value *arg_ssa = vtn_ssa_value(b, arg_id);
1090
1091 /* Make a temporary to store the argument in */
1092 nir_variable *tmp =
1093 nir_local_variable_create(b->impl, arg_ssa->type, "arg_tmp");
1094 call->params[i] = nir_deref_var_create(call, tmp);
1095
1096 vtn_local_store(b, arg_ssa, call->params[i]);
1097 }
1098 }
1099
1100 nir_variable *out_tmp = NULL;
1101 if (!glsl_type_is_void(callee->return_type)) {
1102 out_tmp = nir_local_variable_create(b->impl, callee->return_type,
1103 "out_tmp");
1104 call->return_deref = nir_deref_var_create(call, out_tmp);
1105 }
1106
1107 nir_builder_instr_insert(&b->nb, &call->instr);
1108
1109 if (glsl_type_is_void(callee->return_type)) {
1110 vtn_push_value(b, w[2], vtn_value_type_undef);
1111 } else {
1112 struct vtn_value *retval = vtn_push_value(b, w[2], vtn_value_type_ssa);
1113 retval->ssa = vtn_local_load(b, call->return_deref);
1114 }
1115 }
1116
1117 struct vtn_ssa_value *
1118 vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
1119 {
1120 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
1121 val->type = type;
1122
1123 if (!glsl_type_is_vector_or_scalar(type)) {
1124 unsigned elems = glsl_get_length(type);
1125 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1126 for (unsigned i = 0; i < elems; i++) {
1127 const struct glsl_type *child_type;
1128
1129 switch (glsl_get_base_type(type)) {
1130 case GLSL_TYPE_INT:
1131 case GLSL_TYPE_UINT:
1132 case GLSL_TYPE_BOOL:
1133 case GLSL_TYPE_FLOAT:
1134 case GLSL_TYPE_DOUBLE:
1135 child_type = glsl_get_column_type(type);
1136 break;
1137 case GLSL_TYPE_ARRAY:
1138 child_type = glsl_get_array_element(type);
1139 break;
1140 case GLSL_TYPE_STRUCT:
1141 child_type = glsl_get_struct_field(type, i);
1142 break;
1143 default:
1144 unreachable("unkown base type");
1145 }
1146
1147 val->elems[i] = vtn_create_ssa_value(b, child_type);
1148 }
1149 }
1150
1151 return val;
1152 }
1153
1154 static nir_tex_src
1155 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
1156 {
1157 nir_tex_src src;
1158 src.src = nir_src_for_ssa(vtn_ssa_value(b, index)->def);
1159 src.src_type = type;
1160 return src;
1161 }
1162
1163 static void
1164 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
1165 const uint32_t *w, unsigned count)
1166 {
1167 if (opcode == SpvOpSampledImage) {
1168 struct vtn_value *val =
1169 vtn_push_value(b, w[2], vtn_value_type_sampled_image);
1170 val->sampled_image = ralloc(b, struct vtn_sampled_image);
1171 val->sampled_image->image =
1172 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1173 val->sampled_image->sampler =
1174 vtn_value(b, w[4], vtn_value_type_access_chain)->access_chain;
1175 return;
1176 } else if (opcode == SpvOpImage) {
1177 struct vtn_value *val =
1178 vtn_push_value(b, w[2], vtn_value_type_access_chain);
1179 struct vtn_value *src_val = vtn_untyped_value(b, w[3]);
1180 if (src_val->value_type == vtn_value_type_sampled_image) {
1181 val->access_chain = src_val->sampled_image->image;
1182 } else {
1183 assert(src_val->value_type == vtn_value_type_access_chain);
1184 val->access_chain = src_val->access_chain;
1185 }
1186 return;
1187 }
1188
1189 struct vtn_type *ret_type = vtn_value(b, w[1], vtn_value_type_type)->type;
1190 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1191
1192 struct vtn_sampled_image sampled;
1193 struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]);
1194 if (sampled_val->value_type == vtn_value_type_sampled_image) {
1195 sampled = *sampled_val->sampled_image;
1196 } else {
1197 assert(sampled_val->value_type == vtn_value_type_access_chain);
1198 sampled.image = NULL;
1199 sampled.sampler = sampled_val->access_chain;
1200 }
1201
1202 nir_tex_src srcs[8]; /* 8 should be enough */
1203 nir_tex_src *p = srcs;
1204
1205 unsigned idx = 4;
1206
1207 bool has_coord = false;
1208 switch (opcode) {
1209 case SpvOpImageSampleImplicitLod:
1210 case SpvOpImageSampleExplicitLod:
1211 case SpvOpImageSampleDrefImplicitLod:
1212 case SpvOpImageSampleDrefExplicitLod:
1213 case SpvOpImageSampleProjImplicitLod:
1214 case SpvOpImageSampleProjExplicitLod:
1215 case SpvOpImageSampleProjDrefImplicitLod:
1216 case SpvOpImageSampleProjDrefExplicitLod:
1217 case SpvOpImageFetch:
1218 case SpvOpImageGather:
1219 case SpvOpImageDrefGather:
1220 case SpvOpImageQueryLod: {
1221 /* All these types have the coordinate as their first real argument */
1222 struct vtn_ssa_value *coord = vtn_ssa_value(b, w[idx++]);
1223 has_coord = true;
1224 p->src = nir_src_for_ssa(coord->def);
1225 p->src_type = nir_tex_src_coord;
1226 p++;
1227 break;
1228 }
1229
1230 default:
1231 break;
1232 }
1233
1234 /* These all have an explicit depth value as their next source */
1235 switch (opcode) {
1236 case SpvOpImageSampleDrefImplicitLod:
1237 case SpvOpImageSampleDrefExplicitLod:
1238 case SpvOpImageSampleProjDrefImplicitLod:
1239 case SpvOpImageSampleProjDrefExplicitLod:
1240 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_comparitor);
1241 break;
1242 default:
1243 break;
1244 }
1245
1246 /* For OpImageQuerySizeLod, we always have an LOD */
1247 if (opcode == SpvOpImageQuerySizeLod)
1248 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
1249
1250 /* Figure out the base texture operation */
1251 nir_texop texop;
1252 switch (opcode) {
1253 case SpvOpImageSampleImplicitLod:
1254 case SpvOpImageSampleDrefImplicitLod:
1255 case SpvOpImageSampleProjImplicitLod:
1256 case SpvOpImageSampleProjDrefImplicitLod:
1257 texop = nir_texop_tex;
1258 break;
1259
1260 case SpvOpImageSampleExplicitLod:
1261 case SpvOpImageSampleDrefExplicitLod:
1262 case SpvOpImageSampleProjExplicitLod:
1263 case SpvOpImageSampleProjDrefExplicitLod:
1264 texop = nir_texop_txl;
1265 break;
1266
1267 case SpvOpImageFetch:
1268 texop = nir_texop_txf;
1269 break;
1270
1271 case SpvOpImageGather:
1272 case SpvOpImageDrefGather:
1273 texop = nir_texop_tg4;
1274 break;
1275
1276 case SpvOpImageQuerySizeLod:
1277 case SpvOpImageQuerySize:
1278 texop = nir_texop_txs;
1279 break;
1280
1281 case SpvOpImageQueryLod:
1282 texop = nir_texop_lod;
1283 break;
1284
1285 case SpvOpImageQueryLevels:
1286 texop = nir_texop_query_levels;
1287 break;
1288
1289 case SpvOpImageQuerySamples:
1290 default:
1291 unreachable("Unhandled opcode");
1292 }
1293
1294 nir_constant *const_offset = NULL;
1295
1296 /* Now we need to handle some number of optional arguments */
1297 if (idx < count) {
1298 uint32_t operands = w[idx++];
1299
1300 if (operands & SpvImageOperandsBiasMask) {
1301 assert(texop == nir_texop_tex);
1302 texop = nir_texop_txb;
1303 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_bias);
1304 }
1305
1306 if (operands & SpvImageOperandsLodMask) {
1307 assert(texop == nir_texop_txl || texop == nir_texop_txf ||
1308 texop == nir_texop_txs);
1309 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
1310 }
1311
1312 if (operands & SpvImageOperandsGradMask) {
1313 assert(texop == nir_texop_tex);
1314 texop = nir_texop_txd;
1315 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddx);
1316 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddy);
1317 }
1318
1319 if (operands & SpvImageOperandsConstOffsetMask) {
1320 const_offset =
1321 vtn_value(b, w[idx++], vtn_value_type_constant)->constant;
1322 }
1323
1324 if (operands & SpvImageOperandsOffsetMask)
1325 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_offset);
1326
1327 if (operands & SpvImageOperandsConstOffsetsMask)
1328 assert(!"Constant offsets to texture gather not yet implemented");
1329
1330 if (operands & SpvImageOperandsSampleMask) {
1331 assert(texop == nir_texop_txf);
1332 texop = nir_texop_txf_ms;
1333 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
1334 }
1335 }
1336 /* We should have now consumed exactly all of the arguments */
1337 assert(idx == count);
1338
1339 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
1340 instr->op = texop;
1341
1342 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
1343
1344 const struct glsl_type *image_type;
1345 if (sampled.image) {
1346 image_type = sampled.image->var->var->interface_type;
1347 } else {
1348 image_type = sampled.sampler->var->var->interface_type;
1349 }
1350
1351 instr->sampler_dim = glsl_get_sampler_dim(image_type);
1352 instr->is_array = glsl_sampler_type_is_array(image_type);
1353 instr->is_shadow = glsl_sampler_type_is_shadow(image_type);
1354 instr->is_new_style_shadow = instr->is_shadow;
1355
1356 if (const_offset) {
1357 for (unsigned i = 0; i < 4; i++)
1358 instr->const_offset[i] = const_offset->value.u[i];
1359 }
1360
1361 if (has_coord) {
1362 switch (instr->sampler_dim) {
1363 case GLSL_SAMPLER_DIM_1D:
1364 case GLSL_SAMPLER_DIM_BUF:
1365 instr->coord_components = 1;
1366 break;
1367 case GLSL_SAMPLER_DIM_2D:
1368 case GLSL_SAMPLER_DIM_RECT:
1369 instr->coord_components = 2;
1370 break;
1371 case GLSL_SAMPLER_DIM_3D:
1372 case GLSL_SAMPLER_DIM_CUBE:
1373 case GLSL_SAMPLER_DIM_MS:
1374 instr->coord_components = 3;
1375 break;
1376 default:
1377 assert("Invalid sampler type");
1378 }
1379
1380 if (instr->is_array)
1381 instr->coord_components++;
1382 } else {
1383 instr->coord_components = 0;
1384 }
1385
1386 switch (glsl_get_sampler_result_type(image_type)) {
1387 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
1388 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
1389 case GLSL_TYPE_UINT: instr->dest_type = nir_type_uint; break;
1390 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
1391 default:
1392 unreachable("Invalid base type for sampler result");
1393 }
1394
1395 nir_deref_var *sampler = vtn_access_chain_to_deref(b, sampled.sampler);
1396 if (sampled.image) {
1397 nir_deref_var *image = vtn_access_chain_to_deref(b, sampled.image);
1398 instr->texture = nir_deref_as_var(nir_copy_deref(instr, &image->deref));
1399 } else {
1400 instr->texture = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
1401 }
1402
1403 switch (instr->op) {
1404 case nir_texop_tex:
1405 case nir_texop_txb:
1406 case nir_texop_txl:
1407 case nir_texop_txd:
1408 /* These operations require a sampler */
1409 instr->sampler = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
1410 break;
1411 case nir_texop_txf:
1412 case nir_texop_txf_ms:
1413 case nir_texop_txs:
1414 case nir_texop_lod:
1415 case nir_texop_tg4:
1416 case nir_texop_query_levels:
1417 case nir_texop_texture_samples:
1418 case nir_texop_samples_identical:
1419 /* These don't */
1420 instr->sampler = NULL;
1421 break;
1422 }
1423
1424 nir_ssa_dest_init(&instr->instr, &instr->dest,
1425 nir_tex_instr_dest_size(instr), NULL);
1426
1427 assert(glsl_get_vector_elements(ret_type->type) ==
1428 nir_tex_instr_dest_size(instr));
1429
1430 val->ssa = vtn_create_ssa_value(b, ret_type->type);
1431 val->ssa->def = &instr->dest.ssa;
1432
1433 nir_builder_instr_insert(&b->nb, &instr->instr);
1434 }
1435
1436 static nir_ssa_def *
1437 get_image_coord(struct vtn_builder *b, uint32_t value)
1438 {
1439 struct vtn_ssa_value *coord = vtn_ssa_value(b, value);
1440
1441 /* The image_load_store intrinsics assume a 4-dim coordinate */
1442 unsigned dim = glsl_get_vector_elements(coord->type);
1443 unsigned swizzle[4];
1444 for (unsigned i = 0; i < 4; i++)
1445 swizzle[i] = MIN2(i, dim - 1);
1446
1447 return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);
1448 }
1449
1450 static void
1451 vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
1452 const uint32_t *w, unsigned count)
1453 {
1454 /* Just get this one out of the way */
1455 if (opcode == SpvOpImageTexelPointer) {
1456 struct vtn_value *val =
1457 vtn_push_value(b, w[2], vtn_value_type_image_pointer);
1458 val->image = ralloc(b, struct vtn_image_pointer);
1459
1460 val->image->image =
1461 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1462 val->image->coord = get_image_coord(b, w[4]);
1463 val->image->sample = vtn_ssa_value(b, w[5])->def;
1464 return;
1465 }
1466
1467 struct vtn_image_pointer image;
1468
1469 switch (opcode) {
1470 case SpvOpAtomicExchange:
1471 case SpvOpAtomicCompareExchange:
1472 case SpvOpAtomicCompareExchangeWeak:
1473 case SpvOpAtomicIIncrement:
1474 case SpvOpAtomicIDecrement:
1475 case SpvOpAtomicIAdd:
1476 case SpvOpAtomicISub:
1477 case SpvOpAtomicSMin:
1478 case SpvOpAtomicUMin:
1479 case SpvOpAtomicSMax:
1480 case SpvOpAtomicUMax:
1481 case SpvOpAtomicAnd:
1482 case SpvOpAtomicOr:
1483 case SpvOpAtomicXor:
1484 image = *vtn_value(b, w[3], vtn_value_type_image_pointer)->image;
1485 break;
1486
1487 case SpvOpImageQuerySize:
1488 image.image =
1489 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1490 image.coord = NULL;
1491 image.sample = NULL;
1492 break;
1493
1494 case SpvOpImageRead:
1495 image.image =
1496 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1497 image.coord = get_image_coord(b, w[4]);
1498
1499 if (count > 5 && (w[5] & SpvImageOperandsSampleMask)) {
1500 assert(w[5] == SpvImageOperandsSampleMask);
1501 image.sample = vtn_ssa_value(b, w[6])->def;
1502 } else {
1503 image.sample = nir_ssa_undef(&b->nb, 1);
1504 }
1505 break;
1506
1507 case SpvOpImageWrite:
1508 image.image =
1509 vtn_value(b, w[1], vtn_value_type_access_chain)->access_chain;
1510 image.coord = get_image_coord(b, w[2]);
1511
1512 /* texel = w[3] */
1513
1514 if (count > 4 && (w[4] & SpvImageOperandsSampleMask)) {
1515 assert(w[4] == SpvImageOperandsSampleMask);
1516 image.sample = vtn_ssa_value(b, w[5])->def;
1517 } else {
1518 image.sample = nir_ssa_undef(&b->nb, 1);
1519 }
1520 break;
1521
1522 default:
1523 unreachable("Invalid image opcode");
1524 }
1525
1526 nir_intrinsic_op op;
1527 switch (opcode) {
1528 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
1529 OP(ImageQuerySize, size)
1530 OP(ImageRead, load)
1531 OP(ImageWrite, store)
1532 OP(AtomicExchange, atomic_exchange)
1533 OP(AtomicCompareExchange, atomic_comp_swap)
1534 OP(AtomicIIncrement, atomic_add)
1535 OP(AtomicIDecrement, atomic_add)
1536 OP(AtomicIAdd, atomic_add)
1537 OP(AtomicISub, atomic_add)
1538 OP(AtomicSMin, atomic_min)
1539 OP(AtomicUMin, atomic_min)
1540 OP(AtomicSMax, atomic_max)
1541 OP(AtomicUMax, atomic_max)
1542 OP(AtomicAnd, atomic_and)
1543 OP(AtomicOr, atomic_or)
1544 OP(AtomicXor, atomic_xor)
1545 #undef OP
1546 default:
1547 unreachable("Invalid image opcode");
1548 }
1549
1550 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
1551
1552 nir_deref_var *image_deref = vtn_access_chain_to_deref(b, image.image);
1553 intrin->variables[0] =
1554 nir_deref_as_var(nir_copy_deref(&intrin->instr, &image_deref->deref));
1555
1556 /* ImageQuerySize doesn't take any extra parameters */
1557 if (opcode != SpvOpImageQuerySize) {
1558 /* The image coordinate is always 4 components but we may not have that
1559 * many. Swizzle to compensate.
1560 */
1561 unsigned swiz[4];
1562 for (unsigned i = 0; i < 4; i++)
1563 swiz[i] = i < image.coord->num_components ? i : 0;
1564 intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
1565 swiz, 4, false));
1566 intrin->src[1] = nir_src_for_ssa(image.sample);
1567 }
1568
1569 switch (opcode) {
1570 case SpvOpImageQuerySize:
1571 case SpvOpImageRead:
1572 break;
1573 case SpvOpImageWrite:
1574 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
1575 break;
1576 case SpvOpAtomicIIncrement:
1577 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
1578 break;
1579 case SpvOpAtomicIDecrement:
1580 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
1581 break;
1582
1583 case SpvOpAtomicExchange:
1584 case SpvOpAtomicIAdd:
1585 case SpvOpAtomicSMin:
1586 case SpvOpAtomicUMin:
1587 case SpvOpAtomicSMax:
1588 case SpvOpAtomicUMax:
1589 case SpvOpAtomicAnd:
1590 case SpvOpAtomicOr:
1591 case SpvOpAtomicXor:
1592 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1593 break;
1594
1595 case SpvOpAtomicCompareExchange:
1596 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
1597 intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1598 break;
1599
1600 case SpvOpAtomicISub:
1601 intrin->src[2] = nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
1602 break;
1603
1604 default:
1605 unreachable("Invalid image opcode");
1606 }
1607
1608 if (opcode != SpvOpImageWrite) {
1609 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1610 struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
1611 nir_ssa_dest_init(&intrin->instr, &intrin->dest, 4, NULL);
1612
1613 nir_builder_instr_insert(&b->nb, &intrin->instr);
1614
1615 /* The image intrinsics always return 4 channels but we may not want
1616 * that many. Emit a mov to trim it down.
1617 */
1618 unsigned swiz[4] = {0, 1, 2, 3};
1619 val->ssa = vtn_create_ssa_value(b, type->type);
1620 val->ssa->def = nir_swizzle(&b->nb, &intrin->dest.ssa, swiz,
1621 glsl_get_vector_elements(type->type), false);
1622 } else {
1623 nir_builder_instr_insert(&b->nb, &intrin->instr);
1624 }
1625 }
1626
1627 static nir_intrinsic_op
1628 get_ssbo_nir_atomic_op(SpvOp opcode)
1629 {
1630 switch (opcode) {
1631 #define OP(S, N) case SpvOp##S: return nir_intrinsic_ssbo_##N;
1632 OP(AtomicExchange, atomic_exchange)
1633 OP(AtomicCompareExchange, atomic_comp_swap)
1634 OP(AtomicIIncrement, atomic_add)
1635 OP(AtomicIDecrement, atomic_add)
1636 OP(AtomicIAdd, atomic_add)
1637 OP(AtomicISub, atomic_add)
1638 OP(AtomicSMin, atomic_imin)
1639 OP(AtomicUMin, atomic_umin)
1640 OP(AtomicSMax, atomic_imax)
1641 OP(AtomicUMax, atomic_umax)
1642 OP(AtomicAnd, atomic_and)
1643 OP(AtomicOr, atomic_or)
1644 OP(AtomicXor, atomic_xor)
1645 #undef OP
1646 default:
1647 unreachable("Invalid SSBO atomic");
1648 }
1649 }
1650
1651 static nir_intrinsic_op
1652 get_shared_nir_atomic_op(SpvOp opcode)
1653 {
1654 switch (opcode) {
1655 #define OP(S, N) case SpvOp##S: return nir_intrinsic_var_##N;
1656 OP(AtomicExchange, atomic_exchange)
1657 OP(AtomicCompareExchange, atomic_comp_swap)
1658 OP(AtomicIIncrement, atomic_add)
1659 OP(AtomicIDecrement, atomic_add)
1660 OP(AtomicIAdd, atomic_add)
1661 OP(AtomicISub, atomic_add)
1662 OP(AtomicSMin, atomic_imin)
1663 OP(AtomicUMin, atomic_umin)
1664 OP(AtomicSMax, atomic_imax)
1665 OP(AtomicUMax, atomic_umax)
1666 OP(AtomicAnd, atomic_and)
1667 OP(AtomicOr, atomic_or)
1668 OP(AtomicXor, atomic_xor)
1669 #undef OP
1670 default:
1671 unreachable("Invalid shared atomic");
1672 }
1673 }
1674
1675 static void
1676 fill_common_atomic_sources(struct vtn_builder *b, SpvOp opcode,
1677 const uint32_t *w, nir_src *src)
1678 {
1679 switch (opcode) {
1680 case SpvOpAtomicIIncrement:
1681 src[0] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
1682 break;
1683
1684 case SpvOpAtomicIDecrement:
1685 src[0] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
1686 break;
1687
1688 case SpvOpAtomicISub:
1689 src[0] =
1690 nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
1691 break;
1692
1693 case SpvOpAtomicCompareExchange:
1694 src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
1695 src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[8])->def);
1696 break;
1697 /* Fall through */
1698
1699 case SpvOpAtomicExchange:
1700 case SpvOpAtomicIAdd:
1701 case SpvOpAtomicSMin:
1702 case SpvOpAtomicUMin:
1703 case SpvOpAtomicSMax:
1704 case SpvOpAtomicUMax:
1705 case SpvOpAtomicAnd:
1706 case SpvOpAtomicOr:
1707 case SpvOpAtomicXor:
1708 src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1709 break;
1710
1711 default:
1712 unreachable("Invalid SPIR-V atomic");
1713 }
1714 }
1715
1716 static void
1717 vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode,
1718 const uint32_t *w, unsigned count)
1719 {
1720 struct vtn_access_chain *chain =
1721 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1722 nir_intrinsic_instr *atomic;
1723
1724 /*
1725 SpvScope scope = w[4];
1726 SpvMemorySemanticsMask semantics = w[5];
1727 */
1728
1729 if (chain->var->mode == vtn_variable_mode_workgroup) {
1730 nir_deref *deref = &vtn_access_chain_to_deref(b, chain)->deref;
1731 nir_intrinsic_op op = get_shared_nir_atomic_op(opcode);
1732 atomic = nir_intrinsic_instr_create(b->nb.shader, op);
1733 atomic->variables[0] = nir_deref_as_var(nir_copy_deref(atomic, deref));
1734 fill_common_atomic_sources(b, opcode, w, &atomic->src[0]);
1735 } else {
1736 assert(chain->var->mode == vtn_variable_mode_ssbo);
1737 struct vtn_type *type;
1738 nir_ssa_def *offset, *index;
1739 offset = vtn_access_chain_to_offset(b, chain, &index, &type, NULL, false);
1740
1741 nir_intrinsic_op op = get_ssbo_nir_atomic_op(opcode);
1742
1743 atomic = nir_intrinsic_instr_create(b->nb.shader, op);
1744 atomic->src[0] = nir_src_for_ssa(index);
1745 atomic->src[1] = nir_src_for_ssa(offset);
1746 fill_common_atomic_sources(b, opcode, w, &atomic->src[2]);
1747 }
1748
1749 nir_ssa_dest_init(&atomic->instr, &atomic->dest, 1, NULL);
1750
1751 struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
1752 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1753 val->ssa = rzalloc(b, struct vtn_ssa_value);
1754 val->ssa->def = &atomic->dest.ssa;
1755 val->ssa->type = type->type;
1756
1757 nir_builder_instr_insert(&b->nb, &atomic->instr);
1758 }
1759
1760 static nir_alu_instr *
1761 create_vec(nir_shader *shader, unsigned num_components)
1762 {
1763 nir_op op;
1764 switch (num_components) {
1765 case 1: op = nir_op_fmov; break;
1766 case 2: op = nir_op_vec2; break;
1767 case 3: op = nir_op_vec3; break;
1768 case 4: op = nir_op_vec4; break;
1769 default: unreachable("bad vector size");
1770 }
1771
1772 nir_alu_instr *vec = nir_alu_instr_create(shader, op);
1773 nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components, NULL);
1774 vec->dest.write_mask = (1 << num_components) - 1;
1775
1776 return vec;
1777 }
1778
1779 struct vtn_ssa_value *
1780 vtn_ssa_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
1781 {
1782 if (src->transposed)
1783 return src->transposed;
1784
1785 struct vtn_ssa_value *dest =
1786 vtn_create_ssa_value(b, glsl_transposed_type(src->type));
1787
1788 for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
1789 nir_alu_instr *vec = create_vec(b->shader,
1790 glsl_get_matrix_columns(src->type));
1791 if (glsl_type_is_vector_or_scalar(src->type)) {
1792 vec->src[0].src = nir_src_for_ssa(src->def);
1793 vec->src[0].swizzle[0] = i;
1794 } else {
1795 for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
1796 vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
1797 vec->src[j].swizzle[0] = i;
1798 }
1799 }
1800 nir_builder_instr_insert(&b->nb, &vec->instr);
1801 dest->elems[i]->def = &vec->dest.dest.ssa;
1802 }
1803
1804 dest->transposed = src;
1805
1806 return dest;
1807 }
1808
1809 nir_ssa_def *
1810 vtn_vector_extract(struct vtn_builder *b, nir_ssa_def *src, unsigned index)
1811 {
1812 unsigned swiz[4] = { index };
1813 return nir_swizzle(&b->nb, src, swiz, 1, true);
1814 }
1815
1816 nir_ssa_def *
1817 vtn_vector_insert(struct vtn_builder *b, nir_ssa_def *src, nir_ssa_def *insert,
1818 unsigned index)
1819 {
1820 nir_alu_instr *vec = create_vec(b->shader, src->num_components);
1821
1822 for (unsigned i = 0; i < src->num_components; i++) {
1823 if (i == index) {
1824 vec->src[i].src = nir_src_for_ssa(insert);
1825 } else {
1826 vec->src[i].src = nir_src_for_ssa(src);
1827 vec->src[i].swizzle[0] = i;
1828 }
1829 }
1830
1831 nir_builder_instr_insert(&b->nb, &vec->instr);
1832
1833 return &vec->dest.dest.ssa;
1834 }
1835
1836 nir_ssa_def *
1837 vtn_vector_extract_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1838 nir_ssa_def *index)
1839 {
1840 nir_ssa_def *dest = vtn_vector_extract(b, src, 0);
1841 for (unsigned i = 1; i < src->num_components; i++)
1842 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1843 vtn_vector_extract(b, src, i), dest);
1844
1845 return dest;
1846 }
1847
1848 nir_ssa_def *
1849 vtn_vector_insert_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1850 nir_ssa_def *insert, nir_ssa_def *index)
1851 {
1852 nir_ssa_def *dest = vtn_vector_insert(b, src, insert, 0);
1853 for (unsigned i = 1; i < src->num_components; i++)
1854 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1855 vtn_vector_insert(b, src, insert, i), dest);
1856
1857 return dest;
1858 }
1859
1860 static nir_ssa_def *
1861 vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
1862 nir_ssa_def *src0, nir_ssa_def *src1,
1863 const uint32_t *indices)
1864 {
1865 nir_alu_instr *vec = create_vec(b->shader, num_components);
1866
1867 nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(b->shader, 1);
1868 nir_builder_instr_insert(&b->nb, &undef->instr);
1869
1870 for (unsigned i = 0; i < num_components; i++) {
1871 uint32_t index = indices[i];
1872 if (index == 0xffffffff) {
1873 vec->src[i].src = nir_src_for_ssa(&undef->def);
1874 } else if (index < src0->num_components) {
1875 vec->src[i].src = nir_src_for_ssa(src0);
1876 vec->src[i].swizzle[0] = index;
1877 } else {
1878 vec->src[i].src = nir_src_for_ssa(src1);
1879 vec->src[i].swizzle[0] = index - src0->num_components;
1880 }
1881 }
1882
1883 nir_builder_instr_insert(&b->nb, &vec->instr);
1884
1885 return &vec->dest.dest.ssa;
1886 }
1887
1888 /*
1889 * Concatentates a number of vectors/scalars together to produce a vector
1890 */
1891 static nir_ssa_def *
1892 vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
1893 unsigned num_srcs, nir_ssa_def **srcs)
1894 {
1895 nir_alu_instr *vec = create_vec(b->shader, num_components);
1896
1897 unsigned dest_idx = 0;
1898 for (unsigned i = 0; i < num_srcs; i++) {
1899 nir_ssa_def *src = srcs[i];
1900 for (unsigned j = 0; j < src->num_components; j++) {
1901 vec->src[dest_idx].src = nir_src_for_ssa(src);
1902 vec->src[dest_idx].swizzle[0] = j;
1903 dest_idx++;
1904 }
1905 }
1906
1907 nir_builder_instr_insert(&b->nb, &vec->instr);
1908
1909 return &vec->dest.dest.ssa;
1910 }
1911
1912 static struct vtn_ssa_value *
1913 vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
1914 {
1915 struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
1916 dest->type = src->type;
1917
1918 if (glsl_type_is_vector_or_scalar(src->type)) {
1919 dest->def = src->def;
1920 } else {
1921 unsigned elems = glsl_get_length(src->type);
1922
1923 dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
1924 for (unsigned i = 0; i < elems; i++)
1925 dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
1926 }
1927
1928 return dest;
1929 }
1930
1931 static struct vtn_ssa_value *
1932 vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
1933 struct vtn_ssa_value *insert, const uint32_t *indices,
1934 unsigned num_indices)
1935 {
1936 struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
1937
1938 struct vtn_ssa_value *cur = dest;
1939 unsigned i;
1940 for (i = 0; i < num_indices - 1; i++) {
1941 cur = cur->elems[indices[i]];
1942 }
1943
1944 if (glsl_type_is_vector_or_scalar(cur->type)) {
1945 /* According to the SPIR-V spec, OpCompositeInsert may work down to
1946 * the component granularity. In that case, the last index will be
1947 * the index to insert the scalar into the vector.
1948 */
1949
1950 cur->def = vtn_vector_insert(b, cur->def, insert->def, indices[i]);
1951 } else {
1952 cur->elems[indices[i]] = insert;
1953 }
1954
1955 return dest;
1956 }
1957
1958 static struct vtn_ssa_value *
1959 vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
1960 const uint32_t *indices, unsigned num_indices)
1961 {
1962 struct vtn_ssa_value *cur = src;
1963 for (unsigned i = 0; i < num_indices; i++) {
1964 if (glsl_type_is_vector_or_scalar(cur->type)) {
1965 assert(i == num_indices - 1);
1966 /* According to the SPIR-V spec, OpCompositeExtract may work down to
1967 * the component granularity. The last index will be the index of the
1968 * vector to extract.
1969 */
1970
1971 struct vtn_ssa_value *ret = rzalloc(b, struct vtn_ssa_value);
1972 ret->type = glsl_scalar_type(glsl_get_base_type(cur->type));
1973 ret->def = vtn_vector_extract(b, cur->def, indices[i]);
1974 return ret;
1975 } else {
1976 cur = cur->elems[indices[i]];
1977 }
1978 }
1979
1980 return cur;
1981 }
1982
1983 static void
1984 vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
1985 const uint32_t *w, unsigned count)
1986 {
1987 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1988 const struct glsl_type *type =
1989 vtn_value(b, w[1], vtn_value_type_type)->type->type;
1990 val->ssa = vtn_create_ssa_value(b, type);
1991
1992 switch (opcode) {
1993 case SpvOpVectorExtractDynamic:
1994 val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def,
1995 vtn_ssa_value(b, w[4])->def);
1996 break;
1997
1998 case SpvOpVectorInsertDynamic:
1999 val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def,
2000 vtn_ssa_value(b, w[4])->def,
2001 vtn_ssa_value(b, w[5])->def);
2002 break;
2003
2004 case SpvOpVectorShuffle:
2005 val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type),
2006 vtn_ssa_value(b, w[3])->def,
2007 vtn_ssa_value(b, w[4])->def,
2008 w + 5);
2009 break;
2010
2011 case SpvOpCompositeConstruct: {
2012 unsigned elems = count - 3;
2013 if (glsl_type_is_vector_or_scalar(type)) {
2014 nir_ssa_def *srcs[4];
2015 for (unsigned i = 0; i < elems; i++)
2016 srcs[i] = vtn_ssa_value(b, w[3 + i])->def;
2017 val->ssa->def =
2018 vtn_vector_construct(b, glsl_get_vector_elements(type),
2019 elems, srcs);
2020 } else {
2021 val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
2022 for (unsigned i = 0; i < elems; i++)
2023 val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
2024 }
2025 break;
2026 }
2027 case SpvOpCompositeExtract:
2028 val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
2029 w + 4, count - 4);
2030 break;
2031
2032 case SpvOpCompositeInsert:
2033 val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
2034 vtn_ssa_value(b, w[3]),
2035 w + 5, count - 5);
2036 break;
2037
2038 case SpvOpCopyObject:
2039 val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
2040 break;
2041
2042 default:
2043 unreachable("unknown composite operation");
2044 }
2045 }
2046
2047 static void
2048 vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
2049 const uint32_t *w, unsigned count)
2050 {
2051 nir_intrinsic_op intrinsic_op;
2052 switch (opcode) {
2053 case SpvOpEmitVertex:
2054 case SpvOpEmitStreamVertex:
2055 intrinsic_op = nir_intrinsic_emit_vertex;
2056 break;
2057 case SpvOpEndPrimitive:
2058 case SpvOpEndStreamPrimitive:
2059 intrinsic_op = nir_intrinsic_end_primitive;
2060 break;
2061 case SpvOpMemoryBarrier:
2062 intrinsic_op = nir_intrinsic_memory_barrier;
2063 break;
2064 case SpvOpControlBarrier:
2065 intrinsic_op = nir_intrinsic_barrier;
2066 break;
2067 default:
2068 unreachable("unknown barrier instruction");
2069 }
2070
2071 nir_intrinsic_instr *intrin =
2072 nir_intrinsic_instr_create(b->shader, intrinsic_op);
2073
2074 if (opcode == SpvOpEmitStreamVertex || opcode == SpvOpEndStreamPrimitive)
2075 nir_intrinsic_set_stream_id(intrin, w[1]);
2076
2077 nir_builder_instr_insert(&b->nb, &intrin->instr);
2078 }
2079
2080 static unsigned
2081 gl_primitive_from_spv_execution_mode(SpvExecutionMode mode)
2082 {
2083 switch (mode) {
2084 case SpvExecutionModeInputPoints:
2085 case SpvExecutionModeOutputPoints:
2086 return 0; /* GL_POINTS */
2087 case SpvExecutionModeInputLines:
2088 return 1; /* GL_LINES */
2089 case SpvExecutionModeInputLinesAdjacency:
2090 return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
2091 case SpvExecutionModeTriangles:
2092 return 4; /* GL_TRIANGLES */
2093 case SpvExecutionModeInputTrianglesAdjacency:
2094 return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
2095 case SpvExecutionModeQuads:
2096 return 7; /* GL_QUADS */
2097 case SpvExecutionModeIsolines:
2098 return 0x8E7A; /* GL_ISOLINES */
2099 case SpvExecutionModeOutputLineStrip:
2100 return 3; /* GL_LINE_STRIP */
2101 case SpvExecutionModeOutputTriangleStrip:
2102 return 5; /* GL_TRIANGLE_STRIP */
2103 default:
2104 assert(!"Invalid primitive type");
2105 return 4;
2106 }
2107 }
2108
2109 static unsigned
2110 vertices_in_from_spv_execution_mode(SpvExecutionMode mode)
2111 {
2112 switch (mode) {
2113 case SpvExecutionModeInputPoints:
2114 return 1;
2115 case SpvExecutionModeInputLines:
2116 return 2;
2117 case SpvExecutionModeInputLinesAdjacency:
2118 return 4;
2119 case SpvExecutionModeTriangles:
2120 return 3;
2121 case SpvExecutionModeInputTrianglesAdjacency:
2122 return 6;
2123 default:
2124 assert(!"Invalid GS input mode");
2125 return 0;
2126 }
2127 }
2128
2129 static gl_shader_stage
2130 stage_for_execution_model(SpvExecutionModel model)
2131 {
2132 switch (model) {
2133 case SpvExecutionModelVertex:
2134 return MESA_SHADER_VERTEX;
2135 case SpvExecutionModelTessellationControl:
2136 return MESA_SHADER_TESS_CTRL;
2137 case SpvExecutionModelTessellationEvaluation:
2138 return MESA_SHADER_TESS_EVAL;
2139 case SpvExecutionModelGeometry:
2140 return MESA_SHADER_GEOMETRY;
2141 case SpvExecutionModelFragment:
2142 return MESA_SHADER_FRAGMENT;
2143 case SpvExecutionModelGLCompute:
2144 return MESA_SHADER_COMPUTE;
2145 default:
2146 unreachable("Unsupported execution model");
2147 }
2148 }
2149
2150 static bool
2151 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
2152 const uint32_t *w, unsigned count)
2153 {
2154 switch (opcode) {
2155 case SpvOpSource:
2156 case SpvOpSourceExtension:
2157 case SpvOpSourceContinued:
2158 case SpvOpExtension:
2159 /* Unhandled, but these are for debug so that's ok. */
2160 break;
2161
2162 case SpvOpCapability:
2163 switch ((SpvCapability)w[1]) {
2164 case SpvCapabilityMatrix:
2165 case SpvCapabilityShader:
2166 case SpvCapabilityGeometry:
2167 break;
2168 default:
2169 assert(!"Unsupported capability");
2170 }
2171 break;
2172
2173 case SpvOpExtInstImport:
2174 vtn_handle_extension(b, opcode, w, count);
2175 break;
2176
2177 case SpvOpMemoryModel:
2178 assert(w[1] == SpvAddressingModelLogical);
2179 assert(w[2] == SpvMemoryModelGLSL450);
2180 break;
2181
2182 case SpvOpEntryPoint: {
2183 struct vtn_value *entry_point = &b->values[w[2]];
2184 /* Let this be a name label regardless */
2185 unsigned name_words;
2186 entry_point->name = vtn_string_literal(b, &w[3], count - 3, &name_words);
2187
2188 if (strcmp(entry_point->name, b->entry_point_name) != 0 ||
2189 stage_for_execution_model(w[1]) != b->entry_point_stage)
2190 break;
2191
2192 assert(b->entry_point == NULL);
2193 b->entry_point = entry_point;
2194 break;
2195 }
2196
2197 case SpvOpString:
2198 vtn_push_value(b, w[1], vtn_value_type_string)->str =
2199 vtn_string_literal(b, &w[2], count - 2, NULL);
2200 break;
2201
2202 case SpvOpName:
2203 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2, NULL);
2204 break;
2205
2206 case SpvOpMemberName:
2207 /* TODO */
2208 break;
2209
2210 case SpvOpExecutionMode:
2211 case SpvOpDecorationGroup:
2212 case SpvOpDecorate:
2213 case SpvOpMemberDecorate:
2214 case SpvOpGroupDecorate:
2215 case SpvOpGroupMemberDecorate:
2216 vtn_handle_decoration(b, opcode, w, count);
2217 break;
2218
2219 default:
2220 return false; /* End of preamble */
2221 }
2222
2223 return true;
2224 }
2225
2226 static void
2227 vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
2228 const struct vtn_decoration *mode, void *data)
2229 {
2230 assert(b->entry_point == entry_point);
2231
2232 switch(mode->exec_mode) {
2233 case SpvExecutionModeOriginUpperLeft:
2234 case SpvExecutionModeOriginLowerLeft:
2235 b->origin_upper_left =
2236 (mode->exec_mode == SpvExecutionModeOriginUpperLeft);
2237 break;
2238
2239 case SpvExecutionModeEarlyFragmentTests:
2240 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2241 b->shader->info.fs.early_fragment_tests = true;
2242 break;
2243
2244 case SpvExecutionModeInvocations:
2245 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2246 b->shader->info.gs.invocations = MAX2(1, mode->literals[0]);
2247 break;
2248
2249 case SpvExecutionModeDepthReplacing:
2250 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2251 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
2252 break;
2253 case SpvExecutionModeDepthGreater:
2254 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2255 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
2256 break;
2257 case SpvExecutionModeDepthLess:
2258 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2259 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
2260 break;
2261 case SpvExecutionModeDepthUnchanged:
2262 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2263 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
2264 break;
2265
2266 case SpvExecutionModeLocalSize:
2267 assert(b->shader->stage == MESA_SHADER_COMPUTE);
2268 b->shader->info.cs.local_size[0] = mode->literals[0];
2269 b->shader->info.cs.local_size[1] = mode->literals[1];
2270 b->shader->info.cs.local_size[2] = mode->literals[2];
2271 break;
2272 case SpvExecutionModeLocalSizeHint:
2273 break; /* Nothing do do with this */
2274
2275 case SpvExecutionModeOutputVertices:
2276 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2277 b->shader->info.gs.vertices_out = mode->literals[0];
2278 break;
2279
2280 case SpvExecutionModeInputPoints:
2281 case SpvExecutionModeInputLines:
2282 case SpvExecutionModeInputLinesAdjacency:
2283 case SpvExecutionModeTriangles:
2284 case SpvExecutionModeInputTrianglesAdjacency:
2285 case SpvExecutionModeQuads:
2286 case SpvExecutionModeIsolines:
2287 if (b->shader->stage == MESA_SHADER_GEOMETRY) {
2288 b->shader->info.gs.vertices_in =
2289 vertices_in_from_spv_execution_mode(mode->exec_mode);
2290 } else {
2291 assert(!"Tesselation shaders not yet supported");
2292 }
2293 break;
2294
2295 case SpvExecutionModeOutputPoints:
2296 case SpvExecutionModeOutputLineStrip:
2297 case SpvExecutionModeOutputTriangleStrip:
2298 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2299 b->shader->info.gs.output_primitive =
2300 gl_primitive_from_spv_execution_mode(mode->exec_mode);
2301 break;
2302
2303 case SpvExecutionModeSpacingEqual:
2304 case SpvExecutionModeSpacingFractionalEven:
2305 case SpvExecutionModeSpacingFractionalOdd:
2306 case SpvExecutionModeVertexOrderCw:
2307 case SpvExecutionModeVertexOrderCcw:
2308 case SpvExecutionModePointMode:
2309 assert(!"TODO: Add tessellation metadata");
2310 break;
2311
2312 case SpvExecutionModePixelCenterInteger:
2313 case SpvExecutionModeXfb:
2314 assert(!"Unhandled execution mode");
2315 break;
2316
2317 case SpvExecutionModeVecTypeHint:
2318 case SpvExecutionModeContractionOff:
2319 break; /* OpenCL */
2320 }
2321 }
2322
2323 static bool
2324 vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
2325 const uint32_t *w, unsigned count)
2326 {
2327 switch (opcode) {
2328 case SpvOpSource:
2329 case SpvOpSourceContinued:
2330 case SpvOpSourceExtension:
2331 case SpvOpExtension:
2332 case SpvOpCapability:
2333 case SpvOpExtInstImport:
2334 case SpvOpMemoryModel:
2335 case SpvOpEntryPoint:
2336 case SpvOpExecutionMode:
2337 case SpvOpString:
2338 case SpvOpName:
2339 case SpvOpMemberName:
2340 case SpvOpDecorationGroup:
2341 case SpvOpDecorate:
2342 case SpvOpMemberDecorate:
2343 case SpvOpGroupDecorate:
2344 case SpvOpGroupMemberDecorate:
2345 assert(!"Invalid opcode types and variables section");
2346 break;
2347
2348 case SpvOpTypeVoid:
2349 case SpvOpTypeBool:
2350 case SpvOpTypeInt:
2351 case SpvOpTypeFloat:
2352 case SpvOpTypeVector:
2353 case SpvOpTypeMatrix:
2354 case SpvOpTypeImage:
2355 case SpvOpTypeSampler:
2356 case SpvOpTypeSampledImage:
2357 case SpvOpTypeArray:
2358 case SpvOpTypeRuntimeArray:
2359 case SpvOpTypeStruct:
2360 case SpvOpTypeOpaque:
2361 case SpvOpTypePointer:
2362 case SpvOpTypeFunction:
2363 case SpvOpTypeEvent:
2364 case SpvOpTypeDeviceEvent:
2365 case SpvOpTypeReserveId:
2366 case SpvOpTypeQueue:
2367 case SpvOpTypePipe:
2368 vtn_handle_type(b, opcode, w, count);
2369 break;
2370
2371 case SpvOpConstantTrue:
2372 case SpvOpConstantFalse:
2373 case SpvOpConstant:
2374 case SpvOpConstantComposite:
2375 case SpvOpConstantSampler:
2376 case SpvOpConstantNull:
2377 case SpvOpSpecConstantTrue:
2378 case SpvOpSpecConstantFalse:
2379 case SpvOpSpecConstant:
2380 case SpvOpSpecConstantComposite:
2381 case SpvOpSpecConstantOp:
2382 vtn_handle_constant(b, opcode, w, count);
2383 break;
2384
2385 case SpvOpVariable:
2386 vtn_handle_variables(b, opcode, w, count);
2387 break;
2388
2389 default:
2390 return false; /* End of preamble */
2391 }
2392
2393 return true;
2394 }
2395
2396 static bool
2397 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
2398 const uint32_t *w, unsigned count)
2399 {
2400 switch (opcode) {
2401 case SpvOpLabel:
2402 break;
2403
2404 case SpvOpLoopMerge:
2405 case SpvOpSelectionMerge:
2406 /* This is handled by cfg pre-pass and walk_blocks */
2407 break;
2408
2409 case SpvOpUndef: {
2410 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
2411 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
2412 break;
2413 }
2414
2415 case SpvOpExtInst:
2416 vtn_handle_extension(b, opcode, w, count);
2417 break;
2418
2419 case SpvOpVariable:
2420 case SpvOpLoad:
2421 case SpvOpStore:
2422 case SpvOpCopyMemory:
2423 case SpvOpCopyMemorySized:
2424 case SpvOpAccessChain:
2425 case SpvOpInBoundsAccessChain:
2426 case SpvOpArrayLength:
2427 vtn_handle_variables(b, opcode, w, count);
2428 break;
2429
2430 case SpvOpFunctionCall:
2431 vtn_handle_function_call(b, opcode, w, count);
2432 break;
2433
2434 case SpvOpSampledImage:
2435 case SpvOpImage:
2436 case SpvOpImageSampleImplicitLod:
2437 case SpvOpImageSampleExplicitLod:
2438 case SpvOpImageSampleDrefImplicitLod:
2439 case SpvOpImageSampleDrefExplicitLod:
2440 case SpvOpImageSampleProjImplicitLod:
2441 case SpvOpImageSampleProjExplicitLod:
2442 case SpvOpImageSampleProjDrefImplicitLod:
2443 case SpvOpImageSampleProjDrefExplicitLod:
2444 case SpvOpImageFetch:
2445 case SpvOpImageGather:
2446 case SpvOpImageDrefGather:
2447 case SpvOpImageQuerySizeLod:
2448 case SpvOpImageQueryLod:
2449 case SpvOpImageQueryLevels:
2450 case SpvOpImageQuerySamples:
2451 vtn_handle_texture(b, opcode, w, count);
2452 break;
2453
2454 case SpvOpImageRead:
2455 case SpvOpImageWrite:
2456 case SpvOpImageTexelPointer:
2457 vtn_handle_image(b, opcode, w, count);
2458 break;
2459
2460 case SpvOpImageQuerySize: {
2461 struct vtn_access_chain *image =
2462 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
2463 if (glsl_type_is_image(image->var->var->interface_type)) {
2464 vtn_handle_image(b, opcode, w, count);
2465 } else {
2466 vtn_handle_texture(b, opcode, w, count);
2467 }
2468 break;
2469 }
2470
2471 case SpvOpAtomicExchange:
2472 case SpvOpAtomicCompareExchange:
2473 case SpvOpAtomicCompareExchangeWeak:
2474 case SpvOpAtomicIIncrement:
2475 case SpvOpAtomicIDecrement:
2476 case SpvOpAtomicIAdd:
2477 case SpvOpAtomicISub:
2478 case SpvOpAtomicSMin:
2479 case SpvOpAtomicUMin:
2480 case SpvOpAtomicSMax:
2481 case SpvOpAtomicUMax:
2482 case SpvOpAtomicAnd:
2483 case SpvOpAtomicOr:
2484 case SpvOpAtomicXor: {
2485 struct vtn_value *pointer = vtn_untyped_value(b, w[3]);
2486 if (pointer->value_type == vtn_value_type_image_pointer) {
2487 vtn_handle_image(b, opcode, w, count);
2488 } else {
2489 assert(pointer->value_type == vtn_value_type_access_chain);
2490 vtn_handle_ssbo_or_shared_atomic(b, opcode, w, count);
2491 }
2492 break;
2493 }
2494
2495 case SpvOpSNegate:
2496 case SpvOpFNegate:
2497 case SpvOpNot:
2498 case SpvOpAny:
2499 case SpvOpAll:
2500 case SpvOpConvertFToU:
2501 case SpvOpConvertFToS:
2502 case SpvOpConvertSToF:
2503 case SpvOpConvertUToF:
2504 case SpvOpUConvert:
2505 case SpvOpSConvert:
2506 case SpvOpFConvert:
2507 case SpvOpQuantizeToF16:
2508 case SpvOpConvertPtrToU:
2509 case SpvOpConvertUToPtr:
2510 case SpvOpPtrCastToGeneric:
2511 case SpvOpGenericCastToPtr:
2512 case SpvOpBitcast:
2513 case SpvOpIsNan:
2514 case SpvOpIsInf:
2515 case SpvOpIsFinite:
2516 case SpvOpIsNormal:
2517 case SpvOpSignBitSet:
2518 case SpvOpLessOrGreater:
2519 case SpvOpOrdered:
2520 case SpvOpUnordered:
2521 case SpvOpIAdd:
2522 case SpvOpFAdd:
2523 case SpvOpISub:
2524 case SpvOpFSub:
2525 case SpvOpIMul:
2526 case SpvOpFMul:
2527 case SpvOpUDiv:
2528 case SpvOpSDiv:
2529 case SpvOpFDiv:
2530 case SpvOpUMod:
2531 case SpvOpSRem:
2532 case SpvOpSMod:
2533 case SpvOpFRem:
2534 case SpvOpFMod:
2535 case SpvOpVectorTimesScalar:
2536 case SpvOpDot:
2537 case SpvOpIAddCarry:
2538 case SpvOpISubBorrow:
2539 case SpvOpUMulExtended:
2540 case SpvOpSMulExtended:
2541 case SpvOpShiftRightLogical:
2542 case SpvOpShiftRightArithmetic:
2543 case SpvOpShiftLeftLogical:
2544 case SpvOpLogicalEqual:
2545 case SpvOpLogicalNotEqual:
2546 case SpvOpLogicalOr:
2547 case SpvOpLogicalAnd:
2548 case SpvOpLogicalNot:
2549 case SpvOpBitwiseOr:
2550 case SpvOpBitwiseXor:
2551 case SpvOpBitwiseAnd:
2552 case SpvOpSelect:
2553 case SpvOpIEqual:
2554 case SpvOpFOrdEqual:
2555 case SpvOpFUnordEqual:
2556 case SpvOpINotEqual:
2557 case SpvOpFOrdNotEqual:
2558 case SpvOpFUnordNotEqual:
2559 case SpvOpULessThan:
2560 case SpvOpSLessThan:
2561 case SpvOpFOrdLessThan:
2562 case SpvOpFUnordLessThan:
2563 case SpvOpUGreaterThan:
2564 case SpvOpSGreaterThan:
2565 case SpvOpFOrdGreaterThan:
2566 case SpvOpFUnordGreaterThan:
2567 case SpvOpULessThanEqual:
2568 case SpvOpSLessThanEqual:
2569 case SpvOpFOrdLessThanEqual:
2570 case SpvOpFUnordLessThanEqual:
2571 case SpvOpUGreaterThanEqual:
2572 case SpvOpSGreaterThanEqual:
2573 case SpvOpFOrdGreaterThanEqual:
2574 case SpvOpFUnordGreaterThanEqual:
2575 case SpvOpDPdx:
2576 case SpvOpDPdy:
2577 case SpvOpFwidth:
2578 case SpvOpDPdxFine:
2579 case SpvOpDPdyFine:
2580 case SpvOpFwidthFine:
2581 case SpvOpDPdxCoarse:
2582 case SpvOpDPdyCoarse:
2583 case SpvOpFwidthCoarse:
2584 case SpvOpBitFieldInsert:
2585 case SpvOpBitFieldSExtract:
2586 case SpvOpBitFieldUExtract:
2587 case SpvOpBitReverse:
2588 case SpvOpBitCount:
2589 case SpvOpTranspose:
2590 case SpvOpOuterProduct:
2591 case SpvOpMatrixTimesScalar:
2592 case SpvOpVectorTimesMatrix:
2593 case SpvOpMatrixTimesVector:
2594 case SpvOpMatrixTimesMatrix:
2595 vtn_handle_alu(b, opcode, w, count);
2596 break;
2597
2598 case SpvOpVectorExtractDynamic:
2599 case SpvOpVectorInsertDynamic:
2600 case SpvOpVectorShuffle:
2601 case SpvOpCompositeConstruct:
2602 case SpvOpCompositeExtract:
2603 case SpvOpCompositeInsert:
2604 case SpvOpCopyObject:
2605 vtn_handle_composite(b, opcode, w, count);
2606 break;
2607
2608 case SpvOpEmitVertex:
2609 case SpvOpEndPrimitive:
2610 case SpvOpEmitStreamVertex:
2611 case SpvOpEndStreamPrimitive:
2612 case SpvOpControlBarrier:
2613 case SpvOpMemoryBarrier:
2614 vtn_handle_barrier(b, opcode, w, count);
2615 break;
2616
2617 default:
2618 unreachable("Unhandled opcode");
2619 }
2620
2621 return true;
2622 }
2623
2624 nir_function *
2625 spirv_to_nir(const uint32_t *words, size_t word_count,
2626 struct nir_spirv_specialization *spec, unsigned num_spec,
2627 gl_shader_stage stage, const char *entry_point_name,
2628 const nir_shader_compiler_options *options)
2629 {
2630 const uint32_t *word_end = words + word_count;
2631
2632 /* Handle the SPIR-V header (first 4 dwords) */
2633 assert(word_count > 5);
2634
2635 assert(words[0] == SpvMagicNumber);
2636 assert(words[1] >= 0x10000);
2637 /* words[2] == generator magic */
2638 unsigned value_id_bound = words[3];
2639 assert(words[4] == 0);
2640
2641 words+= 5;
2642
2643 /* Initialize the stn_builder object */
2644 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
2645 b->value_id_bound = value_id_bound;
2646 b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
2647 exec_list_make_empty(&b->functions);
2648 b->entry_point_stage = stage;
2649 b->entry_point_name = entry_point_name;
2650
2651 /* Handle all the preamble instructions */
2652 words = vtn_foreach_instruction(b, words, word_end,
2653 vtn_handle_preamble_instruction);
2654
2655 if (b->entry_point == NULL) {
2656 assert(!"Entry point not found");
2657 ralloc_free(b);
2658 return NULL;
2659 }
2660
2661 b->shader = nir_shader_create(NULL, stage, options);
2662
2663 /* Parse execution modes */
2664 vtn_foreach_execution_mode(b, b->entry_point,
2665 vtn_handle_execution_mode, NULL);
2666
2667 b->specializations = spec;
2668 b->num_specializations = num_spec;
2669
2670 /* Handle all variable, type, and constant instructions */
2671 words = vtn_foreach_instruction(b, words, word_end,
2672 vtn_handle_variable_or_type_instruction);
2673
2674 vtn_build_cfg(b, words, word_end);
2675
2676 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
2677 b->impl = func->impl;
2678 b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
2679 _mesa_key_pointer_equal);
2680
2681 vtn_function_emit(b, func, vtn_handle_body_instruction);
2682 }
2683
2684 assert(b->entry_point->value_type == vtn_value_type_function);
2685 nir_function *entry_point = b->entry_point->func->impl->function;
2686 assert(entry_point);
2687
2688 ralloc_free(b);
2689
2690 return entry_point;
2691 }