nir/spirv: Let OpEntryPoint act as an OpName
[mesa.git] / src / glsl / 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
32 static struct vtn_ssa_value *
33 vtn_undef_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
34 {
35 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
36 val->type = type;
37
38 if (glsl_type_is_vector_or_scalar(type)) {
39 unsigned num_components = glsl_get_vector_elements(val->type);
40 nir_ssa_undef_instr *undef =
41 nir_ssa_undef_instr_create(b->shader, num_components);
42
43 nir_instr_insert_before_cf_list(&b->impl->body, &undef->instr);
44 val->def = &undef->def;
45 } else {
46 unsigned elems = glsl_get_length(val->type);
47 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
48 if (glsl_type_is_matrix(type)) {
49 const struct glsl_type *elem_type =
50 glsl_vector_type(glsl_get_base_type(type),
51 glsl_get_vector_elements(type));
52
53 for (unsigned i = 0; i < elems; i++)
54 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
55 } else if (glsl_type_is_array(type)) {
56 const struct glsl_type *elem_type = glsl_get_array_element(type);
57 for (unsigned i = 0; i < elems; i++)
58 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
59 } else {
60 for (unsigned i = 0; i < elems; i++) {
61 const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
62 val->elems[i] = vtn_undef_ssa_value(b, elem_type);
63 }
64 }
65 }
66
67 return val;
68 }
69
70 static struct vtn_ssa_value *
71 vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
72 const struct glsl_type *type)
73 {
74 struct hash_entry *entry = _mesa_hash_table_search(b->const_table, constant);
75
76 if (entry)
77 return entry->data;
78
79 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
80 val->type = type;
81
82 switch (glsl_get_base_type(type)) {
83 case GLSL_TYPE_INT:
84 case GLSL_TYPE_UINT:
85 case GLSL_TYPE_BOOL:
86 case GLSL_TYPE_FLOAT:
87 case GLSL_TYPE_DOUBLE:
88 if (glsl_type_is_vector_or_scalar(type)) {
89 unsigned num_components = glsl_get_vector_elements(val->type);
90 nir_load_const_instr *load =
91 nir_load_const_instr_create(b->shader, num_components);
92
93 for (unsigned i = 0; i < num_components; i++)
94 load->value.u[i] = constant->value.u[i];
95
96 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
97 val->def = &load->def;
98 } else {
99 assert(glsl_type_is_matrix(type));
100 unsigned rows = glsl_get_vector_elements(val->type);
101 unsigned columns = glsl_get_matrix_columns(val->type);
102 val->elems = ralloc_array(b, struct vtn_ssa_value *, columns);
103
104 for (unsigned i = 0; i < columns; i++) {
105 struct vtn_ssa_value *col_val = rzalloc(b, struct vtn_ssa_value);
106 col_val->type = glsl_get_column_type(val->type);
107 nir_load_const_instr *load =
108 nir_load_const_instr_create(b->shader, rows);
109
110 for (unsigned j = 0; j < rows; j++)
111 load->value.u[j] = constant->value.u[rows * i + j];
112
113 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
114 col_val->def = &load->def;
115
116 val->elems[i] = col_val;
117 }
118 }
119 break;
120
121 case GLSL_TYPE_ARRAY: {
122 unsigned elems = glsl_get_length(val->type);
123 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
124 const struct glsl_type *elem_type = glsl_get_array_element(val->type);
125 for (unsigned i = 0; i < elems; i++)
126 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
127 elem_type);
128 break;
129 }
130
131 case GLSL_TYPE_STRUCT: {
132 unsigned elems = glsl_get_length(val->type);
133 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
134 for (unsigned i = 0; i < elems; i++) {
135 const struct glsl_type *elem_type =
136 glsl_get_struct_field(val->type, i);
137 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
138 elem_type);
139 }
140 break;
141 }
142
143 default:
144 unreachable("bad constant type");
145 }
146
147 return val;
148 }
149
150 static struct vtn_ssa_value *
151 vtn_variable_load(struct vtn_builder *b, nir_deref_var *src,
152 struct vtn_type *src_type);
153
154 struct vtn_ssa_value *
155 vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
156 {
157 struct vtn_value *val = vtn_untyped_value(b, value_id);
158 switch (val->value_type) {
159 case vtn_value_type_undef:
160 return vtn_undef_ssa_value(b, val->type->type);
161
162 case vtn_value_type_constant:
163 return vtn_const_ssa_value(b, val->constant, val->const_type);
164
165 case vtn_value_type_ssa:
166 return val->ssa;
167
168 case vtn_value_type_deref:
169 /* This is needed for function parameters */
170 return vtn_variable_load(b, val->deref, val->deref_type);
171
172 default:
173 unreachable("Invalid type for an SSA value");
174 }
175 }
176
177 static char *
178 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
179 unsigned word_count)
180 {
181 return ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
182 }
183
184 const uint32_t *
185 vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
186 const uint32_t *end, vtn_instruction_handler handler)
187 {
188 const uint32_t *w = start;
189 while (w < end) {
190 SpvOp opcode = w[0] & SpvOpCodeMask;
191 unsigned count = w[0] >> SpvWordCountShift;
192 assert(count >= 1 && w + count <= end);
193
194 if (opcode == SpvOpNop) {
195 w++;
196 continue;
197 }
198
199 if (!handler(b, opcode, w, count))
200 return w;
201
202 w += count;
203 }
204 assert(w == end);
205 return w;
206 }
207
208 static void
209 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
210 const uint32_t *w, unsigned count)
211 {
212 switch (opcode) {
213 case SpvOpExtInstImport: {
214 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
215 if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) {
216 val->ext_handler = vtn_handle_glsl450_instruction;
217 } else {
218 assert(!"Unsupported extension");
219 }
220 break;
221 }
222
223 case SpvOpExtInst: {
224 struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
225 bool handled = val->ext_handler(b, w[4], w, count);
226 (void)handled;
227 assert(handled);
228 break;
229 }
230
231 default:
232 unreachable("Unhandled opcode");
233 }
234 }
235
236 static void
237 _foreach_decoration_helper(struct vtn_builder *b,
238 struct vtn_value *base_value,
239 int parent_member,
240 struct vtn_value *value,
241 vtn_decoration_foreach_cb cb, void *data)
242 {
243 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
244 int member;
245 if (dec->scope == VTN_DEC_DECORATION) {
246 member = parent_member;
247 } else if (dec->scope >= VTN_DEC_STRUCT_MEMBER0) {
248 assert(parent_member == -1);
249 member = dec->scope - VTN_DEC_STRUCT_MEMBER0;
250 } else {
251 /* Not a decoration */
252 continue;
253 }
254
255 if (dec->group) {
256 assert(dec->group->value_type == vtn_value_type_decoration_group);
257 _foreach_decoration_helper(b, base_value, member, dec->group,
258 cb, data);
259 } else {
260 cb(b, base_value, member, dec, data);
261 }
262 }
263 }
264
265 /** Iterates (recursively if needed) over all of the decorations on a value
266 *
267 * This function iterates over all of the decorations applied to a given
268 * value. If it encounters a decoration group, it recurses into the group
269 * and iterates over all of those decorations as well.
270 */
271 void
272 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
273 vtn_decoration_foreach_cb cb, void *data)
274 {
275 _foreach_decoration_helper(b, value, -1, value, cb, data);
276 }
277
278 void
279 vtn_foreach_execution_mode(struct vtn_builder *b, struct vtn_value *value,
280 vtn_execution_mode_foreach_cb cb, void *data)
281 {
282 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
283 if (dec->scope != VTN_DEC_EXECUTION_MODE)
284 continue;
285
286 assert(dec->group == NULL);
287 cb(b, value, dec, data);
288 }
289 }
290
291 static void
292 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
293 const uint32_t *w, unsigned count)
294 {
295 const uint32_t *w_end = w + count;
296 const uint32_t target = w[1];
297 w += 2;
298
299 switch (opcode) {
300 case SpvOpDecorationGroup:
301 vtn_push_value(b, target, vtn_value_type_undef);
302 break;
303
304 case SpvOpDecorate:
305 case SpvOpMemberDecorate:
306 case SpvOpExecutionMode: {
307 struct vtn_value *val = &b->values[target];
308
309 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
310 switch (opcode) {
311 case SpvOpDecorate:
312 dec->scope = VTN_DEC_DECORATION;
313 break;
314 case SpvOpMemberDecorate:
315 dec->scope = VTN_DEC_STRUCT_MEMBER0 + *(w++);
316 break;
317 case SpvOpExecutionMode:
318 dec->scope = VTN_DEC_EXECUTION_MODE;
319 break;
320 default:
321 unreachable("Invalid decoration opcode");
322 }
323 dec->decoration = *(w++);
324 dec->literals = w;
325
326 /* Link into the list */
327 dec->next = val->decoration;
328 val->decoration = dec;
329 break;
330 }
331
332 case SpvOpGroupMemberDecorate:
333 case SpvOpGroupDecorate: {
334 struct vtn_value *group = &b->values[target];
335 assert(group->value_type == vtn_value_type_decoration_group);
336
337 int scope;
338 if (opcode == SpvOpGroupDecorate) {
339 scope = VTN_DEC_DECORATION;
340 } else {
341 scope = VTN_DEC_STRUCT_MEMBER0 + *(w++);
342 }
343
344 for (; w < w_end; w++) {
345 struct vtn_value *val = &b->values[*w];
346 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
347 dec->scope = scope;
348 dec->group = group;
349
350 /* Link into the list */
351 dec->next = val->decoration;
352 val->decoration = dec;
353 }
354 break;
355 }
356
357 default:
358 unreachable("Unhandled opcode");
359 }
360 }
361
362 struct member_decoration_ctx {
363 struct glsl_struct_field *fields;
364 struct vtn_type *type;
365 };
366
367 /* does a shallow copy of a vtn_type */
368
369 static struct vtn_type *
370 vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
371 {
372 struct vtn_type *dest = ralloc(b, struct vtn_type);
373 dest->type = src->type;
374 dest->is_builtin = src->is_builtin;
375 if (src->is_builtin)
376 dest->builtin = src->builtin;
377
378 if (!glsl_type_is_vector_or_scalar(src->type)) {
379 switch (glsl_get_base_type(src->type)) {
380 case GLSL_TYPE_ARRAY:
381 dest->array_element = src->array_element;
382 dest->stride = src->stride;
383 break;
384
385 case GLSL_TYPE_INT:
386 case GLSL_TYPE_UINT:
387 case GLSL_TYPE_BOOL:
388 case GLSL_TYPE_FLOAT:
389 case GLSL_TYPE_DOUBLE:
390 /* matrices */
391 dest->row_major = src->row_major;
392 dest->stride = src->stride;
393 break;
394
395 case GLSL_TYPE_STRUCT: {
396 unsigned elems = glsl_get_length(src->type);
397
398 dest->members = ralloc_array(b, struct vtn_type *, elems);
399 memcpy(dest->members, src->members, elems * sizeof(struct vtn_type *));
400
401 dest->offsets = ralloc_array(b, unsigned, elems);
402 memcpy(dest->offsets, src->offsets, elems * sizeof(unsigned));
403 break;
404 }
405
406 default:
407 unreachable("unhandled type");
408 }
409 }
410
411 return dest;
412 }
413
414 static void
415 struct_member_decoration_cb(struct vtn_builder *b,
416 struct vtn_value *val, int member,
417 const struct vtn_decoration *dec, void *void_ctx)
418 {
419 struct member_decoration_ctx *ctx = void_ctx;
420
421 if (member < 0)
422 return;
423
424 switch (dec->decoration) {
425 case SpvDecorationRelaxedPrecision:
426 break; /* FIXME: Do nothing with this for now. */
427 case SpvDecorationNoPerspective:
428 ctx->fields[member].interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
429 break;
430 case SpvDecorationFlat:
431 ctx->fields[member].interpolation = INTERP_QUALIFIER_FLAT;
432 break;
433 case SpvDecorationCentroid:
434 ctx->fields[member].centroid = true;
435 break;
436 case SpvDecorationSample:
437 ctx->fields[member].sample = true;
438 break;
439 case SpvDecorationLocation:
440 ctx->fields[member].location = dec->literals[0];
441 break;
442 case SpvDecorationBuiltIn:
443 ctx->type->members[member] = vtn_type_copy(b,
444 ctx->type->members[member]);
445 ctx->type->members[member]->is_builtin = true;
446 ctx->type->members[member]->builtin = dec->literals[0];
447 ctx->type->builtin_block = true;
448 break;
449 case SpvDecorationOffset:
450 ctx->type->offsets[member] = dec->literals[0];
451 break;
452 case SpvDecorationMatrixStride:
453 ctx->type->members[member]->stride = dec->literals[0];
454 break;
455 case SpvDecorationColMajor:
456 break; /* Nothing to do here. Column-major is the default. */
457 default:
458 unreachable("Unhandled member decoration");
459 }
460 }
461
462 static void
463 type_decoration_cb(struct vtn_builder *b,
464 struct vtn_value *val, int member,
465 const struct vtn_decoration *dec, void *ctx)
466 {
467 struct vtn_type *type = val->type;
468
469 if (member != -1)
470 return;
471
472 switch (dec->decoration) {
473 case SpvDecorationArrayStride:
474 type->stride = dec->literals[0];
475 break;
476 case SpvDecorationBlock:
477 type->block = true;
478 break;
479 case SpvDecorationBufferBlock:
480 type->buffer_block = true;
481 break;
482 case SpvDecorationGLSLShared:
483 case SpvDecorationGLSLPacked:
484 /* Ignore these, since we get explicit offsets anyways */
485 break;
486
487 case SpvDecorationStream:
488 assert(dec->literals[0] == 0);
489 break;
490
491 default:
492 unreachable("Unhandled type decoration");
493 }
494 }
495
496 static unsigned
497 translate_image_format(SpvImageFormat format)
498 {
499 switch (format) {
500 case SpvImageFormatUnknown: return 0; /* GL_NONE */
501 case SpvImageFormatRgba32f: return 0x8814; /* GL_RGBA32F */
502 case SpvImageFormatRgba16f: return 0x881A; /* GL_RGBA16F */
503 case SpvImageFormatR32f: return 0x822E; /* GL_R32F */
504 case SpvImageFormatRgba8: return 0x8058; /* GL_RGBA8 */
505 case SpvImageFormatRgba8Snorm: return 0x8F97; /* GL_RGBA8_SNORM */
506 case SpvImageFormatRg32f: return 0x8230; /* GL_RG32F */
507 case SpvImageFormatRg16f: return 0x822F; /* GL_RG16F */
508 case SpvImageFormatR11fG11fB10f: return 0x8C3A; /* GL_R11F_G11F_B10F */
509 case SpvImageFormatR16f: return 0x822D; /* GL_R16F */
510 case SpvImageFormatRgba16: return 0x805B; /* GL_RGBA16 */
511 case SpvImageFormatRgb10A2: return 0x8059; /* GL_RGB10_A2 */
512 case SpvImageFormatRg16: return 0x822C; /* GL_RG16 */
513 case SpvImageFormatRg8: return 0x822B; /* GL_RG8 */
514 case SpvImageFormatR16: return 0x822A; /* GL_R16 */
515 case SpvImageFormatR8: return 0x8229; /* GL_R8 */
516 case SpvImageFormatRgba16Snorm: return 0x8F9B; /* GL_RGBA16_SNORM */
517 case SpvImageFormatRg16Snorm: return 0x8F99; /* GL_RG16_SNORM */
518 case SpvImageFormatRg8Snorm: return 0x8F95; /* GL_RG8_SNORM */
519 case SpvImageFormatR16Snorm: return 0x8F98; /* GL_R16_SNORM */
520 case SpvImageFormatR8Snorm: return 0x8F94; /* GL_R8_SNORM */
521 case SpvImageFormatRgba32i: return 0x8D82; /* GL_RGBA32I */
522 case SpvImageFormatRgba16i: return 0x8D88; /* GL_RGBA16I */
523 case SpvImageFormatRgba8i: return 0x8D8E; /* GL_RGBA8I */
524 case SpvImageFormatR32i: return 0x8235; /* GL_R32I */
525 case SpvImageFormatRg32i: return 0x823B; /* GL_RG32I */
526 case SpvImageFormatRg16i: return 0x8239; /* GL_RG16I */
527 case SpvImageFormatRg8i: return 0x8237; /* GL_RG8I */
528 case SpvImageFormatR16i: return 0x8233; /* GL_R16I */
529 case SpvImageFormatR8i: return 0x8231; /* GL_R8I */
530 case SpvImageFormatRgba32ui: return 0x8D70; /* GL_RGBA32UI */
531 case SpvImageFormatRgba16ui: return 0x8D76; /* GL_RGBA16UI */
532 case SpvImageFormatRgba8ui: return 0x8D7C; /* GL_RGBA8UI */
533 case SpvImageFormatR32ui: return 0x8236; /* GL_R32UI */
534 case SpvImageFormatRgb10a2ui: return 0x906F; /* GL_RGB10_A2UI */
535 case SpvImageFormatRg32ui: return 0x823C; /* GL_RG32UI */
536 case SpvImageFormatRg16ui: return 0x823A; /* GL_RG16UI */
537 case SpvImageFormatRg8ui: return 0x8238; /* GL_RG8UI */
538 case SpvImageFormatR16ui: return 0x823A; /* GL_RG16UI */
539 case SpvImageFormatR8ui: return 0x8232; /* GL_R8UI */
540 default:
541 assert(!"Invalid image format");
542 return 0;
543 }
544 }
545
546 static void
547 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
548 const uint32_t *w, unsigned count)
549 {
550 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_type);
551
552 val->type = rzalloc(b, struct vtn_type);
553 val->type->is_builtin = false;
554
555 switch (opcode) {
556 case SpvOpTypeVoid:
557 val->type->type = glsl_void_type();
558 break;
559 case SpvOpTypeBool:
560 val->type->type = glsl_bool_type();
561 break;
562 case SpvOpTypeInt:
563 val->type->type = glsl_int_type();
564 break;
565 case SpvOpTypeFloat:
566 val->type->type = glsl_float_type();
567 break;
568
569 case SpvOpTypeVector: {
570 const struct glsl_type *base =
571 vtn_value(b, w[2], vtn_value_type_type)->type->type;
572 unsigned elems = w[3];
573
574 assert(glsl_type_is_scalar(base));
575 val->type->type = glsl_vector_type(glsl_get_base_type(base), elems);
576 break;
577 }
578
579 case SpvOpTypeMatrix: {
580 struct vtn_type *base =
581 vtn_value(b, w[2], vtn_value_type_type)->type;
582 unsigned columns = w[3];
583
584 assert(glsl_type_is_vector(base->type));
585 val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
586 glsl_get_vector_elements(base->type),
587 columns);
588 val->type->array_element = base;
589 val->type->row_major = false;
590 val->type->stride = 0;
591 break;
592 }
593
594 case SpvOpTypeRuntimeArray:
595 case SpvOpTypeArray: {
596 struct vtn_type *array_element =
597 vtn_value(b, w[2], vtn_value_type_type)->type;
598
599 unsigned length;
600 if (opcode == SpvOpTypeRuntimeArray) {
601 /* A length of 0 is used to denote unsized arrays */
602 length = 0;
603 } else {
604 length =
605 vtn_value(b, w[3], vtn_value_type_constant)->constant->value.u[0];
606 }
607
608 val->type->type = glsl_array_type(array_element->type, length);
609 val->type->array_element = array_element;
610 val->type->stride = 0;
611 break;
612 }
613
614 case SpvOpTypeStruct: {
615 unsigned num_fields = count - 2;
616 val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
617 val->type->offsets = ralloc_array(b, unsigned, num_fields);
618
619 NIR_VLA(struct glsl_struct_field, fields, count);
620 for (unsigned i = 0; i < num_fields; i++) {
621 val->type->members[i] =
622 vtn_value(b, w[i + 2], vtn_value_type_type)->type;
623 fields[i] = (struct glsl_struct_field) {
624 .type = val->type->members[i]->type,
625 .name = ralloc_asprintf(b, "field%d", i),
626 .location = -1,
627 };
628 }
629
630 struct member_decoration_ctx ctx = {
631 .fields = fields,
632 .type = val->type
633 };
634
635 vtn_foreach_decoration(b, val, struct_member_decoration_cb, &ctx);
636
637 const char *name = val->name ? val->name : "struct";
638
639 val->type->type = glsl_struct_type(fields, num_fields, name);
640 break;
641 }
642
643 case SpvOpTypeFunction: {
644 const struct glsl_type *return_type =
645 vtn_value(b, w[2], vtn_value_type_type)->type->type;
646 NIR_VLA(struct glsl_function_param, params, count - 3);
647 for (unsigned i = 0; i < count - 3; i++) {
648 params[i].type = vtn_value(b, w[i + 3], vtn_value_type_type)->type->type;
649
650 /* FIXME: */
651 params[i].in = true;
652 params[i].out = true;
653 }
654 val->type->type = glsl_function_type(return_type, params, count - 3);
655 break;
656 }
657
658 case SpvOpTypePointer:
659 /* FIXME: For now, we'll just do the really lame thing and return
660 * the same type. The validator should ensure that the proper number
661 * of dereferences happen
662 */
663 val->type = vtn_value(b, w[3], vtn_value_type_type)->type;
664 break;
665
666 case SpvOpTypeImage: {
667 const struct glsl_type *sampled_type =
668 vtn_value(b, w[2], vtn_value_type_type)->type->type;
669
670 assert(glsl_type_is_vector_or_scalar(sampled_type));
671
672 enum glsl_sampler_dim dim;
673 switch ((SpvDim)w[3]) {
674 case SpvDim1D: dim = GLSL_SAMPLER_DIM_1D; break;
675 case SpvDim2D: dim = GLSL_SAMPLER_DIM_2D; break;
676 case SpvDim3D: dim = GLSL_SAMPLER_DIM_3D; break;
677 case SpvDimCube: dim = GLSL_SAMPLER_DIM_CUBE; break;
678 case SpvDimRect: dim = GLSL_SAMPLER_DIM_RECT; break;
679 case SpvDimBuffer: dim = GLSL_SAMPLER_DIM_BUF; break;
680 default:
681 unreachable("Invalid SPIR-V Sampler dimension");
682 }
683
684 bool is_shadow = w[4];
685 bool is_array = w[5];
686 bool multisampled = w[6];
687 unsigned sampled = w[7];
688 SpvImageFormat format = w[8];
689
690 assert(!multisampled && "FIXME: Handl multi-sampled textures");
691
692 val->type->image_format = translate_image_format(format);
693
694 if (sampled == 1) {
695 val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
696 glsl_get_base_type(sampled_type));
697 } else if (sampled == 2) {
698 assert(format);
699 assert(!is_shadow);
700 val->type->type = glsl_image_type(dim, is_array,
701 glsl_get_base_type(sampled_type));
702 } else {
703 assert(!"We need to know if the image will be sampled");
704 }
705 break;
706 }
707
708 case SpvOpTypeSampledImage:
709 val->type = vtn_value(b, w[2], vtn_value_type_type)->type;
710 break;
711
712 case SpvOpTypeSampler:
713 /* The actual sampler type here doesn't really matter. It gets
714 * thrown away the moment you combine it with an image. What really
715 * matters is that it's a sampler type as opposed to an integer type
716 * so the backend knows what to do.
717 *
718 * TODO: Eventually we should consider adding a "bare sampler" type
719 * to glsl_types.
720 */
721 val->type->type = glsl_sampler_type(GLSL_SAMPLER_DIM_2D, false, false,
722 GLSL_TYPE_FLOAT);
723 break;
724
725 case SpvOpTypeOpaque:
726 case SpvOpTypeEvent:
727 case SpvOpTypeDeviceEvent:
728 case SpvOpTypeReserveId:
729 case SpvOpTypeQueue:
730 case SpvOpTypePipe:
731 default:
732 unreachable("Unhandled opcode");
733 }
734
735 vtn_foreach_decoration(b, val, type_decoration_cb, NULL);
736 }
737
738 static void
739 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
740 const uint32_t *w, unsigned count)
741 {
742 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
743 val->const_type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
744 val->constant = ralloc(b, nir_constant);
745 switch (opcode) {
746 case SpvOpConstantTrue:
747 assert(val->const_type == glsl_bool_type());
748 val->constant->value.u[0] = NIR_TRUE;
749 break;
750 case SpvOpConstantFalse:
751 assert(val->const_type == glsl_bool_type());
752 val->constant->value.u[0] = NIR_FALSE;
753 break;
754 case SpvOpConstant:
755 assert(glsl_type_is_scalar(val->const_type));
756 val->constant->value.u[0] = w[3];
757 break;
758 case SpvOpConstantComposite: {
759 unsigned elem_count = count - 3;
760 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
761 for (unsigned i = 0; i < elem_count; i++)
762 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
763
764 switch (glsl_get_base_type(val->const_type)) {
765 case GLSL_TYPE_UINT:
766 case GLSL_TYPE_INT:
767 case GLSL_TYPE_FLOAT:
768 case GLSL_TYPE_BOOL:
769 if (glsl_type_is_matrix(val->const_type)) {
770 unsigned rows = glsl_get_vector_elements(val->const_type);
771 assert(glsl_get_matrix_columns(val->const_type) == elem_count);
772 for (unsigned i = 0; i < elem_count; i++)
773 for (unsigned j = 0; j < rows; j++)
774 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
775 } else {
776 assert(glsl_type_is_vector(val->const_type));
777 assert(glsl_get_vector_elements(val->const_type) == elem_count);
778 for (unsigned i = 0; i < elem_count; i++)
779 val->constant->value.u[i] = elems[i]->value.u[0];
780 }
781 ralloc_free(elems);
782 break;
783
784 case GLSL_TYPE_STRUCT:
785 case GLSL_TYPE_ARRAY:
786 ralloc_steal(val->constant, elems);
787 val->constant->elements = elems;
788 break;
789
790 default:
791 unreachable("Unsupported type for constants");
792 }
793 break;
794 }
795
796 default:
797 unreachable("Unhandled opcode");
798 }
799 }
800
801 static void
802 set_mode_system_value(nir_variable_mode *mode)
803 {
804 assert(*mode == nir_var_system_value || *mode == nir_var_shader_in);
805 *mode = nir_var_system_value;
806 }
807
808 static void
809 validate_per_vertex_mode(struct vtn_builder *b, nir_variable_mode mode)
810 {
811 switch (b->shader->stage) {
812 case MESA_SHADER_VERTEX:
813 assert(mode == nir_var_shader_out);
814 break;
815 case MESA_SHADER_GEOMETRY:
816 assert(mode == nir_var_shader_out || mode == nir_var_shader_in);
817 break;
818 default:
819 assert(!"Invalid shader stage");
820 }
821 }
822
823 static void
824 vtn_get_builtin_location(struct vtn_builder *b,
825 SpvBuiltIn builtin, int *location,
826 nir_variable_mode *mode)
827 {
828 switch (builtin) {
829 case SpvBuiltInPosition:
830 *location = VARYING_SLOT_POS;
831 validate_per_vertex_mode(b, *mode);
832 break;
833 case SpvBuiltInPointSize:
834 *location = VARYING_SLOT_PSIZ;
835 validate_per_vertex_mode(b, *mode);
836 break;
837 case SpvBuiltInClipDistance:
838 *location = VARYING_SLOT_CLIP_DIST0; /* XXX CLIP_DIST1? */
839 validate_per_vertex_mode(b, *mode);
840 break;
841 case SpvBuiltInCullDistance:
842 /* XXX figure this out */
843 unreachable("unhandled builtin");
844 case SpvBuiltInVertexId:
845 /* Vulkan defines VertexID to be zero-based and reserves the new
846 * builtin keyword VertexIndex to indicate the non-zero-based value.
847 */
848 *location = SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
849 set_mode_system_value(mode);
850 break;
851 case SpvBuiltInInstanceId:
852 *location = SYSTEM_VALUE_INSTANCE_ID;
853 set_mode_system_value(mode);
854 break;
855 case SpvBuiltInPrimitiveId:
856 *location = VARYING_SLOT_PRIMITIVE_ID;
857 *mode = nir_var_shader_out;
858 break;
859 case SpvBuiltInInvocationId:
860 *location = SYSTEM_VALUE_INVOCATION_ID;
861 set_mode_system_value(mode);
862 break;
863 case SpvBuiltInLayer:
864 *location = VARYING_SLOT_LAYER;
865 *mode = nir_var_shader_out;
866 break;
867 case SpvBuiltInTessLevelOuter:
868 case SpvBuiltInTessLevelInner:
869 case SpvBuiltInTessCoord:
870 case SpvBuiltInPatchVertices:
871 unreachable("no tessellation support");
872 case SpvBuiltInFragCoord:
873 *location = VARYING_SLOT_POS;
874 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
875 assert(*mode == nir_var_shader_in);
876 break;
877 case SpvBuiltInPointCoord:
878 *location = VARYING_SLOT_PNTC;
879 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
880 assert(*mode == nir_var_shader_in);
881 break;
882 case SpvBuiltInFrontFacing:
883 *location = VARYING_SLOT_FACE;
884 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
885 assert(*mode == nir_var_shader_in);
886 break;
887 case SpvBuiltInSampleId:
888 *location = SYSTEM_VALUE_SAMPLE_ID;
889 set_mode_system_value(mode);
890 break;
891 case SpvBuiltInSamplePosition:
892 *location = SYSTEM_VALUE_SAMPLE_POS;
893 set_mode_system_value(mode);
894 break;
895 case SpvBuiltInSampleMask:
896 *location = SYSTEM_VALUE_SAMPLE_MASK_IN; /* XXX out? */
897 set_mode_system_value(mode);
898 break;
899 case SpvBuiltInFragDepth:
900 *location = FRAG_RESULT_DEPTH;
901 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
902 assert(*mode == nir_var_shader_out);
903 break;
904 case SpvBuiltInNumWorkgroups:
905 *location = SYSTEM_VALUE_NUM_WORK_GROUPS;
906 set_mode_system_value(mode);
907 break;
908 case SpvBuiltInWorkgroupSize:
909 /* This should already be handled */
910 unreachable("unsupported builtin");
911 break;
912 case SpvBuiltInWorkgroupId:
913 *location = SYSTEM_VALUE_WORK_GROUP_ID;
914 set_mode_system_value(mode);
915 break;
916 case SpvBuiltInLocalInvocationId:
917 *location = SYSTEM_VALUE_LOCAL_INVOCATION_ID;
918 set_mode_system_value(mode);
919 break;
920 case SpvBuiltInLocalInvocationIndex:
921 *location = SYSTEM_VALUE_LOCAL_INVOCATION_INDEX;
922 set_mode_system_value(mode);
923 break;
924 case SpvBuiltInGlobalInvocationId:
925 *location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
926 set_mode_system_value(mode);
927 break;
928 case SpvBuiltInHelperInvocation:
929 default:
930 unreachable("unsupported builtin");
931 }
932 }
933
934 static void
935 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
936 const struct vtn_decoration *dec, void *void_var)
937 {
938 assert(val->value_type == vtn_value_type_deref);
939 assert(val->deref->deref.child == NULL);
940 assert(val->deref->var == void_var);
941
942 nir_variable *var = void_var;
943 switch (dec->decoration) {
944 case SpvDecorationRelaxedPrecision:
945 break; /* FIXME: Do nothing with this for now. */
946 case SpvDecorationNoPerspective:
947 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
948 break;
949 case SpvDecorationFlat:
950 var->data.interpolation = INTERP_QUALIFIER_FLAT;
951 break;
952 case SpvDecorationCentroid:
953 var->data.centroid = true;
954 break;
955 case SpvDecorationSample:
956 var->data.sample = true;
957 break;
958 case SpvDecorationInvariant:
959 var->data.invariant = true;
960 break;
961 case SpvDecorationConstant:
962 assert(var->constant_initializer != NULL);
963 var->data.read_only = true;
964 break;
965 case SpvDecorationNonWritable:
966 var->data.read_only = true;
967 break;
968 case SpvDecorationLocation:
969 var->data.location = dec->literals[0];
970 break;
971 case SpvDecorationComponent:
972 var->data.location_frac = dec->literals[0];
973 break;
974 case SpvDecorationIndex:
975 var->data.explicit_index = true;
976 var->data.index = dec->literals[0];
977 break;
978 case SpvDecorationBinding:
979 var->data.explicit_binding = true;
980 var->data.binding = dec->literals[0];
981 break;
982 case SpvDecorationDescriptorSet:
983 var->data.descriptor_set = dec->literals[0];
984 break;
985 case SpvDecorationBuiltIn: {
986 SpvBuiltIn builtin = dec->literals[0];
987
988 if (builtin == SpvBuiltInWorkgroupSize) {
989 /* This shouldn't be a builtin. It's actually a constant. */
990 var->data.mode = nir_var_global;
991 var->data.read_only = true;
992
993 nir_constant *val = ralloc(var, nir_constant);
994 val->value.u[0] = b->shader->info.cs.local_size[0];
995 val->value.u[1] = b->shader->info.cs.local_size[1];
996 val->value.u[2] = b->shader->info.cs.local_size[2];
997 var->constant_initializer = val;
998 break;
999 }
1000
1001 nir_variable_mode mode = var->data.mode;
1002 vtn_get_builtin_location(b, builtin, &var->data.location, &mode);
1003 var->data.explicit_location = true;
1004 var->data.mode = mode;
1005 if (mode == nir_var_shader_in || mode == nir_var_system_value)
1006 var->data.read_only = true;
1007
1008 if (builtin == SpvBuiltInFragCoord || builtin == SpvBuiltInSamplePosition)
1009 var->data.origin_upper_left = b->origin_upper_left;
1010
1011 if (mode == nir_var_shader_out)
1012 b->builtins[dec->literals[0]].out = var;
1013 else
1014 b->builtins[dec->literals[0]].in = var;
1015 break;
1016 }
1017 case SpvDecorationRowMajor:
1018 case SpvDecorationColMajor:
1019 case SpvDecorationGLSLShared:
1020 case SpvDecorationPatch:
1021 case SpvDecorationRestrict:
1022 case SpvDecorationAliased:
1023 case SpvDecorationVolatile:
1024 case SpvDecorationCoherent:
1025 case SpvDecorationNonReadable:
1026 case SpvDecorationUniform:
1027 /* This is really nice but we have no use for it right now. */
1028 case SpvDecorationCPacked:
1029 case SpvDecorationSaturatedConversion:
1030 case SpvDecorationStream:
1031 case SpvDecorationOffset:
1032 case SpvDecorationXfbBuffer:
1033 case SpvDecorationFuncParamAttr:
1034 case SpvDecorationFPRoundingMode:
1035 case SpvDecorationFPFastMathMode:
1036 case SpvDecorationLinkageAttributes:
1037 case SpvDecorationSpecId:
1038 break;
1039 default:
1040 unreachable("Unhandled variable decoration");
1041 }
1042 }
1043
1044 static nir_variable *
1045 get_builtin_variable(struct vtn_builder *b,
1046 nir_variable_mode mode,
1047 const struct glsl_type *type,
1048 SpvBuiltIn builtin)
1049 {
1050 nir_variable *var;
1051 if (mode == nir_var_shader_out)
1052 var = b->builtins[builtin].out;
1053 else
1054 var = b->builtins[builtin].in;
1055
1056 if (!var) {
1057 int location;
1058 vtn_get_builtin_location(b, builtin, &location, &mode);
1059
1060 var = nir_variable_create(b->shader, mode, type, "builtin");
1061
1062 var->data.location = location;
1063 var->data.explicit_location = true;
1064
1065 if (builtin == SpvBuiltInFragCoord || builtin == SpvBuiltInSamplePosition)
1066 var->data.origin_upper_left = b->origin_upper_left;
1067
1068 if (mode == nir_var_shader_out)
1069 b->builtins[builtin].out = var;
1070 else
1071 b->builtins[builtin].in = var;
1072 }
1073
1074 return var;
1075 }
1076
1077 static struct vtn_ssa_value *
1078 _vtn_variable_load(struct vtn_builder *b,
1079 nir_deref_var *src_deref, nir_deref *src_deref_tail)
1080 {
1081 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
1082 val->type = src_deref_tail->type;
1083
1084 /* The deref tail may contain a deref to select a component of a vector (in
1085 * other words, it might not be an actual tail) so we have to save it away
1086 * here since we overwrite it later.
1087 */
1088 nir_deref *old_child = src_deref_tail->child;
1089
1090 if (glsl_type_is_vector_or_scalar(val->type)) {
1091 /* Terminate the deref chain in case there is one more link to pick
1092 * off a component of the vector.
1093 */
1094 src_deref_tail->child = NULL;
1095
1096 nir_intrinsic_instr *load =
1097 nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
1098 load->variables[0] =
1099 nir_deref_as_var(nir_copy_deref(load, &src_deref->deref));
1100 load->num_components = glsl_get_vector_elements(val->type);
1101 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, NULL);
1102
1103 nir_builder_instr_insert(&b->nb, &load->instr);
1104
1105 if (src_deref->var->data.mode == nir_var_uniform &&
1106 glsl_get_base_type(val->type) == GLSL_TYPE_BOOL) {
1107 /* Uniform boolean loads need to be fixed up since they're defined
1108 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
1109 */
1110 val->def = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
1111 } else {
1112 val->def = &load->dest.ssa;
1113 }
1114 } else if (glsl_get_base_type(val->type) == GLSL_TYPE_ARRAY ||
1115 glsl_type_is_matrix(val->type)) {
1116 unsigned elems = glsl_get_length(val->type);
1117 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1118
1119 nir_deref_array *deref = nir_deref_array_create(b);
1120 deref->deref_array_type = nir_deref_array_type_direct;
1121 deref->deref.type = glsl_get_array_element(val->type);
1122 src_deref_tail->child = &deref->deref;
1123 for (unsigned i = 0; i < elems; i++) {
1124 deref->base_offset = i;
1125 val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
1126 }
1127 } else {
1128 assert(glsl_get_base_type(val->type) == GLSL_TYPE_STRUCT);
1129 unsigned elems = glsl_get_length(val->type);
1130 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1131
1132 nir_deref_struct *deref = nir_deref_struct_create(b, 0);
1133 src_deref_tail->child = &deref->deref;
1134 for (unsigned i = 0; i < elems; i++) {
1135 deref->index = i;
1136 deref->deref.type = glsl_get_struct_field(val->type, i);
1137 val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
1138 }
1139 }
1140
1141 src_deref_tail->child = old_child;
1142
1143 return val;
1144 }
1145
1146 static void
1147 _vtn_variable_store(struct vtn_builder *b,
1148 nir_deref_var *dest_deref, nir_deref *dest_deref_tail,
1149 struct vtn_ssa_value *src)
1150 {
1151 nir_deref *old_child = dest_deref_tail->child;
1152
1153 if (glsl_type_is_vector_or_scalar(src->type)) {
1154 /* Terminate the deref chain in case there is one more link to pick
1155 * off a component of the vector.
1156 */
1157 dest_deref_tail->child = NULL;
1158
1159 nir_intrinsic_instr *store =
1160 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
1161 store->variables[0] =
1162 nir_deref_as_var(nir_copy_deref(store, &dest_deref->deref));
1163 store->num_components = glsl_get_vector_elements(src->type);
1164 store->const_index[0] = (1 << store->num_components) - 1;
1165 store->src[0] = nir_src_for_ssa(src->def);
1166
1167 nir_builder_instr_insert(&b->nb, &store->instr);
1168 } else if (glsl_get_base_type(src->type) == GLSL_TYPE_ARRAY ||
1169 glsl_type_is_matrix(src->type)) {
1170 unsigned elems = glsl_get_length(src->type);
1171
1172 nir_deref_array *deref = nir_deref_array_create(b);
1173 deref->deref_array_type = nir_deref_array_type_direct;
1174 deref->deref.type = glsl_get_array_element(src->type);
1175 dest_deref_tail->child = &deref->deref;
1176 for (unsigned i = 0; i < elems; i++) {
1177 deref->base_offset = i;
1178 _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
1179 }
1180 } else {
1181 assert(glsl_get_base_type(src->type) == GLSL_TYPE_STRUCT);
1182 unsigned elems = glsl_get_length(src->type);
1183
1184 nir_deref_struct *deref = nir_deref_struct_create(b, 0);
1185 dest_deref_tail->child = &deref->deref;
1186 for (unsigned i = 0; i < elems; i++) {
1187 deref->index = i;
1188 deref->deref.type = glsl_get_struct_field(src->type, i);
1189 _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
1190 }
1191 }
1192
1193 dest_deref_tail->child = old_child;
1194 }
1195
1196 static nir_ssa_def *
1197 nir_vulkan_resource_index(nir_builder *b, unsigned set, unsigned binding,
1198 nir_variable_mode mode, nir_ssa_def *array_index)
1199 {
1200 if (array_index == NULL)
1201 array_index = nir_imm_int(b, 0);
1202
1203 nir_intrinsic_instr *instr =
1204 nir_intrinsic_instr_create(b->shader,
1205 nir_intrinsic_vulkan_resource_index);
1206 instr->src[0] = nir_src_for_ssa(array_index);
1207 instr->const_index[0] = set;
1208 instr->const_index[1] = binding;
1209 instr->const_index[2] = mode;
1210
1211 nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
1212 nir_builder_instr_insert(b, &instr->instr);
1213
1214 return &instr->dest.ssa;
1215 }
1216
1217 static struct vtn_ssa_value *
1218 _vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
1219 unsigned set, unsigned binding, nir_variable_mode mode,
1220 nir_ssa_def *index, nir_ssa_def *offset, struct vtn_type *type)
1221 {
1222 struct vtn_ssa_value *val = ralloc(b, struct vtn_ssa_value);
1223 val->type = type->type;
1224 val->transposed = NULL;
1225 if (glsl_type_is_vector_or_scalar(type->type)) {
1226 nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);
1227 load->num_components = glsl_get_vector_elements(type->type);
1228
1229 switch (op) {
1230 case nir_intrinsic_load_ubo:
1231 case nir_intrinsic_load_ssbo: {
1232 nir_ssa_def *res_index = nir_vulkan_resource_index(&b->nb,
1233 set, binding,
1234 mode, index);
1235 load->src[0] = nir_src_for_ssa(res_index);
1236 load->src[1] = nir_src_for_ssa(offset);
1237 break;
1238 }
1239
1240 case nir_intrinsic_load_push_constant:
1241 load->src[0] = nir_src_for_ssa(offset);
1242 break;
1243
1244 default:
1245 unreachable("Invalid block load intrinsic");
1246 }
1247
1248 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, NULL);
1249 nir_builder_instr_insert(&b->nb, &load->instr);
1250
1251 if (glsl_get_base_type(type->type) == GLSL_TYPE_BOOL) {
1252 /* Loads of booleans from externally visible memory need to be
1253 * fixed up since they're defined to be zero/nonzero rather than
1254 * NIR_FALSE/NIR_TRUE.
1255 */
1256 val->def = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
1257 } else {
1258 val->def = &load->dest.ssa;
1259 }
1260 } else {
1261 unsigned elems = glsl_get_length(type->type);
1262 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1263 if (glsl_type_is_struct(type->type)) {
1264 for (unsigned i = 0; i < elems; i++) {
1265 nir_ssa_def *child_offset =
1266 nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, type->offsets[i]));
1267 val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
1268 child_offset, type->members[i]);
1269 }
1270 } else {
1271 for (unsigned i = 0; i < elems; i++) {
1272 nir_ssa_def *child_offset =
1273 nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, i * type->stride));
1274 val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
1275 child_offset,type->array_element);
1276 }
1277 }
1278 }
1279
1280 return val;
1281 }
1282
1283 static void
1284 vtn_block_get_offset(struct vtn_builder *b, nir_deref_var *src,
1285 struct vtn_type **type, nir_deref *src_tail,
1286 nir_ssa_def **index, nir_ssa_def **offset)
1287 {
1288 nir_deref *deref = &src->deref;
1289
1290 if (deref->child->deref_type == nir_deref_type_array) {
1291 deref = deref->child;
1292 *type = (*type)->array_element;
1293 nir_deref_array *deref_array = nir_deref_as_array(deref);
1294 *index = nir_imm_int(&b->nb, deref_array->base_offset);
1295
1296 if (deref_array->deref_array_type == nir_deref_array_type_indirect)
1297 *index = nir_iadd(&b->nb, *index, deref_array->indirect.ssa);
1298 } else {
1299 *index = nir_imm_int(&b->nb, 0);
1300 }
1301
1302 *offset = nir_imm_int(&b->nb, 0);
1303 while (deref != src_tail) {
1304 deref = deref->child;
1305 switch (deref->deref_type) {
1306 case nir_deref_type_array: {
1307 nir_deref_array *deref_array = nir_deref_as_array(deref);
1308 nir_ssa_def *off = nir_imm_int(&b->nb, deref_array->base_offset);
1309
1310 if (deref_array->deref_array_type == nir_deref_array_type_indirect)
1311 off = nir_iadd(&b->nb, off, deref_array->indirect.ssa);
1312
1313 off = nir_imul(&b->nb, off, nir_imm_int(&b->nb, (*type)->stride));
1314 *offset = nir_iadd(&b->nb, *offset, off);
1315
1316 *type = (*type)->array_element;
1317 break;
1318 }
1319
1320 case nir_deref_type_struct: {
1321 nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
1322
1323 unsigned elem_off = (*type)->offsets[deref_struct->index];
1324 *offset = nir_iadd(&b->nb, *offset, nir_imm_int(&b->nb, elem_off));
1325
1326 *type = (*type)->members[deref_struct->index];
1327 break;
1328 }
1329
1330 default:
1331 unreachable("unknown deref type");
1332 }
1333 }
1334 }
1335
1336 static struct vtn_ssa_value *
1337 vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
1338 struct vtn_type *type, nir_deref *src_tail)
1339 {
1340 nir_ssa_def *index;
1341 nir_ssa_def *offset;
1342 vtn_block_get_offset(b, src, &type, src_tail, &index, &offset);
1343
1344 nir_intrinsic_op op;
1345 if (src->var->data.mode == nir_var_uniform) {
1346 if (src->var->data.descriptor_set >= 0) {
1347 /* UBO load */
1348 assert(src->var->data.binding >= 0);
1349
1350 op = nir_intrinsic_load_ubo;
1351 } else {
1352 /* Push constant load */
1353 assert(src->var->data.descriptor_set == -1 &&
1354 src->var->data.binding == -1);
1355
1356 op = nir_intrinsic_load_push_constant;
1357 }
1358 } else {
1359 assert(src->var->data.mode == nir_var_shader_storage);
1360 op = nir_intrinsic_load_ssbo;
1361 }
1362
1363 return _vtn_block_load(b, op, src->var->data.descriptor_set,
1364 src->var->data.binding, src->var->data.mode,
1365 index, offset, type);
1366 }
1367
1368 /*
1369 * Gets the NIR-level deref tail, which may have as a child an array deref
1370 * selecting which component due to OpAccessChain supporting per-component
1371 * indexing in SPIR-V.
1372 */
1373
1374 static nir_deref *
1375 get_deref_tail(nir_deref_var *deref)
1376 {
1377 nir_deref *cur = &deref->deref;
1378 while (!glsl_type_is_vector_or_scalar(cur->type) && cur->child)
1379 cur = cur->child;
1380
1381 return cur;
1382 }
1383
1384 static nir_ssa_def *vtn_vector_extract(struct vtn_builder *b,
1385 nir_ssa_def *src, unsigned index);
1386
1387 static nir_ssa_def *vtn_vector_extract_dynamic(struct vtn_builder *b,
1388 nir_ssa_def *src,
1389 nir_ssa_def *index);
1390
1391 static bool
1392 variable_is_external_block(nir_variable *var)
1393 {
1394 return var->interface_type &&
1395 glsl_type_is_struct(var->interface_type) &&
1396 (var->data.mode == nir_var_uniform ||
1397 var->data.mode == nir_var_shader_storage);
1398 }
1399
1400 static struct vtn_ssa_value *
1401 vtn_variable_load(struct vtn_builder *b, nir_deref_var *src,
1402 struct vtn_type *src_type)
1403 {
1404 nir_deref *src_tail = get_deref_tail(src);
1405
1406 struct vtn_ssa_value *val;
1407 if (variable_is_external_block(src->var))
1408 val = vtn_block_load(b, src, src_type, src_tail);
1409 else
1410 val = _vtn_variable_load(b, src, src_tail);
1411
1412 if (src_tail->child) {
1413 nir_deref_array *vec_deref = nir_deref_as_array(src_tail->child);
1414 assert(vec_deref->deref.child == NULL);
1415 val->type = vec_deref->deref.type;
1416 if (vec_deref->deref_array_type == nir_deref_array_type_direct)
1417 val->def = vtn_vector_extract(b, val->def, vec_deref->base_offset);
1418 else
1419 val->def = vtn_vector_extract_dynamic(b, val->def,
1420 vec_deref->indirect.ssa);
1421 }
1422
1423 return val;
1424 }
1425
1426 static void
1427 _vtn_block_store(struct vtn_builder *b, nir_intrinsic_op op,
1428 struct vtn_ssa_value *src, unsigned set, unsigned binding,
1429 nir_variable_mode mode, nir_ssa_def *index,
1430 nir_ssa_def *offset, struct vtn_type *type)
1431 {
1432 assert(src->type == type->type);
1433 if (glsl_type_is_vector_or_scalar(type->type)) {
1434 nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, op);
1435 store->num_components = glsl_get_vector_elements(type->type);
1436 store->const_index[0] = (1 << store->num_components) - 1;
1437 store->src[0] = nir_src_for_ssa(src->def);
1438
1439 nir_ssa_def *res_index = nir_vulkan_resource_index(&b->nb,
1440 set, binding,
1441 mode, index);
1442 store->src[1] = nir_src_for_ssa(res_index);
1443 store->src[2] = nir_src_for_ssa(offset);
1444
1445 nir_builder_instr_insert(&b->nb, &store->instr);
1446 } else {
1447 unsigned elems = glsl_get_length(type->type);
1448 if (glsl_type_is_struct(type->type)) {
1449 for (unsigned i = 0; i < elems; i++) {
1450 nir_ssa_def *child_offset =
1451 nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, type->offsets[i]));
1452 _vtn_block_store(b, op, src->elems[i], set, binding, mode,
1453 index, child_offset, type->members[i]);
1454 }
1455 } else {
1456 for (unsigned i = 0; i < elems; i++) {
1457 nir_ssa_def *child_offset =
1458 nir_iadd(&b->nb, offset, nir_imm_int(&b->nb, i * type->stride));
1459 _vtn_block_store(b, op, src->elems[i], set, binding, mode,
1460 index, child_offset, type->array_element);
1461 }
1462 }
1463 }
1464 }
1465
1466 static void
1467 vtn_block_store(struct vtn_builder *b, struct vtn_ssa_value *src,
1468 nir_deref_var *dest, struct vtn_type *type,
1469 nir_deref *dest_tail)
1470 {
1471 nir_ssa_def *index;
1472 nir_ssa_def *offset;
1473 vtn_block_get_offset(b, dest, &type, dest_tail, &index, &offset);
1474
1475 nir_intrinsic_op op = nir_intrinsic_store_ssbo;
1476
1477 return _vtn_block_store(b, op, src, dest->var->data.descriptor_set,
1478 dest->var->data.binding, dest->var->data.mode,
1479 index, offset, type);
1480 }
1481
1482 static nir_ssa_def * vtn_vector_insert(struct vtn_builder *b,
1483 nir_ssa_def *src, nir_ssa_def *insert,
1484 unsigned index);
1485
1486 static nir_ssa_def * vtn_vector_insert_dynamic(struct vtn_builder *b,
1487 nir_ssa_def *src,
1488 nir_ssa_def *insert,
1489 nir_ssa_def *index);
1490 void
1491 vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
1492 nir_deref_var *dest, struct vtn_type *dest_type)
1493 {
1494 nir_deref *dest_tail = get_deref_tail(dest);
1495 if (variable_is_external_block(dest->var)) {
1496 assert(dest->var->data.mode == nir_var_shader_storage);
1497 vtn_block_store(b, src, dest, dest_type, dest_tail);
1498 } else {
1499 if (dest_tail->child) {
1500 struct vtn_ssa_value *val = _vtn_variable_load(b, dest, dest_tail);
1501 nir_deref_array *deref = nir_deref_as_array(dest_tail->child);
1502 assert(deref->deref.child == NULL);
1503 if (deref->deref_array_type == nir_deref_array_type_direct)
1504 val->def = vtn_vector_insert(b, val->def, src->def,
1505 deref->base_offset);
1506 else
1507 val->def = vtn_vector_insert_dynamic(b, val->def, src->def,
1508 deref->indirect.ssa);
1509 _vtn_variable_store(b, dest, dest_tail, val);
1510 } else {
1511 _vtn_variable_store(b, dest, dest_tail, src);
1512 }
1513 }
1514 }
1515
1516 static void
1517 vtn_variable_copy(struct vtn_builder *b, nir_deref_var *src,
1518 nir_deref_var *dest, struct vtn_type *type)
1519 {
1520 nir_deref *src_tail = get_deref_tail(src);
1521
1522 if (src_tail->child || src->var->interface_type) {
1523 assert(get_deref_tail(dest)->child);
1524 struct vtn_ssa_value *val = vtn_variable_load(b, src, type);
1525 vtn_variable_store(b, val, dest, type);
1526 } else {
1527 nir_intrinsic_instr *copy =
1528 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
1529 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
1530 copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
1531
1532 nir_builder_instr_insert(&b->nb, &copy->instr);
1533 }
1534 }
1535
1536 /* Tries to compute the size of an interface block based on the strides and
1537 * offsets that are provided to us in the SPIR-V source.
1538 */
1539 static unsigned
1540 vtn_type_block_size(struct vtn_type *type)
1541 {
1542 enum glsl_base_type base_type = glsl_get_base_type(type->type);
1543 switch (base_type) {
1544 case GLSL_TYPE_UINT:
1545 case GLSL_TYPE_INT:
1546 case GLSL_TYPE_FLOAT:
1547 case GLSL_TYPE_BOOL:
1548 case GLSL_TYPE_DOUBLE: {
1549 unsigned cols = type->row_major ? glsl_get_vector_elements(type->type) :
1550 glsl_get_matrix_columns(type->type);
1551 if (cols > 1) {
1552 assert(type->stride > 0);
1553 return type->stride * cols;
1554 } else if (base_type == GLSL_TYPE_DOUBLE) {
1555 return glsl_get_vector_elements(type->type) * 8;
1556 } else {
1557 return glsl_get_vector_elements(type->type) * 4;
1558 }
1559 }
1560
1561 case GLSL_TYPE_STRUCT:
1562 case GLSL_TYPE_INTERFACE: {
1563 unsigned size = 0;
1564 unsigned num_fields = glsl_get_length(type->type);
1565 for (unsigned f = 0; f < num_fields; f++) {
1566 unsigned field_end = type->offsets[f] +
1567 vtn_type_block_size(type->members[f]);
1568 size = MAX2(size, field_end);
1569 }
1570 return size;
1571 }
1572
1573 case GLSL_TYPE_ARRAY:
1574 assert(type->stride > 0);
1575 assert(glsl_get_length(type->type) > 0);
1576 return type->stride * glsl_get_length(type->type);
1577
1578 default:
1579 assert(!"Invalid block type");
1580 return 0;
1581 }
1582 }
1583
1584 static bool
1585 is_interface_type(struct vtn_type *type)
1586 {
1587 return type->block || type->buffer_block ||
1588 glsl_type_is_sampler(type->type) ||
1589 glsl_type_is_image(type->type);
1590 }
1591
1592 static void
1593 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
1594 const uint32_t *w, unsigned count)
1595 {
1596 switch (opcode) {
1597 case SpvOpVariable: {
1598 struct vtn_type *type =
1599 vtn_value(b, w[1], vtn_value_type_type)->type;
1600 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
1601
1602 nir_variable *var = rzalloc(b->shader, nir_variable);
1603
1604 var->type = type->type;
1605 var->name = ralloc_strdup(var, val->name);
1606
1607 struct vtn_type *interface_type;
1608 if (is_interface_type(type)) {
1609 interface_type = type;
1610 } else if (glsl_type_is_array(type->type) &&
1611 is_interface_type(type->array_element)) {
1612 interface_type = type->array_element;
1613 } else {
1614 interface_type = NULL;
1615 }
1616
1617 if (interface_type)
1618 var->interface_type = interface_type->type;
1619
1620 switch ((SpvStorageClass)w[3]) {
1621 case SpvStorageClassUniform:
1622 case SpvStorageClassUniformConstant:
1623 if (interface_type && interface_type->buffer_block) {
1624 var->data.mode = nir_var_shader_storage;
1625 b->shader->info.num_ssbos++;
1626 } else {
1627 /* UBO's and samplers */
1628 var->data.mode = nir_var_uniform;
1629 var->data.read_only = true;
1630 if (interface_type) {
1631 if (glsl_type_is_image(interface_type->type)) {
1632 b->shader->info.num_images++;
1633 var->data.image.format = interface_type->image_format;
1634 } else if (glsl_type_is_sampler(interface_type->type)) {
1635 b->shader->info.num_textures++;
1636 } else {
1637 assert(glsl_type_is_struct(interface_type->type));
1638 b->shader->info.num_ubos++;
1639 }
1640 }
1641 }
1642 break;
1643 case SpvStorageClassPushConstant:
1644 assert(interface_type && interface_type->block);
1645 var->data.mode = nir_var_uniform;
1646 var->data.read_only = true;
1647 var->data.descriptor_set = -1;
1648 var->data.binding = -1;
1649
1650 /* We have exactly one push constant block */
1651 assert(b->shader->num_uniforms == 0);
1652 b->shader->num_uniforms = vtn_type_block_size(type) * 4;
1653 break;
1654 case SpvStorageClassInput:
1655 var->data.mode = nir_var_shader_in;
1656 var->data.read_only = true;
1657 break;
1658 case SpvStorageClassOutput:
1659 var->data.mode = nir_var_shader_out;
1660 break;
1661 case SpvStorageClassPrivate:
1662 var->data.mode = nir_var_global;
1663 break;
1664 case SpvStorageClassFunction:
1665 var->data.mode = nir_var_local;
1666 break;
1667 case SpvStorageClassWorkgroup:
1668 case SpvStorageClassCrossWorkgroup:
1669 case SpvStorageClassGeneric:
1670 case SpvStorageClassAtomicCounter:
1671 default:
1672 unreachable("Unhandled variable storage class");
1673 }
1674
1675 if (count > 4) {
1676 assert(count == 5);
1677 var->constant_initializer =
1678 vtn_value(b, w[4], vtn_value_type_constant)->constant;
1679 }
1680
1681 val->deref = nir_deref_var_create(b, var);
1682 val->deref_type = type;
1683
1684 /* We handle decorations first because decorations might give us
1685 * location information. We use the data.explicit_location field to
1686 * note that the location provided is the "final" location. If
1687 * data.explicit_location == false, this means that it's relative to
1688 * whatever the base location is.
1689 */
1690 vtn_foreach_decoration(b, val, var_decoration_cb, var);
1691
1692 if (!var->data.explicit_location) {
1693 if (b->shader->stage == MESA_SHADER_FRAGMENT &&
1694 var->data.mode == nir_var_shader_out) {
1695 var->data.location += FRAG_RESULT_DATA0;
1696 } else if (b->shader->stage == MESA_SHADER_VERTEX &&
1697 var->data.mode == nir_var_shader_in) {
1698 var->data.location += VERT_ATTRIB_GENERIC0;
1699 } else if (var->data.mode == nir_var_shader_in ||
1700 var->data.mode == nir_var_shader_out) {
1701 var->data.location += VARYING_SLOT_VAR0;
1702 }
1703 }
1704
1705 /* Interface block variables aren't actually going to be referenced
1706 * by the generated NIR, so we don't put them in the list
1707 */
1708 if (interface_type && glsl_type_is_struct(interface_type->type))
1709 break;
1710
1711 if (var->data.mode == nir_var_local) {
1712 nir_function_impl_add_variable(b->impl, var);
1713 } else {
1714 nir_shader_add_variable(b->shader, var);
1715 }
1716
1717 break;
1718 }
1719
1720 case SpvOpAccessChain:
1721 case SpvOpInBoundsAccessChain: {
1722 nir_deref_var *base;
1723 struct vtn_value *base_val = vtn_untyped_value(b, w[3]);
1724 if (base_val->value_type == vtn_value_type_sampled_image) {
1725 /* This is rather insane. SPIR-V allows you to use OpSampledImage
1726 * to combine an array of images with a single sampler to get an
1727 * array of sampled images that all share the same sampler.
1728 * Fortunately, this means that we can more-or-less ignore the
1729 * sampler when crawling the access chain, but it does leave us
1730 * with this rather awkward little special-case.
1731 */
1732 base = base_val->sampled_image->image;
1733 } else {
1734 assert(base_val->value_type == vtn_value_type_deref);
1735 base = base_val->deref;
1736 }
1737
1738 nir_deref_var *deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
1739 struct vtn_type *deref_type = vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
1740
1741 nir_deref *tail = &deref->deref;
1742 while (tail->child)
1743 tail = tail->child;
1744
1745 for (unsigned i = 0; i < count - 4; i++) {
1746 assert(w[i + 4] < b->value_id_bound);
1747 struct vtn_value *idx_val = &b->values[w[i + 4]];
1748
1749 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
1750 switch (base_type) {
1751 case GLSL_TYPE_UINT:
1752 case GLSL_TYPE_INT:
1753 case GLSL_TYPE_FLOAT:
1754 case GLSL_TYPE_DOUBLE:
1755 case GLSL_TYPE_BOOL:
1756 case GLSL_TYPE_ARRAY: {
1757 nir_deref_array *deref_arr = nir_deref_array_create(b);
1758 if (base_type == GLSL_TYPE_ARRAY ||
1759 glsl_type_is_matrix(tail->type)) {
1760 deref_type = deref_type->array_element;
1761 } else {
1762 assert(glsl_type_is_vector(tail->type));
1763 deref_type = ralloc(b, struct vtn_type);
1764 deref_type->type = glsl_scalar_type(base_type);
1765 }
1766
1767 deref_arr->deref.type = deref_type->type;
1768
1769 if (idx_val->value_type == vtn_value_type_constant) {
1770 unsigned idx = idx_val->constant->value.u[0];
1771 deref_arr->deref_array_type = nir_deref_array_type_direct;
1772 deref_arr->base_offset = idx;
1773 } else {
1774 assert(idx_val->value_type == vtn_value_type_ssa);
1775 assert(glsl_type_is_scalar(idx_val->ssa->type));
1776 deref_arr->deref_array_type = nir_deref_array_type_indirect;
1777 deref_arr->base_offset = 0;
1778 deref_arr->indirect = nir_src_for_ssa(idx_val->ssa->def);
1779 }
1780 tail->child = &deref_arr->deref;
1781 break;
1782 }
1783
1784 case GLSL_TYPE_STRUCT: {
1785 assert(idx_val->value_type == vtn_value_type_constant);
1786 unsigned idx = idx_val->constant->value.u[0];
1787 deref_type = deref_type->members[idx];
1788 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
1789 deref_struct->deref.type = deref_type->type;
1790 tail->child = &deref_struct->deref;
1791 break;
1792 }
1793 default:
1794 unreachable("Invalid type for deref");
1795 }
1796
1797 if (deref_type->is_builtin) {
1798 /* If we encounter a builtin, we throw away the ress of the
1799 * access chain, jump to the builtin, and keep building.
1800 */
1801 const struct glsl_type *builtin_type = deref_type->type;
1802
1803 nir_deref_array *per_vertex_deref = NULL;
1804 if (glsl_type_is_array(base->var->type)) {
1805 /* This builtin is a per-vertex builtin */
1806 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
1807 assert(base->var->data.mode == nir_var_shader_in);
1808 builtin_type = glsl_array_type(builtin_type,
1809 b->shader->info.gs.vertices_in);
1810
1811 /* The first non-var deref should be an array deref. */
1812 assert(deref->deref.child->deref_type ==
1813 nir_deref_type_array);
1814 per_vertex_deref = nir_deref_as_array(deref->deref.child);
1815 }
1816
1817 nir_variable *builtin = get_builtin_variable(b,
1818 base->var->data.mode,
1819 builtin_type,
1820 deref_type->builtin);
1821 deref = nir_deref_var_create(b, builtin);
1822
1823 if (per_vertex_deref) {
1824 /* Since deref chains start at the variable, we can just
1825 * steal that link and use it.
1826 */
1827 deref->deref.child = &per_vertex_deref->deref;
1828 per_vertex_deref->deref.child = NULL;
1829 per_vertex_deref->deref.type =
1830 glsl_get_array_element(builtin_type);
1831
1832 tail = &per_vertex_deref->deref;
1833 } else {
1834 tail = &deref->deref;
1835 }
1836 } else {
1837 tail = tail->child;
1838 }
1839 }
1840
1841 /* For uniform blocks, we don't resolve the access chain until we
1842 * actually access the variable, so we need to keep around the original
1843 * type of the variable.
1844 */
1845 if (variable_is_external_block(base->var))
1846 deref_type = vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
1847
1848 if (base_val->value_type == vtn_value_type_sampled_image) {
1849 struct vtn_value *val =
1850 vtn_push_value(b, w[2], vtn_value_type_sampled_image);
1851 val->sampled_image = ralloc(b, struct vtn_sampled_image);
1852 val->sampled_image->image = deref;
1853 val->sampled_image->sampler = base_val->sampled_image->sampler;
1854 } else {
1855 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
1856 val->deref = deref;
1857 val->deref_type = deref_type;
1858 }
1859
1860 break;
1861 }
1862
1863 case SpvOpCopyMemory: {
1864 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
1865 nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
1866 struct vtn_type *type =
1867 vtn_value(b, w[1], vtn_value_type_deref)->deref_type;
1868
1869 vtn_variable_copy(b, src, dest, type);
1870 break;
1871 }
1872
1873 case SpvOpLoad: {
1874 nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
1875 struct vtn_type *src_type =
1876 vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
1877
1878 if (src->var->interface_type &&
1879 (glsl_type_is_sampler(src->var->interface_type) ||
1880 glsl_type_is_image(src->var->interface_type))) {
1881 vtn_push_value(b, w[2], vtn_value_type_deref)->deref = src;
1882 return;
1883 }
1884
1885 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1886 val->ssa = vtn_variable_load(b, src, src_type);
1887 break;
1888 }
1889
1890 case SpvOpStore: {
1891 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
1892 struct vtn_type *dest_type =
1893 vtn_value(b, w[1], vtn_value_type_deref)->deref_type;
1894 struct vtn_ssa_value *src = vtn_ssa_value(b, w[2]);
1895 vtn_variable_store(b, src, dest, dest_type);
1896 break;
1897 }
1898
1899 case SpvOpCopyMemorySized:
1900 case SpvOpArrayLength:
1901 default:
1902 unreachable("Unhandled opcode");
1903 }
1904 }
1905
1906 static void
1907 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
1908 const uint32_t *w, unsigned count)
1909 {
1910 struct nir_function *callee =
1911 vtn_value(b, w[3], vtn_value_type_function)->func->impl->function;
1912
1913 nir_call_instr *call = nir_call_instr_create(b->nb.shader, callee);
1914 for (unsigned i = 0; i < call->num_params; i++) {
1915 unsigned arg_id = w[4 + i];
1916 struct vtn_value *arg = vtn_untyped_value(b, arg_id);
1917 if (arg->value_type == vtn_value_type_deref) {
1918 call->params[i] =
1919 nir_deref_as_var(nir_copy_deref(call, &arg->deref->deref));
1920 } else {
1921 struct vtn_ssa_value *arg_ssa = vtn_ssa_value(b, arg_id);
1922
1923 /* Make a temporary to store the argument in */
1924 nir_variable *tmp =
1925 nir_local_variable_create(b->impl, arg_ssa->type, "arg_tmp");
1926 call->params[i] = nir_deref_var_create(call, tmp);
1927
1928 vtn_variable_store(b, arg_ssa, call->params[i], arg->type);
1929 }
1930 }
1931
1932 nir_variable *out_tmp = NULL;
1933 if (!glsl_type_is_void(callee->return_type)) {
1934 out_tmp = nir_local_variable_create(b->impl, callee->return_type,
1935 "out_tmp");
1936 call->return_deref = nir_deref_var_create(call, out_tmp);
1937 }
1938
1939 nir_builder_instr_insert(&b->nb, &call->instr);
1940
1941 if (glsl_type_is_void(callee->return_type)) {
1942 vtn_push_value(b, w[2], vtn_value_type_undef);
1943 } else {
1944 struct vtn_type *rettype = vtn_value(b, w[1], vtn_value_type_type)->type;
1945 struct vtn_value *retval = vtn_push_value(b, w[2], vtn_value_type_ssa);
1946 retval->ssa = vtn_variable_load(b, call->return_deref, rettype);
1947 }
1948 }
1949
1950 static struct vtn_ssa_value *
1951 vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
1952 {
1953 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
1954 val->type = type;
1955
1956 if (!glsl_type_is_vector_or_scalar(type)) {
1957 unsigned elems = glsl_get_length(type);
1958 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1959 for (unsigned i = 0; i < elems; i++) {
1960 const struct glsl_type *child_type;
1961
1962 switch (glsl_get_base_type(type)) {
1963 case GLSL_TYPE_INT:
1964 case GLSL_TYPE_UINT:
1965 case GLSL_TYPE_BOOL:
1966 case GLSL_TYPE_FLOAT:
1967 case GLSL_TYPE_DOUBLE:
1968 child_type = glsl_get_column_type(type);
1969 break;
1970 case GLSL_TYPE_ARRAY:
1971 child_type = glsl_get_array_element(type);
1972 break;
1973 case GLSL_TYPE_STRUCT:
1974 child_type = glsl_get_struct_field(type, i);
1975 break;
1976 default:
1977 unreachable("unkown base type");
1978 }
1979
1980 val->elems[i] = vtn_create_ssa_value(b, child_type);
1981 }
1982 }
1983
1984 return val;
1985 }
1986
1987 static nir_tex_src
1988 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
1989 {
1990 nir_tex_src src;
1991 src.src = nir_src_for_ssa(vtn_ssa_value(b, index)->def);
1992 src.src_type = type;
1993 return src;
1994 }
1995
1996 static void
1997 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
1998 const uint32_t *w, unsigned count)
1999 {
2000 if (opcode == SpvOpSampledImage) {
2001 struct vtn_value *val =
2002 vtn_push_value(b, w[2], vtn_value_type_sampled_image);
2003 val->sampled_image = ralloc(b, struct vtn_sampled_image);
2004 val->sampled_image->image =
2005 vtn_value(b, w[3], vtn_value_type_deref)->deref;
2006 val->sampled_image->sampler =
2007 vtn_value(b, w[4], vtn_value_type_deref)->deref;
2008 return;
2009 }
2010
2011 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
2012
2013 struct vtn_sampled_image sampled;
2014 struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]);
2015 if (sampled_val->value_type == vtn_value_type_sampled_image) {
2016 sampled = *sampled_val->sampled_image;
2017 } else {
2018 assert(sampled_val->value_type == vtn_value_type_deref);
2019 sampled.image = NULL;
2020 sampled.sampler = sampled_val->deref;
2021 }
2022
2023 nir_tex_src srcs[8]; /* 8 should be enough */
2024 nir_tex_src *p = srcs;
2025
2026 unsigned idx = 4;
2027
2028 unsigned coord_components = 0;
2029 switch (opcode) {
2030 case SpvOpImageSampleImplicitLod:
2031 case SpvOpImageSampleExplicitLod:
2032 case SpvOpImageSampleDrefImplicitLod:
2033 case SpvOpImageSampleDrefExplicitLod:
2034 case SpvOpImageSampleProjImplicitLod:
2035 case SpvOpImageSampleProjExplicitLod:
2036 case SpvOpImageSampleProjDrefImplicitLod:
2037 case SpvOpImageSampleProjDrefExplicitLod:
2038 case SpvOpImageFetch:
2039 case SpvOpImageGather:
2040 case SpvOpImageDrefGather:
2041 case SpvOpImageQueryLod: {
2042 /* All these types have the coordinate as their first real argument */
2043 struct vtn_ssa_value *coord = vtn_ssa_value(b, w[idx++]);
2044 coord_components = glsl_get_vector_elements(coord->type);
2045 p->src = nir_src_for_ssa(coord->def);
2046 p->src_type = nir_tex_src_coord;
2047 p++;
2048 break;
2049 }
2050
2051 default:
2052 break;
2053 }
2054
2055 /* These all have an explicit depth value as their next source */
2056 switch (opcode) {
2057 case SpvOpImageSampleDrefImplicitLod:
2058 case SpvOpImageSampleDrefExplicitLod:
2059 case SpvOpImageSampleProjDrefImplicitLod:
2060 case SpvOpImageSampleProjDrefExplicitLod:
2061 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_comparitor);
2062 break;
2063 default:
2064 break;
2065 }
2066
2067 /* Figure out the base texture operation */
2068 nir_texop texop;
2069 switch (opcode) {
2070 case SpvOpImageSampleImplicitLod:
2071 case SpvOpImageSampleDrefImplicitLod:
2072 case SpvOpImageSampleProjImplicitLod:
2073 case SpvOpImageSampleProjDrefImplicitLod:
2074 texop = nir_texop_tex;
2075 break;
2076
2077 case SpvOpImageSampleExplicitLod:
2078 case SpvOpImageSampleDrefExplicitLod:
2079 case SpvOpImageSampleProjExplicitLod:
2080 case SpvOpImageSampleProjDrefExplicitLod:
2081 texop = nir_texop_txl;
2082 break;
2083
2084 case SpvOpImageFetch:
2085 texop = nir_texop_txf;
2086 break;
2087
2088 case SpvOpImageGather:
2089 case SpvOpImageDrefGather:
2090 texop = nir_texop_tg4;
2091 break;
2092
2093 case SpvOpImageQuerySizeLod:
2094 case SpvOpImageQuerySize:
2095 texop = nir_texop_txs;
2096 break;
2097
2098 case SpvOpImageQueryLod:
2099 texop = nir_texop_lod;
2100 break;
2101
2102 case SpvOpImageQueryLevels:
2103 texop = nir_texop_query_levels;
2104 break;
2105
2106 case SpvOpImageQuerySamples:
2107 default:
2108 unreachable("Unhandled opcode");
2109 }
2110
2111 /* Now we need to handle some number of optional arguments */
2112 if (idx < count) {
2113 uint32_t operands = w[idx++];
2114
2115 if (operands & SpvImageOperandsBiasMask) {
2116 assert(texop == nir_texop_tex);
2117 texop = nir_texop_txb;
2118 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_bias);
2119 }
2120
2121 if (operands & SpvImageOperandsLodMask) {
2122 assert(texop == nir_texop_txl || texop == nir_texop_txf ||
2123 texop == nir_texop_txs);
2124 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
2125 }
2126
2127 if (operands & SpvImageOperandsGradMask) {
2128 assert(texop == nir_texop_tex);
2129 texop = nir_texop_txd;
2130 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddx);
2131 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddy);
2132 }
2133
2134 if (operands & SpvImageOperandsOffsetMask ||
2135 operands & SpvImageOperandsConstOffsetMask)
2136 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_offset);
2137
2138 if (operands & SpvImageOperandsConstOffsetsMask)
2139 assert(!"Constant offsets to texture gather not yet implemented");
2140
2141 if (operands & SpvImageOperandsSampleMask) {
2142 assert(texop == nir_texop_txf);
2143 texop = nir_texop_txf_ms;
2144 (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
2145 }
2146 }
2147 /* We should have now consumed exactly all of the arguments */
2148 assert(idx == count);
2149
2150 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
2151
2152 const struct glsl_type *sampler_type =
2153 nir_deref_tail(&sampled.sampler->deref)->type;
2154 instr->sampler_dim = glsl_get_sampler_dim(sampler_type);
2155
2156 switch (glsl_get_sampler_result_type(sampler_type)) {
2157 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
2158 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
2159 case GLSL_TYPE_UINT: instr->dest_type = nir_type_uint; break;
2160 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
2161 default:
2162 unreachable("Invalid base type for sampler result");
2163 }
2164
2165 instr->op = texop;
2166 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
2167 instr->coord_components = coord_components;
2168 instr->is_array = glsl_sampler_type_is_array(sampler_type);
2169 instr->is_shadow = glsl_sampler_type_is_shadow(sampler_type);
2170
2171 instr->sampler =
2172 nir_deref_as_var(nir_copy_deref(instr, &sampled.sampler->deref));
2173 if (sampled.image) {
2174 instr->texture =
2175 nir_deref_as_var(nir_copy_deref(instr, &sampled.image->deref));
2176 } else {
2177 instr->texture = NULL;
2178 }
2179
2180 nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
2181 val->ssa = vtn_create_ssa_value(b, glsl_vector_type(GLSL_TYPE_FLOAT, 4));
2182 val->ssa->def = &instr->dest.ssa;
2183
2184 nir_builder_instr_insert(&b->nb, &instr->instr);
2185 }
2186
2187 static nir_ssa_def *
2188 get_image_coord(struct vtn_builder *b, uint32_t value)
2189 {
2190 struct vtn_ssa_value *coord = vtn_ssa_value(b, value);
2191
2192 /* The image_load_store intrinsics assume a 4-dim coordinate */
2193 unsigned dim = glsl_get_vector_elements(coord->type);
2194 unsigned swizzle[4];
2195 for (unsigned i = 0; i < 4; i++)
2196 swizzle[i] = MIN2(i, dim - 1);
2197
2198 return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);
2199 }
2200
2201 static void
2202 vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
2203 const uint32_t *w, unsigned count)
2204 {
2205 /* Just get this one out of the way */
2206 if (opcode == SpvOpImageTexelPointer) {
2207 struct vtn_value *val =
2208 vtn_push_value(b, w[2], vtn_value_type_image_pointer);
2209 val->image = ralloc(b, struct vtn_image_pointer);
2210
2211 val->image->deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
2212 val->image->coord = get_image_coord(b, w[4]);
2213 val->image->sample = vtn_ssa_value(b, w[5])->def;
2214 return;
2215 }
2216
2217 struct vtn_image_pointer image;
2218
2219 switch (opcode) {
2220 case SpvOpAtomicExchange:
2221 case SpvOpAtomicCompareExchange:
2222 case SpvOpAtomicCompareExchangeWeak:
2223 case SpvOpAtomicIIncrement:
2224 case SpvOpAtomicIDecrement:
2225 case SpvOpAtomicIAdd:
2226 case SpvOpAtomicISub:
2227 case SpvOpAtomicSMin:
2228 case SpvOpAtomicUMin:
2229 case SpvOpAtomicSMax:
2230 case SpvOpAtomicUMax:
2231 case SpvOpAtomicAnd:
2232 case SpvOpAtomicOr:
2233 case SpvOpAtomicXor:
2234 image = *vtn_value(b, w[3], vtn_value_type_image_pointer)->image;
2235 break;
2236
2237 case SpvOpImageRead:
2238 image.deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
2239 image.coord = get_image_coord(b, w[4]);
2240
2241 if (count > 5 && (w[5] & SpvImageOperandsSampleMask)) {
2242 assert(w[5] == SpvImageOperandsSampleMask);
2243 image.sample = vtn_ssa_value(b, w[6])->def;
2244 } else {
2245 image.sample = nir_ssa_undef(&b->nb, 1);
2246 }
2247 break;
2248
2249 case SpvOpImageWrite:
2250 image.deref = vtn_value(b, w[1], vtn_value_type_deref)->deref;
2251 image.coord = get_image_coord(b, w[2]);
2252
2253 /* texel = w[3] */
2254
2255 if (count > 4 && (w[4] & SpvImageOperandsSampleMask)) {
2256 assert(w[4] == SpvImageOperandsSampleMask);
2257 image.sample = vtn_ssa_value(b, w[5])->def;
2258 } else {
2259 image.sample = nir_ssa_undef(&b->nb, 1);
2260 }
2261
2262 default:
2263 unreachable("Invalid image opcode");
2264 }
2265
2266 nir_intrinsic_op op;
2267 switch (opcode) {
2268 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
2269 OP(ImageRead, load)
2270 OP(ImageWrite, store)
2271 OP(AtomicExchange, atomic_exchange)
2272 OP(AtomicCompareExchange, atomic_comp_swap)
2273 OP(AtomicIIncrement, atomic_add)
2274 OP(AtomicIDecrement, atomic_add)
2275 OP(AtomicIAdd, atomic_add)
2276 OP(AtomicISub, atomic_add)
2277 OP(AtomicSMin, atomic_min)
2278 OP(AtomicUMin, atomic_min)
2279 OP(AtomicSMax, atomic_max)
2280 OP(AtomicUMax, atomic_max)
2281 OP(AtomicAnd, atomic_and)
2282 OP(AtomicOr, atomic_or)
2283 OP(AtomicXor, atomic_xor)
2284 #undef OP
2285 default:
2286 unreachable("Invalid image opcode");
2287 }
2288
2289 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
2290 intrin->variables[0] =
2291 nir_deref_as_var(nir_copy_deref(&intrin->instr, &image.deref->deref));
2292 intrin->src[0] = nir_src_for_ssa(image.coord);
2293 intrin->src[1] = nir_src_for_ssa(image.sample);
2294
2295 switch (opcode) {
2296 case SpvOpImageRead:
2297 break;
2298 case SpvOpImageWrite:
2299 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
2300 break;
2301 case SpvOpAtomicIIncrement:
2302 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
2303 break;
2304 case SpvOpAtomicIDecrement:
2305 intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
2306 break;
2307
2308 case SpvOpAtomicExchange:
2309 case SpvOpAtomicIAdd:
2310 case SpvOpAtomicSMin:
2311 case SpvOpAtomicUMin:
2312 case SpvOpAtomicSMax:
2313 case SpvOpAtomicUMax:
2314 case SpvOpAtomicAnd:
2315 case SpvOpAtomicOr:
2316 case SpvOpAtomicXor:
2317 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
2318 break;
2319
2320 case SpvOpAtomicCompareExchange:
2321 intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
2322 intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
2323 break;
2324
2325 case SpvOpAtomicISub:
2326 intrin->src[2] = nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
2327 break;
2328
2329 default:
2330 unreachable("Invalid image opcode");
2331 }
2332
2333 if (opcode != SpvOpImageWrite) {
2334 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
2335 struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
2336 nir_ssa_dest_init(&intrin->instr, &intrin->dest,
2337 glsl_get_vector_elements(type->type), NULL);
2338 val->ssa = vtn_create_ssa_value(b, type->type);
2339 val->ssa->def = &intrin->dest.ssa;
2340 }
2341
2342 nir_builder_instr_insert(&b->nb, &intrin->instr);
2343 }
2344
2345 static nir_alu_instr *
2346 create_vec(nir_shader *shader, unsigned num_components)
2347 {
2348 nir_op op;
2349 switch (num_components) {
2350 case 1: op = nir_op_fmov; break;
2351 case 2: op = nir_op_vec2; break;
2352 case 3: op = nir_op_vec3; break;
2353 case 4: op = nir_op_vec4; break;
2354 default: unreachable("bad vector size");
2355 }
2356
2357 nir_alu_instr *vec = nir_alu_instr_create(shader, op);
2358 nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components, NULL);
2359 vec->dest.write_mask = (1 << num_components) - 1;
2360
2361 return vec;
2362 }
2363
2364 static struct vtn_ssa_value *
2365 vtn_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
2366 {
2367 if (src->transposed)
2368 return src->transposed;
2369
2370 struct vtn_ssa_value *dest =
2371 vtn_create_ssa_value(b, glsl_transposed_type(src->type));
2372
2373 for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
2374 nir_alu_instr *vec = create_vec(b->shader,
2375 glsl_get_matrix_columns(src->type));
2376 if (glsl_type_is_vector_or_scalar(src->type)) {
2377 vec->src[0].src = nir_src_for_ssa(src->def);
2378 vec->src[0].swizzle[0] = i;
2379 } else {
2380 for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
2381 vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
2382 vec->src[j].swizzle[0] = i;
2383 }
2384 }
2385 nir_builder_instr_insert(&b->nb, &vec->instr);
2386 dest->elems[i]->def = &vec->dest.dest.ssa;
2387 }
2388
2389 dest->transposed = src;
2390
2391 return dest;
2392 }
2393
2394 /*
2395 * Normally, column vectors in SPIR-V correspond to a single NIR SSA
2396 * definition. But for matrix multiplies, we want to do one routine for
2397 * multiplying a matrix by a matrix and then pretend that vectors are matrices
2398 * with one column. So we "wrap" these things, and unwrap the result before we
2399 * send it off.
2400 */
2401
2402 static struct vtn_ssa_value *
2403 vtn_wrap_matrix(struct vtn_builder *b, struct vtn_ssa_value *val)
2404 {
2405 if (val == NULL)
2406 return NULL;
2407
2408 if (glsl_type_is_matrix(val->type))
2409 return val;
2410
2411 struct vtn_ssa_value *dest = rzalloc(b, struct vtn_ssa_value);
2412 dest->type = val->type;
2413 dest->elems = ralloc_array(b, struct vtn_ssa_value *, 1);
2414 dest->elems[0] = val;
2415
2416 return dest;
2417 }
2418
2419 static struct vtn_ssa_value *
2420 vtn_unwrap_matrix(struct vtn_ssa_value *val)
2421 {
2422 if (glsl_type_is_matrix(val->type))
2423 return val;
2424
2425 return val->elems[0];
2426 }
2427
2428 static struct vtn_ssa_value *
2429 vtn_matrix_multiply(struct vtn_builder *b,
2430 struct vtn_ssa_value *_src0, struct vtn_ssa_value *_src1)
2431 {
2432
2433 struct vtn_ssa_value *src0 = vtn_wrap_matrix(b, _src0);
2434 struct vtn_ssa_value *src1 = vtn_wrap_matrix(b, _src1);
2435 struct vtn_ssa_value *src0_transpose = vtn_wrap_matrix(b, _src0->transposed);
2436 struct vtn_ssa_value *src1_transpose = vtn_wrap_matrix(b, _src1->transposed);
2437
2438 unsigned src0_rows = glsl_get_vector_elements(src0->type);
2439 unsigned src0_columns = glsl_get_matrix_columns(src0->type);
2440 unsigned src1_columns = glsl_get_matrix_columns(src1->type);
2441
2442 const struct glsl_type *dest_type;
2443 if (src1_columns > 1) {
2444 dest_type = glsl_matrix_type(glsl_get_base_type(src0->type),
2445 src0_rows, src1_columns);
2446 } else {
2447 dest_type = glsl_vector_type(glsl_get_base_type(src0->type), src0_rows);
2448 }
2449 struct vtn_ssa_value *dest = vtn_create_ssa_value(b, dest_type);
2450
2451 dest = vtn_wrap_matrix(b, dest);
2452
2453 bool transpose_result = false;
2454 if (src0_transpose && src1_transpose) {
2455 /* transpose(A) * transpose(B) = transpose(B * A) */
2456 src1 = src0_transpose;
2457 src0 = src1_transpose;
2458 src0_transpose = NULL;
2459 src1_transpose = NULL;
2460 transpose_result = true;
2461 }
2462
2463 if (src0_transpose && !src1_transpose &&
2464 glsl_get_base_type(src0->type) == GLSL_TYPE_FLOAT) {
2465 /* We already have the rows of src0 and the columns of src1 available,
2466 * so we can just take the dot product of each row with each column to
2467 * get the result.
2468 */
2469
2470 for (unsigned i = 0; i < src1_columns; i++) {
2471 nir_alu_instr *vec = create_vec(b->shader, src0_rows);
2472 for (unsigned j = 0; j < src0_rows; j++) {
2473 vec->src[j].src =
2474 nir_src_for_ssa(nir_fdot(&b->nb, src0_transpose->elems[j]->def,
2475 src1->elems[i]->def));
2476 }
2477
2478 nir_builder_instr_insert(&b->nb, &vec->instr);
2479 dest->elems[i]->def = &vec->dest.dest.ssa;
2480 }
2481 } else {
2482 /* We don't handle the case where src1 is transposed but not src0, since
2483 * the general case only uses individual components of src1 so the
2484 * optimizer should chew through the transpose we emitted for src1.
2485 */
2486
2487 for (unsigned i = 0; i < src1_columns; i++) {
2488 /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
2489 dest->elems[i]->def =
2490 nir_fmul(&b->nb, src0->elems[0]->def,
2491 vtn_vector_extract(b, src1->elems[i]->def, 0));
2492 for (unsigned j = 1; j < src0_columns; j++) {
2493 dest->elems[i]->def =
2494 nir_fadd(&b->nb, dest->elems[i]->def,
2495 nir_fmul(&b->nb, src0->elems[j]->def,
2496 vtn_vector_extract(b,
2497 src1->elems[i]->def, j)));
2498 }
2499 }
2500 }
2501
2502 dest = vtn_unwrap_matrix(dest);
2503
2504 if (transpose_result)
2505 dest = vtn_transpose(b, dest);
2506
2507 return dest;
2508 }
2509
2510 static struct vtn_ssa_value *
2511 vtn_mat_times_scalar(struct vtn_builder *b,
2512 struct vtn_ssa_value *mat,
2513 nir_ssa_def *scalar)
2514 {
2515 struct vtn_ssa_value *dest = vtn_create_ssa_value(b, mat->type);
2516 for (unsigned i = 0; i < glsl_get_matrix_columns(mat->type); i++) {
2517 if (glsl_get_base_type(mat->type) == GLSL_TYPE_FLOAT)
2518 dest->elems[i]->def = nir_fmul(&b->nb, mat->elems[i]->def, scalar);
2519 else
2520 dest->elems[i]->def = nir_imul(&b->nb, mat->elems[i]->def, scalar);
2521 }
2522
2523 return dest;
2524 }
2525
2526 static void
2527 vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
2528 const uint32_t *w, unsigned count)
2529 {
2530 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
2531
2532 switch (opcode) {
2533 case SpvOpTranspose: {
2534 struct vtn_ssa_value *src = vtn_ssa_value(b, w[3]);
2535 val->ssa = vtn_transpose(b, src);
2536 break;
2537 }
2538
2539 case SpvOpOuterProduct: {
2540 struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
2541 struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
2542
2543 val->ssa = vtn_matrix_multiply(b, src0, vtn_transpose(b, src1));
2544 break;
2545 }
2546
2547 case SpvOpMatrixTimesScalar: {
2548 struct vtn_ssa_value *mat = vtn_ssa_value(b, w[3]);
2549 struct vtn_ssa_value *scalar = vtn_ssa_value(b, w[4]);
2550
2551 if (mat->transposed) {
2552 val->ssa = vtn_transpose(b, vtn_mat_times_scalar(b, mat->transposed,
2553 scalar->def));
2554 } else {
2555 val->ssa = vtn_mat_times_scalar(b, mat, scalar->def);
2556 }
2557 break;
2558 }
2559
2560 case SpvOpVectorTimesMatrix:
2561 case SpvOpMatrixTimesVector:
2562 case SpvOpMatrixTimesMatrix: {
2563 struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
2564 struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
2565
2566 if (opcode == SpvOpVectorTimesMatrix) {
2567 val->ssa = vtn_matrix_multiply(b, vtn_transpose(b, src1), src0);
2568 } else {
2569 val->ssa = vtn_matrix_multiply(b, src0, src1);
2570 }
2571 break;
2572 }
2573
2574 default: unreachable("unknown matrix opcode");
2575 }
2576 }
2577
2578 static void
2579 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
2580 const uint32_t *w, unsigned count)
2581 {
2582 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
2583 const struct glsl_type *type =
2584 vtn_value(b, w[1], vtn_value_type_type)->type->type;
2585 val->ssa = vtn_create_ssa_value(b, type);
2586
2587 /* Collect the various SSA sources */
2588 const unsigned num_inputs = count - 3;
2589 nir_ssa_def *src[4];
2590 for (unsigned i = 0; i < num_inputs; i++)
2591 src[i] = vtn_ssa_value(b, w[i + 3])->def;
2592 for (unsigned i = num_inputs; i < 4; i++)
2593 src[i] = NULL;
2594
2595 /* Indicates that the first two arguments should be swapped. This is
2596 * used for implementing greater-than and less-than-or-equal.
2597 */
2598 bool swap = false;
2599
2600 nir_op op;
2601 switch (opcode) {
2602 /* Basic ALU operations */
2603 case SpvOpSNegate: op = nir_op_ineg; break;
2604 case SpvOpFNegate: op = nir_op_fneg; break;
2605 case SpvOpNot: op = nir_op_inot; break;
2606
2607 case SpvOpAny:
2608 if (src[0]->num_components == 1) {
2609 op = nir_op_imov;
2610 } else {
2611 switch (src[0]->num_components) {
2612 case 2: op = nir_op_bany_inequal2; break;
2613 case 3: op = nir_op_bany_inequal3; break;
2614 case 4: op = nir_op_bany_inequal4; break;
2615 }
2616 src[1] = nir_imm_int(&b->nb, NIR_FALSE);
2617 }
2618 break;
2619
2620 case SpvOpAll:
2621 if (src[0]->num_components == 1) {
2622 op = nir_op_imov;
2623 } else {
2624 switch (src[0]->num_components) {
2625 case 2: op = nir_op_ball_iequal2; break;
2626 case 3: op = nir_op_ball_iequal3; break;
2627 case 4: op = nir_op_ball_iequal4; break;
2628 }
2629 src[1] = nir_imm_int(&b->nb, NIR_TRUE);
2630 }
2631 break;
2632
2633 case SpvOpIAdd: op = nir_op_iadd; break;
2634 case SpvOpFAdd: op = nir_op_fadd; break;
2635 case SpvOpISub: op = nir_op_isub; break;
2636 case SpvOpFSub: op = nir_op_fsub; break;
2637 case SpvOpIMul: op = nir_op_imul; break;
2638 case SpvOpFMul: op = nir_op_fmul; break;
2639 case SpvOpUDiv: op = nir_op_udiv; break;
2640 case SpvOpSDiv: op = nir_op_idiv; break;
2641 case SpvOpFDiv: op = nir_op_fdiv; break;
2642 case SpvOpUMod: op = nir_op_umod; break;
2643 case SpvOpSMod: op = nir_op_umod; break; /* FIXME? */
2644 case SpvOpFMod: op = nir_op_fmod; break;
2645
2646 case SpvOpDot:
2647 assert(src[0]->num_components == src[1]->num_components);
2648 switch (src[0]->num_components) {
2649 case 1: op = nir_op_fmul; break;
2650 case 2: op = nir_op_fdot2; break;
2651 case 3: op = nir_op_fdot3; break;
2652 case 4: op = nir_op_fdot4; break;
2653 }
2654 break;
2655
2656 case SpvOpShiftRightLogical: op = nir_op_ushr; break;
2657 case SpvOpShiftRightArithmetic: op = nir_op_ishr; break;
2658 case SpvOpShiftLeftLogical: op = nir_op_ishl; break;
2659 case SpvOpLogicalOr: op = nir_op_ior; break;
2660 case SpvOpLogicalEqual: op = nir_op_ieq; break;
2661 case SpvOpLogicalNotEqual: op = nir_op_ine; break;
2662 case SpvOpLogicalAnd: op = nir_op_iand; break;
2663 case SpvOpLogicalNot: op = nir_op_inot; break;
2664 case SpvOpBitwiseOr: op = nir_op_ior; break;
2665 case SpvOpBitwiseXor: op = nir_op_ixor; break;
2666 case SpvOpBitwiseAnd: op = nir_op_iand; break;
2667 case SpvOpSelect: op = nir_op_bcsel; break;
2668 case SpvOpIEqual: op = nir_op_ieq; break;
2669
2670 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
2671 case SpvOpFOrdEqual: op = nir_op_feq; break;
2672 case SpvOpFUnordEqual: op = nir_op_feq; break;
2673 case SpvOpINotEqual: op = nir_op_ine; break;
2674 case SpvOpFOrdNotEqual: op = nir_op_fne; break;
2675 case SpvOpFUnordNotEqual: op = nir_op_fne; break;
2676 case SpvOpULessThan: op = nir_op_ult; break;
2677 case SpvOpSLessThan: op = nir_op_ilt; break;
2678 case SpvOpFOrdLessThan: op = nir_op_flt; break;
2679 case SpvOpFUnordLessThan: op = nir_op_flt; break;
2680 case SpvOpUGreaterThan: op = nir_op_ult; swap = true; break;
2681 case SpvOpSGreaterThan: op = nir_op_ilt; swap = true; break;
2682 case SpvOpFOrdGreaterThan: op = nir_op_flt; swap = true; break;
2683 case SpvOpFUnordGreaterThan: op = nir_op_flt; swap = true; break;
2684 case SpvOpULessThanEqual: op = nir_op_uge; swap = true; break;
2685 case SpvOpSLessThanEqual: op = nir_op_ige; swap = true; break;
2686 case SpvOpFOrdLessThanEqual: op = nir_op_fge; swap = true; break;
2687 case SpvOpFUnordLessThanEqual: op = nir_op_fge; swap = true; break;
2688 case SpvOpUGreaterThanEqual: op = nir_op_uge; break;
2689 case SpvOpSGreaterThanEqual: op = nir_op_ige; break;
2690 case SpvOpFOrdGreaterThanEqual: op = nir_op_fge; break;
2691 case SpvOpFUnordGreaterThanEqual:op = nir_op_fge; break;
2692
2693 /* Conversions: */
2694 case SpvOpConvertFToU: op = nir_op_f2u; break;
2695 case SpvOpConvertFToS: op = nir_op_f2i; break;
2696 case SpvOpConvertSToF: op = nir_op_i2f; break;
2697 case SpvOpConvertUToF: op = nir_op_u2f; break;
2698 case SpvOpBitcast: op = nir_op_imov; break;
2699 case SpvOpUConvert:
2700 case SpvOpSConvert:
2701 op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
2702 break;
2703 case SpvOpFConvert:
2704 op = nir_op_fmov;
2705 break;
2706
2707 /* Derivatives: */
2708 case SpvOpDPdx: op = nir_op_fddx; break;
2709 case SpvOpDPdy: op = nir_op_fddy; break;
2710 case SpvOpDPdxFine: op = nir_op_fddx_fine; break;
2711 case SpvOpDPdyFine: op = nir_op_fddy_fine; break;
2712 case SpvOpDPdxCoarse: op = nir_op_fddx_coarse; break;
2713 case SpvOpDPdyCoarse: op = nir_op_fddy_coarse; break;
2714 case SpvOpFwidth:
2715 val->ssa->def = nir_fadd(&b->nb,
2716 nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
2717 nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
2718 return;
2719 case SpvOpFwidthFine:
2720 val->ssa->def = nir_fadd(&b->nb,
2721 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
2722 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
2723 return;
2724 case SpvOpFwidthCoarse:
2725 val->ssa->def = nir_fadd(&b->nb,
2726 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
2727 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
2728 return;
2729
2730 case SpvOpVectorTimesScalar:
2731 /* The builder will take care of splatting for us. */
2732 val->ssa->def = nir_fmul(&b->nb, src[0], src[1]);
2733 return;
2734
2735 case SpvOpSRem:
2736 case SpvOpFRem:
2737 unreachable("No NIR equivalent");
2738
2739 case SpvOpIsNan:
2740 val->ssa->def = nir_fne(&b->nb, src[0], src[0]);
2741 return;
2742
2743 case SpvOpIsInf:
2744 val->ssa->def = nir_feq(&b->nb, nir_fabs(&b->nb, src[0]),
2745 nir_imm_float(&b->nb, INFINITY));
2746 return;
2747
2748 case SpvOpIsFinite:
2749 case SpvOpIsNormal:
2750 case SpvOpSignBitSet:
2751 case SpvOpLessOrGreater:
2752 case SpvOpOrdered:
2753 case SpvOpUnordered:
2754 default:
2755 unreachable("Unhandled opcode");
2756 }
2757
2758 if (swap) {
2759 nir_ssa_def *tmp = src[0];
2760 src[0] = src[1];
2761 src[1] = tmp;
2762 }
2763
2764 val->ssa->def = nir_build_alu(&b->nb, op, src[0], src[1], src[2], src[3]);
2765 }
2766
2767 static nir_ssa_def *
2768 vtn_vector_extract(struct vtn_builder *b, nir_ssa_def *src, unsigned index)
2769 {
2770 unsigned swiz[4] = { index };
2771 return nir_swizzle(&b->nb, src, swiz, 1, true);
2772 }
2773
2774
2775 static nir_ssa_def *
2776 vtn_vector_insert(struct vtn_builder *b, nir_ssa_def *src, nir_ssa_def *insert,
2777 unsigned index)
2778 {
2779 nir_alu_instr *vec = create_vec(b->shader, src->num_components);
2780
2781 for (unsigned i = 0; i < src->num_components; i++) {
2782 if (i == index) {
2783 vec->src[i].src = nir_src_for_ssa(insert);
2784 } else {
2785 vec->src[i].src = nir_src_for_ssa(src);
2786 vec->src[i].swizzle[0] = i;
2787 }
2788 }
2789
2790 nir_builder_instr_insert(&b->nb, &vec->instr);
2791
2792 return &vec->dest.dest.ssa;
2793 }
2794
2795 static nir_ssa_def *
2796 vtn_vector_extract_dynamic(struct vtn_builder *b, nir_ssa_def *src,
2797 nir_ssa_def *index)
2798 {
2799 nir_ssa_def *dest = vtn_vector_extract(b, src, 0);
2800 for (unsigned i = 1; i < src->num_components; i++)
2801 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
2802 vtn_vector_extract(b, src, i), dest);
2803
2804 return dest;
2805 }
2806
2807 static nir_ssa_def *
2808 vtn_vector_insert_dynamic(struct vtn_builder *b, nir_ssa_def *src,
2809 nir_ssa_def *insert, nir_ssa_def *index)
2810 {
2811 nir_ssa_def *dest = vtn_vector_insert(b, src, insert, 0);
2812 for (unsigned i = 1; i < src->num_components; i++)
2813 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
2814 vtn_vector_insert(b, src, insert, i), dest);
2815
2816 return dest;
2817 }
2818
2819 static nir_ssa_def *
2820 vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
2821 nir_ssa_def *src0, nir_ssa_def *src1,
2822 const uint32_t *indices)
2823 {
2824 nir_alu_instr *vec = create_vec(b->shader, num_components);
2825
2826 nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(b->shader, 1);
2827 nir_builder_instr_insert(&b->nb, &undef->instr);
2828
2829 for (unsigned i = 0; i < num_components; i++) {
2830 uint32_t index = indices[i];
2831 if (index == 0xffffffff) {
2832 vec->src[i].src = nir_src_for_ssa(&undef->def);
2833 } else if (index < src0->num_components) {
2834 vec->src[i].src = nir_src_for_ssa(src0);
2835 vec->src[i].swizzle[0] = index;
2836 } else {
2837 vec->src[i].src = nir_src_for_ssa(src1);
2838 vec->src[i].swizzle[0] = index - src0->num_components;
2839 }
2840 }
2841
2842 nir_builder_instr_insert(&b->nb, &vec->instr);
2843
2844 return &vec->dest.dest.ssa;
2845 }
2846
2847 /*
2848 * Concatentates a number of vectors/scalars together to produce a vector
2849 */
2850 static nir_ssa_def *
2851 vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
2852 unsigned num_srcs, nir_ssa_def **srcs)
2853 {
2854 nir_alu_instr *vec = create_vec(b->shader, num_components);
2855
2856 unsigned dest_idx = 0;
2857 for (unsigned i = 0; i < num_srcs; i++) {
2858 nir_ssa_def *src = srcs[i];
2859 for (unsigned j = 0; j < src->num_components; j++) {
2860 vec->src[dest_idx].src = nir_src_for_ssa(src);
2861 vec->src[dest_idx].swizzle[0] = j;
2862 dest_idx++;
2863 }
2864 }
2865
2866 nir_builder_instr_insert(&b->nb, &vec->instr);
2867
2868 return &vec->dest.dest.ssa;
2869 }
2870
2871 static struct vtn_ssa_value *
2872 vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
2873 {
2874 struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
2875 dest->type = src->type;
2876
2877 if (glsl_type_is_vector_or_scalar(src->type)) {
2878 dest->def = src->def;
2879 } else {
2880 unsigned elems = glsl_get_length(src->type);
2881
2882 dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
2883 for (unsigned i = 0; i < elems; i++)
2884 dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
2885 }
2886
2887 return dest;
2888 }
2889
2890 static struct vtn_ssa_value *
2891 vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
2892 struct vtn_ssa_value *insert, const uint32_t *indices,
2893 unsigned num_indices)
2894 {
2895 struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
2896
2897 struct vtn_ssa_value *cur = dest;
2898 unsigned i;
2899 for (i = 0; i < num_indices - 1; i++) {
2900 cur = cur->elems[indices[i]];
2901 }
2902
2903 if (glsl_type_is_vector_or_scalar(cur->type)) {
2904 /* According to the SPIR-V spec, OpCompositeInsert may work down to
2905 * the component granularity. In that case, the last index will be
2906 * the index to insert the scalar into the vector.
2907 */
2908
2909 cur->def = vtn_vector_insert(b, cur->def, insert->def, indices[i]);
2910 } else {
2911 cur->elems[indices[i]] = insert;
2912 }
2913
2914 return dest;
2915 }
2916
2917 static struct vtn_ssa_value *
2918 vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
2919 const uint32_t *indices, unsigned num_indices)
2920 {
2921 struct vtn_ssa_value *cur = src;
2922 for (unsigned i = 0; i < num_indices; i++) {
2923 if (glsl_type_is_vector_or_scalar(cur->type)) {
2924 assert(i == num_indices - 1);
2925 /* According to the SPIR-V spec, OpCompositeExtract may work down to
2926 * the component granularity. The last index will be the index of the
2927 * vector to extract.
2928 */
2929
2930 struct vtn_ssa_value *ret = rzalloc(b, struct vtn_ssa_value);
2931 ret->type = glsl_scalar_type(glsl_get_base_type(cur->type));
2932 ret->def = vtn_vector_extract(b, cur->def, indices[i]);
2933 return ret;
2934 } else {
2935 cur = cur->elems[indices[i]];
2936 }
2937 }
2938
2939 return cur;
2940 }
2941
2942 static void
2943 vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
2944 const uint32_t *w, unsigned count)
2945 {
2946 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
2947 const struct glsl_type *type =
2948 vtn_value(b, w[1], vtn_value_type_type)->type->type;
2949 val->ssa = vtn_create_ssa_value(b, type);
2950
2951 switch (opcode) {
2952 case SpvOpVectorExtractDynamic:
2953 val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def,
2954 vtn_ssa_value(b, w[4])->def);
2955 break;
2956
2957 case SpvOpVectorInsertDynamic:
2958 val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def,
2959 vtn_ssa_value(b, w[4])->def,
2960 vtn_ssa_value(b, w[5])->def);
2961 break;
2962
2963 case SpvOpVectorShuffle:
2964 val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type),
2965 vtn_ssa_value(b, w[3])->def,
2966 vtn_ssa_value(b, w[4])->def,
2967 w + 5);
2968 break;
2969
2970 case SpvOpCompositeConstruct: {
2971 unsigned elems = count - 3;
2972 if (glsl_type_is_vector_or_scalar(type)) {
2973 nir_ssa_def *srcs[4];
2974 for (unsigned i = 0; i < elems; i++)
2975 srcs[i] = vtn_ssa_value(b, w[3 + i])->def;
2976 val->ssa->def =
2977 vtn_vector_construct(b, glsl_get_vector_elements(type),
2978 elems, srcs);
2979 } else {
2980 val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
2981 for (unsigned i = 0; i < elems; i++)
2982 val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
2983 }
2984 break;
2985 }
2986 case SpvOpCompositeExtract:
2987 val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
2988 w + 4, count - 4);
2989 break;
2990
2991 case SpvOpCompositeInsert:
2992 val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
2993 vtn_ssa_value(b, w[3]),
2994 w + 5, count - 5);
2995 break;
2996
2997 case SpvOpCopyObject:
2998 val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
2999 break;
3000
3001 default:
3002 unreachable("unknown composite operation");
3003 }
3004 }
3005
3006 static void
3007 vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
3008 const uint32_t *w, unsigned count)
3009 {
3010 nir_intrinsic_op intrinsic_op;
3011 switch (opcode) {
3012 case SpvOpEmitVertex:
3013 case SpvOpEmitStreamVertex:
3014 intrinsic_op = nir_intrinsic_emit_vertex;
3015 break;
3016 case SpvOpEndPrimitive:
3017 case SpvOpEndStreamPrimitive:
3018 intrinsic_op = nir_intrinsic_end_primitive;
3019 break;
3020 case SpvOpMemoryBarrier:
3021 intrinsic_op = nir_intrinsic_memory_barrier;
3022 break;
3023 case SpvOpControlBarrier:
3024 default:
3025 unreachable("unknown barrier instruction");
3026 }
3027
3028 nir_intrinsic_instr *intrin =
3029 nir_intrinsic_instr_create(b->shader, intrinsic_op);
3030
3031 if (opcode == SpvOpEmitStreamVertex || opcode == SpvOpEndStreamPrimitive)
3032 intrin->const_index[0] = w[1];
3033
3034 nir_builder_instr_insert(&b->nb, &intrin->instr);
3035 }
3036
3037 static void
3038 vtn_phi_node_init(struct vtn_builder *b, struct vtn_ssa_value *val)
3039 {
3040 if (glsl_type_is_vector_or_scalar(val->type)) {
3041 nir_phi_instr *phi = nir_phi_instr_create(b->shader);
3042 nir_ssa_dest_init(&phi->instr, &phi->dest,
3043 glsl_get_vector_elements(val->type), NULL);
3044 exec_list_make_empty(&phi->srcs);
3045 nir_builder_instr_insert(&b->nb, &phi->instr);
3046 val->def = &phi->dest.ssa;
3047 } else {
3048 unsigned elems = glsl_get_length(val->type);
3049 for (unsigned i = 0; i < elems; i++)
3050 vtn_phi_node_init(b, val->elems[i]);
3051 }
3052 }
3053
3054 static struct vtn_ssa_value *
3055 vtn_phi_node_create(struct vtn_builder *b, const struct glsl_type *type)
3056 {
3057 struct vtn_ssa_value *val = vtn_create_ssa_value(b, type);
3058 vtn_phi_node_init(b, val);
3059 return val;
3060 }
3061
3062 static void
3063 vtn_handle_phi_first_pass(struct vtn_builder *b, const uint32_t *w)
3064 {
3065 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
3066 const struct glsl_type *type =
3067 vtn_value(b, w[1], vtn_value_type_type)->type->type;
3068 val->ssa = vtn_phi_node_create(b, type);
3069 }
3070
3071 static void
3072 vtn_phi_node_add_src(struct vtn_ssa_value *phi, const nir_block *pred,
3073 struct vtn_ssa_value *val)
3074 {
3075 assert(phi->type == val->type);
3076 if (glsl_type_is_vector_or_scalar(phi->type)) {
3077 nir_phi_instr *phi_instr = nir_instr_as_phi(phi->def->parent_instr);
3078 nir_phi_src *src = ralloc(phi_instr, nir_phi_src);
3079 src->pred = (nir_block *) pred;
3080 src->src = NIR_SRC_INIT;
3081 exec_list_push_tail(&phi_instr->srcs, &src->node);
3082 nir_instr_rewrite_src(&phi_instr->instr, &src->src,
3083 nir_src_for_ssa(val->def));
3084 } else {
3085 unsigned elems = glsl_get_length(phi->type);
3086 for (unsigned i = 0; i < elems; i++)
3087 vtn_phi_node_add_src(phi->elems[i], pred, val->elems[i]);
3088 }
3089 }
3090
3091 static struct vtn_ssa_value *
3092 vtn_get_phi_node_src(struct vtn_builder *b, nir_block *block,
3093 const struct glsl_type *type, const uint32_t *w,
3094 unsigned count)
3095 {
3096 struct hash_entry *entry = _mesa_hash_table_search(b->block_table, block);
3097 if (entry) {
3098 struct vtn_block *spv_block = entry->data;
3099 for (unsigned off = 4; off < count; off += 2) {
3100 if (spv_block == vtn_value(b, w[off], vtn_value_type_block)->block) {
3101 return vtn_ssa_value(b, w[off - 1]);
3102 }
3103 }
3104 }
3105
3106 b->nb.cursor = nir_before_block(block);
3107 struct vtn_ssa_value *phi = vtn_phi_node_create(b, type);
3108
3109 struct set_entry *entry2;
3110 set_foreach(block->predecessors, entry2) {
3111 nir_block *pred = (nir_block *) entry2->key;
3112 struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, type, w,
3113 count);
3114 vtn_phi_node_add_src(phi, pred, val);
3115 }
3116
3117 return phi;
3118 }
3119
3120 static bool
3121 vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
3122 const uint32_t *w, unsigned count)
3123 {
3124 if (opcode == SpvOpLabel) {
3125 b->block = vtn_value(b, w[1], vtn_value_type_block)->block;
3126 return true;
3127 }
3128
3129 if (opcode != SpvOpPhi)
3130 return true;
3131
3132 struct vtn_ssa_value *phi = vtn_value(b, w[2], vtn_value_type_ssa)->ssa;
3133
3134 struct set_entry *entry;
3135 set_foreach(b->block->block->predecessors, entry) {
3136 nir_block *pred = (nir_block *) entry->key;
3137
3138 struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, phi->type, w,
3139 count);
3140 vtn_phi_node_add_src(phi, pred, val);
3141 }
3142
3143 return true;
3144 }
3145
3146 static unsigned
3147 gl_primitive_from_spv_execution_mode(SpvExecutionMode mode)
3148 {
3149 switch (mode) {
3150 case SpvExecutionModeInputPoints:
3151 case SpvExecutionModeOutputPoints:
3152 return 0; /* GL_POINTS */
3153 case SpvExecutionModeInputLines:
3154 return 1; /* GL_LINES */
3155 case SpvExecutionModeInputLinesAdjacency:
3156 return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
3157 case SpvExecutionModeTriangles:
3158 return 4; /* GL_TRIANGLES */
3159 case SpvExecutionModeInputTrianglesAdjacency:
3160 return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
3161 case SpvExecutionModeQuads:
3162 return 7; /* GL_QUADS */
3163 case SpvExecutionModeIsolines:
3164 return 0x8E7A; /* GL_ISOLINES */
3165 case SpvExecutionModeOutputLineStrip:
3166 return 3; /* GL_LINE_STRIP */
3167 case SpvExecutionModeOutputTriangleStrip:
3168 return 5; /* GL_TRIANGLE_STRIP */
3169 default:
3170 assert(!"Invalid primitive type");
3171 return 4;
3172 }
3173 }
3174
3175 static unsigned
3176 vertices_in_from_spv_execution_mode(SpvExecutionMode mode)
3177 {
3178 switch (mode) {
3179 case SpvExecutionModeInputPoints:
3180 return 1;
3181 case SpvExecutionModeInputLines:
3182 return 2;
3183 case SpvExecutionModeInputLinesAdjacency:
3184 return 4;
3185 case SpvExecutionModeTriangles:
3186 return 3;
3187 case SpvExecutionModeInputTrianglesAdjacency:
3188 return 6;
3189 default:
3190 assert(!"Invalid GS input mode");
3191 return 0;
3192 }
3193 }
3194
3195 static bool
3196 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
3197 const uint32_t *w, unsigned count)
3198 {
3199 switch (opcode) {
3200 case SpvOpSource:
3201 case SpvOpSourceExtension:
3202 case SpvOpExtension:
3203 /* Unhandled, but these are for debug so that's ok. */
3204 break;
3205
3206 case SpvOpCapability:
3207 switch ((SpvCapability)w[1]) {
3208 case SpvCapabilityMatrix:
3209 case SpvCapabilityShader:
3210 case SpvCapabilityGeometry:
3211 break;
3212 default:
3213 assert(!"Unsupported capability");
3214 }
3215 break;
3216
3217 case SpvOpExtInstImport:
3218 vtn_handle_extension(b, opcode, w, count);
3219 break;
3220
3221 case SpvOpMemoryModel:
3222 assert(w[1] == SpvAddressingModelLogical);
3223 assert(w[2] == SpvMemoryModelGLSL450);
3224 break;
3225
3226 case SpvOpEntryPoint:
3227 /* Let this be a name label regardless */
3228 b->values[w[2]].name = vtn_string_literal(b, &w[3], count - 3);
3229
3230 if (strcmp(b->values[w[2]].name, b->entry_point_name) != 0)
3231 break;
3232
3233 assert(b->entry_point == NULL);
3234 b->entry_point = &b->values[w[2]];
3235 b->execution_model = w[1];
3236 break;
3237
3238 case SpvOpString:
3239 vtn_push_value(b, w[1], vtn_value_type_string)->str =
3240 vtn_string_literal(b, &w[2], count - 2);
3241 break;
3242
3243 case SpvOpName:
3244 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
3245 break;
3246
3247 case SpvOpMemberName:
3248 /* TODO */
3249 break;
3250
3251 case SpvOpLine:
3252 break; /* Ignored for now */
3253
3254 case SpvOpExecutionMode:
3255 case SpvOpDecorationGroup:
3256 case SpvOpDecorate:
3257 case SpvOpMemberDecorate:
3258 case SpvOpGroupDecorate:
3259 case SpvOpGroupMemberDecorate:
3260 vtn_handle_decoration(b, opcode, w, count);
3261 break;
3262
3263 default:
3264 return false; /* End of preamble */
3265 }
3266
3267 return true;
3268 }
3269
3270 static void
3271 vtn_handle_execution_mode(struct vtn_builder *b, struct vtn_value *entry_point,
3272 const struct vtn_decoration *mode, void *data)
3273 {
3274 assert(b->entry_point == entry_point);
3275
3276 switch(mode->exec_mode) {
3277 case SpvExecutionModeOriginUpperLeft:
3278 case SpvExecutionModeOriginLowerLeft:
3279 b->origin_upper_left =
3280 (mode->exec_mode == SpvExecutionModeOriginUpperLeft);
3281 break;
3282
3283 case SpvExecutionModeEarlyFragmentTests:
3284 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
3285 b->shader->info.fs.early_fragment_tests = true;
3286 break;
3287
3288 case SpvExecutionModeInvocations:
3289 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
3290 b->shader->info.gs.invocations = MAX2(1, mode->literals[0]);
3291 break;
3292
3293 case SpvExecutionModeDepthReplacing:
3294 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
3295 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
3296 break;
3297 case SpvExecutionModeDepthGreater:
3298 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
3299 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
3300 break;
3301 case SpvExecutionModeDepthLess:
3302 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
3303 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
3304 break;
3305 case SpvExecutionModeDepthUnchanged:
3306 assert(b->shader->stage == MESA_SHADER_FRAGMENT);
3307 b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
3308 break;
3309
3310 case SpvExecutionModeLocalSize:
3311 assert(b->shader->stage == MESA_SHADER_COMPUTE);
3312 b->shader->info.cs.local_size[0] = mode->literals[0];
3313 b->shader->info.cs.local_size[1] = mode->literals[1];
3314 b->shader->info.cs.local_size[2] = mode->literals[2];
3315 break;
3316 case SpvExecutionModeLocalSizeHint:
3317 break; /* Nothing do do with this */
3318
3319 case SpvExecutionModeOutputVertices:
3320 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
3321 b->shader->info.gs.vertices_out = mode->literals[0];
3322 break;
3323
3324 case SpvExecutionModeInputPoints:
3325 case SpvExecutionModeInputLines:
3326 case SpvExecutionModeInputLinesAdjacency:
3327 case SpvExecutionModeTriangles:
3328 case SpvExecutionModeInputTrianglesAdjacency:
3329 case SpvExecutionModeQuads:
3330 case SpvExecutionModeIsolines:
3331 if (b->shader->stage == MESA_SHADER_GEOMETRY) {
3332 b->shader->info.gs.vertices_in =
3333 vertices_in_from_spv_execution_mode(mode->exec_mode);
3334 } else {
3335 assert(!"Tesselation shaders not yet supported");
3336 }
3337 break;
3338
3339 case SpvExecutionModeOutputPoints:
3340 case SpvExecutionModeOutputLineStrip:
3341 case SpvExecutionModeOutputTriangleStrip:
3342 assert(b->shader->stage == MESA_SHADER_GEOMETRY);
3343 b->shader->info.gs.output_primitive =
3344 gl_primitive_from_spv_execution_mode(mode->exec_mode);
3345 break;
3346
3347 case SpvExecutionModeSpacingEqual:
3348 case SpvExecutionModeSpacingFractionalEven:
3349 case SpvExecutionModeSpacingFractionalOdd:
3350 case SpvExecutionModeVertexOrderCw:
3351 case SpvExecutionModeVertexOrderCcw:
3352 case SpvExecutionModePointMode:
3353 assert(!"TODO: Add tessellation metadata");
3354 break;
3355
3356 case SpvExecutionModePixelCenterInteger:
3357 case SpvExecutionModeXfb:
3358 assert(!"Unhandled execution mode");
3359 break;
3360
3361 case SpvExecutionModeVecTypeHint:
3362 case SpvExecutionModeContractionOff:
3363 break; /* OpenCL */
3364 }
3365 }
3366
3367 static bool
3368 vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
3369 const uint32_t *w, unsigned count)
3370 {
3371 switch (opcode) {
3372 case SpvOpSource:
3373 case SpvOpSourceExtension:
3374 case SpvOpExtension:
3375 case SpvOpCapability:
3376 case SpvOpExtInstImport:
3377 case SpvOpMemoryModel:
3378 case SpvOpEntryPoint:
3379 case SpvOpExecutionMode:
3380 case SpvOpString:
3381 case SpvOpName:
3382 case SpvOpMemberName:
3383 case SpvOpLine:
3384 case SpvOpDecorationGroup:
3385 case SpvOpDecorate:
3386 case SpvOpMemberDecorate:
3387 case SpvOpGroupDecorate:
3388 case SpvOpGroupMemberDecorate:
3389 assert(!"Invalid opcode types and variables section");
3390 break;
3391
3392 case SpvOpTypeVoid:
3393 case SpvOpTypeBool:
3394 case SpvOpTypeInt:
3395 case SpvOpTypeFloat:
3396 case SpvOpTypeVector:
3397 case SpvOpTypeMatrix:
3398 case SpvOpTypeImage:
3399 case SpvOpTypeSampler:
3400 case SpvOpTypeSampledImage:
3401 case SpvOpTypeArray:
3402 case SpvOpTypeRuntimeArray:
3403 case SpvOpTypeStruct:
3404 case SpvOpTypeOpaque:
3405 case SpvOpTypePointer:
3406 case SpvOpTypeFunction:
3407 case SpvOpTypeEvent:
3408 case SpvOpTypeDeviceEvent:
3409 case SpvOpTypeReserveId:
3410 case SpvOpTypeQueue:
3411 case SpvOpTypePipe:
3412 vtn_handle_type(b, opcode, w, count);
3413 break;
3414
3415 case SpvOpConstantTrue:
3416 case SpvOpConstantFalse:
3417 case SpvOpConstant:
3418 case SpvOpConstantComposite:
3419 case SpvOpConstantSampler:
3420 case SpvOpSpecConstantTrue:
3421 case SpvOpSpecConstantFalse:
3422 case SpvOpSpecConstant:
3423 case SpvOpSpecConstantComposite:
3424 vtn_handle_constant(b, opcode, w, count);
3425 break;
3426
3427 case SpvOpVariable:
3428 vtn_handle_variables(b, opcode, w, count);
3429 break;
3430
3431 default:
3432 return false; /* End of preamble */
3433 }
3434
3435 return true;
3436 }
3437
3438 static bool
3439 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
3440 const uint32_t *w, unsigned count)
3441 {
3442 switch (opcode) {
3443 case SpvOpLabel: {
3444 struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
3445 assert(block->block == nir_cursor_current_block(b->nb.cursor));
3446 break;
3447 }
3448
3449 case SpvOpLoopMerge:
3450 case SpvOpSelectionMerge:
3451 /* This is handled by cfg pre-pass and walk_blocks */
3452 break;
3453
3454 case SpvOpUndef: {
3455 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_undef);
3456 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
3457 break;
3458 }
3459
3460 case SpvOpExtInst:
3461 vtn_handle_extension(b, opcode, w, count);
3462 break;
3463
3464 case SpvOpVariable:
3465 case SpvOpLoad:
3466 case SpvOpStore:
3467 case SpvOpCopyMemory:
3468 case SpvOpCopyMemorySized:
3469 case SpvOpAccessChain:
3470 case SpvOpInBoundsAccessChain:
3471 case SpvOpArrayLength:
3472 vtn_handle_variables(b, opcode, w, count);
3473 break;
3474
3475 case SpvOpFunctionCall:
3476 vtn_handle_function_call(b, opcode, w, count);
3477 break;
3478
3479 case SpvOpSampledImage:
3480 case SpvOpImageSampleImplicitLod:
3481 case SpvOpImageSampleExplicitLod:
3482 case SpvOpImageSampleDrefImplicitLod:
3483 case SpvOpImageSampleDrefExplicitLod:
3484 case SpvOpImageSampleProjImplicitLod:
3485 case SpvOpImageSampleProjExplicitLod:
3486 case SpvOpImageSampleProjDrefImplicitLod:
3487 case SpvOpImageSampleProjDrefExplicitLod:
3488 case SpvOpImageFetch:
3489 case SpvOpImageGather:
3490 case SpvOpImageDrefGather:
3491 case SpvOpImageQuerySizeLod:
3492 case SpvOpImageQuerySize:
3493 case SpvOpImageQueryLod:
3494 case SpvOpImageQueryLevels:
3495 case SpvOpImageQuerySamples:
3496 vtn_handle_texture(b, opcode, w, count);
3497 break;
3498
3499 case SpvOpImageRead:
3500 case SpvOpImageWrite:
3501 case SpvOpImageTexelPointer:
3502 vtn_handle_image(b, opcode, w, count);
3503 break;
3504
3505 case SpvOpAtomicExchange:
3506 case SpvOpAtomicCompareExchange:
3507 case SpvOpAtomicCompareExchangeWeak:
3508 case SpvOpAtomicIIncrement:
3509 case SpvOpAtomicIDecrement:
3510 case SpvOpAtomicIAdd:
3511 case SpvOpAtomicISub:
3512 case SpvOpAtomicSMin:
3513 case SpvOpAtomicUMin:
3514 case SpvOpAtomicSMax:
3515 case SpvOpAtomicUMax:
3516 case SpvOpAtomicAnd:
3517 case SpvOpAtomicOr:
3518 case SpvOpAtomicXor: {
3519 struct vtn_value *pointer = vtn_untyped_value(b, w[3]);
3520 if (pointer->value_type == vtn_value_type_image_pointer) {
3521 vtn_handle_image(b, opcode, w, count);
3522 } else {
3523 assert(!"Atomic buffers not yet implemented");
3524 }
3525 }
3526
3527 case SpvOpSNegate:
3528 case SpvOpFNegate:
3529 case SpvOpNot:
3530 case SpvOpAny:
3531 case SpvOpAll:
3532 case SpvOpConvertFToU:
3533 case SpvOpConvertFToS:
3534 case SpvOpConvertSToF:
3535 case SpvOpConvertUToF:
3536 case SpvOpUConvert:
3537 case SpvOpSConvert:
3538 case SpvOpFConvert:
3539 case SpvOpConvertPtrToU:
3540 case SpvOpConvertUToPtr:
3541 case SpvOpPtrCastToGeneric:
3542 case SpvOpGenericCastToPtr:
3543 case SpvOpBitcast:
3544 case SpvOpIsNan:
3545 case SpvOpIsInf:
3546 case SpvOpIsFinite:
3547 case SpvOpIsNormal:
3548 case SpvOpSignBitSet:
3549 case SpvOpLessOrGreater:
3550 case SpvOpOrdered:
3551 case SpvOpUnordered:
3552 case SpvOpIAdd:
3553 case SpvOpFAdd:
3554 case SpvOpISub:
3555 case SpvOpFSub:
3556 case SpvOpIMul:
3557 case SpvOpFMul:
3558 case SpvOpUDiv:
3559 case SpvOpSDiv:
3560 case SpvOpFDiv:
3561 case SpvOpUMod:
3562 case SpvOpSRem:
3563 case SpvOpSMod:
3564 case SpvOpFRem:
3565 case SpvOpFMod:
3566 case SpvOpVectorTimesScalar:
3567 case SpvOpDot:
3568 case SpvOpShiftRightLogical:
3569 case SpvOpShiftRightArithmetic:
3570 case SpvOpShiftLeftLogical:
3571 case SpvOpLogicalEqual:
3572 case SpvOpLogicalNotEqual:
3573 case SpvOpLogicalOr:
3574 case SpvOpLogicalAnd:
3575 case SpvOpLogicalNot:
3576 case SpvOpBitwiseOr:
3577 case SpvOpBitwiseXor:
3578 case SpvOpBitwiseAnd:
3579 case SpvOpSelect:
3580 case SpvOpIEqual:
3581 case SpvOpFOrdEqual:
3582 case SpvOpFUnordEqual:
3583 case SpvOpINotEqual:
3584 case SpvOpFOrdNotEqual:
3585 case SpvOpFUnordNotEqual:
3586 case SpvOpULessThan:
3587 case SpvOpSLessThan:
3588 case SpvOpFOrdLessThan:
3589 case SpvOpFUnordLessThan:
3590 case SpvOpUGreaterThan:
3591 case SpvOpSGreaterThan:
3592 case SpvOpFOrdGreaterThan:
3593 case SpvOpFUnordGreaterThan:
3594 case SpvOpULessThanEqual:
3595 case SpvOpSLessThanEqual:
3596 case SpvOpFOrdLessThanEqual:
3597 case SpvOpFUnordLessThanEqual:
3598 case SpvOpUGreaterThanEqual:
3599 case SpvOpSGreaterThanEqual:
3600 case SpvOpFOrdGreaterThanEqual:
3601 case SpvOpFUnordGreaterThanEqual:
3602 case SpvOpDPdx:
3603 case SpvOpDPdy:
3604 case SpvOpFwidth:
3605 case SpvOpDPdxFine:
3606 case SpvOpDPdyFine:
3607 case SpvOpFwidthFine:
3608 case SpvOpDPdxCoarse:
3609 case SpvOpDPdyCoarse:
3610 case SpvOpFwidthCoarse:
3611 vtn_handle_alu(b, opcode, w, count);
3612 break;
3613
3614 case SpvOpTranspose:
3615 case SpvOpOuterProduct:
3616 case SpvOpMatrixTimesScalar:
3617 case SpvOpVectorTimesMatrix:
3618 case SpvOpMatrixTimesVector:
3619 case SpvOpMatrixTimesMatrix:
3620 vtn_handle_matrix_alu(b, opcode, w, count);
3621 break;
3622
3623 case SpvOpVectorExtractDynamic:
3624 case SpvOpVectorInsertDynamic:
3625 case SpvOpVectorShuffle:
3626 case SpvOpCompositeConstruct:
3627 case SpvOpCompositeExtract:
3628 case SpvOpCompositeInsert:
3629 case SpvOpCopyObject:
3630 vtn_handle_composite(b, opcode, w, count);
3631 break;
3632
3633 case SpvOpPhi:
3634 vtn_handle_phi_first_pass(b, w);
3635 break;
3636
3637 case SpvOpEmitVertex:
3638 case SpvOpEndPrimitive:
3639 case SpvOpEmitStreamVertex:
3640 case SpvOpEndStreamPrimitive:
3641 case SpvOpControlBarrier:
3642 case SpvOpMemoryBarrier:
3643 vtn_handle_barrier(b, opcode, w, count);
3644 break;
3645
3646 default:
3647 unreachable("Unhandled opcode");
3648 }
3649
3650 return true;
3651 }
3652
3653 static gl_shader_stage
3654 stage_for_execution_model(SpvExecutionModel model)
3655 {
3656 switch (model) {
3657 case SpvExecutionModelVertex:
3658 return MESA_SHADER_VERTEX;
3659 case SpvExecutionModelTessellationControl:
3660 return MESA_SHADER_TESS_CTRL;
3661 case SpvExecutionModelTessellationEvaluation:
3662 return MESA_SHADER_TESS_EVAL;
3663 case SpvExecutionModelGeometry:
3664 return MESA_SHADER_GEOMETRY;
3665 case SpvExecutionModelFragment:
3666 return MESA_SHADER_FRAGMENT;
3667 case SpvExecutionModelGLCompute:
3668 return MESA_SHADER_COMPUTE;
3669 default:
3670 unreachable("Unsupported execution model");
3671 }
3672 }
3673
3674 nir_function *
3675 spirv_to_nir(const uint32_t *words, size_t word_count,
3676 const char *entry_point_name,
3677 const nir_shader_compiler_options *options)
3678 {
3679 const uint32_t *word_end = words + word_count;
3680
3681 /* Handle the SPIR-V header (first 4 dwords) */
3682 assert(word_count > 5);
3683
3684 assert(words[0] == SpvMagicNumber);
3685 assert(words[1] >= 0x10000);
3686 /* words[2] == generator magic */
3687 unsigned value_id_bound = words[3];
3688 assert(words[4] == 0);
3689
3690 words+= 5;
3691
3692 /* Initialize the stn_builder object */
3693 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
3694 b->value_id_bound = value_id_bound;
3695 b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
3696 exec_list_make_empty(&b->functions);
3697 b->entry_point_name = entry_point_name;
3698
3699 /* Handle all the preamble instructions */
3700 words = vtn_foreach_instruction(b, words, word_end,
3701 vtn_handle_preamble_instruction);
3702
3703 if (b->entry_point == NULL) {
3704 assert(!"Entry point not found");
3705 ralloc_free(b);
3706 return NULL;
3707 }
3708
3709 gl_shader_stage stage = stage_for_execution_model(b->execution_model);
3710 b->shader = nir_shader_create(NULL, stage, options);
3711
3712 /* Parse execution modes */
3713 vtn_foreach_execution_mode(b, b->entry_point,
3714 vtn_handle_execution_mode, NULL);
3715
3716 /* Handle all variable, type, and constant instructions */
3717 words = vtn_foreach_instruction(b, words, word_end,
3718 vtn_handle_variable_or_type_instruction);
3719
3720 vtn_build_cfg(b, words, word_end);
3721
3722 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
3723 b->impl = func->impl;
3724 b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
3725 _mesa_key_pointer_equal);
3726 b->block_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
3727 _mesa_key_pointer_equal);
3728 vtn_function_emit(b, func, vtn_handle_body_instruction);
3729 vtn_foreach_instruction(b, func->start_block->label, func->end,
3730 vtn_handle_phi_second_pass);
3731 }
3732
3733 assert(b->entry_point->value_type == vtn_value_type_function);
3734 nir_function *entry_point = b->entry_point->func->impl->function;
3735 assert(entry_point);
3736
3737 ralloc_free(b);
3738
3739 /* Because we can still have output reads in NIR, we need to lower
3740 * outputs to temporaries before we are truely finished.
3741 */
3742 nir_lower_outputs_to_temporaries(entry_point->shader, entry_point);
3743
3744 return entry_point;
3745 }