Merge remote-tracking branch 'origin/master' into vulkan
[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 if (multisampled) {
743 assert(dim == GLSL_SAMPLER_DIM_2D);
744 dim = GLSL_SAMPLER_DIM_MS;
745 }
746
747 val->type->image_format = translate_image_format(format);
748
749 if (sampled == 1) {
750 val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
751 glsl_get_base_type(sampled_type));
752 } else if (sampled == 2) {
753 assert(format);
754 assert(!is_shadow);
755 val->type->type = glsl_image_type(dim, is_array,
756 glsl_get_base_type(sampled_type));
757 } else {
758 assert(!"We need to know if the image will be sampled");
759 }
760 break;
761 }
762
763 case SpvOpTypeSampledImage:
764 val->type = vtn_value(b, w[2], vtn_value_type_type)->type;
765 break;
766
767 case SpvOpTypeSampler:
768 /* The actual sampler type here doesn't really matter. It gets
769 * thrown away the moment you combine it with an image. What really
770 * matters is that it's a sampler type as opposed to an integer type
771 * so the backend knows what to do.
772 *
773 * TODO: Eventually we should consider adding a "bare sampler" type
774 * to glsl_types.
775 */
776 val->type->type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false,
777 GLSL_TYPE_FLOAT);
778 break;
779
780 case SpvOpTypeOpaque:
781 case SpvOpTypeEvent:
782 case SpvOpTypeDeviceEvent:
783 case SpvOpTypeReserveId:
784 case SpvOpTypeQueue:
785 case SpvOpTypePipe:
786 default:
787 unreachable("Unhandled opcode");
788 }
789
790 vtn_foreach_decoration(b, val, type_decoration_cb, NULL);
791 }
792
793 static nir_constant *
794 vtn_null_constant(struct vtn_builder *b, const struct glsl_type *type)
795 {
796 nir_constant *c = rzalloc(b, nir_constant);
797
798 switch (glsl_get_base_type(type)) {
799 case GLSL_TYPE_INT:
800 case GLSL_TYPE_UINT:
801 case GLSL_TYPE_BOOL:
802 case GLSL_TYPE_FLOAT:
803 case GLSL_TYPE_DOUBLE:
804 /* Nothing to do here. It's already initialized to zero */
805 break;
806
807 case GLSL_TYPE_ARRAY:
808 assert(glsl_get_length(type) > 0);
809 c->num_elements = glsl_get_length(type);
810 c->elements = ralloc_array(b, nir_constant *, c->num_elements);
811
812 c->elements[0] = vtn_null_constant(b, glsl_get_array_element(type));
813 for (unsigned i = 1; i < c->num_elements; i++)
814 c->elements[i] = c->elements[0];
815 break;
816
817 case GLSL_TYPE_STRUCT:
818 c->num_elements = glsl_get_length(type);
819 c->elements = ralloc_array(b, nir_constant *, c->num_elements);
820
821 for (unsigned i = 0; i < c->num_elements; i++) {
822 c->elements[i] = vtn_null_constant(b, glsl_get_struct_field(type, i));
823 }
824 break;
825
826 default:
827 unreachable("Invalid type for null constant");
828 }
829
830 return c;
831 }
832
833 static void
834 spec_constant_deocoration_cb(struct vtn_builder *b, struct vtn_value *v,
835 int member, const struct vtn_decoration *dec,
836 void *data)
837 {
838 assert(member == -1);
839 if (dec->decoration != SpvDecorationSpecId)
840 return;
841
842 uint32_t *const_value = data;
843
844 for (unsigned i = 0; i < b->num_specializations; i++) {
845 if (b->specializations[i].id == dec->literals[0]) {
846 *const_value = b->specializations[i].data;
847 return;
848 }
849 }
850 }
851
852 static uint32_t
853 get_specialization(struct vtn_builder *b, struct vtn_value *val,
854 uint32_t const_value)
855 {
856 vtn_foreach_decoration(b, val, spec_constant_deocoration_cb, &const_value);
857 return const_value;
858 }
859
860 static void
861 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
862 const uint32_t *w, unsigned count)
863 {
864 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
865 val->const_type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
866 val->constant = rzalloc(b, nir_constant);
867 switch (opcode) {
868 case SpvOpConstantTrue:
869 assert(val->const_type == glsl_bool_type());
870 val->constant->value.u[0] = NIR_TRUE;
871 break;
872 case SpvOpConstantFalse:
873 assert(val->const_type == glsl_bool_type());
874 val->constant->value.u[0] = NIR_FALSE;
875 break;
876
877 case SpvOpSpecConstantTrue:
878 case SpvOpSpecConstantFalse: {
879 assert(val->const_type == glsl_bool_type());
880 uint32_t int_val =
881 get_specialization(b, val, (opcode == SpvOpSpecConstantTrue));
882 val->constant->value.u[0] = int_val ? NIR_TRUE : NIR_FALSE;
883 break;
884 }
885
886 case SpvOpConstant:
887 assert(glsl_type_is_scalar(val->const_type));
888 val->constant->value.u[0] = w[3];
889 break;
890 case SpvOpSpecConstant:
891 assert(glsl_type_is_scalar(val->const_type));
892 val->constant->value.u[0] = get_specialization(b, val, w[3]);
893 break;
894 case SpvOpSpecConstantComposite:
895 case SpvOpConstantComposite: {
896 unsigned elem_count = count - 3;
897 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
898 for (unsigned i = 0; i < elem_count; i++)
899 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
900
901 switch (glsl_get_base_type(val->const_type)) {
902 case GLSL_TYPE_UINT:
903 case GLSL_TYPE_INT:
904 case GLSL_TYPE_FLOAT:
905 case GLSL_TYPE_BOOL:
906 if (glsl_type_is_matrix(val->const_type)) {
907 unsigned rows = glsl_get_vector_elements(val->const_type);
908 assert(glsl_get_matrix_columns(val->const_type) == elem_count);
909 for (unsigned i = 0; i < elem_count; i++)
910 for (unsigned j = 0; j < rows; j++)
911 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
912 } else {
913 assert(glsl_type_is_vector(val->const_type));
914 assert(glsl_get_vector_elements(val->const_type) == elem_count);
915 for (unsigned i = 0; i < elem_count; i++)
916 val->constant->value.u[i] = elems[i]->value.u[0];
917 }
918 ralloc_free(elems);
919 break;
920
921 case GLSL_TYPE_STRUCT:
922 case GLSL_TYPE_ARRAY:
923 ralloc_steal(val->constant, elems);
924 val->constant->num_elements = elem_count;
925 val->constant->elements = elems;
926 break;
927
928 default:
929 unreachable("Unsupported type for constants");
930 }
931 break;
932 }
933
934 case SpvOpSpecConstantOp: {
935 SpvOp opcode = get_specialization(b, val, w[3]);
936 switch (opcode) {
937 case SpvOpVectorShuffle: {
938 struct vtn_value *v0 = vtn_value(b, w[4], vtn_value_type_constant);
939 struct vtn_value *v1 = vtn_value(b, w[5], vtn_value_type_constant);
940 unsigned len0 = glsl_get_vector_elements(v0->const_type);
941 unsigned len1 = glsl_get_vector_elements(v1->const_type);
942
943 uint32_t u[8];
944 for (unsigned i = 0; i < len0; i++)
945 u[i] = v0->constant->value.u[i];
946 for (unsigned i = 0; i < len1; i++)
947 u[len0 + i] = v1->constant->value.u[i];
948
949 for (unsigned i = 0; i < count - 6; i++) {
950 uint32_t comp = w[i + 6];
951 if (comp == (uint32_t)-1) {
952 val->constant->value.u[i] = 0xdeadbeef;
953 } else {
954 val->constant->value.u[i] = u[comp];
955 }
956 }
957 return;
958 }
959
960 case SpvOpCompositeExtract:
961 case SpvOpCompositeInsert: {
962 struct vtn_value *comp;
963 unsigned deref_start;
964 struct nir_constant **c;
965 if (opcode == SpvOpCompositeExtract) {
966 comp = vtn_value(b, w[4], vtn_value_type_constant);
967 deref_start = 5;
968 c = &comp->constant;
969 } else {
970 comp = vtn_value(b, w[5], vtn_value_type_constant);
971 deref_start = 6;
972 val->constant = nir_constant_clone(comp->constant,
973 (nir_variable *)b);
974 c = &val->constant;
975 }
976
977 int elem = -1;
978 const struct glsl_type *type = comp->const_type;
979 for (unsigned i = deref_start; i < count; i++) {
980 switch (glsl_get_base_type(type)) {
981 case GLSL_TYPE_UINT:
982 case GLSL_TYPE_INT:
983 case GLSL_TYPE_FLOAT:
984 case GLSL_TYPE_BOOL:
985 /* If we hit this granularity, we're picking off an element */
986 if (elem < 0)
987 elem = 0;
988
989 if (glsl_type_is_matrix(type)) {
990 elem += w[i] * glsl_get_vector_elements(type);
991 type = glsl_get_column_type(type);
992 } else {
993 assert(glsl_type_is_vector(type));
994 elem += w[i];
995 type = glsl_scalar_type(glsl_get_base_type(type));
996 }
997 continue;
998
999 case GLSL_TYPE_ARRAY:
1000 c = &(*c)->elements[w[i]];
1001 type = glsl_get_array_element(type);
1002 continue;
1003
1004 case GLSL_TYPE_STRUCT:
1005 c = &(*c)->elements[w[i]];
1006 type = glsl_get_struct_field(type, w[i]);
1007 continue;
1008
1009 default:
1010 unreachable("Invalid constant type");
1011 }
1012 }
1013
1014 if (opcode == SpvOpCompositeExtract) {
1015 if (elem == -1) {
1016 val->constant = *c;
1017 } else {
1018 unsigned num_components = glsl_get_vector_elements(type);
1019 for (unsigned i = 0; i < num_components; i++)
1020 val->constant->value.u[i] = (*c)->value.u[elem + i];
1021 }
1022 } else {
1023 struct vtn_value *insert =
1024 vtn_value(b, w[4], vtn_value_type_constant);
1025 assert(insert->const_type == type);
1026 if (elem == -1) {
1027 *c = insert->constant;
1028 } else {
1029 unsigned num_components = glsl_get_vector_elements(type);
1030 for (unsigned i = 0; i < num_components; i++)
1031 (*c)->value.u[elem + i] = insert->constant->value.u[i];
1032 }
1033 }
1034 return;
1035 }
1036
1037 default: {
1038 bool swap;
1039 nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
1040
1041 unsigned num_components = glsl_get_vector_elements(val->const_type);
1042
1043 nir_const_value src[3];
1044 assert(count <= 7);
1045 for (unsigned i = 0; i < count - 4; i++) {
1046 nir_constant *c =
1047 vtn_value(b, w[4 + i], vtn_value_type_constant)->constant;
1048
1049 unsigned j = swap ? 1 - i : i;
1050 for (unsigned k = 0; k < num_components; k++)
1051 src[j].u[k] = c->value.u[k];
1052 }
1053
1054 nir_const_value res = nir_eval_const_opcode(op, num_components, src);
1055
1056 for (unsigned k = 0; k < num_components; k++)
1057 val->constant->value.u[k] = res.u[k];
1058
1059 return;
1060 } /* default */
1061 }
1062 }
1063
1064 case SpvOpConstantNull:
1065 val->constant = vtn_null_constant(b, val->const_type);
1066 break;
1067
1068 case SpvOpConstantSampler:
1069 assert(!"OpConstantSampler requires Kernel Capability");
1070 break;
1071
1072 default:
1073 unreachable("Unhandled opcode");
1074 }
1075 }
1076
1077 static void
1078 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
1079 const uint32_t *w, unsigned count)
1080 {
1081 struct nir_function *callee =
1082 vtn_value(b, w[3], vtn_value_type_function)->func->impl->function;
1083
1084 nir_call_instr *call = nir_call_instr_create(b->nb.shader, callee);
1085 for (unsigned i = 0; i < call->num_params; i++) {
1086 unsigned arg_id = w[4 + i];
1087 struct vtn_value *arg = vtn_untyped_value(b, arg_id);
1088 if (arg->value_type == vtn_value_type_access_chain) {
1089 nir_deref_var *d = vtn_access_chain_to_deref(b, arg->access_chain);
1090 call->params[i] = nir_deref_as_var(nir_copy_deref(call, &d->deref));
1091 } else {
1092 struct vtn_ssa_value *arg_ssa = vtn_ssa_value(b, arg_id);
1093
1094 /* Make a temporary to store the argument in */
1095 nir_variable *tmp =
1096 nir_local_variable_create(b->impl, arg_ssa->type, "arg_tmp");
1097 call->params[i] = nir_deref_var_create(call, tmp);
1098
1099 vtn_local_store(b, arg_ssa, call->params[i]);
1100 }
1101 }
1102
1103 nir_variable *out_tmp = NULL;
1104 if (!glsl_type_is_void(callee->return_type)) {
1105 out_tmp = nir_local_variable_create(b->impl, callee->return_type,
1106 "out_tmp");
1107 call->return_deref = nir_deref_var_create(call, out_tmp);
1108 }
1109
1110 nir_builder_instr_insert(&b->nb, &call->instr);
1111
1112 if (glsl_type_is_void(callee->return_type)) {
1113 vtn_push_value(b, w[2], vtn_value_type_undef);
1114 } else {
1115 struct vtn_value *retval = vtn_push_value(b, w[2], vtn_value_type_ssa);
1116 retval->ssa = vtn_local_load(b, call->return_deref);
1117 }
1118 }
1119
1120 struct vtn_ssa_value *
1121 vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
1122 {
1123 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
1124 val->type = type;
1125
1126 if (!glsl_type_is_vector_or_scalar(type)) {
1127 unsigned elems = glsl_get_length(type);
1128 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1129 for (unsigned i = 0; i < elems; i++) {
1130 const struct glsl_type *child_type;
1131
1132 switch (glsl_get_base_type(type)) {
1133 case GLSL_TYPE_INT:
1134 case GLSL_TYPE_UINT:
1135 case GLSL_TYPE_BOOL:
1136 case GLSL_TYPE_FLOAT:
1137 case GLSL_TYPE_DOUBLE:
1138 child_type = glsl_get_column_type(type);
1139 break;
1140 case GLSL_TYPE_ARRAY:
1141 child_type = glsl_get_array_element(type);
1142 break;
1143 case GLSL_TYPE_STRUCT:
1144 child_type = glsl_get_struct_field(type, i);
1145 break;
1146 default:
1147 unreachable("unkown base type");
1148 }
1149
1150 val->elems[i] = vtn_create_ssa_value(b, child_type);
1151 }
1152 }
1153
1154 return val;
1155 }
1156
1157 static nir_tex_src
1158 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
1159 {
1160 nir_tex_src src;
1161 src.src = nir_src_for_ssa(vtn_ssa_value(b, index)->def);
1162 src.src_type = type;
1163 return src;
1164 }
1165
1166 static void
1167 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
1168 const uint32_t *w, unsigned count)
1169 {
1170 if (opcode == SpvOpSampledImage) {
1171 struct vtn_value *val =
1172 vtn_push_value(b, w[2], vtn_value_type_sampled_image);
1173 val->sampled_image = ralloc(b, struct vtn_sampled_image);
1174 val->sampled_image->image =
1175 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1176 val->sampled_image->sampler =
1177 vtn_value(b, w[4], vtn_value_type_access_chain)->access_chain;
1178 return;
1179 } else if (opcode == SpvOpImage) {
1180 struct vtn_value *val =
1181 vtn_push_value(b, w[2], vtn_value_type_access_chain);
1182 struct vtn_value *src_val = vtn_untyped_value(b, w[3]);
1183 if (src_val->value_type == vtn_value_type_sampled_image) {
1184 val->access_chain = src_val->sampled_image->image;
1185 } else {
1186 assert(src_val->value_type == vtn_value_type_access_chain);
1187 val->access_chain = src_val->access_chain;
1188 }
1189 return;
1190 }
1191
1192 struct vtn_type *ret_type = vtn_value(b, w[1], vtn_value_type_type)->type;
1193 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1194
1195 struct vtn_sampled_image sampled;
1196 struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]);
1197 if (sampled_val->value_type == vtn_value_type_sampled_image) {
1198 sampled = *sampled_val->sampled_image;
1199 } else {
1200 assert(sampled_val->value_type == vtn_value_type_access_chain);
1201 sampled.image = NULL;
1202 sampled.sampler = sampled_val->access_chain;
1203 }
1204
1205 const struct glsl_type *image_type;
1206 if (sampled.image) {
1207 image_type = sampled.image->var->var->interface_type;
1208 } else {
1209 image_type = sampled.sampler->var->var->interface_type;
1210 }
1211
1212 nir_tex_src srcs[8]; /* 8 should be enough */
1213 nir_tex_src *p = srcs;
1214
1215 unsigned idx = 4;
1216
1217 bool has_coord = false;
1218 switch (opcode) {
1219 case SpvOpImageSampleImplicitLod:
1220 case SpvOpImageSampleExplicitLod:
1221 case SpvOpImageSampleDrefImplicitLod:
1222 case SpvOpImageSampleDrefExplicitLod:
1223 case SpvOpImageSampleProjImplicitLod:
1224 case SpvOpImageSampleProjExplicitLod:
1225 case SpvOpImageSampleProjDrefImplicitLod:
1226 case SpvOpImageSampleProjDrefExplicitLod:
1227 case SpvOpImageFetch:
1228 case SpvOpImageGather:
1229 case SpvOpImageDrefGather:
1230 case SpvOpImageQueryLod: {
1231 /* All these types have the coordinate as their first real argument */
1232 struct vtn_ssa_value *coord = vtn_ssa_value(b, w[idx++]);
1233 has_coord = true;
1234 p->src = nir_src_for_ssa(coord->def);
1235 p->src_type = nir_tex_src_coord;
1236 p++;
1237 break;
1238 }
1239
1240 default:
1241 break;
1242 }
1243
1244 /* These all have an explicit depth value as their next source */
1245 switch (opcode) {
1246 case SpvOpImageSampleDrefImplicitLod:
1247 case SpvOpImageSampleDrefExplicitLod:
1248 case SpvOpImageSampleProjDrefImplicitLod:
1249 case SpvOpImageSampleProjDrefExplicitLod:
1250 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_comparitor);
1251 break;
1252 default:
1253 break;
1254 }
1255
1256 /* For OpImageQuerySizeLod, we always have an LOD */
1257 if (opcode == SpvOpImageQuerySizeLod)
1258 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
1259
1260 /* Figure out the base texture operation */
1261 nir_texop texop;
1262 switch (opcode) {
1263 case SpvOpImageSampleImplicitLod:
1264 case SpvOpImageSampleDrefImplicitLod:
1265 case SpvOpImageSampleProjImplicitLod:
1266 case SpvOpImageSampleProjDrefImplicitLod:
1267 texop = nir_texop_tex;
1268 break;
1269
1270 case SpvOpImageSampleExplicitLod:
1271 case SpvOpImageSampleDrefExplicitLod:
1272 case SpvOpImageSampleProjExplicitLod:
1273 case SpvOpImageSampleProjDrefExplicitLod:
1274 texop = nir_texop_txl;
1275 break;
1276
1277 case SpvOpImageFetch:
1278 if (glsl_get_sampler_dim(image_type) == GLSL_SAMPLER_DIM_MS) {
1279 texop = nir_texop_txf_ms;
1280 } else {
1281 texop = nir_texop_txf;
1282 }
1283 break;
1284
1285 case SpvOpImageGather:
1286 case SpvOpImageDrefGather:
1287 texop = nir_texop_tg4;
1288 break;
1289
1290 case SpvOpImageQuerySizeLod:
1291 case SpvOpImageQuerySize:
1292 texop = nir_texop_txs;
1293 break;
1294
1295 case SpvOpImageQueryLod:
1296 texop = nir_texop_lod;
1297 break;
1298
1299 case SpvOpImageQueryLevels:
1300 texop = nir_texop_query_levels;
1301 break;
1302
1303 case SpvOpImageQuerySamples:
1304 default:
1305 unreachable("Unhandled opcode");
1306 }
1307
1308 /* Now we need to handle some number of optional arguments */
1309 if (idx < count) {
1310 uint32_t operands = w[idx++];
1311
1312 if (operands & SpvImageOperandsBiasMask) {
1313 assert(texop == nir_texop_tex);
1314 texop = nir_texop_txb;
1315 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_bias);
1316 }
1317
1318 if (operands & SpvImageOperandsLodMask) {
1319 assert(texop == nir_texop_txl || texop == nir_texop_txf ||
1320 texop == nir_texop_txf_ms || texop == nir_texop_txs);
1321 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
1322 }
1323
1324 if (operands & SpvImageOperandsGradMask) {
1325 assert(texop == nir_texop_tex);
1326 texop = nir_texop_txd;
1327 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddx);
1328 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddy);
1329 }
1330
1331 if (operands & SpvImageOperandsOffsetMask ||
1332 operands & SpvImageOperandsConstOffsetMask)
1333 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_offset);
1334
1335 if (operands & SpvImageOperandsConstOffsetsMask)
1336 assert(!"Constant offsets to texture gather not yet implemented");
1337
1338 if (operands & SpvImageOperandsSampleMask) {
1339 assert(texop == nir_texop_txf_ms);
1340 texop = nir_texop_txf_ms;
1341 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
1342 }
1343 }
1344 /* We should have now consumed exactly all of the arguments */
1345 assert(idx == count);
1346
1347 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
1348 instr->op = texop;
1349
1350 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
1351
1352 instr->sampler_dim = glsl_get_sampler_dim(image_type);
1353 instr->is_array = glsl_sampler_type_is_array(image_type);
1354 instr->is_shadow = glsl_sampler_type_is_shadow(image_type);
1355 instr->is_new_style_shadow = instr->is_shadow;
1356
1357 if (has_coord) {
1358 switch (instr->sampler_dim) {
1359 case GLSL_SAMPLER_DIM_1D:
1360 case GLSL_SAMPLER_DIM_BUF:
1361 instr->coord_components = 1;
1362 break;
1363 case GLSL_SAMPLER_DIM_2D:
1364 case GLSL_SAMPLER_DIM_RECT:
1365 case GLSL_SAMPLER_DIM_MS:
1366 instr->coord_components = 2;
1367 break;
1368 case GLSL_SAMPLER_DIM_3D:
1369 case GLSL_SAMPLER_DIM_CUBE:
1370 instr->coord_components = 3;
1371 break;
1372 default:
1373 assert("Invalid sampler type");
1374 }
1375
1376 if (instr->is_array)
1377 instr->coord_components++;
1378 } else {
1379 instr->coord_components = 0;
1380 }
1381
1382 switch (glsl_get_sampler_result_type(image_type)) {
1383 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
1384 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
1385 case GLSL_TYPE_UINT: instr->dest_type = nir_type_uint; break;
1386 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
1387 default:
1388 unreachable("Invalid base type for sampler result");
1389 }
1390
1391 nir_deref_var *sampler = vtn_access_chain_to_deref(b, sampled.sampler);
1392 if (sampled.image) {
1393 nir_deref_var *image = vtn_access_chain_to_deref(b, sampled.image);
1394 instr->texture = nir_deref_as_var(nir_copy_deref(instr, &image->deref));
1395 } else {
1396 instr->texture = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
1397 }
1398
1399 switch (instr->op) {
1400 case nir_texop_tex:
1401 case nir_texop_txb:
1402 case nir_texop_txl:
1403 case nir_texop_txd:
1404 /* These operations require a sampler */
1405 instr->sampler = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
1406 break;
1407 case nir_texop_txf:
1408 case nir_texop_txf_ms:
1409 case nir_texop_txs:
1410 case nir_texop_lod:
1411 case nir_texop_tg4:
1412 case nir_texop_query_levels:
1413 case nir_texop_texture_samples:
1414 case nir_texop_samples_identical:
1415 /* These don't */
1416 instr->sampler = NULL;
1417 break;
1418 }
1419
1420 nir_ssa_dest_init(&instr->instr, &instr->dest,
1421 nir_tex_instr_dest_size(instr), NULL);
1422
1423 assert(glsl_get_vector_elements(ret_type->type) ==
1424 nir_tex_instr_dest_size(instr));
1425
1426 val->ssa = vtn_create_ssa_value(b, ret_type->type);
1427 val->ssa->def = &instr->dest.ssa;
1428
1429 nir_builder_instr_insert(&b->nb, &instr->instr);
1430 }
1431
1432 static nir_ssa_def *
1433 get_image_coord(struct vtn_builder *b, uint32_t value)
1434 {
1435 struct vtn_ssa_value *coord = vtn_ssa_value(b, value);
1436
1437 /* The image_load_store intrinsics assume a 4-dim coordinate */
1438 unsigned dim = glsl_get_vector_elements(coord->type);
1439 unsigned swizzle[4];
1440 for (unsigned i = 0; i < 4; i++)
1441 swizzle[i] = MIN2(i, dim - 1);
1442
1443 return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);
1444 }
1445
1446 static void
1447 vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
1448 const uint32_t *w, unsigned count)
1449 {
1450 /* Just get this one out of the way */
1451 if (opcode == SpvOpImageTexelPointer) {
1452 struct vtn_value *val =
1453 vtn_push_value(b, w[2], vtn_value_type_image_pointer);
1454 val->image = ralloc(b, struct vtn_image_pointer);
1455
1456 val->image->image =
1457 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1458 val->image->coord = get_image_coord(b, w[4]);
1459 val->image->sample = vtn_ssa_value(b, w[5])->def;
1460 return;
1461 }
1462
1463 struct vtn_image_pointer image;
1464
1465 switch (opcode) {
1466 case SpvOpAtomicExchange:
1467 case SpvOpAtomicCompareExchange:
1468 case SpvOpAtomicCompareExchangeWeak:
1469 case SpvOpAtomicIIncrement:
1470 case SpvOpAtomicIDecrement:
1471 case SpvOpAtomicIAdd:
1472 case SpvOpAtomicISub:
1473 case SpvOpAtomicSMin:
1474 case SpvOpAtomicUMin:
1475 case SpvOpAtomicSMax:
1476 case SpvOpAtomicUMax:
1477 case SpvOpAtomicAnd:
1478 case SpvOpAtomicOr:
1479 case SpvOpAtomicXor:
1480 image = *vtn_value(b, w[3], vtn_value_type_image_pointer)->image;
1481 break;
1482
1483 case SpvOpImageQuerySize:
1484 image.image =
1485 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1486 image.coord = NULL;
1487 image.sample = NULL;
1488 break;
1489
1490 case SpvOpImageRead:
1491 image.image =
1492 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1493 image.coord = get_image_coord(b, w[4]);
1494
1495 if (count > 5 && (w[5] & SpvImageOperandsSampleMask)) {
1496 assert(w[5] == SpvImageOperandsSampleMask);
1497 image.sample = vtn_ssa_value(b, w[6])->def;
1498 } else {
1499 image.sample = nir_ssa_undef(&b->nb, 1);
1500 }
1501 break;
1502
1503 case SpvOpImageWrite:
1504 image.image =
1505 vtn_value(b, w[1], vtn_value_type_access_chain)->access_chain;
1506 image.coord = get_image_coord(b, w[2]);
1507
1508 /* texel = w[3] */
1509
1510 if (count > 4 && (w[4] & SpvImageOperandsSampleMask)) {
1511 assert(w[4] == SpvImageOperandsSampleMask);
1512 image.sample = vtn_ssa_value(b, w[5])->def;
1513 } else {
1514 image.sample = nir_ssa_undef(&b->nb, 1);
1515 }
1516 break;
1517
1518 default:
1519 unreachable("Invalid image opcode");
1520 }
1521
1522 nir_intrinsic_op op;
1523 switch (opcode) {
1524 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
1525 OP(ImageQuerySize, size)
1526 OP(ImageRead, load)
1527 OP(ImageWrite, store)
1528 OP(AtomicExchange, atomic_exchange)
1529 OP(AtomicCompareExchange, atomic_comp_swap)
1530 OP(AtomicIIncrement, atomic_add)
1531 OP(AtomicIDecrement, atomic_add)
1532 OP(AtomicIAdd, atomic_add)
1533 OP(AtomicISub, atomic_add)
1534 OP(AtomicSMin, atomic_min)
1535 OP(AtomicUMin, atomic_min)
1536 OP(AtomicSMax, atomic_max)
1537 OP(AtomicUMax, atomic_max)
1538 OP(AtomicAnd, atomic_and)
1539 OP(AtomicOr, atomic_or)
1540 OP(AtomicXor, atomic_xor)
1541 #undef OP
1542 default:
1543 unreachable("Invalid image opcode");
1544 }
1545
1546 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
1547
1548 nir_deref_var *image_deref = vtn_access_chain_to_deref(b, image.image);
1549 intrin->variables[0] =
1550 nir_deref_as_var(nir_copy_deref(&intrin->instr, &image_deref->deref));
1551
1552 /* ImageQuerySize doesn't take any extra parameters */
1553 if (opcode != SpvOpImageQuerySize) {
1554 /* The image coordinate is always 4 components but we may not have that
1555 * many. Swizzle to compensate.
1556 */
1557 unsigned swiz[4];
1558 for (unsigned i = 0; i < 4; i++)
1559 swiz[i] = i < image.coord->num_components ? i : 0;
1560 intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
1561 swiz, 4, false));
1562 intrin->src[1] = nir_src_for_ssa(image.sample);
1563 }
1564
1565 switch (opcode) {
1566 case SpvOpImageQuerySize:
1567 case SpvOpImageRead:
1568 break;
1569 case SpvOpImageWrite:
1570 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
1571 break;
1572 case SpvOpAtomicIIncrement:
1573 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
1574 break;
1575 case SpvOpAtomicIDecrement:
1576 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
1577 break;
1578
1579 case SpvOpAtomicExchange:
1580 case SpvOpAtomicIAdd:
1581 case SpvOpAtomicSMin:
1582 case SpvOpAtomicUMin:
1583 case SpvOpAtomicSMax:
1584 case SpvOpAtomicUMax:
1585 case SpvOpAtomicAnd:
1586 case SpvOpAtomicOr:
1587 case SpvOpAtomicXor:
1588 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1589 break;
1590
1591 case SpvOpAtomicCompareExchange:
1592 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
1593 intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1594 break;
1595
1596 case SpvOpAtomicISub:
1597 intrin->src[2] = nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
1598 break;
1599
1600 default:
1601 unreachable("Invalid image opcode");
1602 }
1603
1604 if (opcode != SpvOpImageWrite) {
1605 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1606 struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
1607 nir_ssa_dest_init(&intrin->instr, &intrin->dest, 4, NULL);
1608
1609 nir_builder_instr_insert(&b->nb, &intrin->instr);
1610
1611 /* The image intrinsics always return 4 channels but we may not want
1612 * that many. Emit a mov to trim it down.
1613 */
1614 unsigned swiz[4] = {0, 1, 2, 3};
1615 val->ssa = vtn_create_ssa_value(b, type->type);
1616 val->ssa->def = nir_swizzle(&b->nb, &intrin->dest.ssa, swiz,
1617 glsl_get_vector_elements(type->type), false);
1618 } else {
1619 nir_builder_instr_insert(&b->nb, &intrin->instr);
1620 }
1621 }
1622
1623 static nir_intrinsic_op
1624 get_ssbo_nir_atomic_op(SpvOp opcode)
1625 {
1626 switch (opcode) {
1627 #define OP(S, N) case SpvOp##S: return nir_intrinsic_ssbo_##N;
1628 OP(AtomicExchange, atomic_exchange)
1629 OP(AtomicCompareExchange, atomic_comp_swap)
1630 OP(AtomicIIncrement, atomic_add)
1631 OP(AtomicIDecrement, atomic_add)
1632 OP(AtomicIAdd, atomic_add)
1633 OP(AtomicISub, atomic_add)
1634 OP(AtomicSMin, atomic_imin)
1635 OP(AtomicUMin, atomic_umin)
1636 OP(AtomicSMax, atomic_imax)
1637 OP(AtomicUMax, atomic_umax)
1638 OP(AtomicAnd, atomic_and)
1639 OP(AtomicOr, atomic_or)
1640 OP(AtomicXor, atomic_xor)
1641 #undef OP
1642 default:
1643 unreachable("Invalid SSBO atomic");
1644 }
1645 }
1646
1647 static nir_intrinsic_op
1648 get_shared_nir_atomic_op(SpvOp opcode)
1649 {
1650 switch (opcode) {
1651 #define OP(S, N) case SpvOp##S: return nir_intrinsic_var_##N;
1652 OP(AtomicExchange, atomic_exchange)
1653 OP(AtomicCompareExchange, atomic_comp_swap)
1654 OP(AtomicIIncrement, atomic_add)
1655 OP(AtomicIDecrement, atomic_add)
1656 OP(AtomicIAdd, atomic_add)
1657 OP(AtomicISub, atomic_add)
1658 OP(AtomicSMin, atomic_imin)
1659 OP(AtomicUMin, atomic_umin)
1660 OP(AtomicSMax, atomic_imax)
1661 OP(AtomicUMax, atomic_umax)
1662 OP(AtomicAnd, atomic_and)
1663 OP(AtomicOr, atomic_or)
1664 OP(AtomicXor, atomic_xor)
1665 #undef OP
1666 default:
1667 unreachable("Invalid shared atomic");
1668 }
1669 }
1670
1671 static void
1672 fill_common_atomic_sources(struct vtn_builder *b, SpvOp opcode,
1673 const uint32_t *w, nir_src *src)
1674 {
1675 switch (opcode) {
1676 case SpvOpAtomicIIncrement:
1677 src[0] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
1678 break;
1679
1680 case SpvOpAtomicIDecrement:
1681 src[0] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
1682 break;
1683
1684 case SpvOpAtomicISub:
1685 src[0] =
1686 nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
1687 break;
1688
1689 case SpvOpAtomicCompareExchange:
1690 src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
1691 src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[8])->def);
1692 break;
1693 /* Fall through */
1694
1695 case SpvOpAtomicExchange:
1696 case SpvOpAtomicIAdd:
1697 case SpvOpAtomicSMin:
1698 case SpvOpAtomicUMin:
1699 case SpvOpAtomicSMax:
1700 case SpvOpAtomicUMax:
1701 case SpvOpAtomicAnd:
1702 case SpvOpAtomicOr:
1703 case SpvOpAtomicXor:
1704 src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
1705 break;
1706
1707 default:
1708 unreachable("Invalid SPIR-V atomic");
1709 }
1710 }
1711
1712 static void
1713 vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode,
1714 const uint32_t *w, unsigned count)
1715 {
1716 struct vtn_access_chain *chain =
1717 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
1718 nir_intrinsic_instr *atomic;
1719
1720 /*
1721 SpvScope scope = w[4];
1722 SpvMemorySemanticsMask semantics = w[5];
1723 */
1724
1725 if (chain->var->mode == vtn_variable_mode_workgroup) {
1726 nir_deref *deref = &vtn_access_chain_to_deref(b, chain)->deref;
1727 nir_intrinsic_op op = get_shared_nir_atomic_op(opcode);
1728 atomic = nir_intrinsic_instr_create(b->nb.shader, op);
1729 atomic->variables[0] = nir_deref_as_var(nir_copy_deref(atomic, deref));
1730 fill_common_atomic_sources(b, opcode, w, &atomic->src[0]);
1731 } else {
1732 assert(chain->var->mode == vtn_variable_mode_ssbo);
1733 struct vtn_type *type;
1734 nir_ssa_def *offset, *index;
1735 offset = vtn_access_chain_to_offset(b, chain, &index, &type, NULL, false);
1736
1737 nir_intrinsic_op op = get_ssbo_nir_atomic_op(opcode);
1738
1739 atomic = nir_intrinsic_instr_create(b->nb.shader, op);
1740 atomic->src[0] = nir_src_for_ssa(index);
1741 atomic->src[1] = nir_src_for_ssa(offset);
1742 fill_common_atomic_sources(b, opcode, w, &atomic->src[2]);
1743 }
1744
1745 nir_ssa_dest_init(&atomic->instr, &atomic->dest, 1, NULL);
1746
1747 struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
1748 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1749 val->ssa = rzalloc(b, struct vtn_ssa_value);
1750 val->ssa->def = &atomic->dest.ssa;
1751 val->ssa->type = type->type;
1752
1753 nir_builder_instr_insert(&b->nb, &atomic->instr);
1754 }
1755
1756 static nir_alu_instr *
1757 create_vec(nir_shader *shader, unsigned num_components)
1758 {
1759 nir_op op;
1760 switch (num_components) {
1761 case 1: op = nir_op_fmov; break;
1762 case 2: op = nir_op_vec2; break;
1763 case 3: op = nir_op_vec3; break;
1764 case 4: op = nir_op_vec4; break;
1765 default: unreachable("bad vector size");
1766 }
1767
1768 nir_alu_instr *vec = nir_alu_instr_create(shader, op);
1769 nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components, NULL);
1770 vec->dest.write_mask = (1 << num_components) - 1;
1771
1772 return vec;
1773 }
1774
1775 struct vtn_ssa_value *
1776 vtn_ssa_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
1777 {
1778 if (src->transposed)
1779 return src->transposed;
1780
1781 struct vtn_ssa_value *dest =
1782 vtn_create_ssa_value(b, glsl_transposed_type(src->type));
1783
1784 for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
1785 nir_alu_instr *vec = create_vec(b->shader,
1786 glsl_get_matrix_columns(src->type));
1787 if (glsl_type_is_vector_or_scalar(src->type)) {
1788 vec->src[0].src = nir_src_for_ssa(src->def);
1789 vec->src[0].swizzle[0] = i;
1790 } else {
1791 for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
1792 vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
1793 vec->src[j].swizzle[0] = i;
1794 }
1795 }
1796 nir_builder_instr_insert(&b->nb, &vec->instr);
1797 dest->elems[i]->def = &vec->dest.dest.ssa;
1798 }
1799
1800 dest->transposed = src;
1801
1802 return dest;
1803 }
1804
1805 nir_ssa_def *
1806 vtn_vector_extract(struct vtn_builder *b, nir_ssa_def *src, unsigned index)
1807 {
1808 unsigned swiz[4] = { index };
1809 return nir_swizzle(&b->nb, src, swiz, 1, true);
1810 }
1811
1812 nir_ssa_def *
1813 vtn_vector_insert(struct vtn_builder *b, nir_ssa_def *src, nir_ssa_def *insert,
1814 unsigned index)
1815 {
1816 nir_alu_instr *vec = create_vec(b->shader, src->num_components);
1817
1818 for (unsigned i = 0; i < src->num_components; i++) {
1819 if (i == index) {
1820 vec->src[i].src = nir_src_for_ssa(insert);
1821 } else {
1822 vec->src[i].src = nir_src_for_ssa(src);
1823 vec->src[i].swizzle[0] = i;
1824 }
1825 }
1826
1827 nir_builder_instr_insert(&b->nb, &vec->instr);
1828
1829 return &vec->dest.dest.ssa;
1830 }
1831
1832 nir_ssa_def *
1833 vtn_vector_extract_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1834 nir_ssa_def *index)
1835 {
1836 nir_ssa_def *dest = vtn_vector_extract(b, src, 0);
1837 for (unsigned i = 1; i < src->num_components; i++)
1838 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1839 vtn_vector_extract(b, src, i), dest);
1840
1841 return dest;
1842 }
1843
1844 nir_ssa_def *
1845 vtn_vector_insert_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1846 nir_ssa_def *insert, nir_ssa_def *index)
1847 {
1848 nir_ssa_def *dest = vtn_vector_insert(b, src, insert, 0);
1849 for (unsigned i = 1; i < src->num_components; i++)
1850 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1851 vtn_vector_insert(b, src, insert, i), dest);
1852
1853 return dest;
1854 }
1855
1856 static nir_ssa_def *
1857 vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
1858 nir_ssa_def *src0, nir_ssa_def *src1,
1859 const uint32_t *indices)
1860 {
1861 nir_alu_instr *vec = create_vec(b->shader, num_components);
1862
1863 nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(b->shader, 1);
1864 nir_builder_instr_insert(&b->nb, &undef->instr);
1865
1866 for (unsigned i = 0; i < num_components; i++) {
1867 uint32_t index = indices[i];
1868 if (index == 0xffffffff) {
1869 vec->src[i].src = nir_src_for_ssa(&undef->def);
1870 } else if (index < src0->num_components) {
1871 vec->src[i].src = nir_src_for_ssa(src0);
1872 vec->src[i].swizzle[0] = index;
1873 } else {
1874 vec->src[i].src = nir_src_for_ssa(src1);
1875 vec->src[i].swizzle[0] = index - src0->num_components;
1876 }
1877 }
1878
1879 nir_builder_instr_insert(&b->nb, &vec->instr);
1880
1881 return &vec->dest.dest.ssa;
1882 }
1883
1884 /*
1885 * Concatentates a number of vectors/scalars together to produce a vector
1886 */
1887 static nir_ssa_def *
1888 vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
1889 unsigned num_srcs, nir_ssa_def **srcs)
1890 {
1891 nir_alu_instr *vec = create_vec(b->shader, num_components);
1892
1893 unsigned dest_idx = 0;
1894 for (unsigned i = 0; i < num_srcs; i++) {
1895 nir_ssa_def *src = srcs[i];
1896 for (unsigned j = 0; j < src->num_components; j++) {
1897 vec->src[dest_idx].src = nir_src_for_ssa(src);
1898 vec->src[dest_idx].swizzle[0] = j;
1899 dest_idx++;
1900 }
1901 }
1902
1903 nir_builder_instr_insert(&b->nb, &vec->instr);
1904
1905 return &vec->dest.dest.ssa;
1906 }
1907
1908 static struct vtn_ssa_value *
1909 vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
1910 {
1911 struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
1912 dest->type = src->type;
1913
1914 if (glsl_type_is_vector_or_scalar(src->type)) {
1915 dest->def = src->def;
1916 } else {
1917 unsigned elems = glsl_get_length(src->type);
1918
1919 dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
1920 for (unsigned i = 0; i < elems; i++)
1921 dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
1922 }
1923
1924 return dest;
1925 }
1926
1927 static struct vtn_ssa_value *
1928 vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
1929 struct vtn_ssa_value *insert, const uint32_t *indices,
1930 unsigned num_indices)
1931 {
1932 struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
1933
1934 struct vtn_ssa_value *cur = dest;
1935 unsigned i;
1936 for (i = 0; i < num_indices - 1; i++) {
1937 cur = cur->elems[indices[i]];
1938 }
1939
1940 if (glsl_type_is_vector_or_scalar(cur->type)) {
1941 /* According to the SPIR-V spec, OpCompositeInsert may work down to
1942 * the component granularity. In that case, the last index will be
1943 * the index to insert the scalar into the vector.
1944 */
1945
1946 cur->def = vtn_vector_insert(b, cur->def, insert->def, indices[i]);
1947 } else {
1948 cur->elems[indices[i]] = insert;
1949 }
1950
1951 return dest;
1952 }
1953
1954 static struct vtn_ssa_value *
1955 vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
1956 const uint32_t *indices, unsigned num_indices)
1957 {
1958 struct vtn_ssa_value *cur = src;
1959 for (unsigned i = 0; i < num_indices; i++) {
1960 if (glsl_type_is_vector_or_scalar(cur->type)) {
1961 assert(i == num_indices - 1);
1962 /* According to the SPIR-V spec, OpCompositeExtract may work down to
1963 * the component granularity. The last index will be the index of the
1964 * vector to extract.
1965 */
1966
1967 struct vtn_ssa_value *ret = rzalloc(b, struct vtn_ssa_value);
1968 ret->type = glsl_scalar_type(glsl_get_base_type(cur->type));
1969 ret->def = vtn_vector_extract(b, cur->def, indices[i]);
1970 return ret;
1971 } else {
1972 cur = cur->elems[indices[i]];
1973 }
1974 }
1975
1976 return cur;
1977 }
1978
1979 static void
1980 vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
1981 const uint32_t *w, unsigned count)
1982 {
1983 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1984 const struct glsl_type *type =
1985 vtn_value(b, w[1], vtn_value_type_type)->type->type;
1986 val->ssa = vtn_create_ssa_value(b, type);
1987
1988 switch (opcode) {
1989 case SpvOpVectorExtractDynamic:
1990 val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def,
1991 vtn_ssa_value(b, w[4])->def);
1992 break;
1993
1994 case SpvOpVectorInsertDynamic:
1995 val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def,
1996 vtn_ssa_value(b, w[4])->def,
1997 vtn_ssa_value(b, w[5])->def);
1998 break;
1999
2000 case SpvOpVectorShuffle:
2001 val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type),
2002 vtn_ssa_value(b, w[3])->def,
2003 vtn_ssa_value(b, w[4])->def,
2004 w + 5);
2005 break;
2006
2007 case SpvOpCompositeConstruct: {
2008 unsigned elems = count - 3;
2009 if (glsl_type_is_vector_or_scalar(type)) {
2010 nir_ssa_def *srcs[4];
2011 for (unsigned i = 0; i < elems; i++)
2012 srcs[i] = vtn_ssa_value(b, w[3 + i])->def;
2013 val->ssa->def =
2014 vtn_vector_construct(b, glsl_get_vector_elements(type),
2015 elems, srcs);
2016 } else {
2017 val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
2018 for (unsigned i = 0; i < elems; i++)
2019 val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
2020 }
2021 break;
2022 }
2023 case SpvOpCompositeExtract:
2024 val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
2025 w + 4, count - 4);
2026 break;
2027
2028 case SpvOpCompositeInsert:
2029 val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
2030 vtn_ssa_value(b, w[3]),
2031 w + 5, count - 5);
2032 break;
2033
2034 case SpvOpCopyObject:
2035 val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
2036 break;
2037
2038 default:
2039 unreachable("unknown composite operation");
2040 }
2041 }
2042
2043 static void
2044 vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
2045 const uint32_t *w, unsigned count)
2046 {
2047 nir_intrinsic_op intrinsic_op;
2048 switch (opcode) {
2049 case SpvOpEmitVertex:
2050 case SpvOpEmitStreamVertex:
2051 intrinsic_op = nir_intrinsic_emit_vertex;
2052 break;
2053 case SpvOpEndPrimitive:
2054 case SpvOpEndStreamPrimitive:
2055 intrinsic_op = nir_intrinsic_end_primitive;
2056 break;
2057 case SpvOpMemoryBarrier:
2058 intrinsic_op = nir_intrinsic_memory_barrier;
2059 break;
2060 case SpvOpControlBarrier:
2061 intrinsic_op = nir_intrinsic_barrier;
2062 break;
2063 default:
2064 unreachable("unknown barrier instruction");
2065 }
2066
2067 nir_intrinsic_instr *intrin =
2068 nir_intrinsic_instr_create(b->shader, intrinsic_op);
2069
2070 if (opcode == SpvOpEmitStreamVertex || opcode == SpvOpEndStreamPrimitive)
2071 nir_intrinsic_set_stream_id(intrin, w[1]);
2072
2073 nir_builder_instr_insert(&b->nb, &intrin->instr);
2074 }
2075
2076 static unsigned
2077 gl_primitive_from_spv_execution_mode(SpvExecutionMode mode)
2078 {
2079 switch (mode) {
2080 case SpvExecutionModeInputPoints:
2081 case SpvExecutionModeOutputPoints:
2082 return 0; /* GL_POINTS */
2083 case SpvExecutionModeInputLines:
2084 return 1; /* GL_LINES */
2085 case SpvExecutionModeInputLinesAdjacency:
2086 return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
2087 case SpvExecutionModeTriangles:
2088 return 4; /* GL_TRIANGLES */
2089 case SpvExecutionModeInputTrianglesAdjacency:
2090 return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
2091 case SpvExecutionModeQuads:
2092 return 7; /* GL_QUADS */
2093 case SpvExecutionModeIsolines:
2094 return 0x8E7A; /* GL_ISOLINES */
2095 case SpvExecutionModeOutputLineStrip:
2096 return 3; /* GL_LINE_STRIP */
2097 case SpvExecutionModeOutputTriangleStrip:
2098 return 5; /* GL_TRIANGLE_STRIP */
2099 default:
2100 assert(!"Invalid primitive type");
2101 return 4;
2102 }
2103 }
2104
2105 static unsigned
2106 vertices_in_from_spv_execution_mode(SpvExecutionMode mode)
2107 {
2108 switch (mode) {
2109 case SpvExecutionModeInputPoints:
2110 return 1;
2111 case SpvExecutionModeInputLines:
2112 return 2;
2113 case SpvExecutionModeInputLinesAdjacency:
2114 return 4;
2115 case SpvExecutionModeTriangles:
2116 return 3;
2117 case SpvExecutionModeInputTrianglesAdjacency:
2118 return 6;
2119 default:
2120 assert(!"Invalid GS input mode");
2121 return 0;
2122 }
2123 }
2124
2125 static gl_shader_stage
2126 stage_for_execution_model(SpvExecutionModel model)
2127 {
2128 switch (model) {
2129 case SpvExecutionModelVertex:
2130 return MESA_SHADER_VERTEX;
2131 case SpvExecutionModelTessellationControl:
2132 return MESA_SHADER_TESS_CTRL;
2133 case SpvExecutionModelTessellationEvaluation:
2134 return MESA_SHADER_TESS_EVAL;
2135 case SpvExecutionModelGeometry:
2136 return MESA_SHADER_GEOMETRY;
2137 case SpvExecutionModelFragment:
2138 return MESA_SHADER_FRAGMENT;
2139 case SpvExecutionModelGLCompute:
2140 return MESA_SHADER_COMPUTE;
2141 default:
2142 unreachable("Unsupported execution model");
2143 }
2144 }
2145
2146 static bool
2147 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
2148 const uint32_t *w, unsigned count)
2149 {
2150 switch (opcode) {
2151 case SpvOpSource:
2152 case SpvOpSourceExtension:
2153 case SpvOpSourceContinued:
2154 case SpvOpExtension:
2155 /* Unhandled, but these are for debug so that's ok. */
2156 break;
2157
2158 case SpvOpCapability: {
2159 SpvCapability cap = w[1];
2160 switch (cap) {
2161 case SpvCapabilityMatrix:
2162 case SpvCapabilityShader:
2163 case SpvCapabilityGeometry:
2164 case SpvCapabilityTessellationPointSize:
2165 case SpvCapabilityGeometryPointSize:
2166 case SpvCapabilityUniformBufferArrayDynamicIndexing:
2167 case SpvCapabilitySampledImageArrayDynamicIndexing:
2168 case SpvCapabilityStorageBufferArrayDynamicIndexing:
2169 case SpvCapabilityStorageImageArrayDynamicIndexing:
2170 case SpvCapabilityImageRect:
2171 case SpvCapabilitySampledRect:
2172 case SpvCapabilitySampled1D:
2173 case SpvCapabilityImage1D:
2174 case SpvCapabilitySampledCubeArray:
2175 case SpvCapabilitySampledBuffer:
2176 case SpvCapabilityImageBuffer:
2177 case SpvCapabilityImageQuery:
2178 break;
2179 case SpvCapabilityClipDistance:
2180 case SpvCapabilityCullDistance:
2181 case SpvCapabilityGeometryStreams:
2182 fprintf(stderr, "WARNING: Unsupported SPIR-V Capability\n");
2183 break;
2184 default:
2185 assert(!"Unsupported capability");
2186 }
2187 break;
2188 }
2189
2190 case SpvOpExtInstImport:
2191 vtn_handle_extension(b, opcode, w, count);
2192 break;
2193
2194 case SpvOpMemoryModel:
2195 assert(w[1] == SpvAddressingModelLogical);
2196 assert(w[2] == SpvMemoryModelGLSL450);
2197 break;
2198
2199 case SpvOpEntryPoint: {
2200 struct vtn_value *entry_point = &b->values[w[2]];
2201 /* Let this be a name label regardless */
2202 unsigned name_words;
2203 entry_point->name = vtn_string_literal(b, &w[3], count - 3, &name_words);
2204
2205 if (strcmp(entry_point->name, b->entry_point_name) != 0 ||
2206 stage_for_execution_model(w[1]) != b->entry_point_stage)
2207 break;
2208
2209 assert(b->entry_point == NULL);
2210 b->entry_point = entry_point;
2211 break;
2212 }
2213
2214 case SpvOpString:
2215 vtn_push_value(b, w[1], vtn_value_type_string)->str =
2216 vtn_string_literal(b, &w[2], count - 2, NULL);
2217 break;
2218
2219 case SpvOpName:
2220 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2, NULL);
2221 break;
2222
2223 case SpvOpMemberName:
2224 /* TODO */
2225 break;
2226
2227 case SpvOpExecutionMode:
2228 case SpvOpDecorationGroup:
2229 case SpvOpDecorate:
2230 case SpvOpMemberDecorate:
2231 case SpvOpGroupDecorate:
2232 case SpvOpGroupMemberDecorate:
2233 vtn_handle_decoration(b, opcode, w, count);
2234 break;
2235
2236 default:
2237 return false; /* End of preamble */
2238 }
2239
2240 return true;
2241 }
2242
2243 static void
2244 vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
2245 const struct vtn_decoration *mode, void *data)
2246 {
2247 assert(b->entry_point == entry_point);
2248
2249 switch(mode->exec_mode) {
2250 case SpvExecutionModeOriginUpperLeft:
2251 case SpvExecutionModeOriginLowerLeft:
2252 b->origin_upper_left =
2253 (mode->exec_mode == SpvExecutionModeOriginUpperLeft);
2254 break;
2255
2256 case SpvExecutionModeEarlyFragmentTests:
2257 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2258 b->shader->info.fs.early_fragment_tests = true;
2259 break;
2260
2261 case SpvExecutionModeInvocations:
2262 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2263 b->shader->info.gs.invocations = MAX2(1, mode->literals[0]);
2264 break;
2265
2266 case SpvExecutionModeDepthReplacing:
2267 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2268 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
2269 break;
2270 case SpvExecutionModeDepthGreater:
2271 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2272 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
2273 break;
2274 case SpvExecutionModeDepthLess:
2275 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2276 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
2277 break;
2278 case SpvExecutionModeDepthUnchanged:
2279 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
2280 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
2281 break;
2282
2283 case SpvExecutionModeLocalSize:
2284 assert(b->shader->stage == MESA_SHADER_COMPUTE);
2285 b->shader->info.cs.local_size[0] = mode->literals[0];
2286 b->shader->info.cs.local_size[1] = mode->literals[1];
2287 b->shader->info.cs.local_size[2] = mode->literals[2];
2288 break;
2289 case SpvExecutionModeLocalSizeHint:
2290 break; /* Nothing do do with this */
2291
2292 case SpvExecutionModeOutputVertices:
2293 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2294 b->shader->info.gs.vertices_out = mode->literals[0];
2295 break;
2296
2297 case SpvExecutionModeInputPoints:
2298 case SpvExecutionModeInputLines:
2299 case SpvExecutionModeInputLinesAdjacency:
2300 case SpvExecutionModeTriangles:
2301 case SpvExecutionModeInputTrianglesAdjacency:
2302 case SpvExecutionModeQuads:
2303 case SpvExecutionModeIsolines:
2304 if (b->shader->stage == MESA_SHADER_GEOMETRY) {
2305 b->shader->info.gs.vertices_in =
2306 vertices_in_from_spv_execution_mode(mode->exec_mode);
2307 } else {
2308 assert(!"Tesselation shaders not yet supported");
2309 }
2310 break;
2311
2312 case SpvExecutionModeOutputPoints:
2313 case SpvExecutionModeOutputLineStrip:
2314 case SpvExecutionModeOutputTriangleStrip:
2315 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
2316 b->shader->info.gs.output_primitive =
2317 gl_primitive_from_spv_execution_mode(mode->exec_mode);
2318 break;
2319
2320 case SpvExecutionModeSpacingEqual:
2321 case SpvExecutionModeSpacingFractionalEven:
2322 case SpvExecutionModeSpacingFractionalOdd:
2323 case SpvExecutionModeVertexOrderCw:
2324 case SpvExecutionModeVertexOrderCcw:
2325 case SpvExecutionModePointMode:
2326 assert(!"TODO: Add tessellation metadata");
2327 break;
2328
2329 case SpvExecutionModePixelCenterInteger:
2330 case SpvExecutionModeXfb:
2331 assert(!"Unhandled execution mode");
2332 break;
2333
2334 case SpvExecutionModeVecTypeHint:
2335 case SpvExecutionModeContractionOff:
2336 break; /* OpenCL */
2337 }
2338 }
2339
2340 static bool
2341 vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
2342 const uint32_t *w, unsigned count)
2343 {
2344 switch (opcode) {
2345 case SpvOpSource:
2346 case SpvOpSourceContinued:
2347 case SpvOpSourceExtension:
2348 case SpvOpExtension:
2349 case SpvOpCapability:
2350 case SpvOpExtInstImport:
2351 case SpvOpMemoryModel:
2352 case SpvOpEntryPoint:
2353 case SpvOpExecutionMode:
2354 case SpvOpString:
2355 case SpvOpName:
2356 case SpvOpMemberName:
2357 case SpvOpDecorationGroup:
2358 case SpvOpDecorate:
2359 case SpvOpMemberDecorate:
2360 case SpvOpGroupDecorate:
2361 case SpvOpGroupMemberDecorate:
2362 assert(!"Invalid opcode types and variables section");
2363 break;
2364
2365 case SpvOpTypeVoid:
2366 case SpvOpTypeBool:
2367 case SpvOpTypeInt:
2368 case SpvOpTypeFloat:
2369 case SpvOpTypeVector:
2370 case SpvOpTypeMatrix:
2371 case SpvOpTypeImage:
2372 case SpvOpTypeSampler:
2373 case SpvOpTypeSampledImage:
2374 case SpvOpTypeArray:
2375 case SpvOpTypeRuntimeArray:
2376 case SpvOpTypeStruct:
2377 case SpvOpTypeOpaque:
2378 case SpvOpTypePointer:
2379 case SpvOpTypeFunction:
2380 case SpvOpTypeEvent:
2381 case SpvOpTypeDeviceEvent:
2382 case SpvOpTypeReserveId:
2383 case SpvOpTypeQueue:
2384 case SpvOpTypePipe:
2385 vtn_handle_type(b, opcode, w, count);
2386 break;
2387
2388 case SpvOpConstantTrue:
2389 case SpvOpConstantFalse:
2390 case SpvOpConstant:
2391 case SpvOpConstantComposite:
2392 case SpvOpConstantSampler:
2393 case SpvOpConstantNull:
2394 case SpvOpSpecConstantTrue:
2395 case SpvOpSpecConstantFalse:
2396 case SpvOpSpecConstant:
2397 case SpvOpSpecConstantComposite:
2398 case SpvOpSpecConstantOp:
2399 vtn_handle_constant(b, opcode, w, count);
2400 break;
2401
2402 case SpvOpVariable:
2403 vtn_handle_variables(b, opcode, w, count);
2404 break;
2405
2406 default:
2407 return false; /* End of preamble */
2408 }
2409
2410 return true;
2411 }
2412
2413 static bool
2414 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
2415 const uint32_t *w, unsigned count)
2416 {
2417 switch (opcode) {
2418 case SpvOpLabel:
2419 break;
2420
2421 case SpvOpLoopMerge:
2422 case SpvOpSelectionMerge:
2423 /* This is handled by cfg pre-pass and walk_blocks */
2424 break;
2425
2426 case SpvOpUndef: {
2427 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
2428 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
2429 break;
2430 }
2431
2432 case SpvOpExtInst:
2433 vtn_handle_extension(b, opcode, w, count);
2434 break;
2435
2436 case SpvOpVariable:
2437 case SpvOpLoad:
2438 case SpvOpStore:
2439 case SpvOpCopyMemory:
2440 case SpvOpCopyMemorySized:
2441 case SpvOpAccessChain:
2442 case SpvOpInBoundsAccessChain:
2443 case SpvOpArrayLength:
2444 vtn_handle_variables(b, opcode, w, count);
2445 break;
2446
2447 case SpvOpFunctionCall:
2448 vtn_handle_function_call(b, opcode, w, count);
2449 break;
2450
2451 case SpvOpSampledImage:
2452 case SpvOpImage:
2453 case SpvOpImageSampleImplicitLod:
2454 case SpvOpImageSampleExplicitLod:
2455 case SpvOpImageSampleDrefImplicitLod:
2456 case SpvOpImageSampleDrefExplicitLod:
2457 case SpvOpImageSampleProjImplicitLod:
2458 case SpvOpImageSampleProjExplicitLod:
2459 case SpvOpImageSampleProjDrefImplicitLod:
2460 case SpvOpImageSampleProjDrefExplicitLod:
2461 case SpvOpImageFetch:
2462 case SpvOpImageGather:
2463 case SpvOpImageDrefGather:
2464 case SpvOpImageQuerySizeLod:
2465 case SpvOpImageQueryLod:
2466 case SpvOpImageQueryLevels:
2467 case SpvOpImageQuerySamples:
2468 vtn_handle_texture(b, opcode, w, count);
2469 break;
2470
2471 case SpvOpImageRead:
2472 case SpvOpImageWrite:
2473 case SpvOpImageTexelPointer:
2474 vtn_handle_image(b, opcode, w, count);
2475 break;
2476
2477 case SpvOpImageQuerySize: {
2478 struct vtn_access_chain *image =
2479 vtn_value(b, w[3], vtn_value_type_access_chain)->access_chain;
2480 if (glsl_type_is_image(image->var->var->interface_type)) {
2481 vtn_handle_image(b, opcode, w, count);
2482 } else {
2483 vtn_handle_texture(b, opcode, w, count);
2484 }
2485 break;
2486 }
2487
2488 case SpvOpAtomicExchange:
2489 case SpvOpAtomicCompareExchange:
2490 case SpvOpAtomicCompareExchangeWeak:
2491 case SpvOpAtomicIIncrement:
2492 case SpvOpAtomicIDecrement:
2493 case SpvOpAtomicIAdd:
2494 case SpvOpAtomicISub:
2495 case SpvOpAtomicSMin:
2496 case SpvOpAtomicUMin:
2497 case SpvOpAtomicSMax:
2498 case SpvOpAtomicUMax:
2499 case SpvOpAtomicAnd:
2500 case SpvOpAtomicOr:
2501 case SpvOpAtomicXor: {
2502 struct vtn_value *pointer = vtn_untyped_value(b, w[3]);
2503 if (pointer->value_type == vtn_value_type_image_pointer) {
2504 vtn_handle_image(b, opcode, w, count);
2505 } else {
2506 assert(pointer->value_type == vtn_value_type_access_chain);
2507 vtn_handle_ssbo_or_shared_atomic(b, opcode, w, count);
2508 }
2509 break;
2510 }
2511
2512 case SpvOpSNegate:
2513 case SpvOpFNegate:
2514 case SpvOpNot:
2515 case SpvOpAny:
2516 case SpvOpAll:
2517 case SpvOpConvertFToU:
2518 case SpvOpConvertFToS:
2519 case SpvOpConvertSToF:
2520 case SpvOpConvertUToF:
2521 case SpvOpUConvert:
2522 case SpvOpSConvert:
2523 case SpvOpFConvert:
2524 case SpvOpQuantizeToF16:
2525 case SpvOpConvertPtrToU:
2526 case SpvOpConvertUToPtr:
2527 case SpvOpPtrCastToGeneric:
2528 case SpvOpGenericCastToPtr:
2529 case SpvOpBitcast:
2530 case SpvOpIsNan:
2531 case SpvOpIsInf:
2532 case SpvOpIsFinite:
2533 case SpvOpIsNormal:
2534 case SpvOpSignBitSet:
2535 case SpvOpLessOrGreater:
2536 case SpvOpOrdered:
2537 case SpvOpUnordered:
2538 case SpvOpIAdd:
2539 case SpvOpFAdd:
2540 case SpvOpISub:
2541 case SpvOpFSub:
2542 case SpvOpIMul:
2543 case SpvOpFMul:
2544 case SpvOpUDiv:
2545 case SpvOpSDiv:
2546 case SpvOpFDiv:
2547 case SpvOpUMod:
2548 case SpvOpSRem:
2549 case SpvOpSMod:
2550 case SpvOpFRem:
2551 case SpvOpFMod:
2552 case SpvOpVectorTimesScalar:
2553 case SpvOpDot:
2554 case SpvOpIAddCarry:
2555 case SpvOpISubBorrow:
2556 case SpvOpUMulExtended:
2557 case SpvOpSMulExtended:
2558 case SpvOpShiftRightLogical:
2559 case SpvOpShiftRightArithmetic:
2560 case SpvOpShiftLeftLogical:
2561 case SpvOpLogicalEqual:
2562 case SpvOpLogicalNotEqual:
2563 case SpvOpLogicalOr:
2564 case SpvOpLogicalAnd:
2565 case SpvOpLogicalNot:
2566 case SpvOpBitwiseOr:
2567 case SpvOpBitwiseXor:
2568 case SpvOpBitwiseAnd:
2569 case SpvOpSelect:
2570 case SpvOpIEqual:
2571 case SpvOpFOrdEqual:
2572 case SpvOpFUnordEqual:
2573 case SpvOpINotEqual:
2574 case SpvOpFOrdNotEqual:
2575 case SpvOpFUnordNotEqual:
2576 case SpvOpULessThan:
2577 case SpvOpSLessThan:
2578 case SpvOpFOrdLessThan:
2579 case SpvOpFUnordLessThan:
2580 case SpvOpUGreaterThan:
2581 case SpvOpSGreaterThan:
2582 case SpvOpFOrdGreaterThan:
2583 case SpvOpFUnordGreaterThan:
2584 case SpvOpULessThanEqual:
2585 case SpvOpSLessThanEqual:
2586 case SpvOpFOrdLessThanEqual:
2587 case SpvOpFUnordLessThanEqual:
2588 case SpvOpUGreaterThanEqual:
2589 case SpvOpSGreaterThanEqual:
2590 case SpvOpFOrdGreaterThanEqual:
2591 case SpvOpFUnordGreaterThanEqual:
2592 case SpvOpDPdx:
2593 case SpvOpDPdy:
2594 case SpvOpFwidth:
2595 case SpvOpDPdxFine:
2596 case SpvOpDPdyFine:
2597 case SpvOpFwidthFine:
2598 case SpvOpDPdxCoarse:
2599 case SpvOpDPdyCoarse:
2600 case SpvOpFwidthCoarse:
2601 case SpvOpBitFieldInsert:
2602 case SpvOpBitFieldSExtract:
2603 case SpvOpBitFieldUExtract:
2604 case SpvOpBitReverse:
2605 case SpvOpBitCount:
2606 case SpvOpTranspose:
2607 case SpvOpOuterProduct:
2608 case SpvOpMatrixTimesScalar:
2609 case SpvOpVectorTimesMatrix:
2610 case SpvOpMatrixTimesVector:
2611 case SpvOpMatrixTimesMatrix:
2612 vtn_handle_alu(b, opcode, w, count);
2613 break;
2614
2615 case SpvOpVectorExtractDynamic:
2616 case SpvOpVectorInsertDynamic:
2617 case SpvOpVectorShuffle:
2618 case SpvOpCompositeConstruct:
2619 case SpvOpCompositeExtract:
2620 case SpvOpCompositeInsert:
2621 case SpvOpCopyObject:
2622 vtn_handle_composite(b, opcode, w, count);
2623 break;
2624
2625 case SpvOpEmitVertex:
2626 case SpvOpEndPrimitive:
2627 case SpvOpEmitStreamVertex:
2628 case SpvOpEndStreamPrimitive:
2629 case SpvOpControlBarrier:
2630 case SpvOpMemoryBarrier:
2631 vtn_handle_barrier(b, opcode, w, count);
2632 break;
2633
2634 default:
2635 unreachable("Unhandled opcode");
2636 }
2637
2638 return true;
2639 }
2640
2641 nir_function *
2642 spirv_to_nir(const uint32_t *words, size_t word_count,
2643 struct nir_spirv_specialization *spec, unsigned num_spec,
2644 gl_shader_stage stage, const char *entry_point_name,
2645 const nir_shader_compiler_options *options)
2646 {
2647 const uint32_t *word_end = words + word_count;
2648
2649 /* Handle the SPIR-V header (first 4 dwords) */
2650 assert(word_count > 5);
2651
2652 assert(words[0] == SpvMagicNumber);
2653 assert(words[1] >= 0x10000);
2654 /* words[2] == generator magic */
2655 unsigned value_id_bound = words[3];
2656 assert(words[4] == 0);
2657
2658 words+= 5;
2659
2660 /* Initialize the stn_builder object */
2661 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
2662 b->value_id_bound = value_id_bound;
2663 b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
2664 exec_list_make_empty(&b->functions);
2665 b->entry_point_stage = stage;
2666 b->entry_point_name = entry_point_name;
2667
2668 /* Handle all the preamble instructions */
2669 words = vtn_foreach_instruction(b, words, word_end,
2670 vtn_handle_preamble_instruction);
2671
2672 if (b->entry_point == NULL) {
2673 assert(!"Entry point not found");
2674 ralloc_free(b);
2675 return NULL;
2676 }
2677
2678 b->shader = nir_shader_create(NULL, stage, options);
2679
2680 /* Parse execution modes */
2681 vtn_foreach_execution_mode(b, b->entry_point,
2682 vtn_handle_execution_mode, NULL);
2683
2684 b->specializations = spec;
2685 b->num_specializations = num_spec;
2686
2687 /* Handle all variable, type, and constant instructions */
2688 words = vtn_foreach_instruction(b, words, word_end,
2689 vtn_handle_variable_or_type_instruction);
2690
2691 vtn_build_cfg(b, words, word_end);
2692
2693 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
2694 b->impl = func->impl;
2695 b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
2696 _mesa_key_pointer_equal);
2697
2698 vtn_function_emit(b, func, vtn_handle_body_instruction);
2699 }
2700
2701 assert(b->entry_point->value_type == vtn_value_type_function);
2702 nir_function *entry_point = b->entry_point->func->impl->function;
2703 assert(entry_point);
2704
2705 ralloc_free(b);
2706
2707 return entry_point;
2708 }