Merge branch 'wip/nir-vtn' into vulkan
[mesa.git] / src / glsl / nir / 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 "spirv_to_nir_private.h"
29 #include "nir_vla.h"
30
31 static struct vtn_ssa_value *
32 vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
33 const struct glsl_type *type)
34 {
35 struct hash_entry *entry = _mesa_hash_table_search(b->const_table, constant);
36
37 if (entry)
38 return entry->data;
39
40 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
41 val->type = type;
42
43 switch (glsl_get_base_type(type)) {
44 case GLSL_TYPE_INT:
45 case GLSL_TYPE_UINT:
46 case GLSL_TYPE_BOOL:
47 case GLSL_TYPE_FLOAT:
48 case GLSL_TYPE_DOUBLE:
49 if (glsl_type_is_vector_or_scalar(type)) {
50 unsigned num_components = glsl_get_vector_elements(val->type);
51 nir_load_const_instr *load =
52 nir_load_const_instr_create(b->shader, num_components);
53
54 for (unsigned i = 0; i < num_components; i++)
55 load->value.u[i] = constant->value.u[i];
56
57 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
58 val->def = &load->def;
59 } else {
60 assert(glsl_type_is_matrix(type));
61 unsigned rows = glsl_get_vector_elements(val->type);
62 unsigned columns = glsl_get_matrix_columns(val->type);
63 val->elems = ralloc_array(b, struct vtn_ssa_value *, columns);
64
65 for (unsigned i = 0; i < columns; i++) {
66 struct vtn_ssa_value *col_val = rzalloc(b, struct vtn_ssa_value);
67 col_val->type = glsl_get_column_type(val->type);
68 nir_load_const_instr *load =
69 nir_load_const_instr_create(b->shader, rows);
70
71 for (unsigned j = 0; j < rows; j++)
72 load->value.u[j] = constant->value.u[rows * i + j];
73
74 nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
75 col_val->def = &load->def;
76
77 val->elems[i] = col_val;
78 }
79 }
80 break;
81
82 case GLSL_TYPE_ARRAY: {
83 unsigned elems = glsl_get_length(val->type);
84 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
85 const struct glsl_type *elem_type = glsl_get_array_element(val->type);
86 for (unsigned i = 0; i < elems; i++)
87 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
88 elem_type);
89 break;
90 }
91
92 case GLSL_TYPE_STRUCT: {
93 unsigned elems = glsl_get_length(val->type);
94 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
95 for (unsigned i = 0; i < elems; i++) {
96 const struct glsl_type *elem_type =
97 glsl_get_struct_field(val->type, i);
98 val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
99 elem_type);
100 }
101 break;
102 }
103
104 default:
105 unreachable("bad constant type");
106 }
107
108 return val;
109 }
110
111 struct vtn_ssa_value *
112 vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
113 {
114 struct vtn_value *val = vtn_untyped_value(b, value_id);
115 switch (val->value_type) {
116 case vtn_value_type_constant:
117 return vtn_const_ssa_value(b, val->constant, val->type);
118
119 case vtn_value_type_ssa:
120 return val->ssa;
121 default:
122 unreachable("Invalid type for an SSA value");
123 }
124 }
125
126 static char *
127 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
128 unsigned word_count)
129 {
130 return ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
131 }
132
133 static const uint32_t *
134 vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
135 const uint32_t *end, vtn_instruction_handler handler)
136 {
137 const uint32_t *w = start;
138 while (w < end) {
139 SpvOp opcode = w[0] & SpvOpCodeMask;
140 unsigned count = w[0] >> SpvWordCountShift;
141 assert(count >= 1 && w + count <= end);
142
143 if (!handler(b, opcode, w, count))
144 return w;
145
146 w += count;
147 }
148 assert(w == end);
149 return w;
150 }
151
152 static void
153 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
154 const uint32_t *w, unsigned count)
155 {
156 switch (opcode) {
157 case SpvOpExtInstImport: {
158 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
159 if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) {
160 val->ext_handler = vtn_handle_glsl450_instruction;
161 } else {
162 assert(!"Unsupported extension");
163 }
164 break;
165 }
166
167 case SpvOpExtInst: {
168 struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
169 bool handled = val->ext_handler(b, w[4], w, count);
170 (void)handled;
171 assert(handled);
172 break;
173 }
174
175 default:
176 unreachable("Unhandled opcode");
177 }
178 }
179
180 static void
181 _foreach_decoration_helper(struct vtn_builder *b,
182 struct vtn_value *base_value,
183 struct vtn_value *value,
184 vtn_decoration_foreach_cb cb, void *data)
185 {
186 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
187 if (dec->group) {
188 assert(dec->group->value_type == vtn_value_type_decoration_group);
189 _foreach_decoration_helper(b, base_value, dec->group, cb, data);
190 } else {
191 cb(b, base_value, dec, data);
192 }
193 }
194 }
195
196 /** Iterates (recursively if needed) over all of the decorations on a value
197 *
198 * This function iterates over all of the decorations applied to a given
199 * value. If it encounters a decoration group, it recurses into the group
200 * and iterates over all of those decorations as well.
201 */
202 void
203 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
204 vtn_decoration_foreach_cb cb, void *data)
205 {
206 _foreach_decoration_helper(b, value, value, cb, data);
207 }
208
209 static void
210 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
211 const uint32_t *w, unsigned count)
212 {
213 switch (opcode) {
214 case SpvOpDecorationGroup:
215 vtn_push_value(b, w[1], vtn_value_type_undef);
216 break;
217
218 case SpvOpDecorate: {
219 struct vtn_value *val = &b->values[w[1]];
220
221 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
222 dec->decoration = w[2];
223 dec->literals = &w[3];
224
225 /* Link into the list */
226 dec->next = val->decoration;
227 val->decoration = dec;
228 break;
229 }
230
231 case SpvOpGroupDecorate: {
232 struct vtn_value *group = &b->values[w[1]];
233 assert(group->value_type == vtn_value_type_decoration_group);
234
235 for (unsigned i = 2; i < count; i++) {
236 struct vtn_value *val = &b->values[w[i]];
237 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
238 dec->group = group;
239
240 /* Link into the list */
241 dec->next = val->decoration;
242 val->decoration = dec;
243 }
244 break;
245 }
246
247 case SpvOpGroupMemberDecorate:
248 assert(!"Bad instruction. Khronos Bug #13513");
249 break;
250
251 default:
252 unreachable("Unhandled opcode");
253 }
254 }
255
256 static const struct glsl_type *
257 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
258 const uint32_t *args, unsigned count)
259 {
260 switch (opcode) {
261 case SpvOpTypeVoid:
262 return glsl_void_type();
263 case SpvOpTypeBool:
264 return glsl_bool_type();
265 case SpvOpTypeInt:
266 return glsl_int_type();
267 case SpvOpTypeFloat:
268 return glsl_float_type();
269
270 case SpvOpTypeVector: {
271 const struct glsl_type *base =
272 vtn_value(b, args[0], vtn_value_type_type)->type;
273 unsigned elems = args[1];
274
275 assert(glsl_type_is_scalar(base));
276 return glsl_vector_type(glsl_get_base_type(base), elems);
277 }
278
279 case SpvOpTypeMatrix: {
280 const struct glsl_type *base =
281 vtn_value(b, args[0], vtn_value_type_type)->type;
282 unsigned columns = args[1];
283
284 assert(glsl_type_is_vector(base));
285 return glsl_matrix_type(glsl_get_base_type(base),
286 glsl_get_vector_elements(base),
287 columns);
288 }
289
290 case SpvOpTypeArray:
291 return glsl_array_type(b->values[args[0]].type, args[1]);
292
293 case SpvOpTypeStruct: {
294 NIR_VLA(struct glsl_struct_field, fields, count);
295 for (unsigned i = 0; i < count; i++) {
296 /* TODO: Handle decorators */
297 fields[i].type = vtn_value(b, args[i], vtn_value_type_type)->type;
298 fields[i].name = ralloc_asprintf(b, "field%d", i);
299 fields[i].location = -1;
300 fields[i].interpolation = 0;
301 fields[i].centroid = 0;
302 fields[i].sample = 0;
303 fields[i].matrix_layout = 2;
304 fields[i].stream = -1;
305 }
306 return glsl_struct_type(fields, count, "struct");
307 }
308
309 case SpvOpTypeFunction: {
310 const struct glsl_type *return_type = b->values[args[0]].type;
311 NIR_VLA(struct glsl_function_param, params, count - 1);
312 for (unsigned i = 1; i < count; i++) {
313 params[i - 1].type = vtn_value(b, args[i], vtn_value_type_type)->type;
314
315 /* FIXME: */
316 params[i - 1].in = true;
317 params[i - 1].out = true;
318 }
319 return glsl_function_type(return_type, params, count - 1);
320 }
321
322 case SpvOpTypePointer:
323 /* FIXME: For now, we'll just do the really lame thing and return
324 * the same type. The validator should ensure that the proper number
325 * of dereferences happen
326 */
327 return vtn_value(b, args[1], vtn_value_type_type)->type;
328
329 case SpvOpTypeSampler: {
330 const struct glsl_type *sampled_type =
331 vtn_value(b, args[0], vtn_value_type_type)->type;
332
333 assert(glsl_type_is_vector_or_scalar(sampled_type));
334
335 enum glsl_sampler_dim dim;
336 switch ((SpvDim)args[1]) {
337 case SpvDim1D: dim = GLSL_SAMPLER_DIM_1D; break;
338 case SpvDim2D: dim = GLSL_SAMPLER_DIM_2D; break;
339 case SpvDim3D: dim = GLSL_SAMPLER_DIM_3D; break;
340 case SpvDimCube: dim = GLSL_SAMPLER_DIM_CUBE; break;
341 case SpvDimRect: dim = GLSL_SAMPLER_DIM_RECT; break;
342 case SpvDimBuffer: dim = GLSL_SAMPLER_DIM_BUF; break;
343 default:
344 unreachable("Invalid SPIR-V Sampler dimension");
345 }
346
347 /* TODO: Handle the various texture image/filter options */
348 (void)args[2];
349
350 bool is_array = args[3];
351 bool is_shadow = args[4];
352
353 assert(args[5] == 0 && "FIXME: Handl multi-sampled textures");
354
355 return glsl_sampler_type(dim, is_shadow, is_array,
356 glsl_get_base_type(sampled_type));
357 }
358
359 case SpvOpTypeRuntimeArray:
360 case SpvOpTypeOpaque:
361 case SpvOpTypeEvent:
362 case SpvOpTypeDeviceEvent:
363 case SpvOpTypeReserveId:
364 case SpvOpTypeQueue:
365 case SpvOpTypePipe:
366 default:
367 unreachable("Unhandled opcode");
368 }
369 }
370
371 static void
372 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
373 const uint32_t *w, unsigned count)
374 {
375 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
376 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
377 val->constant = ralloc(b, nir_constant);
378 switch (opcode) {
379 case SpvOpConstantTrue:
380 assert(val->type == glsl_bool_type());
381 val->constant->value.u[0] = NIR_TRUE;
382 break;
383 case SpvOpConstantFalse:
384 assert(val->type == glsl_bool_type());
385 val->constant->value.u[0] = NIR_FALSE;
386 break;
387 case SpvOpConstant:
388 assert(glsl_type_is_scalar(val->type));
389 val->constant->value.u[0] = w[3];
390 break;
391 case SpvOpConstantComposite: {
392 unsigned elem_count = count - 3;
393 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
394 for (unsigned i = 0; i < elem_count; i++)
395 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
396
397 switch (glsl_get_base_type(val->type)) {
398 case GLSL_TYPE_UINT:
399 case GLSL_TYPE_INT:
400 case GLSL_TYPE_FLOAT:
401 case GLSL_TYPE_BOOL:
402 if (glsl_type_is_matrix(val->type)) {
403 unsigned rows = glsl_get_vector_elements(val->type);
404 assert(glsl_get_matrix_columns(val->type) == elem_count);
405 for (unsigned i = 0; i < elem_count; i++)
406 for (unsigned j = 0; j < rows; j++)
407 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
408 } else {
409 assert(glsl_type_is_vector(val->type));
410 assert(glsl_get_vector_elements(val->type) == elem_count);
411 for (unsigned i = 0; i < elem_count; i++)
412 val->constant->value.u[i] = elems[i]->value.u[0];
413 }
414 ralloc_free(elems);
415 break;
416
417 case GLSL_TYPE_STRUCT:
418 case GLSL_TYPE_ARRAY:
419 ralloc_steal(val->constant, elems);
420 val->constant->elements = elems;
421 break;
422
423 default:
424 unreachable("Unsupported type for constants");
425 }
426 break;
427 }
428
429 default:
430 unreachable("Unhandled opcode");
431 }
432 }
433
434 static void
435 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
436 const struct vtn_decoration *dec, void *void_var)
437 {
438 assert(val->value_type == vtn_value_type_deref);
439 assert(val->deref->deref.child == NULL);
440 assert(val->deref->var == void_var);
441
442 nir_variable *var = void_var;
443 switch (dec->decoration) {
444 case SpvDecorationPrecisionLow:
445 case SpvDecorationPrecisionMedium:
446 case SpvDecorationPrecisionHigh:
447 break; /* FIXME: Do nothing with these for now. */
448 case SpvDecorationSmooth:
449 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
450 break;
451 case SpvDecorationNoperspective:
452 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
453 break;
454 case SpvDecorationFlat:
455 var->data.interpolation = INTERP_QUALIFIER_FLAT;
456 break;
457 case SpvDecorationCentroid:
458 var->data.centroid = true;
459 break;
460 case SpvDecorationSample:
461 var->data.sample = true;
462 break;
463 case SpvDecorationInvariant:
464 var->data.invariant = true;
465 break;
466 case SpvDecorationConstant:
467 assert(var->constant_initializer != NULL);
468 var->data.read_only = true;
469 break;
470 case SpvDecorationNonwritable:
471 var->data.read_only = true;
472 break;
473 case SpvDecorationLocation:
474 var->data.explicit_location = true;
475 var->data.location = dec->literals[0];
476 break;
477 case SpvDecorationComponent:
478 var->data.location_frac = dec->literals[0];
479 break;
480 case SpvDecorationIndex:
481 var->data.explicit_index = true;
482 var->data.index = dec->literals[0];
483 break;
484 case SpvDecorationBinding:
485 var->data.explicit_binding = true;
486 var->data.binding = dec->literals[0];
487 break;
488 case SpvDecorationDescriptorSet:
489 var->data.descriptor_set = dec->literals[0];
490 break;
491 case SpvDecorationBuiltIn:
492 var->data.mode = nir_var_system_value;
493 var->data.read_only = true;
494 switch ((SpvBuiltIn)dec->literals[0]) {
495 case SpvBuiltInFrontFacing:
496 var->data.location = SYSTEM_VALUE_FRONT_FACE;
497 break;
498 case SpvBuiltInVertexId:
499 var->data.location = SYSTEM_VALUE_VERTEX_ID;
500 break;
501 case SpvBuiltInInstanceId:
502 var->data.location = SYSTEM_VALUE_INSTANCE_ID;
503 break;
504 case SpvBuiltInSampleId:
505 var->data.location = SYSTEM_VALUE_SAMPLE_ID;
506 break;
507 case SpvBuiltInSamplePosition:
508 var->data.location = SYSTEM_VALUE_SAMPLE_POS;
509 break;
510 case SpvBuiltInSampleMask:
511 var->data.location = SYSTEM_VALUE_SAMPLE_MASK_IN;
512 break;
513 case SpvBuiltInInvocationId:
514 var->data.location = SYSTEM_VALUE_INVOCATION_ID;
515 break;
516 case SpvBuiltInPrimitiveId:
517 case SpvBuiltInPosition:
518 case SpvBuiltInPointSize:
519 case SpvBuiltInClipVertex:
520 case SpvBuiltInClipDistance:
521 case SpvBuiltInCullDistance:
522 case SpvBuiltInLayer:
523 case SpvBuiltInViewportIndex:
524 case SpvBuiltInTessLevelOuter:
525 case SpvBuiltInTessLevelInner:
526 case SpvBuiltInTessCoord:
527 case SpvBuiltInPatchVertices:
528 case SpvBuiltInFragCoord:
529 case SpvBuiltInPointCoord:
530 case SpvBuiltInFragColor:
531 case SpvBuiltInFragDepth:
532 case SpvBuiltInHelperInvocation:
533 case SpvBuiltInNumWorkgroups:
534 case SpvBuiltInWorkgroupSize:
535 case SpvBuiltInWorkgroupId:
536 case SpvBuiltInLocalInvocationId:
537 case SpvBuiltInGlobalInvocationId:
538 case SpvBuiltInLocalInvocationIndex:
539 case SpvBuiltInWorkDim:
540 case SpvBuiltInGlobalSize:
541 case SpvBuiltInEnqueuedWorkgroupSize:
542 case SpvBuiltInGlobalOffset:
543 case SpvBuiltInGlobalLinearId:
544 case SpvBuiltInWorkgroupLinearId:
545 case SpvBuiltInSubgroupSize:
546 case SpvBuiltInSubgroupMaxSize:
547 case SpvBuiltInNumSubgroups:
548 case SpvBuiltInNumEnqueuedSubgroups:
549 case SpvBuiltInSubgroupId:
550 case SpvBuiltInSubgroupLocalInvocationId:
551 unreachable("Unhandled builtin enum");
552 }
553 break;
554 case SpvDecorationNoStaticUse:
555 /* This can safely be ignored */
556 break;
557 case SpvDecorationBlock:
558 case SpvDecorationBufferBlock:
559 case SpvDecorationRowMajor:
560 case SpvDecorationColMajor:
561 case SpvDecorationGLSLShared:
562 case SpvDecorationGLSLStd140:
563 case SpvDecorationGLSLStd430:
564 case SpvDecorationGLSLPacked:
565 case SpvDecorationPatch:
566 case SpvDecorationRestrict:
567 case SpvDecorationAliased:
568 case SpvDecorationVolatile:
569 case SpvDecorationCoherent:
570 case SpvDecorationNonreadable:
571 case SpvDecorationUniform:
572 /* This is really nice but we have no use for it right now. */
573 case SpvDecorationCPacked:
574 case SpvDecorationSaturatedConversion:
575 case SpvDecorationStream:
576 case SpvDecorationOffset:
577 case SpvDecorationAlignment:
578 case SpvDecorationXfbBuffer:
579 case SpvDecorationStride:
580 case SpvDecorationFuncParamAttr:
581 case SpvDecorationFPRoundingMode:
582 case SpvDecorationFPFastMathMode:
583 case SpvDecorationLinkageAttributes:
584 case SpvDecorationSpecId:
585 break;
586 default:
587 unreachable("Unhandled variable decoration");
588 }
589 }
590
591 static struct vtn_ssa_value *
592 _vtn_variable_load(struct vtn_builder *b,
593 nir_deref_var *src_deref, nir_deref *src_deref_tail)
594 {
595 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
596 val->type = src_deref_tail->type;
597
598 /* The deref tail may contain a deref to select a component of a vector (in
599 * other words, it might not be an actual tail) so we have to save it away
600 * here since we overwrite it later.
601 */
602 nir_deref *old_child = src_deref_tail->child;
603
604 if (glsl_type_is_vector_or_scalar(val->type)) {
605 nir_intrinsic_instr *load =
606 nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
607 load->variables[0] =
608 nir_deref_as_var(nir_copy_deref(load, &src_deref->deref));
609 load->num_components = glsl_get_vector_elements(val->type);
610 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, NULL);
611
612 nir_builder_instr_insert(&b->nb, &load->instr);
613
614 if (src_deref->var->data.mode == nir_var_uniform &&
615 glsl_get_base_type(val->type) == GLSL_TYPE_BOOL) {
616 /* Uniform boolean loads need to be fixed up since they're defined
617 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
618 */
619 val->def = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
620 } else {
621 val->def = &load->dest.ssa;
622 }
623 } else if (glsl_get_base_type(val->type) == GLSL_TYPE_ARRAY ||
624 glsl_type_is_matrix(val->type)) {
625 unsigned elems = glsl_get_length(val->type);
626 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
627
628 nir_deref_array *deref = nir_deref_array_create(b);
629 deref->deref_array_type = nir_deref_array_type_direct;
630 deref->deref.type = glsl_get_array_element(val->type);
631 src_deref_tail->child = &deref->deref;
632 for (unsigned i = 0; i < elems; i++) {
633 deref->base_offset = i;
634 val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
635 }
636 } else {
637 assert(glsl_get_base_type(val->type) == GLSL_TYPE_STRUCT);
638 unsigned elems = glsl_get_length(val->type);
639 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
640
641 nir_deref_struct *deref = nir_deref_struct_create(b, 0);
642 src_deref_tail->child = &deref->deref;
643 for (unsigned i = 0; i < elems; i++) {
644 deref->index = i;
645 deref->deref.type = glsl_get_struct_field(val->type, i);
646 val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
647 }
648 }
649
650 src_deref_tail->child = old_child;
651
652 return val;
653 }
654
655 static void
656 _vtn_variable_store(struct vtn_builder *b, nir_deref_var *dest_deref,
657 nir_deref *dest_deref_tail, struct vtn_ssa_value *src)
658 {
659 nir_deref *old_child = dest_deref_tail->child;
660
661 if (glsl_type_is_vector_or_scalar(src->type)) {
662 nir_intrinsic_instr *store =
663 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
664 store->variables[0] =
665 nir_deref_as_var(nir_copy_deref(store, &dest_deref->deref));
666 store->src[0] = nir_src_for_ssa(src->def);
667
668 nir_builder_instr_insert(&b->nb, &store->instr);
669 } else if (glsl_get_base_type(src->type) == GLSL_TYPE_ARRAY ||
670 glsl_type_is_matrix(src->type)) {
671 unsigned elems = glsl_get_length(src->type);
672
673 nir_deref_array *deref = nir_deref_array_create(b);
674 deref->deref_array_type = nir_deref_array_type_direct;
675 deref->deref.type = glsl_get_array_element(src->type);
676 dest_deref_tail->child = &deref->deref;
677 for (unsigned i = 0; i < elems; i++) {
678 deref->base_offset = i;
679 _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
680 }
681 } else {
682 assert(glsl_get_base_type(src->type) == GLSL_TYPE_STRUCT);
683 unsigned elems = glsl_get_length(src->type);
684
685 nir_deref_struct *deref = nir_deref_struct_create(b, 0);
686 dest_deref_tail->child = &deref->deref;
687 for (unsigned i = 0; i < elems; i++) {
688 deref->index = i;
689 deref->deref.type = glsl_get_struct_field(src->type, i);
690 _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
691 }
692 }
693
694 dest_deref_tail->child = old_child;
695 }
696
697 /*
698 * Gets the NIR-level deref tail, which may have as a child an array deref
699 * selecting which component due to OpAccessChain supporting per-component
700 * indexing in SPIR-V.
701 */
702
703 static nir_deref *
704 get_deref_tail(nir_deref_var *deref)
705 {
706 nir_deref *cur = &deref->deref;
707 while (!glsl_type_is_vector_or_scalar(cur->type) && cur->child)
708 cur = cur->child;
709
710 return cur;
711 }
712
713 static nir_ssa_def *vtn_vector_extract(struct vtn_builder *b,
714 nir_ssa_def *src, unsigned index);
715
716 static nir_ssa_def *vtn_vector_extract_dynamic(struct vtn_builder *b,
717 nir_ssa_def *src,
718 nir_ssa_def *index);
719
720 static struct vtn_ssa_value *
721 vtn_variable_load(struct vtn_builder *b, nir_deref_var *src)
722 {
723 nir_deref *src_tail = get_deref_tail(src);
724 struct vtn_ssa_value *val = _vtn_variable_load(b, src, src_tail);
725
726 if (src_tail->child) {
727 nir_deref_array *vec_deref = nir_deref_as_array(src_tail->child);
728 assert(vec_deref->deref.child == NULL);
729 val->type = vec_deref->deref.type;
730 if (vec_deref->deref_array_type == nir_deref_array_type_direct)
731 val->def = vtn_vector_extract(b, val->def, vec_deref->base_offset);
732 else
733 val->def = vtn_vector_extract_dynamic(b, val->def,
734 vec_deref->indirect.ssa);
735 }
736
737 return val;
738 }
739
740 static nir_ssa_def * vtn_vector_insert(struct vtn_builder *b,
741 nir_ssa_def *src, nir_ssa_def *insert,
742 unsigned index);
743
744 static nir_ssa_def * vtn_vector_insert_dynamic(struct vtn_builder *b,
745 nir_ssa_def *src,
746 nir_ssa_def *insert,
747 nir_ssa_def *index);
748 static void
749 vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
750 nir_deref_var *dest)
751 {
752 nir_deref *dest_tail = get_deref_tail(dest);
753 if (dest_tail->child) {
754 struct vtn_ssa_value *val = _vtn_variable_load(b, dest, dest_tail);
755 nir_deref_array *deref = nir_deref_as_array(dest_tail->child);
756 assert(deref->deref.child == NULL);
757 if (deref->deref_array_type == nir_deref_array_type_direct)
758 val->def = vtn_vector_insert(b, val->def, src->def,
759 deref->base_offset);
760 else
761 val->def = vtn_vector_insert_dynamic(b, val->def, src->def,
762 deref->indirect.ssa);
763 _vtn_variable_store(b, dest, dest_tail, val);
764 } else {
765 _vtn_variable_store(b, dest, dest_tail, src);
766 }
767 }
768
769 static void
770 vtn_variable_copy(struct vtn_builder *b, nir_deref_var *src,
771 nir_deref_var *dest)
772 {
773 nir_deref *src_tail = get_deref_tail(src);
774
775 if (src_tail->child) {
776 assert(get_deref_tail(dest)->child);
777 struct vtn_ssa_value *val = vtn_variable_load(b, src);
778 vtn_variable_store(b, val, dest);
779 } else {
780 nir_intrinsic_instr *copy =
781 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
782 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
783 copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
784
785 nir_builder_instr_insert(&b->nb, &copy->instr);
786 }
787 }
788
789 static void
790 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
791 const uint32_t *w, unsigned count)
792 {
793 switch (opcode) {
794 case SpvOpVariable: {
795 const struct glsl_type *type =
796 vtn_value(b, w[1], vtn_value_type_type)->type;
797 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
798
799 nir_variable *var = ralloc(b->shader, nir_variable);
800
801 var->type = type;
802 var->name = ralloc_strdup(var, val->name);
803
804 switch ((SpvStorageClass)w[3]) {
805 case SpvStorageClassUniform:
806 case SpvStorageClassUniformConstant:
807 var->data.mode = nir_var_uniform;
808 var->data.read_only = true;
809 var->interface_type = type;
810 break;
811 case SpvStorageClassInput:
812 var->data.mode = nir_var_shader_in;
813 var->data.read_only = true;
814 break;
815 case SpvStorageClassOutput:
816 var->data.mode = nir_var_shader_out;
817 break;
818 case SpvStorageClassPrivateGlobal:
819 var->data.mode = nir_var_global;
820 break;
821 case SpvStorageClassFunction:
822 var->data.mode = nir_var_local;
823 break;
824 case SpvStorageClassWorkgroupLocal:
825 case SpvStorageClassWorkgroupGlobal:
826 case SpvStorageClassGeneric:
827 case SpvStorageClassPrivate:
828 case SpvStorageClassAtomicCounter:
829 default:
830 unreachable("Unhandled variable storage class");
831 }
832
833 if (count > 4) {
834 assert(count == 5);
835 var->constant_initializer =
836 vtn_value(b, w[4], vtn_value_type_constant)->constant;
837 }
838
839 val->deref = nir_deref_var_create(b, var);
840
841 vtn_foreach_decoration(b, val, var_decoration_cb, var);
842
843 if (b->execution_model == SpvExecutionModelFragment &&
844 var->data.mode == nir_var_shader_out) {
845 var->data.location += FRAG_RESULT_DATA0;
846 } else if (b->execution_model == SpvExecutionModelVertex &&
847 var->data.mode == nir_var_shader_in) {
848 var->data.location += VERT_ATTRIB_GENERIC0;
849 } else if (var->data.mode == nir_var_shader_in ||
850 var->data.mode == nir_var_shader_out) {
851 var->data.location += VARYING_SLOT_VAR0;
852 }
853
854 switch (var->data.mode) {
855 case nir_var_shader_in:
856 exec_list_push_tail(&b->shader->inputs, &var->node);
857 break;
858 case nir_var_shader_out:
859 exec_list_push_tail(&b->shader->outputs, &var->node);
860 break;
861 case nir_var_global:
862 exec_list_push_tail(&b->shader->globals, &var->node);
863 break;
864 case nir_var_local:
865 exec_list_push_tail(&b->impl->locals, &var->node);
866 break;
867 case nir_var_uniform:
868 exec_list_push_tail(&b->shader->uniforms, &var->node);
869 break;
870 case nir_var_system_value:
871 exec_list_push_tail(&b->shader->system_values, &var->node);
872 break;
873 }
874 break;
875 }
876
877 case SpvOpAccessChain:
878 case SpvOpInBoundsAccessChain: {
879 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
880 nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
881 val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
882
883 nir_deref *tail = &val->deref->deref;
884 while (tail->child)
885 tail = tail->child;
886
887 for (unsigned i = 0; i < count - 4; i++) {
888 assert(w[i + 4] < b->value_id_bound);
889 struct vtn_value *idx_val = &b->values[w[i + 4]];
890
891 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
892 switch (base_type) {
893 case GLSL_TYPE_UINT:
894 case GLSL_TYPE_INT:
895 case GLSL_TYPE_FLOAT:
896 case GLSL_TYPE_DOUBLE:
897 case GLSL_TYPE_BOOL:
898 case GLSL_TYPE_ARRAY: {
899 nir_deref_array *deref_arr = nir_deref_array_create(b);
900 if (base_type == GLSL_TYPE_ARRAY) {
901 deref_arr->deref.type = glsl_get_array_element(tail->type);
902 } else if (glsl_type_is_matrix(tail->type)) {
903 deref_arr->deref.type = glsl_get_column_type(tail->type);
904 } else {
905 assert(glsl_type_is_vector(tail->type));
906 deref_arr->deref.type = glsl_scalar_type(base_type);
907 }
908
909 if (idx_val->value_type == vtn_value_type_constant) {
910 unsigned idx = idx_val->constant->value.u[0];
911 deref_arr->deref_array_type = nir_deref_array_type_direct;
912 deref_arr->base_offset = idx;
913 } else {
914 assert(idx_val->value_type == vtn_value_type_ssa);
915 deref_arr->deref_array_type = nir_deref_array_type_indirect;
916 deref_arr->base_offset = 0;
917 deref_arr->indirect =
918 nir_src_for_ssa(vtn_ssa_value(b, w[1])->def);
919 }
920 tail->child = &deref_arr->deref;
921 break;
922 }
923
924 case GLSL_TYPE_STRUCT: {
925 assert(idx_val->value_type == vtn_value_type_constant);
926 unsigned idx = idx_val->constant->value.u[0];
927 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
928 deref_struct->deref.type = glsl_get_struct_field(tail->type, idx);
929 tail->child = &deref_struct->deref;
930 break;
931 }
932 default:
933 unreachable("Invalid type for deref");
934 }
935 tail = tail->child;
936 }
937 break;
938 }
939
940 case SpvOpCopyMemory: {
941 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
942 nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
943
944 vtn_variable_copy(b, src, dest);
945 break;
946 }
947
948 case SpvOpLoad: {
949 nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
950 const struct glsl_type *src_type = nir_deref_tail(&src->deref)->type;
951
952 if (glsl_get_base_type(src_type) == GLSL_TYPE_SAMPLER) {
953 vtn_push_value(b, w[2], vtn_value_type_deref)->deref = src;
954 return;
955 }
956
957 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
958 val->ssa = vtn_variable_load(b, src);
959 break;
960 }
961
962 case SpvOpStore: {
963 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
964 struct vtn_ssa_value *src = vtn_ssa_value(b, w[2]);
965 vtn_variable_store(b, src, dest);
966 break;
967 }
968
969 case SpvOpVariableArray:
970 case SpvOpCopyMemorySized:
971 case SpvOpArrayLength:
972 case SpvOpImagePointer:
973 default:
974 unreachable("Unhandled opcode");
975 }
976 }
977
978 static void
979 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
980 const uint32_t *w, unsigned count)
981 {
982 unreachable("Unhandled opcode");
983 }
984
985 static nir_tex_src
986 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
987 {
988 nir_tex_src src;
989 src.src = nir_src_for_ssa(vtn_value(b, index, vtn_value_type_ssa)->ssa->def);
990 src.src_type = type;
991 return src;
992 }
993
994 static void
995 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
996 const uint32_t *w, unsigned count)
997 {
998 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
999 nir_deref_var *sampler = vtn_value(b, w[3], vtn_value_type_deref)->deref;
1000
1001 nir_tex_src srcs[8]; /* 8 should be enough */
1002 nir_tex_src *p = srcs;
1003
1004 unsigned coord_components = 0;
1005 switch (opcode) {
1006 case SpvOpTextureSample:
1007 case SpvOpTextureSampleDref:
1008 case SpvOpTextureSampleLod:
1009 case SpvOpTextureSampleProj:
1010 case SpvOpTextureSampleGrad:
1011 case SpvOpTextureSampleOffset:
1012 case SpvOpTextureSampleProjLod:
1013 case SpvOpTextureSampleProjGrad:
1014 case SpvOpTextureSampleLodOffset:
1015 case SpvOpTextureSampleProjOffset:
1016 case SpvOpTextureSampleGradOffset:
1017 case SpvOpTextureSampleProjLodOffset:
1018 case SpvOpTextureSampleProjGradOffset:
1019 case SpvOpTextureFetchTexelLod:
1020 case SpvOpTextureFetchTexelOffset:
1021 case SpvOpTextureFetchSample:
1022 case SpvOpTextureFetchTexel:
1023 case SpvOpTextureGather:
1024 case SpvOpTextureGatherOffset:
1025 case SpvOpTextureGatherOffsets:
1026 case SpvOpTextureQueryLod: {
1027 /* All these types have the coordinate as their first real argument */
1028 struct vtn_ssa_value *coord = vtn_ssa_value(b, w[4]);
1029 coord_components = glsl_get_vector_elements(coord->type);
1030 p->src = nir_src_for_ssa(coord->def);
1031 p->src_type = nir_tex_src_coord;
1032 p++;
1033 break;
1034 }
1035
1036 default:
1037 break;
1038 }
1039
1040 nir_texop texop;
1041 switch (opcode) {
1042 case SpvOpTextureSample:
1043 texop = nir_texop_tex;
1044
1045 if (count == 6) {
1046 texop = nir_texop_txb;
1047 *p++ = vtn_tex_src(b, w[5], nir_tex_src_bias);
1048 }
1049 break;
1050
1051 case SpvOpTextureSampleDref:
1052 case SpvOpTextureSampleLod:
1053 case SpvOpTextureSampleProj:
1054 case SpvOpTextureSampleGrad:
1055 case SpvOpTextureSampleOffset:
1056 case SpvOpTextureSampleProjLod:
1057 case SpvOpTextureSampleProjGrad:
1058 case SpvOpTextureSampleLodOffset:
1059 case SpvOpTextureSampleProjOffset:
1060 case SpvOpTextureSampleGradOffset:
1061 case SpvOpTextureSampleProjLodOffset:
1062 case SpvOpTextureSampleProjGradOffset:
1063 case SpvOpTextureFetchTexelLod:
1064 case SpvOpTextureFetchTexelOffset:
1065 case SpvOpTextureFetchSample:
1066 case SpvOpTextureFetchTexel:
1067 case SpvOpTextureGather:
1068 case SpvOpTextureGatherOffset:
1069 case SpvOpTextureGatherOffsets:
1070 case SpvOpTextureQuerySizeLod:
1071 case SpvOpTextureQuerySize:
1072 case SpvOpTextureQueryLod:
1073 case SpvOpTextureQueryLevels:
1074 case SpvOpTextureQuerySamples:
1075 default:
1076 unreachable("Unhandled opcode");
1077 }
1078
1079 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
1080
1081 const struct glsl_type *sampler_type = nir_deref_tail(&sampler->deref)->type;
1082 instr->sampler_dim = glsl_get_sampler_dim(sampler_type);
1083
1084 switch (glsl_get_sampler_result_type(sampler_type)) {
1085 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
1086 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
1087 case GLSL_TYPE_UINT: instr->dest_type = nir_type_unsigned; break;
1088 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
1089 default:
1090 unreachable("Invalid base type for sampler result");
1091 }
1092
1093 instr->op = texop;
1094 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
1095 instr->coord_components = coord_components;
1096 instr->is_array = glsl_sampler_type_is_array(sampler_type);
1097 instr->is_shadow = glsl_sampler_type_is_shadow(sampler_type);
1098
1099 instr->sampler = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
1100
1101 nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
1102 val->ssa->def = &instr->dest.ssa;
1103 val->ssa->type = val->type;
1104
1105 nir_builder_instr_insert(&b->nb, &instr->instr);
1106 }
1107
1108 static struct vtn_ssa_value *
1109 vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
1110 {
1111 struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
1112 val->type = type;
1113
1114 if (!glsl_type_is_vector_or_scalar(type)) {
1115 unsigned elems = glsl_get_length(type);
1116 val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1117 for (unsigned i = 0; i < elems; i++) {
1118 const struct glsl_type *child_type;
1119
1120 switch (glsl_get_base_type(type)) {
1121 case GLSL_TYPE_INT:
1122 case GLSL_TYPE_UINT:
1123 case GLSL_TYPE_BOOL:
1124 case GLSL_TYPE_FLOAT:
1125 case GLSL_TYPE_DOUBLE:
1126 child_type = glsl_get_column_type(type);
1127 break;
1128 case GLSL_TYPE_ARRAY:
1129 child_type = glsl_get_array_element(type);
1130 break;
1131 case GLSL_TYPE_STRUCT:
1132 child_type = glsl_get_struct_field(type, i);
1133 break;
1134 default:
1135 unreachable("unkown base type");
1136 }
1137
1138 val->elems[i] = vtn_create_ssa_value(b, child_type);
1139 }
1140 }
1141
1142 return val;
1143 }
1144
1145 static nir_alu_instr *
1146 create_vec(void *mem_ctx, unsigned num_components)
1147 {
1148 nir_op op;
1149 switch (num_components) {
1150 case 1: op = nir_op_fmov; break;
1151 case 2: op = nir_op_vec2; break;
1152 case 3: op = nir_op_vec3; break;
1153 case 4: op = nir_op_vec4; break;
1154 default: unreachable("bad vector size");
1155 }
1156
1157 nir_alu_instr *vec = nir_alu_instr_create(mem_ctx, op);
1158 nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components, NULL);
1159
1160 return vec;
1161 }
1162
1163 static struct vtn_ssa_value *
1164 vtn_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
1165 {
1166 if (src->transposed)
1167 return src->transposed;
1168
1169 struct vtn_ssa_value *dest =
1170 vtn_create_ssa_value(b, glsl_transposed_type(src->type));
1171
1172 for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
1173 nir_alu_instr *vec = create_vec(b, glsl_get_matrix_columns(src->type));
1174 if (glsl_type_is_vector_or_scalar(src->type)) {
1175 vec->src[0].src = nir_src_for_ssa(src->def);
1176 vec->src[0].swizzle[0] = i;
1177 } else {
1178 for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
1179 vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
1180 vec->src[j].swizzle[0] = i;
1181 }
1182 }
1183 nir_builder_instr_insert(&b->nb, &vec->instr);
1184 dest->elems[i]->def = &vec->dest.dest.ssa;
1185 }
1186
1187 dest->transposed = src;
1188
1189 return dest;
1190 }
1191
1192 /*
1193 * Normally, column vectors in SPIR-V correspond to a single NIR SSA
1194 * definition. But for matrix multiplies, we want to do one routine for
1195 * multiplying a matrix by a matrix and then pretend that vectors are matrices
1196 * with one column. So we "wrap" these things, and unwrap the result before we
1197 * send it off.
1198 */
1199
1200 static struct vtn_ssa_value *
1201 vtn_wrap_matrix(struct vtn_builder *b, struct vtn_ssa_value *val)
1202 {
1203 if (val == NULL)
1204 return NULL;
1205
1206 if (glsl_type_is_matrix(val->type))
1207 return val;
1208
1209 struct vtn_ssa_value *dest = rzalloc(b, struct vtn_ssa_value);
1210 dest->type = val->type;
1211 dest->elems = ralloc_array(b, struct vtn_ssa_value *, 1);
1212 dest->elems[0] = val;
1213
1214 return dest;
1215 }
1216
1217 static struct vtn_ssa_value *
1218 vtn_unwrap_matrix(struct vtn_ssa_value *val)
1219 {
1220 if (glsl_type_is_matrix(val->type))
1221 return val;
1222
1223 return val->elems[0];
1224 }
1225
1226 static struct vtn_ssa_value *
1227 vtn_matrix_multiply(struct vtn_builder *b,
1228 struct vtn_ssa_value *_src0, struct vtn_ssa_value *_src1)
1229 {
1230
1231 struct vtn_ssa_value *src0 = vtn_wrap_matrix(b, _src0);
1232 struct vtn_ssa_value *src1 = vtn_wrap_matrix(b, _src1);
1233 struct vtn_ssa_value *src0_transpose = vtn_wrap_matrix(b, _src0->transposed);
1234 struct vtn_ssa_value *src1_transpose = vtn_wrap_matrix(b, _src1->transposed);
1235
1236 unsigned src0_rows = glsl_get_vector_elements(src0->type);
1237 unsigned src0_columns = glsl_get_matrix_columns(src0->type);
1238 unsigned src1_columns = glsl_get_matrix_columns(src1->type);
1239
1240 struct vtn_ssa_value *dest =
1241 vtn_create_ssa_value(b, glsl_matrix_type(glsl_get_base_type(src0->type),
1242 src0_rows, src1_columns));
1243
1244 dest = vtn_wrap_matrix(b, dest);
1245
1246 bool transpose_result = false;
1247 if (src0_transpose && src1_transpose) {
1248 /* transpose(A) * transpose(B) = transpose(B * A) */
1249 src1 = src0_transpose;
1250 src0 = src1_transpose;
1251 src0_transpose = NULL;
1252 src1_transpose = NULL;
1253 transpose_result = true;
1254 }
1255
1256 if (src0_transpose && !src1_transpose &&
1257 glsl_get_base_type(src0->type) == GLSL_TYPE_FLOAT) {
1258 /* We already have the rows of src0 and the columns of src1 available,
1259 * so we can just take the dot product of each row with each column to
1260 * get the result.
1261 */
1262
1263 for (unsigned i = 0; i < src1_columns; i++) {
1264 nir_alu_instr *vec = create_vec(b, src0_rows);
1265 for (unsigned j = 0; j < src0_rows; j++) {
1266 vec->src[j].src =
1267 nir_src_for_ssa(nir_fdot(&b->nb, src0_transpose->elems[j]->def,
1268 src1->elems[i]->def));
1269 }
1270
1271 nir_builder_instr_insert(&b->nb, &vec->instr);
1272 dest->elems[i]->def = &vec->dest.dest.ssa;
1273 }
1274 } else {
1275 /* We don't handle the case where src1 is transposed but not src0, since
1276 * the general case only uses individual components of src1 so the
1277 * optimizer should chew through the transpose we emitted for src1.
1278 */
1279
1280 for (unsigned i = 0; i < src1_columns; i++) {
1281 /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
1282 dest->elems[i]->def =
1283 nir_fmul(&b->nb, src0->elems[0]->def,
1284 vtn_vector_extract(b, src1->elems[i]->def, 0));
1285 for (unsigned j = 1; j < src0_columns; j++) {
1286 dest->elems[i]->def =
1287 nir_fadd(&b->nb, dest->elems[i]->def,
1288 nir_fmul(&b->nb, src0->elems[j]->def,
1289 vtn_vector_extract(b,
1290 src1->elems[i]->def, j)));
1291 }
1292 }
1293 }
1294
1295 dest = vtn_unwrap_matrix(dest);
1296
1297 if (transpose_result)
1298 dest = vtn_transpose(b, dest);
1299
1300 return dest;
1301 }
1302
1303 static struct vtn_ssa_value *
1304 vtn_mat_times_scalar(struct vtn_builder *b,
1305 struct vtn_ssa_value *mat,
1306 nir_ssa_def *scalar)
1307 {
1308 struct vtn_ssa_value *dest = vtn_create_ssa_value(b, mat->type);
1309 for (unsigned i = 0; i < glsl_get_matrix_columns(mat->type); i++) {
1310 if (glsl_get_base_type(mat->type) == GLSL_TYPE_FLOAT)
1311 dest->elems[i]->def = nir_fmul(&b->nb, mat->elems[i]->def, scalar);
1312 else
1313 dest->elems[i]->def = nir_imul(&b->nb, mat->elems[i]->def, scalar);
1314 }
1315
1316 return dest;
1317 }
1318
1319 static void
1320 vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
1321 const uint32_t *w, unsigned count)
1322 {
1323 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1324 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
1325
1326 switch (opcode) {
1327 case SpvOpTranspose: {
1328 struct vtn_ssa_value *src = vtn_ssa_value(b, w[3]);
1329 val->ssa = vtn_transpose(b, src);
1330 break;
1331 }
1332
1333 case SpvOpOuterProduct: {
1334 struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
1335 struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
1336
1337 val->ssa = vtn_matrix_multiply(b, src0, vtn_transpose(b, src1));
1338 break;
1339 }
1340
1341 case SpvOpMatrixTimesScalar: {
1342 struct vtn_ssa_value *mat = vtn_ssa_value(b, w[3]);
1343 struct vtn_ssa_value *scalar = vtn_ssa_value(b, w[4]);
1344
1345 if (mat->transposed) {
1346 val->ssa = vtn_transpose(b, vtn_mat_times_scalar(b, mat->transposed,
1347 scalar->def));
1348 } else {
1349 val->ssa = vtn_mat_times_scalar(b, mat, scalar->def);
1350 }
1351 break;
1352 }
1353
1354 case SpvOpVectorTimesMatrix:
1355 case SpvOpMatrixTimesVector:
1356 case SpvOpMatrixTimesMatrix: {
1357 struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
1358 struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
1359
1360 val->ssa = vtn_matrix_multiply(b, src0, src1);
1361 break;
1362 }
1363
1364 default: unreachable("unknown matrix opcode");
1365 }
1366 }
1367
1368 static void
1369 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
1370 const uint32_t *w, unsigned count)
1371 {
1372 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1373 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
1374 val->ssa = vtn_create_ssa_value(b, val->type);
1375
1376 /* Collect the various SSA sources */
1377 unsigned num_inputs = count - 3;
1378 nir_ssa_def *src[4];
1379 for (unsigned i = 0; i < num_inputs; i++)
1380 src[i] = vtn_ssa_value(b, w[i + 3])->def;
1381
1382 /* Indicates that the first two arguments should be swapped. This is
1383 * used for implementing greater-than and less-than-or-equal.
1384 */
1385 bool swap = false;
1386
1387 nir_op op;
1388 switch (opcode) {
1389 /* Basic ALU operations */
1390 case SpvOpSNegate: op = nir_op_ineg; break;
1391 case SpvOpFNegate: op = nir_op_fneg; break;
1392 case SpvOpNot: op = nir_op_inot; break;
1393
1394 case SpvOpAny:
1395 switch (src[0]->num_components) {
1396 case 1: op = nir_op_imov; break;
1397 case 2: op = nir_op_bany2; break;
1398 case 3: op = nir_op_bany3; break;
1399 case 4: op = nir_op_bany4; break;
1400 }
1401 break;
1402
1403 case SpvOpAll:
1404 switch (src[0]->num_components) {
1405 case 1: op = nir_op_imov; break;
1406 case 2: op = nir_op_ball2; break;
1407 case 3: op = nir_op_ball3; break;
1408 case 4: op = nir_op_ball4; break;
1409 }
1410 break;
1411
1412 case SpvOpIAdd: op = nir_op_iadd; break;
1413 case SpvOpFAdd: op = nir_op_fadd; break;
1414 case SpvOpISub: op = nir_op_isub; break;
1415 case SpvOpFSub: op = nir_op_fsub; break;
1416 case SpvOpIMul: op = nir_op_imul; break;
1417 case SpvOpFMul: op = nir_op_fmul; break;
1418 case SpvOpUDiv: op = nir_op_udiv; break;
1419 case SpvOpSDiv: op = nir_op_idiv; break;
1420 case SpvOpFDiv: op = nir_op_fdiv; break;
1421 case SpvOpUMod: op = nir_op_umod; break;
1422 case SpvOpSMod: op = nir_op_umod; break; /* FIXME? */
1423 case SpvOpFMod: op = nir_op_fmod; break;
1424
1425 case SpvOpDot:
1426 assert(src[0]->num_components == src[1]->num_components);
1427 switch (src[0]->num_components) {
1428 case 1: op = nir_op_fmul; break;
1429 case 2: op = nir_op_fdot2; break;
1430 case 3: op = nir_op_fdot3; break;
1431 case 4: op = nir_op_fdot4; break;
1432 }
1433 break;
1434
1435 case SpvOpShiftRightLogical: op = nir_op_ushr; break;
1436 case SpvOpShiftRightArithmetic: op = nir_op_ishr; break;
1437 case SpvOpShiftLeftLogical: op = nir_op_ishl; break;
1438 case SpvOpLogicalOr: op = nir_op_ior; break;
1439 case SpvOpLogicalXor: op = nir_op_ixor; break;
1440 case SpvOpLogicalAnd: op = nir_op_iand; break;
1441 case SpvOpBitwiseOr: op = nir_op_ior; break;
1442 case SpvOpBitwiseXor: op = nir_op_ixor; break;
1443 case SpvOpBitwiseAnd: op = nir_op_iand; break;
1444 case SpvOpSelect: op = nir_op_bcsel; break;
1445 case SpvOpIEqual: op = nir_op_ieq; break;
1446
1447 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
1448 case SpvOpFOrdEqual: op = nir_op_feq; break;
1449 case SpvOpFUnordEqual: op = nir_op_feq; break;
1450 case SpvOpINotEqual: op = nir_op_ine; break;
1451 case SpvOpFOrdNotEqual: op = nir_op_fne; break;
1452 case SpvOpFUnordNotEqual: op = nir_op_fne; break;
1453 case SpvOpULessThan: op = nir_op_ult; break;
1454 case SpvOpSLessThan: op = nir_op_ilt; break;
1455 case SpvOpFOrdLessThan: op = nir_op_flt; break;
1456 case SpvOpFUnordLessThan: op = nir_op_flt; break;
1457 case SpvOpUGreaterThan: op = nir_op_ult; swap = true; break;
1458 case SpvOpSGreaterThan: op = nir_op_ilt; swap = true; break;
1459 case SpvOpFOrdGreaterThan: op = nir_op_flt; swap = true; break;
1460 case SpvOpFUnordGreaterThan: op = nir_op_flt; swap = true; break;
1461 case SpvOpULessThanEqual: op = nir_op_uge; swap = true; break;
1462 case SpvOpSLessThanEqual: op = nir_op_ige; swap = true; break;
1463 case SpvOpFOrdLessThanEqual: op = nir_op_fge; swap = true; break;
1464 case SpvOpFUnordLessThanEqual: op = nir_op_fge; swap = true; break;
1465 case SpvOpUGreaterThanEqual: op = nir_op_uge; break;
1466 case SpvOpSGreaterThanEqual: op = nir_op_ige; break;
1467 case SpvOpFOrdGreaterThanEqual: op = nir_op_fge; break;
1468 case SpvOpFUnordGreaterThanEqual:op = nir_op_fge; break;
1469
1470 /* Conversions: */
1471 case SpvOpConvertFToU: op = nir_op_f2u; break;
1472 case SpvOpConvertFToS: op = nir_op_f2i; break;
1473 case SpvOpConvertSToF: op = nir_op_i2f; break;
1474 case SpvOpConvertUToF: op = nir_op_u2f; break;
1475 case SpvOpBitcast: op = nir_op_imov; break;
1476 case SpvOpUConvert:
1477 case SpvOpSConvert:
1478 op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
1479 break;
1480 case SpvOpFConvert:
1481 op = nir_op_fmov;
1482 break;
1483
1484 /* Derivatives: */
1485 case SpvOpDPdx: op = nir_op_fddx; break;
1486 case SpvOpDPdy: op = nir_op_fddy; break;
1487 case SpvOpDPdxFine: op = nir_op_fddx_fine; break;
1488 case SpvOpDPdyFine: op = nir_op_fddy_fine; break;
1489 case SpvOpDPdxCoarse: op = nir_op_fddx_coarse; break;
1490 case SpvOpDPdyCoarse: op = nir_op_fddy_coarse; break;
1491 case SpvOpFwidth:
1492 val->ssa->def = nir_fadd(&b->nb,
1493 nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
1494 nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
1495 return;
1496 case SpvOpFwidthFine:
1497 val->ssa->def = nir_fadd(&b->nb,
1498 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
1499 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
1500 return;
1501 case SpvOpFwidthCoarse:
1502 val->ssa->def = nir_fadd(&b->nb,
1503 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
1504 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
1505 return;
1506
1507 case SpvOpVectorTimesScalar:
1508 /* The builder will take care of splatting for us. */
1509 val->ssa->def = nir_fmul(&b->nb, src[0], src[1]);
1510 return;
1511
1512 case SpvOpSRem:
1513 case SpvOpFRem:
1514 unreachable("No NIR equivalent");
1515
1516 case SpvOpIsNan:
1517 case SpvOpIsInf:
1518 case SpvOpIsFinite:
1519 case SpvOpIsNormal:
1520 case SpvOpSignBitSet:
1521 case SpvOpLessOrGreater:
1522 case SpvOpOrdered:
1523 case SpvOpUnordered:
1524 default:
1525 unreachable("Unhandled opcode");
1526 }
1527
1528 if (swap) {
1529 nir_ssa_def *tmp = src[0];
1530 src[0] = src[1];
1531 src[1] = tmp;
1532 }
1533
1534 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
1535 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
1536 glsl_get_vector_elements(val->type), val->name);
1537 val->ssa->def = &instr->dest.dest.ssa;
1538
1539 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
1540 instr->src[i].src = nir_src_for_ssa(src[i]);
1541
1542 nir_builder_instr_insert(&b->nb, &instr->instr);
1543 }
1544
1545 static nir_ssa_def *
1546 vtn_vector_extract(struct vtn_builder *b, nir_ssa_def *src, unsigned index)
1547 {
1548 unsigned swiz[4] = { index };
1549 return nir_swizzle(&b->nb, src, swiz, 1, true);
1550 }
1551
1552
1553 static nir_ssa_def *
1554 vtn_vector_insert(struct vtn_builder *b, nir_ssa_def *src, nir_ssa_def *insert,
1555 unsigned index)
1556 {
1557 nir_alu_instr *vec = create_vec(b->shader, src->num_components);
1558
1559 for (unsigned i = 0; i < src->num_components; i++) {
1560 if (i == index) {
1561 vec->src[i].src = nir_src_for_ssa(insert);
1562 } else {
1563 vec->src[i].src = nir_src_for_ssa(src);
1564 vec->src[i].swizzle[0] = i;
1565 }
1566 }
1567
1568 nir_builder_instr_insert(&b->nb, &vec->instr);
1569
1570 return &vec->dest.dest.ssa;
1571 }
1572
1573 static nir_ssa_def *
1574 vtn_vector_extract_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1575 nir_ssa_def *index)
1576 {
1577 nir_ssa_def *dest = vtn_vector_extract(b, src, 0);
1578 for (unsigned i = 1; i < src->num_components; i++)
1579 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1580 vtn_vector_extract(b, src, i), dest);
1581
1582 return dest;
1583 }
1584
1585 static nir_ssa_def *
1586 vtn_vector_insert_dynamic(struct vtn_builder *b, nir_ssa_def *src,
1587 nir_ssa_def *insert, nir_ssa_def *index)
1588 {
1589 nir_ssa_def *dest = vtn_vector_insert(b, src, insert, 0);
1590 for (unsigned i = 1; i < src->num_components; i++)
1591 dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
1592 vtn_vector_insert(b, src, insert, i), dest);
1593
1594 return dest;
1595 }
1596
1597 static nir_ssa_def *
1598 vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
1599 nir_ssa_def *src0, nir_ssa_def *src1,
1600 const uint32_t *indices)
1601 {
1602 nir_alu_instr *vec = create_vec(b->shader, num_components);
1603
1604 nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(b->shader, 1);
1605 nir_builder_instr_insert(&b->nb, &undef->instr);
1606
1607 for (unsigned i = 0; i < num_components; i++) {
1608 uint32_t index = indices[i];
1609 if (index == 0xffffffff) {
1610 vec->src[i].src = nir_src_for_ssa(&undef->def);
1611 } else if (index < src0->num_components) {
1612 vec->src[i].src = nir_src_for_ssa(src0);
1613 vec->src[i].swizzle[0] = index;
1614 } else {
1615 vec->src[i].src = nir_src_for_ssa(src1);
1616 vec->src[i].swizzle[0] = index - src0->num_components;
1617 }
1618 }
1619
1620 nir_builder_instr_insert(&b->nb, &vec->instr);
1621
1622 return &vec->dest.dest.ssa;
1623 }
1624
1625 /*
1626 * Concatentates a number of vectors/scalars together to produce a vector
1627 */
1628 static nir_ssa_def *
1629 vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
1630 unsigned num_srcs, nir_ssa_def **srcs)
1631 {
1632 nir_alu_instr *vec = create_vec(b->shader, num_components);
1633
1634 unsigned dest_idx = 0;
1635 for (unsigned i = 0; i < num_srcs; i++) {
1636 nir_ssa_def *src = srcs[i];
1637 for (unsigned j = 0; j < src->num_components; j++) {
1638 vec->src[dest_idx].src = nir_src_for_ssa(src);
1639 vec->src[dest_idx].swizzle[0] = j;
1640 dest_idx++;
1641 }
1642 }
1643
1644 nir_builder_instr_insert(&b->nb, &vec->instr);
1645
1646 return &vec->dest.dest.ssa;
1647 }
1648
1649 static struct vtn_ssa_value *
1650 vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
1651 {
1652 struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
1653 dest->type = src->type;
1654
1655 if (glsl_type_is_vector_or_scalar(src->type)) {
1656 dest->def = src->def;
1657 } else {
1658 unsigned elems = glsl_get_length(src->type);
1659
1660 dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
1661 for (unsigned i = 0; i < elems; i++)
1662 dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
1663 }
1664
1665 return dest;
1666 }
1667
1668 static struct vtn_ssa_value *
1669 vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
1670 struct vtn_ssa_value *insert, const uint32_t *indices,
1671 unsigned num_indices)
1672 {
1673 struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
1674
1675 struct vtn_ssa_value *cur = dest;
1676 unsigned i;
1677 for (i = 0; i < num_indices - 1; i++) {
1678 cur = cur->elems[indices[i]];
1679 }
1680
1681 if (glsl_type_is_vector_or_scalar(cur->type)) {
1682 /* According to the SPIR-V spec, OpCompositeInsert may work down to
1683 * the component granularity. In that case, the last index will be
1684 * the index to insert the scalar into the vector.
1685 */
1686
1687 cur->def = vtn_vector_insert(b, cur->def, insert->def, indices[i]);
1688 } else {
1689 cur->elems[indices[i]] = insert;
1690 }
1691
1692 return dest;
1693 }
1694
1695 static struct vtn_ssa_value *
1696 vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
1697 const uint32_t *indices, unsigned num_indices)
1698 {
1699 struct vtn_ssa_value *cur = src;
1700 for (unsigned i = 0; i < num_indices; i++) {
1701 if (glsl_type_is_vector_or_scalar(cur->type)) {
1702 assert(i == num_indices - 1);
1703 /* According to the SPIR-V spec, OpCompositeExtract may work down to
1704 * the component granularity. The last index will be the index of the
1705 * vector to extract.
1706 */
1707
1708 struct vtn_ssa_value *ret = rzalloc(b, struct vtn_ssa_value);
1709 ret->type = glsl_scalar_type(glsl_get_base_type(cur->type));
1710 ret->def = vtn_vector_extract(b, cur->def, indices[i]);
1711 return ret;
1712 }
1713 }
1714
1715 return cur;
1716 }
1717
1718 static void
1719 vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
1720 const uint32_t *w, unsigned count)
1721 {
1722 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1723 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
1724
1725 switch (opcode) {
1726 case SpvOpVectorExtractDynamic:
1727 val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def,
1728 vtn_ssa_value(b, w[4])->def);
1729 break;
1730
1731 case SpvOpVectorInsertDynamic:
1732 val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def,
1733 vtn_ssa_value(b, w[4])->def,
1734 vtn_ssa_value(b, w[5])->def);
1735 break;
1736
1737 case SpvOpVectorShuffle:
1738 val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(val->type),
1739 vtn_ssa_value(b, w[3])->def,
1740 vtn_ssa_value(b, w[4])->def,
1741 w + 5);
1742 break;
1743
1744 case SpvOpCompositeConstruct: {
1745 val->ssa = rzalloc(b, struct vtn_ssa_value);
1746 unsigned elems = count - 3;
1747 if (glsl_type_is_vector_or_scalar(val->type)) {
1748 nir_ssa_def *srcs[4];
1749 for (unsigned i = 0; i < elems; i++)
1750 srcs[i] = vtn_ssa_value(b, w[3 + i])->def;
1751 val->ssa->def =
1752 vtn_vector_construct(b, glsl_get_vector_elements(val->type),
1753 elems, srcs);
1754 } else {
1755 val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
1756 for (unsigned i = 0; i < elems; i++)
1757 val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
1758 }
1759 break;
1760 }
1761 case SpvOpCompositeExtract:
1762 val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
1763 w + 4, count - 4);
1764 break;
1765
1766 case SpvOpCompositeInsert:
1767 val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
1768 vtn_ssa_value(b, w[3]),
1769 w + 5, count - 5);
1770 break;
1771
1772 case SpvOpCopyObject:
1773 val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
1774 break;
1775
1776 default:
1777 unreachable("unknown composite operation");
1778 }
1779
1780 val->ssa->type = val->type;
1781 }
1782
1783 static void
1784 vtn_phi_node_init(struct vtn_builder *b, struct vtn_ssa_value *val)
1785 {
1786 if (glsl_type_is_vector_or_scalar(val->type)) {
1787 nir_phi_instr *phi = nir_phi_instr_create(b->shader);
1788 nir_ssa_dest_init(&phi->instr, &phi->dest,
1789 glsl_get_vector_elements(val->type), NULL);
1790 exec_list_make_empty(&phi->srcs);
1791 nir_builder_instr_insert(&b->nb, &phi->instr);
1792 val->def = &phi->dest.ssa;
1793 } else {
1794 unsigned elems = glsl_get_length(val->type);
1795 for (unsigned i = 0; i < elems; i++)
1796 vtn_phi_node_init(b, val->elems[i]);
1797 }
1798 }
1799
1800 static struct vtn_ssa_value *
1801 vtn_phi_node_create(struct vtn_builder *b, const struct glsl_type *type)
1802 {
1803 struct vtn_ssa_value *val = vtn_create_ssa_value(b, type);
1804 vtn_phi_node_init(b, val);
1805 return val;
1806 }
1807
1808 static void
1809 vtn_handle_phi_first_pass(struct vtn_builder *b, const uint32_t *w)
1810 {
1811 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
1812 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
1813 val->ssa = vtn_phi_node_create(b, val->type);
1814 }
1815
1816 static void
1817 vtn_phi_node_add_src(struct vtn_ssa_value *phi, const nir_block *pred,
1818 struct vtn_ssa_value *val)
1819 {
1820 assert(phi->type == val->type);
1821 if (glsl_type_is_vector_or_scalar(phi->type)) {
1822 nir_phi_instr *phi_instr = nir_instr_as_phi(phi->def->parent_instr);
1823 nir_phi_src *src = ralloc(phi_instr, nir_phi_src);
1824 src->pred = (nir_block *) pred;
1825 src->src = nir_src_for_ssa(val->def);
1826 exec_list_push_tail(&phi_instr->srcs, &src->node);
1827 } else {
1828 unsigned elems = glsl_get_length(phi->type);
1829 for (unsigned i = 0; i < elems; i++)
1830 vtn_phi_node_add_src(phi->elems[i], pred, val->elems[i]);
1831 }
1832 }
1833
1834 static struct vtn_ssa_value *
1835 vtn_get_phi_node_src(struct vtn_builder *b, nir_block *block,
1836 const struct glsl_type *type, const uint32_t *w,
1837 unsigned count)
1838 {
1839 struct hash_entry *entry = _mesa_hash_table_search(b->block_table, block);
1840 if (entry) {
1841 struct vtn_block *spv_block = entry->data;
1842 for (unsigned off = 4; off < count; off += 2) {
1843 if (spv_block == vtn_value(b, w[off], vtn_value_type_block)->block) {
1844 return vtn_ssa_value(b, w[off - 1]);
1845 }
1846 }
1847 }
1848
1849 nir_builder_insert_before_block(&b->nb, block);
1850 struct vtn_ssa_value *phi = vtn_phi_node_create(b, type);
1851
1852 struct set_entry *entry2;
1853 set_foreach(block->predecessors, entry2) {
1854 nir_block *pred = (nir_block *) entry2->key;
1855 struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, type, w,
1856 count);
1857 vtn_phi_node_add_src(phi, pred, val);
1858 }
1859
1860 return phi;
1861 }
1862
1863 static bool
1864 vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
1865 const uint32_t *w, unsigned count)
1866 {
1867 if (opcode == SpvOpLabel) {
1868 b->block = vtn_value(b, w[1], vtn_value_type_block)->block;
1869 return true;
1870 }
1871
1872 if (opcode != SpvOpPhi)
1873 return true;
1874
1875 struct vtn_ssa_value *phi = vtn_value(b, w[2], vtn_value_type_ssa)->ssa;
1876
1877 struct set_entry *entry;
1878 set_foreach(b->block->block->predecessors, entry) {
1879 nir_block *pred = (nir_block *) entry->key;
1880
1881 struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, phi->type, w,
1882 count);
1883 vtn_phi_node_add_src(phi, pred, val);
1884 }
1885
1886 return true;
1887 }
1888
1889 static bool
1890 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
1891 const uint32_t *w, unsigned count)
1892 {
1893 switch (opcode) {
1894 case SpvOpSource:
1895 case SpvOpSourceExtension:
1896 case SpvOpCompileFlag:
1897 case SpvOpExtension:
1898 /* Unhandled, but these are for debug so that's ok. */
1899 break;
1900
1901 case SpvOpExtInstImport:
1902 vtn_handle_extension(b, opcode, w, count);
1903 break;
1904
1905 case SpvOpMemoryModel:
1906 assert(w[1] == SpvAddressingModelLogical);
1907 assert(w[2] == SpvMemoryModelGLSL450);
1908 break;
1909
1910 case SpvOpEntryPoint:
1911 assert(b->entry_point == NULL);
1912 b->entry_point = &b->values[w[2]];
1913 b->execution_model = w[1];
1914 break;
1915
1916 case SpvOpExecutionMode:
1917 unreachable("Execution modes not yet implemented");
1918 break;
1919
1920 case SpvOpString:
1921 vtn_push_value(b, w[1], vtn_value_type_string)->str =
1922 vtn_string_literal(b, &w[2], count - 2);
1923 break;
1924
1925 case SpvOpName:
1926 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
1927 break;
1928
1929 case SpvOpMemberName:
1930 /* TODO */
1931 break;
1932
1933 case SpvOpLine:
1934 break; /* Ignored for now */
1935
1936 case SpvOpDecorationGroup:
1937 case SpvOpDecorate:
1938 case SpvOpMemberDecorate:
1939 case SpvOpGroupDecorate:
1940 case SpvOpGroupMemberDecorate:
1941 vtn_handle_decoration(b, opcode, w, count);
1942 break;
1943
1944 case SpvOpTypeVoid:
1945 case SpvOpTypeBool:
1946 case SpvOpTypeInt:
1947 case SpvOpTypeFloat:
1948 case SpvOpTypeVector:
1949 case SpvOpTypeMatrix:
1950 case SpvOpTypeSampler:
1951 case SpvOpTypeArray:
1952 case SpvOpTypeRuntimeArray:
1953 case SpvOpTypeStruct:
1954 case SpvOpTypeOpaque:
1955 case SpvOpTypePointer:
1956 case SpvOpTypeFunction:
1957 case SpvOpTypeEvent:
1958 case SpvOpTypeDeviceEvent:
1959 case SpvOpTypeReserveId:
1960 case SpvOpTypeQueue:
1961 case SpvOpTypePipe:
1962 vtn_push_value(b, w[1], vtn_value_type_type)->type =
1963 vtn_handle_type(b, opcode, &w[2], count - 2);
1964 break;
1965
1966 case SpvOpConstantTrue:
1967 case SpvOpConstantFalse:
1968 case SpvOpConstant:
1969 case SpvOpConstantComposite:
1970 case SpvOpConstantSampler:
1971 case SpvOpConstantNullPointer:
1972 case SpvOpConstantNullObject:
1973 case SpvOpSpecConstantTrue:
1974 case SpvOpSpecConstantFalse:
1975 case SpvOpSpecConstant:
1976 case SpvOpSpecConstantComposite:
1977 vtn_handle_constant(b, opcode, w, count);
1978 break;
1979
1980 case SpvOpVariable:
1981 vtn_handle_variables(b, opcode, w, count);
1982 break;
1983
1984 default:
1985 return false; /* End of preamble */
1986 }
1987
1988 return true;
1989 }
1990
1991 static bool
1992 vtn_handle_first_cfg_pass_instruction(struct vtn_builder *b, SpvOp opcode,
1993 const uint32_t *w, unsigned count)
1994 {
1995 switch (opcode) {
1996 case SpvOpFunction: {
1997 assert(b->func == NULL);
1998 b->func = rzalloc(b, struct vtn_function);
1999
2000 const struct glsl_type *result_type =
2001 vtn_value(b, w[1], vtn_value_type_type)->type;
2002 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
2003 const struct glsl_type *func_type =
2004 vtn_value(b, w[4], vtn_value_type_type)->type;
2005
2006 assert(glsl_get_function_return_type(func_type) == result_type);
2007
2008 nir_function *func =
2009 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
2010
2011 nir_function_overload *overload = nir_function_overload_create(func);
2012 overload->num_params = glsl_get_length(func_type);
2013 overload->params = ralloc_array(overload, nir_parameter,
2014 overload->num_params);
2015 for (unsigned i = 0; i < overload->num_params; i++) {
2016 const struct glsl_function_param *param =
2017 glsl_get_function_param(func_type, i);
2018 overload->params[i].type = param->type;
2019 if (param->in) {
2020 if (param->out) {
2021 overload->params[i].param_type = nir_parameter_inout;
2022 } else {
2023 overload->params[i].param_type = nir_parameter_in;
2024 }
2025 } else {
2026 if (param->out) {
2027 overload->params[i].param_type = nir_parameter_out;
2028 } else {
2029 assert(!"Parameter is neither in nor out");
2030 }
2031 }
2032 }
2033 b->func->overload = overload;
2034 break;
2035 }
2036
2037 case SpvOpFunctionEnd:
2038 b->func->end = w;
2039 b->func = NULL;
2040 break;
2041
2042 case SpvOpFunctionParameter:
2043 break; /* Does nothing */
2044
2045 case SpvOpLabel: {
2046 assert(b->block == NULL);
2047 b->block = rzalloc(b, struct vtn_block);
2048 b->block->label = w;
2049 vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
2050
2051 if (b->func->start_block == NULL) {
2052 /* This is the first block encountered for this function. In this
2053 * case, we set the start block and add it to the list of
2054 * implemented functions that we'll walk later.
2055 */
2056 b->func->start_block = b->block;
2057 exec_list_push_tail(&b->functions, &b->func->node);
2058 }
2059 break;
2060 }
2061
2062 case SpvOpBranch:
2063 case SpvOpBranchConditional:
2064 case SpvOpSwitch:
2065 case SpvOpKill:
2066 case SpvOpReturn:
2067 case SpvOpReturnValue:
2068 case SpvOpUnreachable:
2069 assert(b->block);
2070 b->block->branch = w;
2071 b->block = NULL;
2072 break;
2073
2074 case SpvOpSelectionMerge:
2075 case SpvOpLoopMerge:
2076 assert(b->block && b->block->merge_op == SpvOpNop);
2077 b->block->merge_op = opcode;
2078 b->block->merge_block_id = w[1];
2079 break;
2080
2081 default:
2082 /* Continue on as per normal */
2083 return true;
2084 }
2085
2086 return true;
2087 }
2088
2089 static bool
2090 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
2091 const uint32_t *w, unsigned count)
2092 {
2093 switch (opcode) {
2094 case SpvOpLabel: {
2095 struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
2096 assert(block->block == NULL);
2097
2098 struct exec_node *list_tail = exec_list_get_tail(b->nb.cf_node_list);
2099 nir_cf_node *tail_node = exec_node_data(nir_cf_node, list_tail, node);
2100 assert(tail_node->type == nir_cf_node_block);
2101 block->block = nir_cf_node_as_block(tail_node);
2102 break;
2103 }
2104
2105 case SpvOpLoopMerge:
2106 case SpvOpSelectionMerge:
2107 /* This is handled by cfg pre-pass and walk_blocks */
2108 break;
2109
2110 case SpvOpUndef:
2111 vtn_push_value(b, w[2], vtn_value_type_undef);
2112 break;
2113
2114 case SpvOpExtInst:
2115 vtn_handle_extension(b, opcode, w, count);
2116 break;
2117
2118 case SpvOpVariable:
2119 case SpvOpVariableArray:
2120 case SpvOpLoad:
2121 case SpvOpStore:
2122 case SpvOpCopyMemory:
2123 case SpvOpCopyMemorySized:
2124 case SpvOpAccessChain:
2125 case SpvOpInBoundsAccessChain:
2126 case SpvOpArrayLength:
2127 case SpvOpImagePointer:
2128 vtn_handle_variables(b, opcode, w, count);
2129 break;
2130
2131 case SpvOpFunctionCall:
2132 vtn_handle_function_call(b, opcode, w, count);
2133 break;
2134
2135 case SpvOpTextureSample:
2136 case SpvOpTextureSampleDref:
2137 case SpvOpTextureSampleLod:
2138 case SpvOpTextureSampleProj:
2139 case SpvOpTextureSampleGrad:
2140 case SpvOpTextureSampleOffset:
2141 case SpvOpTextureSampleProjLod:
2142 case SpvOpTextureSampleProjGrad:
2143 case SpvOpTextureSampleLodOffset:
2144 case SpvOpTextureSampleProjOffset:
2145 case SpvOpTextureSampleGradOffset:
2146 case SpvOpTextureSampleProjLodOffset:
2147 case SpvOpTextureSampleProjGradOffset:
2148 case SpvOpTextureFetchTexelLod:
2149 case SpvOpTextureFetchTexelOffset:
2150 case SpvOpTextureFetchSample:
2151 case SpvOpTextureFetchTexel:
2152 case SpvOpTextureGather:
2153 case SpvOpTextureGatherOffset:
2154 case SpvOpTextureGatherOffsets:
2155 case SpvOpTextureQuerySizeLod:
2156 case SpvOpTextureQuerySize:
2157 case SpvOpTextureQueryLod:
2158 case SpvOpTextureQueryLevels:
2159 case SpvOpTextureQuerySamples:
2160 vtn_handle_texture(b, opcode, w, count);
2161 break;
2162
2163 case SpvOpSNegate:
2164 case SpvOpFNegate:
2165 case SpvOpNot:
2166 case SpvOpAny:
2167 case SpvOpAll:
2168 case SpvOpConvertFToU:
2169 case SpvOpConvertFToS:
2170 case SpvOpConvertSToF:
2171 case SpvOpConvertUToF:
2172 case SpvOpUConvert:
2173 case SpvOpSConvert:
2174 case SpvOpFConvert:
2175 case SpvOpConvertPtrToU:
2176 case SpvOpConvertUToPtr:
2177 case SpvOpPtrCastToGeneric:
2178 case SpvOpGenericCastToPtr:
2179 case SpvOpBitcast:
2180 case SpvOpIsNan:
2181 case SpvOpIsInf:
2182 case SpvOpIsFinite:
2183 case SpvOpIsNormal:
2184 case SpvOpSignBitSet:
2185 case SpvOpLessOrGreater:
2186 case SpvOpOrdered:
2187 case SpvOpUnordered:
2188 case SpvOpIAdd:
2189 case SpvOpFAdd:
2190 case SpvOpISub:
2191 case SpvOpFSub:
2192 case SpvOpIMul:
2193 case SpvOpFMul:
2194 case SpvOpUDiv:
2195 case SpvOpSDiv:
2196 case SpvOpFDiv:
2197 case SpvOpUMod:
2198 case SpvOpSRem:
2199 case SpvOpSMod:
2200 case SpvOpFRem:
2201 case SpvOpFMod:
2202 case SpvOpVectorTimesScalar:
2203 case SpvOpDot:
2204 case SpvOpShiftRightLogical:
2205 case SpvOpShiftRightArithmetic:
2206 case SpvOpShiftLeftLogical:
2207 case SpvOpLogicalOr:
2208 case SpvOpLogicalXor:
2209 case SpvOpLogicalAnd:
2210 case SpvOpBitwiseOr:
2211 case SpvOpBitwiseXor:
2212 case SpvOpBitwiseAnd:
2213 case SpvOpSelect:
2214 case SpvOpIEqual:
2215 case SpvOpFOrdEqual:
2216 case SpvOpFUnordEqual:
2217 case SpvOpINotEqual:
2218 case SpvOpFOrdNotEqual:
2219 case SpvOpFUnordNotEqual:
2220 case SpvOpULessThan:
2221 case SpvOpSLessThan:
2222 case SpvOpFOrdLessThan:
2223 case SpvOpFUnordLessThan:
2224 case SpvOpUGreaterThan:
2225 case SpvOpSGreaterThan:
2226 case SpvOpFOrdGreaterThan:
2227 case SpvOpFUnordGreaterThan:
2228 case SpvOpULessThanEqual:
2229 case SpvOpSLessThanEqual:
2230 case SpvOpFOrdLessThanEqual:
2231 case SpvOpFUnordLessThanEqual:
2232 case SpvOpUGreaterThanEqual:
2233 case SpvOpSGreaterThanEqual:
2234 case SpvOpFOrdGreaterThanEqual:
2235 case SpvOpFUnordGreaterThanEqual:
2236 case SpvOpDPdx:
2237 case SpvOpDPdy:
2238 case SpvOpFwidth:
2239 case SpvOpDPdxFine:
2240 case SpvOpDPdyFine:
2241 case SpvOpFwidthFine:
2242 case SpvOpDPdxCoarse:
2243 case SpvOpDPdyCoarse:
2244 case SpvOpFwidthCoarse:
2245 vtn_handle_alu(b, opcode, w, count);
2246 break;
2247
2248 case SpvOpTranspose:
2249 case SpvOpOuterProduct:
2250 case SpvOpMatrixTimesScalar:
2251 case SpvOpVectorTimesMatrix:
2252 case SpvOpMatrixTimesVector:
2253 case SpvOpMatrixTimesMatrix:
2254 vtn_handle_matrix_alu(b, opcode, w, count);
2255 break;
2256
2257 case SpvOpVectorExtractDynamic:
2258 case SpvOpVectorInsertDynamic:
2259 case SpvOpVectorShuffle:
2260 case SpvOpCompositeConstruct:
2261 case SpvOpCompositeExtract:
2262 case SpvOpCompositeInsert:
2263 case SpvOpCopyObject:
2264 vtn_handle_composite(b, opcode, w, count);
2265 break;
2266
2267 case SpvOpPhi:
2268 vtn_handle_phi_first_pass(b, w);
2269 break;
2270
2271 default:
2272 unreachable("Unhandled opcode");
2273 }
2274
2275 return true;
2276 }
2277
2278 static void
2279 vtn_walk_blocks(struct vtn_builder *b, struct vtn_block *start,
2280 struct vtn_block *break_block, struct vtn_block *cont_block,
2281 struct vtn_block *end_block)
2282 {
2283 struct vtn_block *block = start;
2284 while (block != end_block) {
2285 if (block->merge_op == SpvOpLoopMerge) {
2286 /* This is the jump into a loop. */
2287 struct vtn_block *new_cont_block = block;
2288 struct vtn_block *new_break_block =
2289 vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
2290
2291 nir_loop *loop = nir_loop_create(b->shader);
2292 nir_cf_node_insert_end(b->nb.cf_node_list, &loop->cf_node);
2293
2294 struct exec_list *old_list = b->nb.cf_node_list;
2295
2296 /* Reset the merge_op to prerevent infinite recursion */
2297 block->merge_op = SpvOpNop;
2298
2299 nir_builder_insert_after_cf_list(&b->nb, &loop->body);
2300 vtn_walk_blocks(b, block, new_break_block, new_cont_block, NULL);
2301
2302 nir_builder_insert_after_cf_list(&b->nb, old_list);
2303 block = new_break_block;
2304 continue;
2305 }
2306
2307 const uint32_t *w = block->branch;
2308 SpvOp branch_op = w[0] & SpvOpCodeMask;
2309
2310 b->block = block;
2311 vtn_foreach_instruction(b, block->label, block->branch,
2312 vtn_handle_body_instruction);
2313
2314 nir_cf_node *cur_cf_node =
2315 exec_node_data(nir_cf_node, exec_list_get_tail(b->nb.cf_node_list),
2316 node);
2317 nir_block *cur_block = nir_cf_node_as_block(cur_cf_node);
2318 _mesa_hash_table_insert(b->block_table, cur_block, block);
2319
2320 switch (branch_op) {
2321 case SpvOpBranch: {
2322 struct vtn_block *branch_block =
2323 vtn_value(b, w[1], vtn_value_type_block)->block;
2324
2325 if (branch_block == break_block) {
2326 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2327 nir_jump_break);
2328 nir_builder_instr_insert(&b->nb, &jump->instr);
2329
2330 return;
2331 } else if (branch_block == cont_block) {
2332 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2333 nir_jump_continue);
2334 nir_builder_instr_insert(&b->nb, &jump->instr);
2335
2336 return;
2337 } else if (branch_block == end_block) {
2338 /* We're branching to the merge block of an if, since for loops
2339 * and functions end_block == NULL, so we're done here.
2340 */
2341 return;
2342 } else {
2343 /* We're branching to another block, and according to the rules,
2344 * we can only branch to another block with one predecessor (so
2345 * we're the only one jumping to it) so we can just process it
2346 * next.
2347 */
2348 block = branch_block;
2349 continue;
2350 }
2351 }
2352
2353 case SpvOpBranchConditional: {
2354 /* Gather up the branch blocks */
2355 struct vtn_block *then_block =
2356 vtn_value(b, w[2], vtn_value_type_block)->block;
2357 struct vtn_block *else_block =
2358 vtn_value(b, w[3], vtn_value_type_block)->block;
2359
2360 nir_if *if_stmt = nir_if_create(b->shader);
2361 if_stmt->condition = nir_src_for_ssa(vtn_ssa_value(b, w[1])->def);
2362 nir_cf_node_insert_end(b->nb.cf_node_list, &if_stmt->cf_node);
2363
2364 if (then_block == break_block) {
2365 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2366 nir_jump_break);
2367 nir_instr_insert_after_cf_list(&if_stmt->then_list,
2368 &jump->instr);
2369 block = else_block;
2370 } else if (else_block == break_block) {
2371 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2372 nir_jump_break);
2373 nir_instr_insert_after_cf_list(&if_stmt->else_list,
2374 &jump->instr);
2375 block = then_block;
2376 } else if (then_block == cont_block) {
2377 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2378 nir_jump_continue);
2379 nir_instr_insert_after_cf_list(&if_stmt->then_list,
2380 &jump->instr);
2381 block = else_block;
2382 } else if (else_block == cont_block) {
2383 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2384 nir_jump_continue);
2385 nir_instr_insert_after_cf_list(&if_stmt->else_list,
2386 &jump->instr);
2387 block = then_block;
2388 } else {
2389 /* According to the rules we're branching to two blocks that don't
2390 * have any other predecessors, so we can handle this as a
2391 * conventional if.
2392 */
2393 assert(block->merge_op == SpvOpSelectionMerge);
2394 struct vtn_block *merge_block =
2395 vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
2396
2397 struct exec_list *old_list = b->nb.cf_node_list;
2398
2399 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->then_list);
2400 vtn_walk_blocks(b, then_block, break_block, cont_block, merge_block);
2401
2402 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->else_list);
2403 vtn_walk_blocks(b, else_block, break_block, cont_block, merge_block);
2404
2405 nir_builder_insert_after_cf_list(&b->nb, old_list);
2406 block = merge_block;
2407 continue;
2408 }
2409
2410 /* If we got here then we inserted a predicated break or continue
2411 * above and we need to handle the other case. We already set
2412 * `block` above to indicate what block to visit after the
2413 * predicated break.
2414 */
2415
2416 /* It's possible that the other branch is also a break/continue.
2417 * If it is, we handle that here.
2418 */
2419 if (block == break_block) {
2420 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2421 nir_jump_break);
2422 nir_builder_instr_insert(&b->nb, &jump->instr);
2423
2424 return;
2425 } else if (block == cont_block) {
2426 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2427 nir_jump_continue);
2428 nir_builder_instr_insert(&b->nb, &jump->instr);
2429
2430 return;
2431 }
2432
2433 /* If we got here then there was a predicated break/continue but
2434 * the other half of the if has stuff in it. `block` was already
2435 * set above so there is nothing left for us to do.
2436 */
2437 continue;
2438 }
2439
2440 case SpvOpReturn: {
2441 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
2442 nir_jump_return);
2443 nir_builder_instr_insert(&b->nb, &jump->instr);
2444 return;
2445 }
2446
2447 case SpvOpKill: {
2448 nir_intrinsic_instr *discard =
2449 nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
2450 nir_builder_instr_insert(&b->nb, &discard->instr);
2451 return;
2452 }
2453
2454 case SpvOpSwitch:
2455 case SpvOpReturnValue:
2456 case SpvOpUnreachable:
2457 default:
2458 unreachable("Unhandled opcode");
2459 }
2460 }
2461 }
2462
2463 nir_shader *
2464 spirv_to_nir(const uint32_t *words, size_t word_count,
2465 const nir_shader_compiler_options *options)
2466 {
2467 const uint32_t *word_end = words + word_count;
2468
2469 /* Handle the SPIR-V header (first 4 dwords) */
2470 assert(word_count > 5);
2471
2472 assert(words[0] == SpvMagicNumber);
2473 assert(words[1] == 99);
2474 /* words[2] == generator magic */
2475 unsigned value_id_bound = words[3];
2476 assert(words[4] == 0);
2477
2478 words+= 5;
2479
2480 nir_shader *shader = nir_shader_create(NULL, options);
2481
2482 /* Initialize the stn_builder object */
2483 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
2484 b->shader = shader;
2485 b->value_id_bound = value_id_bound;
2486 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
2487 exec_list_make_empty(&b->functions);
2488
2489 /* Handle all the preamble instructions */
2490 words = vtn_foreach_instruction(b, words, word_end,
2491 vtn_handle_preamble_instruction);
2492
2493 /* Do a very quick CFG analysis pass */
2494 vtn_foreach_instruction(b, words, word_end,
2495 vtn_handle_first_cfg_pass_instruction);
2496
2497 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
2498 b->impl = nir_function_impl_create(func->overload);
2499 b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
2500 _mesa_key_pointer_equal);
2501 b->block_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
2502 _mesa_key_pointer_equal);
2503 nir_builder_init(&b->nb, b->impl);
2504 nir_builder_insert_after_cf_list(&b->nb, &b->impl->body);
2505 vtn_walk_blocks(b, func->start_block, NULL, NULL, NULL);
2506 vtn_foreach_instruction(b, func->start_block->label, func->end,
2507 vtn_handle_phi_second_pass);
2508 }
2509
2510 ralloc_free(b);
2511
2512 return shader;
2513 }