nir/spirv: Set the system value mode on builtins
[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 nir_ssa_def *
32 vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
33 {
34 struct vtn_value *val = vtn_untyped_value(b, value_id);
35 switch (val->value_type) {
36 case vtn_value_type_constant: {
37 assert(glsl_type_is_vector_or_scalar(val->type));
38 unsigned num_components = glsl_get_vector_elements(val->type);
39 nir_load_const_instr *load =
40 nir_load_const_instr_create(b->shader, num_components);
41
42 for (unsigned i = 0; i < num_components; i++)
43 load->value.u[0] = val->constant->value.u[0];
44
45 nir_builder_instr_insert(&b->nb, &load->instr);
46 return &load->def;
47 }
48
49 case vtn_value_type_ssa:
50 return val->ssa;
51 default:
52 unreachable("Invalid type for an SSA value");
53 }
54 }
55
56 static char *
57 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
58 unsigned word_count)
59 {
60 return ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
61 }
62
63 static const uint32_t *
64 vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
65 const uint32_t *end, vtn_instruction_handler handler)
66 {
67 const uint32_t *w = start;
68 while (w < end) {
69 SpvOp opcode = w[0] & SpvOpCodeMask;
70 unsigned count = w[0] >> SpvWordCountShift;
71 assert(count >= 1 && w + count <= end);
72
73 if (!handler(b, opcode, w, count))
74 return w;
75
76 w += count;
77 }
78 assert(w == end);
79 return w;
80 }
81
82 static void
83 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
84 const uint32_t *w, unsigned count)
85 {
86 switch (opcode) {
87 case SpvOpExtInstImport: {
88 struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
89 if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) {
90 val->ext_handler = vtn_handle_glsl450_instruction;
91 } else {
92 assert(!"Unsupported extension");
93 }
94 break;
95 }
96
97 case SpvOpExtInst: {
98 struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
99 bool handled = val->ext_handler(b, w[4], w, count);
100 (void)handled;
101 assert(handled);
102 break;
103 }
104
105 default:
106 unreachable("Unhandled opcode");
107 }
108 }
109
110 static void
111 _foreach_decoration_helper(struct vtn_builder *b,
112 struct vtn_value *base_value,
113 struct vtn_value *value,
114 vtn_decoration_foreach_cb cb, void *data)
115 {
116 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
117 if (dec->group) {
118 assert(dec->group->value_type == vtn_value_type_decoration_group);
119 _foreach_decoration_helper(b, base_value, dec->group, cb, data);
120 } else {
121 cb(b, base_value, dec, data);
122 }
123 }
124 }
125
126 /** Iterates (recursively if needed) over all of the decorations on a value
127 *
128 * This function iterates over all of the decorations applied to a given
129 * value. If it encounters a decoration group, it recurses into the group
130 * and iterates over all of those decorations as well.
131 */
132 void
133 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
134 vtn_decoration_foreach_cb cb, void *data)
135 {
136 _foreach_decoration_helper(b, value, value, cb, data);
137 }
138
139 static void
140 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
141 const uint32_t *w, unsigned count)
142 {
143 switch (opcode) {
144 case SpvOpDecorationGroup:
145 vtn_push_value(b, w[1], vtn_value_type_undef);
146 break;
147
148 case SpvOpDecorate: {
149 struct vtn_value *val = &b->values[w[1]];
150
151 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
152 dec->decoration = w[2];
153 dec->literals = &w[3];
154
155 /* Link into the list */
156 dec->next = val->decoration;
157 val->decoration = dec;
158 break;
159 }
160
161 case SpvOpGroupDecorate: {
162 struct vtn_value *group = &b->values[w[1]];
163 assert(group->value_type == vtn_value_type_decoration_group);
164
165 for (unsigned i = 2; i < count; i++) {
166 struct vtn_value *val = &b->values[w[i]];
167 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
168 dec->group = group;
169
170 /* Link into the list */
171 dec->next = val->decoration;
172 val->decoration = dec;
173 }
174 break;
175 }
176
177 case SpvOpGroupMemberDecorate:
178 assert(!"Bad instruction. Khronos Bug #13513");
179 break;
180
181 default:
182 unreachable("Unhandled opcode");
183 }
184 }
185
186 static const struct glsl_type *
187 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
188 const uint32_t *args, unsigned count)
189 {
190 switch (opcode) {
191 case SpvOpTypeVoid:
192 return glsl_void_type();
193 case SpvOpTypeBool:
194 return glsl_bool_type();
195 case SpvOpTypeInt:
196 return glsl_int_type();
197 case SpvOpTypeFloat:
198 return glsl_float_type();
199
200 case SpvOpTypeVector: {
201 const struct glsl_type *base =
202 vtn_value(b, args[0], vtn_value_type_type)->type;
203 unsigned elems = args[1];
204
205 assert(glsl_type_is_scalar(base));
206 return glsl_vector_type(glsl_get_base_type(base), elems);
207 }
208
209 case SpvOpTypeMatrix: {
210 const struct glsl_type *base =
211 vtn_value(b, args[0], vtn_value_type_type)->type;
212 unsigned columns = args[1];
213
214 assert(glsl_type_is_vector(base));
215 return glsl_matrix_type(glsl_get_base_type(base),
216 glsl_get_vector_elements(base),
217 columns);
218 }
219
220 case SpvOpTypeArray:
221 return glsl_array_type(b->values[args[0]].type, args[1]);
222
223 case SpvOpTypeStruct: {
224 NIR_VLA(struct glsl_struct_field, fields, count);
225 for (unsigned i = 0; i < count; i++) {
226 /* TODO: Handle decorators */
227 fields[i].type = vtn_value(b, args[i], vtn_value_type_type)->type;
228 fields[i].name = ralloc_asprintf(b, "field%d", i);
229 fields[i].location = -1;
230 fields[i].interpolation = 0;
231 fields[i].centroid = 0;
232 fields[i].sample = 0;
233 fields[i].matrix_layout = 2;
234 fields[i].stream = -1;
235 }
236 return glsl_struct_type(fields, count, "struct");
237 }
238
239 case SpvOpTypeFunction: {
240 const struct glsl_type *return_type = b->values[args[0]].type;
241 NIR_VLA(struct glsl_function_param, params, count - 1);
242 for (unsigned i = 1; i < count; i++) {
243 params[i - 1].type = vtn_value(b, args[i], vtn_value_type_type)->type;
244
245 /* FIXME: */
246 params[i - 1].in = true;
247 params[i - 1].out = true;
248 }
249 return glsl_function_type(return_type, params, count - 1);
250 }
251
252 case SpvOpTypePointer:
253 /* FIXME: For now, we'll just do the really lame thing and return
254 * the same type. The validator should ensure that the proper number
255 * of dereferences happen
256 */
257 return vtn_value(b, args[1], vtn_value_type_type)->type;
258
259 case SpvOpTypeSampler: {
260 const struct glsl_type *sampled_type =
261 vtn_value(b, args[0], vtn_value_type_type)->type;
262
263 assert(glsl_type_is_vector_or_scalar(sampled_type));
264
265 enum glsl_sampler_dim dim;
266 switch ((SpvDim)args[1]) {
267 case SpvDim1D: dim = GLSL_SAMPLER_DIM_1D; break;
268 case SpvDim2D: dim = GLSL_SAMPLER_DIM_2D; break;
269 case SpvDim3D: dim = GLSL_SAMPLER_DIM_3D; break;
270 case SpvDimCube: dim = GLSL_SAMPLER_DIM_CUBE; break;
271 case SpvDimRect: dim = GLSL_SAMPLER_DIM_RECT; break;
272 case SpvDimBuffer: dim = GLSL_SAMPLER_DIM_BUF; break;
273 default:
274 unreachable("Invalid SPIR-V Sampler dimension");
275 }
276
277 /* TODO: Handle the various texture image/filter options */
278 (void)args[2];
279
280 bool is_array = args[3];
281 bool is_shadow = args[4];
282
283 assert(args[5] == 0 && "FIXME: Handl multi-sampled textures");
284
285 return glsl_sampler_type(dim, is_shadow, is_array,
286 glsl_get_base_type(sampled_type));
287 }
288
289 case SpvOpTypeRuntimeArray:
290 case SpvOpTypeOpaque:
291 case SpvOpTypeEvent:
292 case SpvOpTypeDeviceEvent:
293 case SpvOpTypeReserveId:
294 case SpvOpTypeQueue:
295 case SpvOpTypePipe:
296 default:
297 unreachable("Unhandled opcode");
298 }
299 }
300
301 static void
302 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
303 const uint32_t *w, unsigned count)
304 {
305 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
306 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
307 val->constant = ralloc(b, nir_constant);
308 switch (opcode) {
309 case SpvOpConstantTrue:
310 assert(val->type == glsl_bool_type());
311 val->constant->value.u[0] = NIR_TRUE;
312 break;
313 case SpvOpConstantFalse:
314 assert(val->type == glsl_bool_type());
315 val->constant->value.u[0] = NIR_FALSE;
316 break;
317 case SpvOpConstant:
318 assert(glsl_type_is_scalar(val->type));
319 val->constant->value.u[0] = w[3];
320 break;
321 case SpvOpConstantComposite: {
322 unsigned elem_count = count - 3;
323 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
324 for (unsigned i = 0; i < elem_count; i++)
325 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
326
327 switch (glsl_get_base_type(val->type)) {
328 case GLSL_TYPE_UINT:
329 case GLSL_TYPE_INT:
330 case GLSL_TYPE_FLOAT:
331 case GLSL_TYPE_BOOL:
332 if (glsl_type_is_matrix(val->type)) {
333 unsigned rows = glsl_get_vector_elements(val->type);
334 assert(glsl_get_matrix_columns(val->type) == elem_count);
335 for (unsigned i = 0; i < elem_count; i++)
336 for (unsigned j = 0; j < rows; j++)
337 val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
338 } else {
339 assert(glsl_type_is_vector(val->type));
340 assert(glsl_get_vector_elements(val->type) == elem_count);
341 for (unsigned i = 0; i < elem_count; i++)
342 val->constant->value.u[i] = elems[i]->value.u[0];
343 }
344 ralloc_free(elems);
345 break;
346
347 case GLSL_TYPE_STRUCT:
348 case GLSL_TYPE_ARRAY:
349 ralloc_steal(val->constant, elems);
350 val->constant->elements = elems;
351 break;
352
353 default:
354 unreachable("Unsupported type for constants");
355 }
356 break;
357 }
358
359 default:
360 unreachable("Unhandled opcode");
361 }
362 }
363
364 static void
365 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
366 const struct vtn_decoration *dec, void *void_var)
367 {
368 assert(val->value_type == vtn_value_type_deref);
369 assert(val->deref->deref.child == NULL);
370 assert(val->deref->var == void_var);
371
372 nir_variable *var = void_var;
373 switch (dec->decoration) {
374 case SpvDecorationPrecisionLow:
375 case SpvDecorationPrecisionMedium:
376 case SpvDecorationPrecisionHigh:
377 break; /* FIXME: Do nothing with these for now. */
378 case SpvDecorationSmooth:
379 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
380 break;
381 case SpvDecorationNoperspective:
382 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
383 break;
384 case SpvDecorationFlat:
385 var->data.interpolation = INTERP_QUALIFIER_FLAT;
386 break;
387 case SpvDecorationCentroid:
388 var->data.centroid = true;
389 break;
390 case SpvDecorationSample:
391 var->data.sample = true;
392 break;
393 case SpvDecorationInvariant:
394 var->data.invariant = true;
395 break;
396 case SpvDecorationConstant:
397 assert(var->constant_initializer != NULL);
398 var->data.read_only = true;
399 break;
400 case SpvDecorationNonwritable:
401 var->data.read_only = true;
402 break;
403 case SpvDecorationLocation:
404 var->data.explicit_location = true;
405 var->data.location = dec->literals[0];
406 break;
407 case SpvDecorationComponent:
408 var->data.location_frac = dec->literals[0];
409 break;
410 case SpvDecorationIndex:
411 var->data.explicit_index = true;
412 var->data.index = dec->literals[0];
413 break;
414 case SpvDecorationBinding:
415 var->data.explicit_binding = true;
416 var->data.binding = dec->literals[0];
417 break;
418 case SpvDecorationDescriptorSet:
419 var->data.descriptor_set = dec->literals[0];
420 break;
421 case SpvDecorationBuiltIn:
422 var->data.mode = nir_var_system_value;
423 var->data.read_only = true;
424 switch ((SpvBuiltIn)dec->literals[0]) {
425 case SpvBuiltInFrontFacing:
426 var->data.location = SYSTEM_VALUE_FRONT_FACE;
427 break;
428 case SpvBuiltInVertexId:
429 var->data.location = SYSTEM_VALUE_VERTEX_ID;
430 break;
431 case SpvBuiltInInstanceId:
432 var->data.location = SYSTEM_VALUE_INSTANCE_ID;
433 break;
434 case SpvBuiltInSampleId:
435 var->data.location = SYSTEM_VALUE_SAMPLE_ID;
436 break;
437 case SpvBuiltInSamplePosition:
438 var->data.location = SYSTEM_VALUE_SAMPLE_POS;
439 break;
440 case SpvBuiltInSampleMask:
441 var->data.location = SYSTEM_VALUE_SAMPLE_MASK_IN;
442 break;
443 case SpvBuiltInInvocationId:
444 var->data.location = SYSTEM_VALUE_INVOCATION_ID;
445 break;
446 case SpvBuiltInPrimitiveId:
447 case SpvBuiltInPosition:
448 case SpvBuiltInPointSize:
449 case SpvBuiltInClipVertex:
450 case SpvBuiltInClipDistance:
451 case SpvBuiltInCullDistance:
452 case SpvBuiltInLayer:
453 case SpvBuiltInViewportIndex:
454 case SpvBuiltInTessLevelOuter:
455 case SpvBuiltInTessLevelInner:
456 case SpvBuiltInTessCoord:
457 case SpvBuiltInPatchVertices:
458 case SpvBuiltInFragCoord:
459 case SpvBuiltInPointCoord:
460 case SpvBuiltInFragColor:
461 case SpvBuiltInFragDepth:
462 case SpvBuiltInHelperInvocation:
463 case SpvBuiltInNumWorkgroups:
464 case SpvBuiltInWorkgroupSize:
465 case SpvBuiltInWorkgroupId:
466 case SpvBuiltInLocalInvocationId:
467 case SpvBuiltInGlobalInvocationId:
468 case SpvBuiltInLocalInvocationIndex:
469 case SpvBuiltInWorkDim:
470 case SpvBuiltInGlobalSize:
471 case SpvBuiltInEnqueuedWorkgroupSize:
472 case SpvBuiltInGlobalOffset:
473 case SpvBuiltInGlobalLinearId:
474 case SpvBuiltInWorkgroupLinearId:
475 case SpvBuiltInSubgroupSize:
476 case SpvBuiltInSubgroupMaxSize:
477 case SpvBuiltInNumSubgroups:
478 case SpvBuiltInNumEnqueuedSubgroups:
479 case SpvBuiltInSubgroupId:
480 case SpvBuiltInSubgroupLocalInvocationId:
481 unreachable("Unhandled builtin enum");
482 }
483 break;
484 case SpvDecorationNoStaticUse:
485 /* This can safely be ignored */
486 break;
487 case SpvDecorationBlock:
488 case SpvDecorationBufferBlock:
489 case SpvDecorationRowMajor:
490 case SpvDecorationColMajor:
491 case SpvDecorationGLSLShared:
492 case SpvDecorationGLSLStd140:
493 case SpvDecorationGLSLStd430:
494 case SpvDecorationGLSLPacked:
495 case SpvDecorationPatch:
496 case SpvDecorationRestrict:
497 case SpvDecorationAliased:
498 case SpvDecorationVolatile:
499 case SpvDecorationCoherent:
500 case SpvDecorationNonreadable:
501 case SpvDecorationUniform:
502 /* This is really nice but we have no use for it right now. */
503 case SpvDecorationCPacked:
504 case SpvDecorationSaturatedConversion:
505 case SpvDecorationStream:
506 case SpvDecorationOffset:
507 case SpvDecorationAlignment:
508 case SpvDecorationXfbBuffer:
509 case SpvDecorationStride:
510 case SpvDecorationFuncParamAttr:
511 case SpvDecorationFPRoundingMode:
512 case SpvDecorationFPFastMathMode:
513 case SpvDecorationLinkageAttributes:
514 case SpvDecorationSpecId:
515 default:
516 unreachable("Unhandled variable decoration");
517 }
518 }
519
520 static void
521 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
522 const uint32_t *w, unsigned count)
523 {
524 switch (opcode) {
525 case SpvOpVariable: {
526 const struct glsl_type *type =
527 vtn_value(b, w[1], vtn_value_type_type)->type;
528 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
529
530 nir_variable *var = ralloc(b->shader, nir_variable);
531
532 var->type = type;
533 var->name = ralloc_strdup(var, val->name);
534
535 switch ((SpvStorageClass)w[3]) {
536 case SpvStorageClassUniform:
537 case SpvStorageClassUniformConstant:
538 var->data.mode = nir_var_uniform;
539 var->data.read_only = true;
540 break;
541 case SpvStorageClassInput:
542 var->data.mode = nir_var_shader_in;
543 var->data.read_only = true;
544 break;
545 case SpvStorageClassOutput:
546 var->data.mode = nir_var_shader_out;
547 break;
548 case SpvStorageClassPrivateGlobal:
549 var->data.mode = nir_var_global;
550 break;
551 case SpvStorageClassFunction:
552 var->data.mode = nir_var_local;
553 break;
554 case SpvStorageClassWorkgroupLocal:
555 case SpvStorageClassWorkgroupGlobal:
556 case SpvStorageClassGeneric:
557 case SpvStorageClassPrivate:
558 case SpvStorageClassAtomicCounter:
559 default:
560 unreachable("Unhandled variable storage class");
561 }
562
563 if (count > 4) {
564 assert(count == 5);
565 var->constant_initializer =
566 vtn_value(b, w[4], vtn_value_type_constant)->constant;
567 }
568
569 val->deref = nir_deref_var_create(b, var);
570
571 vtn_foreach_decoration(b, val, var_decoration_cb, var);
572
573 switch (var->data.mode) {
574 case nir_var_shader_in:
575 exec_list_push_tail(&b->shader->inputs, &var->node);
576 break;
577 case nir_var_shader_out:
578 exec_list_push_tail(&b->shader->outputs, &var->node);
579 break;
580 case nir_var_global:
581 exec_list_push_tail(&b->shader->globals, &var->node);
582 break;
583 case nir_var_local:
584 exec_list_push_tail(&b->impl->locals, &var->node);
585 break;
586 case nir_var_uniform:
587 exec_list_push_tail(&b->shader->uniforms, &var->node);
588 break;
589 case nir_var_system_value:
590 exec_list_push_tail(&b->shader->system_values, &var->node);
591 break;
592 }
593 break;
594 }
595
596 case SpvOpAccessChain:
597 case SpvOpInBoundsAccessChain: {
598 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
599 nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
600 val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
601
602 nir_deref *tail = &val->deref->deref;
603 while (tail->child)
604 tail = tail->child;
605
606 for (unsigned i = 0; i < count - 4; i++) {
607 assert(w[i + 4] < b->value_id_bound);
608 struct vtn_value *idx_val = &b->values[w[i + 4]];
609
610 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
611 switch (base_type) {
612 case GLSL_TYPE_UINT:
613 case GLSL_TYPE_INT:
614 case GLSL_TYPE_FLOAT:
615 case GLSL_TYPE_DOUBLE:
616 case GLSL_TYPE_BOOL:
617 case GLSL_TYPE_ARRAY: {
618 nir_deref_array *deref_arr = nir_deref_array_create(b);
619 if (base_type == GLSL_TYPE_ARRAY) {
620 deref_arr->deref.type = glsl_get_array_element(tail->type);
621 } else if (glsl_type_is_matrix(tail->type)) {
622 deref_arr->deref.type = glsl_get_column_type(tail->type);
623 } else {
624 assert(glsl_type_is_vector(tail->type));
625 deref_arr->deref.type = glsl_scalar_type(base_type);
626 }
627
628 if (idx_val->value_type == vtn_value_type_constant) {
629 unsigned idx = idx_val->constant->value.u[0];
630 deref_arr->deref_array_type = nir_deref_array_type_direct;
631 deref_arr->base_offset = idx;
632 } else {
633 assert(idx_val->value_type == vtn_value_type_ssa);
634 deref_arr->deref_array_type = nir_deref_array_type_indirect;
635 deref_arr->base_offset = 0;
636 deref_arr->indirect = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
637 }
638 tail->child = &deref_arr->deref;
639 break;
640 }
641
642 case GLSL_TYPE_STRUCT: {
643 assert(idx_val->value_type == vtn_value_type_constant);
644 unsigned idx = idx_val->constant->value.u[0];
645 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
646 deref_struct->deref.type = glsl_get_struct_field(tail->type, idx);
647 tail->child = &deref_struct->deref;
648 break;
649 }
650 default:
651 unreachable("Invalid type for deref");
652 }
653 tail = tail->child;
654 }
655 break;
656 }
657
658 case SpvOpCopyMemory: {
659 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
660 nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
661
662 nir_intrinsic_instr *copy =
663 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
664 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
665 copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
666
667 nir_builder_instr_insert(&b->nb, &copy->instr);
668 break;
669 }
670
671 case SpvOpLoad: {
672 nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
673 const struct glsl_type *src_type = nir_deref_tail(&src->deref)->type;
674
675 if (glsl_get_base_type(src_type) == GLSL_TYPE_SAMPLER) {
676 vtn_push_value(b, w[2], vtn_value_type_deref)->deref = src;
677 return;
678 }
679
680 assert(glsl_type_is_vector_or_scalar(src_type));
681 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
682
683 nir_intrinsic_instr *load =
684 nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
685 load->variables[0] = nir_deref_as_var(nir_copy_deref(load, &src->deref));
686 load->num_components = glsl_get_vector_elements(src_type);
687 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components,
688 val->name);
689
690 nir_builder_instr_insert(&b->nb, &load->instr);
691 val->type = src_type;
692
693 if (src->var->data.mode == nir_var_uniform &&
694 glsl_get_base_type(src_type) == GLSL_TYPE_BOOL) {
695 /* Uniform boolean loads need to be fixed up since they're defined
696 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
697 */
698 val->ssa = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
699 } else {
700 val->ssa = &load->dest.ssa;
701 }
702 break;
703 }
704
705 case SpvOpStore: {
706 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
707 const struct glsl_type *dest_type = nir_deref_tail(&dest->deref)->type;
708 struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
709 if (src_val->value_type == vtn_value_type_ssa) {
710 assert(glsl_type_is_vector_or_scalar(dest_type));
711 nir_intrinsic_instr *store =
712 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
713 store->src[0] = nir_src_for_ssa(src_val->ssa);
714 store->variables[0] = nir_deref_as_var(nir_copy_deref(store, &dest->deref));
715 store->num_components = glsl_get_vector_elements(dest_type);
716
717 nir_builder_instr_insert(&b->nb, &store->instr);
718 } else {
719 assert(src_val->value_type == vtn_value_type_constant);
720
721 nir_variable *const_tmp = rzalloc(b->shader, nir_variable);
722 const_tmp->type = dest_type;
723 const_tmp->name = "const_temp";
724 const_tmp->data.mode = nir_var_local;
725 const_tmp->data.read_only = true;
726 exec_list_push_tail(&b->impl->locals, &const_tmp->node);
727
728 nir_intrinsic_instr *copy =
729 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
730 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
731 copy->variables[1] = nir_deref_var_create(copy, const_tmp);
732
733 nir_builder_instr_insert(&b->nb, &copy->instr);
734 }
735 break;
736 }
737
738 case SpvOpVariableArray:
739 case SpvOpCopyMemorySized:
740 case SpvOpArrayLength:
741 case SpvOpImagePointer:
742 default:
743 unreachable("Unhandled opcode");
744 }
745 }
746
747 static void
748 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
749 const uint32_t *w, unsigned count)
750 {
751 unreachable("Unhandled opcode");
752 }
753
754 static nir_tex_src
755 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
756 {
757 nir_tex_src src;
758 src.src = nir_src_for_ssa(vtn_value(b, index, vtn_value_type_ssa)->ssa);
759 src.src_type = type;
760 return src;
761 }
762
763 static void
764 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
765 const uint32_t *w, unsigned count)
766 {
767 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
768 nir_deref_var *sampler = vtn_value(b, w[3], vtn_value_type_deref)->deref;
769
770 nir_tex_src srcs[8]; /* 8 should be enough */
771 nir_tex_src *p = srcs;
772
773 unsigned coord_components = 0;
774 switch (opcode) {
775 case SpvOpTextureSample:
776 case SpvOpTextureSampleDref:
777 case SpvOpTextureSampleLod:
778 case SpvOpTextureSampleProj:
779 case SpvOpTextureSampleGrad:
780 case SpvOpTextureSampleOffset:
781 case SpvOpTextureSampleProjLod:
782 case SpvOpTextureSampleProjGrad:
783 case SpvOpTextureSampleLodOffset:
784 case SpvOpTextureSampleProjOffset:
785 case SpvOpTextureSampleGradOffset:
786 case SpvOpTextureSampleProjLodOffset:
787 case SpvOpTextureSampleProjGradOffset:
788 case SpvOpTextureFetchTexelLod:
789 case SpvOpTextureFetchTexelOffset:
790 case SpvOpTextureFetchSample:
791 case SpvOpTextureFetchTexel:
792 case SpvOpTextureGather:
793 case SpvOpTextureGatherOffset:
794 case SpvOpTextureGatherOffsets:
795 case SpvOpTextureQueryLod:
796 /* All these types have the coordinate as their first real argument */
797 coord_components = glsl_get_vector_elements(b->values[w[4]].type);
798 p->src = nir_src_for_ssa(vtn_ssa_value(b, w[4]));
799 p->src_type = nir_tex_src_coord;
800 p++;
801 break;
802 default:
803 break;
804 }
805
806 nir_texop texop;
807 switch (opcode) {
808 case SpvOpTextureSample:
809 texop = nir_texop_tex;
810
811 if (count == 6) {
812 texop = nir_texop_txb;
813 *p++ = vtn_tex_src(b, w[5], nir_tex_src_bias);
814 }
815 break;
816
817 case SpvOpTextureSampleDref:
818 case SpvOpTextureSampleLod:
819 case SpvOpTextureSampleProj:
820 case SpvOpTextureSampleGrad:
821 case SpvOpTextureSampleOffset:
822 case SpvOpTextureSampleProjLod:
823 case SpvOpTextureSampleProjGrad:
824 case SpvOpTextureSampleLodOffset:
825 case SpvOpTextureSampleProjOffset:
826 case SpvOpTextureSampleGradOffset:
827 case SpvOpTextureSampleProjLodOffset:
828 case SpvOpTextureSampleProjGradOffset:
829 case SpvOpTextureFetchTexelLod:
830 case SpvOpTextureFetchTexelOffset:
831 case SpvOpTextureFetchSample:
832 case SpvOpTextureFetchTexel:
833 case SpvOpTextureGather:
834 case SpvOpTextureGatherOffset:
835 case SpvOpTextureGatherOffsets:
836 case SpvOpTextureQuerySizeLod:
837 case SpvOpTextureQuerySize:
838 case SpvOpTextureQueryLod:
839 case SpvOpTextureQueryLevels:
840 case SpvOpTextureQuerySamples:
841 default:
842 unreachable("Unhandled opcode");
843 }
844
845 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
846
847 const struct glsl_type *sampler_type = nir_deref_tail(&sampler->deref)->type;
848 instr->sampler_dim = glsl_get_sampler_dim(sampler_type);
849
850 switch (glsl_get_sampler_result_type(sampler_type)) {
851 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
852 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
853 case GLSL_TYPE_UINT: instr->dest_type = nir_type_unsigned; break;
854 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
855 default:
856 unreachable("Invalid base type for sampler result");
857 }
858
859 instr->op = texop;
860 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
861 instr->coord_components = coord_components;
862 instr->is_array = glsl_sampler_type_is_array(sampler_type);
863 instr->is_shadow = glsl_sampler_type_is_shadow(sampler_type);
864
865 instr->sampler = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
866
867 nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
868 val->ssa = &instr->dest.ssa;
869
870 nir_builder_instr_insert(&b->nb, &instr->instr);
871 }
872
873 static void
874 vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
875 const uint32_t *w, unsigned count)
876 {
877 unreachable("Matrix math not handled");
878 }
879
880 static void
881 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
882 const uint32_t *w, unsigned count)
883 {
884 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
885 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
886
887 /* Collect the various SSA sources */
888 unsigned num_inputs = count - 3;
889 nir_ssa_def *src[4];
890 for (unsigned i = 0; i < num_inputs; i++)
891 src[i] = vtn_ssa_value(b, w[i + 3]);
892
893 /* Indicates that the first two arguments should be swapped. This is
894 * used for implementing greater-than and less-than-or-equal.
895 */
896 bool swap = false;
897
898 nir_op op;
899 switch (opcode) {
900 /* Basic ALU operations */
901 case SpvOpSNegate: op = nir_op_ineg; break;
902 case SpvOpFNegate: op = nir_op_fneg; break;
903 case SpvOpNot: op = nir_op_inot; break;
904
905 case SpvOpAny:
906 switch (src[0]->num_components) {
907 case 1: op = nir_op_imov; break;
908 case 2: op = nir_op_bany2; break;
909 case 3: op = nir_op_bany3; break;
910 case 4: op = nir_op_bany4; break;
911 }
912 break;
913
914 case SpvOpAll:
915 switch (src[0]->num_components) {
916 case 1: op = nir_op_imov; break;
917 case 2: op = nir_op_ball2; break;
918 case 3: op = nir_op_ball3; break;
919 case 4: op = nir_op_ball4; break;
920 }
921 break;
922
923 case SpvOpIAdd: op = nir_op_iadd; break;
924 case SpvOpFAdd: op = nir_op_fadd; break;
925 case SpvOpISub: op = nir_op_isub; break;
926 case SpvOpFSub: op = nir_op_fsub; break;
927 case SpvOpIMul: op = nir_op_imul; break;
928 case SpvOpFMul: op = nir_op_fmul; break;
929 case SpvOpUDiv: op = nir_op_udiv; break;
930 case SpvOpSDiv: op = nir_op_idiv; break;
931 case SpvOpFDiv: op = nir_op_fdiv; break;
932 case SpvOpUMod: op = nir_op_umod; break;
933 case SpvOpSMod: op = nir_op_umod; break; /* FIXME? */
934 case SpvOpFMod: op = nir_op_fmod; break;
935
936 case SpvOpDot:
937 assert(src[0]->num_components == src[1]->num_components);
938 switch (src[0]->num_components) {
939 case 1: op = nir_op_fmul; break;
940 case 2: op = nir_op_fdot2; break;
941 case 3: op = nir_op_fdot3; break;
942 case 4: op = nir_op_fdot4; break;
943 }
944 break;
945
946 case SpvOpShiftRightLogical: op = nir_op_ushr; break;
947 case SpvOpShiftRightArithmetic: op = nir_op_ishr; break;
948 case SpvOpShiftLeftLogical: op = nir_op_ishl; break;
949 case SpvOpLogicalOr: op = nir_op_ior; break;
950 case SpvOpLogicalXor: op = nir_op_ixor; break;
951 case SpvOpLogicalAnd: op = nir_op_iand; break;
952 case SpvOpBitwiseOr: op = nir_op_ior; break;
953 case SpvOpBitwiseXor: op = nir_op_ixor; break;
954 case SpvOpBitwiseAnd: op = nir_op_iand; break;
955 case SpvOpSelect: op = nir_op_bcsel; break;
956 case SpvOpIEqual: op = nir_op_ieq; break;
957
958 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
959 case SpvOpFOrdEqual: op = nir_op_feq; break;
960 case SpvOpFUnordEqual: op = nir_op_feq; break;
961 case SpvOpINotEqual: op = nir_op_ine; break;
962 case SpvOpFOrdNotEqual: op = nir_op_fne; break;
963 case SpvOpFUnordNotEqual: op = nir_op_fne; break;
964 case SpvOpULessThan: op = nir_op_ult; break;
965 case SpvOpSLessThan: op = nir_op_ilt; break;
966 case SpvOpFOrdLessThan: op = nir_op_flt; break;
967 case SpvOpFUnordLessThan: op = nir_op_flt; break;
968 case SpvOpUGreaterThan: op = nir_op_ult; swap = true; break;
969 case SpvOpSGreaterThan: op = nir_op_ilt; swap = true; break;
970 case SpvOpFOrdGreaterThan: op = nir_op_flt; swap = true; break;
971 case SpvOpFUnordGreaterThan: op = nir_op_flt; swap = true; break;
972 case SpvOpULessThanEqual: op = nir_op_uge; swap = true; break;
973 case SpvOpSLessThanEqual: op = nir_op_ige; swap = true; break;
974 case SpvOpFOrdLessThanEqual: op = nir_op_fge; swap = true; break;
975 case SpvOpFUnordLessThanEqual: op = nir_op_fge; swap = true; break;
976 case SpvOpUGreaterThanEqual: op = nir_op_uge; break;
977 case SpvOpSGreaterThanEqual: op = nir_op_ige; break;
978 case SpvOpFOrdGreaterThanEqual: op = nir_op_fge; break;
979 case SpvOpFUnordGreaterThanEqual:op = nir_op_fge; break;
980
981 /* Conversions: */
982 case SpvOpConvertFToU: op = nir_op_f2u; break;
983 case SpvOpConvertFToS: op = nir_op_f2i; break;
984 case SpvOpConvertSToF: op = nir_op_i2f; break;
985 case SpvOpConvertUToF: op = nir_op_u2f; break;
986 case SpvOpBitcast: op = nir_op_imov; break;
987 case SpvOpUConvert:
988 case SpvOpSConvert:
989 op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
990 break;
991 case SpvOpFConvert:
992 op = nir_op_fmov;
993 break;
994
995 /* Derivatives: */
996 case SpvOpDPdx: op = nir_op_fddx; break;
997 case SpvOpDPdy: op = nir_op_fddy; break;
998 case SpvOpDPdxFine: op = nir_op_fddx_fine; break;
999 case SpvOpDPdyFine: op = nir_op_fddy_fine; break;
1000 case SpvOpDPdxCoarse: op = nir_op_fddx_coarse; break;
1001 case SpvOpDPdyCoarse: op = nir_op_fddy_coarse; break;
1002 case SpvOpFwidth:
1003 val->ssa = nir_fadd(&b->nb,
1004 nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
1005 nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
1006 return;
1007 case SpvOpFwidthFine:
1008 val->ssa = nir_fadd(&b->nb,
1009 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
1010 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
1011 return;
1012 case SpvOpFwidthCoarse:
1013 val->ssa = nir_fadd(&b->nb,
1014 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
1015 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
1016 return;
1017
1018 case SpvOpVectorTimesScalar:
1019 /* The builder will take care of splatting for us. */
1020 val->ssa = nir_fmul(&b->nb, src[0], src[1]);
1021 return;
1022
1023 case SpvOpSRem:
1024 case SpvOpFRem:
1025 unreachable("No NIR equivalent");
1026
1027 case SpvOpIsNan:
1028 case SpvOpIsInf:
1029 case SpvOpIsFinite:
1030 case SpvOpIsNormal:
1031 case SpvOpSignBitSet:
1032 case SpvOpLessOrGreater:
1033 case SpvOpOrdered:
1034 case SpvOpUnordered:
1035 default:
1036 unreachable("Unhandled opcode");
1037 }
1038
1039 if (swap) {
1040 nir_ssa_def *tmp = src[0];
1041 src[0] = src[1];
1042 src[1] = tmp;
1043 }
1044
1045 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
1046 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
1047 glsl_get_vector_elements(val->type), val->name);
1048 val->ssa = &instr->dest.dest.ssa;
1049
1050 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
1051 instr->src[i].src = nir_src_for_ssa(src[i]);
1052
1053 nir_builder_instr_insert(&b->nb, &instr->instr);
1054 }
1055
1056 static bool
1057 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
1058 const uint32_t *w, unsigned count)
1059 {
1060 switch (opcode) {
1061 case SpvOpSource:
1062 case SpvOpSourceExtension:
1063 case SpvOpCompileFlag:
1064 case SpvOpExtension:
1065 /* Unhandled, but these are for debug so that's ok. */
1066 break;
1067
1068 case SpvOpExtInstImport:
1069 vtn_handle_extension(b, opcode, w, count);
1070 break;
1071
1072 case SpvOpMemoryModel:
1073 assert(w[1] == SpvAddressingModelLogical);
1074 assert(w[2] == SpvMemoryModelGLSL450);
1075 break;
1076
1077 case SpvOpEntryPoint:
1078 assert(b->entry_point == NULL);
1079 b->entry_point = &b->values[w[2]];
1080 b->execution_model = w[1];
1081 break;
1082
1083 case SpvOpExecutionMode:
1084 unreachable("Execution modes not yet implemented");
1085 break;
1086
1087 case SpvOpString:
1088 vtn_push_value(b, w[1], vtn_value_type_string)->str =
1089 vtn_string_literal(b, &w[2], count - 2);
1090 break;
1091
1092 case SpvOpName:
1093 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
1094 break;
1095
1096 case SpvOpMemberName:
1097 /* TODO */
1098 break;
1099
1100 case SpvOpLine:
1101 break; /* Ignored for now */
1102
1103 case SpvOpDecorationGroup:
1104 case SpvOpDecorate:
1105 case SpvOpMemberDecorate:
1106 case SpvOpGroupDecorate:
1107 case SpvOpGroupMemberDecorate:
1108 vtn_handle_decoration(b, opcode, w, count);
1109 break;
1110
1111 case SpvOpTypeVoid:
1112 case SpvOpTypeBool:
1113 case SpvOpTypeInt:
1114 case SpvOpTypeFloat:
1115 case SpvOpTypeVector:
1116 case SpvOpTypeMatrix:
1117 case SpvOpTypeSampler:
1118 case SpvOpTypeArray:
1119 case SpvOpTypeRuntimeArray:
1120 case SpvOpTypeStruct:
1121 case SpvOpTypeOpaque:
1122 case SpvOpTypePointer:
1123 case SpvOpTypeFunction:
1124 case SpvOpTypeEvent:
1125 case SpvOpTypeDeviceEvent:
1126 case SpvOpTypeReserveId:
1127 case SpvOpTypeQueue:
1128 case SpvOpTypePipe:
1129 vtn_push_value(b, w[1], vtn_value_type_type)->type =
1130 vtn_handle_type(b, opcode, &w[2], count - 2);
1131 break;
1132
1133 case SpvOpConstantTrue:
1134 case SpvOpConstantFalse:
1135 case SpvOpConstant:
1136 case SpvOpConstantComposite:
1137 case SpvOpConstantSampler:
1138 case SpvOpConstantNullPointer:
1139 case SpvOpConstantNullObject:
1140 case SpvOpSpecConstantTrue:
1141 case SpvOpSpecConstantFalse:
1142 case SpvOpSpecConstant:
1143 case SpvOpSpecConstantComposite:
1144 vtn_handle_constant(b, opcode, w, count);
1145 break;
1146
1147 case SpvOpVariable:
1148 vtn_handle_variables(b, opcode, w, count);
1149 break;
1150
1151 default:
1152 return false; /* End of preamble */
1153 }
1154
1155 return true;
1156 }
1157
1158 static bool
1159 vtn_handle_first_cfg_pass_instruction(struct vtn_builder *b, SpvOp opcode,
1160 const uint32_t *w, unsigned count)
1161 {
1162 switch (opcode) {
1163 case SpvOpFunction: {
1164 assert(b->func == NULL);
1165 b->func = rzalloc(b, struct vtn_function);
1166
1167 const struct glsl_type *result_type =
1168 vtn_value(b, w[1], vtn_value_type_type)->type;
1169 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
1170 const struct glsl_type *func_type =
1171 vtn_value(b, w[4], vtn_value_type_type)->type;
1172
1173 assert(glsl_get_function_return_type(func_type) == result_type);
1174
1175 nir_function *func =
1176 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
1177
1178 nir_function_overload *overload = nir_function_overload_create(func);
1179 overload->num_params = glsl_get_length(func_type);
1180 overload->params = ralloc_array(overload, nir_parameter,
1181 overload->num_params);
1182 for (unsigned i = 0; i < overload->num_params; i++) {
1183 const struct glsl_function_param *param =
1184 glsl_get_function_param(func_type, i);
1185 overload->params[i].type = param->type;
1186 if (param->in) {
1187 if (param->out) {
1188 overload->params[i].param_type = nir_parameter_inout;
1189 } else {
1190 overload->params[i].param_type = nir_parameter_in;
1191 }
1192 } else {
1193 if (param->out) {
1194 overload->params[i].param_type = nir_parameter_out;
1195 } else {
1196 assert(!"Parameter is neither in nor out");
1197 }
1198 }
1199 }
1200 b->func->overload = overload;
1201 break;
1202 }
1203
1204 case SpvOpFunctionEnd:
1205 b->func = NULL;
1206 break;
1207
1208 case SpvOpFunctionParameter:
1209 break; /* Does nothing */
1210
1211 case SpvOpLabel: {
1212 assert(b->block == NULL);
1213 b->block = rzalloc(b, struct vtn_block);
1214 b->block->label = w;
1215 vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
1216
1217 if (b->func->start_block == NULL) {
1218 /* This is the first block encountered for this function. In this
1219 * case, we set the start block and add it to the list of
1220 * implemented functions that we'll walk later.
1221 */
1222 b->func->start_block = b->block;
1223 exec_list_push_tail(&b->functions, &b->func->node);
1224 }
1225 break;
1226 }
1227
1228 case SpvOpBranch:
1229 case SpvOpBranchConditional:
1230 case SpvOpSwitch:
1231 case SpvOpKill:
1232 case SpvOpReturn:
1233 case SpvOpReturnValue:
1234 case SpvOpUnreachable:
1235 assert(b->block);
1236 b->block->branch = w;
1237 b->block = NULL;
1238 break;
1239
1240 case SpvOpSelectionMerge:
1241 case SpvOpLoopMerge:
1242 assert(b->block && b->block->merge_op == SpvOpNop);
1243 b->block->merge_op = opcode;
1244 b->block->merge_block_id = w[1];
1245 break;
1246
1247 default:
1248 /* Continue on as per normal */
1249 return true;
1250 }
1251
1252 return true;
1253 }
1254
1255 static bool
1256 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
1257 const uint32_t *w, unsigned count)
1258 {
1259 switch (opcode) {
1260 case SpvOpLabel: {
1261 struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
1262 assert(block->block == NULL);
1263
1264 struct exec_node *list_tail = exec_list_get_tail(b->nb.cf_node_list);
1265 nir_cf_node *tail_node = exec_node_data(nir_cf_node, list_tail, node);
1266 assert(tail_node->type == nir_cf_node_block);
1267 block->block = nir_cf_node_as_block(tail_node);
1268 break;
1269 }
1270
1271 case SpvOpLoopMerge:
1272 case SpvOpSelectionMerge:
1273 /* This is handled by cfg pre-pass and walk_blocks */
1274 break;
1275
1276 case SpvOpUndef:
1277 vtn_push_value(b, w[2], vtn_value_type_undef);
1278 break;
1279
1280 case SpvOpExtInst:
1281 vtn_handle_extension(b, opcode, w, count);
1282 break;
1283
1284 case SpvOpVariable:
1285 case SpvOpVariableArray:
1286 case SpvOpLoad:
1287 case SpvOpStore:
1288 case SpvOpCopyMemory:
1289 case SpvOpCopyMemorySized:
1290 case SpvOpAccessChain:
1291 case SpvOpInBoundsAccessChain:
1292 case SpvOpArrayLength:
1293 case SpvOpImagePointer:
1294 vtn_handle_variables(b, opcode, w, count);
1295 break;
1296
1297 case SpvOpFunctionCall:
1298 vtn_handle_function_call(b, opcode, w, count);
1299 break;
1300
1301 case SpvOpTextureSample:
1302 case SpvOpTextureSampleDref:
1303 case SpvOpTextureSampleLod:
1304 case SpvOpTextureSampleProj:
1305 case SpvOpTextureSampleGrad:
1306 case SpvOpTextureSampleOffset:
1307 case SpvOpTextureSampleProjLod:
1308 case SpvOpTextureSampleProjGrad:
1309 case SpvOpTextureSampleLodOffset:
1310 case SpvOpTextureSampleProjOffset:
1311 case SpvOpTextureSampleGradOffset:
1312 case SpvOpTextureSampleProjLodOffset:
1313 case SpvOpTextureSampleProjGradOffset:
1314 case SpvOpTextureFetchTexelLod:
1315 case SpvOpTextureFetchTexelOffset:
1316 case SpvOpTextureFetchSample:
1317 case SpvOpTextureFetchTexel:
1318 case SpvOpTextureGather:
1319 case SpvOpTextureGatherOffset:
1320 case SpvOpTextureGatherOffsets:
1321 case SpvOpTextureQuerySizeLod:
1322 case SpvOpTextureQuerySize:
1323 case SpvOpTextureQueryLod:
1324 case SpvOpTextureQueryLevels:
1325 case SpvOpTextureQuerySamples:
1326 vtn_handle_texture(b, opcode, w, count);
1327 break;
1328
1329 case SpvOpSNegate:
1330 case SpvOpFNegate:
1331 case SpvOpNot:
1332 case SpvOpAny:
1333 case SpvOpAll:
1334 case SpvOpConvertFToU:
1335 case SpvOpConvertFToS:
1336 case SpvOpConvertSToF:
1337 case SpvOpConvertUToF:
1338 case SpvOpUConvert:
1339 case SpvOpSConvert:
1340 case SpvOpFConvert:
1341 case SpvOpConvertPtrToU:
1342 case SpvOpConvertUToPtr:
1343 case SpvOpPtrCastToGeneric:
1344 case SpvOpGenericCastToPtr:
1345 case SpvOpBitcast:
1346 case SpvOpIsNan:
1347 case SpvOpIsInf:
1348 case SpvOpIsFinite:
1349 case SpvOpIsNormal:
1350 case SpvOpSignBitSet:
1351 case SpvOpLessOrGreater:
1352 case SpvOpOrdered:
1353 case SpvOpUnordered:
1354 case SpvOpIAdd:
1355 case SpvOpFAdd:
1356 case SpvOpISub:
1357 case SpvOpFSub:
1358 case SpvOpIMul:
1359 case SpvOpFMul:
1360 case SpvOpUDiv:
1361 case SpvOpSDiv:
1362 case SpvOpFDiv:
1363 case SpvOpUMod:
1364 case SpvOpSRem:
1365 case SpvOpSMod:
1366 case SpvOpFRem:
1367 case SpvOpFMod:
1368 case SpvOpVectorTimesScalar:
1369 case SpvOpDot:
1370 case SpvOpShiftRightLogical:
1371 case SpvOpShiftRightArithmetic:
1372 case SpvOpShiftLeftLogical:
1373 case SpvOpLogicalOr:
1374 case SpvOpLogicalXor:
1375 case SpvOpLogicalAnd:
1376 case SpvOpBitwiseOr:
1377 case SpvOpBitwiseXor:
1378 case SpvOpBitwiseAnd:
1379 case SpvOpSelect:
1380 case SpvOpIEqual:
1381 case SpvOpFOrdEqual:
1382 case SpvOpFUnordEqual:
1383 case SpvOpINotEqual:
1384 case SpvOpFOrdNotEqual:
1385 case SpvOpFUnordNotEqual:
1386 case SpvOpULessThan:
1387 case SpvOpSLessThan:
1388 case SpvOpFOrdLessThan:
1389 case SpvOpFUnordLessThan:
1390 case SpvOpUGreaterThan:
1391 case SpvOpSGreaterThan:
1392 case SpvOpFOrdGreaterThan:
1393 case SpvOpFUnordGreaterThan:
1394 case SpvOpULessThanEqual:
1395 case SpvOpSLessThanEqual:
1396 case SpvOpFOrdLessThanEqual:
1397 case SpvOpFUnordLessThanEqual:
1398 case SpvOpUGreaterThanEqual:
1399 case SpvOpSGreaterThanEqual:
1400 case SpvOpFOrdGreaterThanEqual:
1401 case SpvOpFUnordGreaterThanEqual:
1402 case SpvOpDPdx:
1403 case SpvOpDPdy:
1404 case SpvOpFwidth:
1405 case SpvOpDPdxFine:
1406 case SpvOpDPdyFine:
1407 case SpvOpFwidthFine:
1408 case SpvOpDPdxCoarse:
1409 case SpvOpDPdyCoarse:
1410 case SpvOpFwidthCoarse:
1411 vtn_handle_alu(b, opcode, w, count);
1412 break;
1413
1414 case SpvOpTranspose:
1415 case SpvOpOuterProduct:
1416 case SpvOpMatrixTimesScalar:
1417 case SpvOpVectorTimesMatrix:
1418 case SpvOpMatrixTimesVector:
1419 case SpvOpMatrixTimesMatrix:
1420 vtn_handle_matrix_alu(b, opcode, w, count);
1421 break;
1422
1423 default:
1424 unreachable("Unhandled opcode");
1425 }
1426
1427 return true;
1428 }
1429
1430 static void
1431 vtn_walk_blocks(struct vtn_builder *b, struct vtn_block *start,
1432 struct vtn_block *break_block, struct vtn_block *cont_block,
1433 struct vtn_block *end_block)
1434 {
1435 struct vtn_block *block = start;
1436 while (block != end_block) {
1437 if (block->block != NULL) {
1438 /* We've already visited this block once before so this is a
1439 * back-edge. Back-edges are only allowed to point to a loop
1440 * merge.
1441 */
1442 assert(block == cont_block);
1443 return;
1444 }
1445
1446 if (block->merge_op == SpvOpLoopMerge) {
1447 /* This is the jump into a loop. */
1448 cont_block = block;
1449 break_block = vtn_value(b, block->merge_block_id,
1450 vtn_value_type_block)->block;
1451
1452 nir_loop *loop = nir_loop_create(b->shader);
1453 nir_cf_node_insert_end(b->nb.cf_node_list, &loop->cf_node);
1454
1455 struct exec_list *old_list = b->nb.cf_node_list;
1456
1457 /* Reset the merge_op to prerevent infinite recursion */
1458 block->merge_op = SpvOpNop;
1459
1460 nir_builder_insert_after_cf_list(&b->nb, &loop->body);
1461 vtn_walk_blocks(b, block, break_block, cont_block, NULL);
1462
1463 nir_builder_insert_after_cf_list(&b->nb, old_list);
1464 block = break_block;
1465 continue;
1466 }
1467
1468 const uint32_t *w = block->branch;
1469 SpvOp branch_op = w[0] & SpvOpCodeMask;
1470
1471 b->block = block;
1472 vtn_foreach_instruction(b, block->label, block->branch,
1473 vtn_handle_body_instruction);
1474
1475 switch (branch_op) {
1476 case SpvOpBranch: {
1477 struct vtn_block *branch_block =
1478 vtn_value(b, w[1], vtn_value_type_block)->block;
1479
1480 if (branch_block == break_block) {
1481 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1482 nir_jump_break);
1483 nir_builder_instr_insert(&b->nb, &jump->instr);
1484
1485 return;
1486 } else if (branch_block == cont_block) {
1487 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1488 nir_jump_continue);
1489 nir_builder_instr_insert(&b->nb, &jump->instr);
1490
1491 return;
1492 } else if (branch_block == end_block) {
1493 return;
1494 } else {
1495 block = branch_block;
1496 continue;
1497 }
1498 }
1499
1500 case SpvOpBranchConditional: {
1501 /* Gather up the branch blocks */
1502 struct vtn_block *then_block =
1503 vtn_value(b, w[2], vtn_value_type_block)->block;
1504 struct vtn_block *else_block =
1505 vtn_value(b, w[3], vtn_value_type_block)->block;
1506
1507 nir_if *if_stmt = nir_if_create(b->shader);
1508 if_stmt->condition = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
1509 nir_cf_node_insert_end(b->nb.cf_node_list, &if_stmt->cf_node);
1510
1511 if (then_block == break_block) {
1512 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1513 nir_jump_break);
1514 nir_instr_insert_after_cf_list(&if_stmt->then_list,
1515 &jump->instr);
1516 block = else_block;
1517 } else if (else_block == break_block) {
1518 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1519 nir_jump_break);
1520 nir_instr_insert_after_cf_list(&if_stmt->else_list,
1521 &jump->instr);
1522 block = then_block;
1523 } else if (then_block == cont_block) {
1524 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1525 nir_jump_continue);
1526 nir_instr_insert_after_cf_list(&if_stmt->then_list,
1527 &jump->instr);
1528 block = else_block;
1529 } else if (else_block == cont_block) {
1530 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1531 nir_jump_continue);
1532 nir_instr_insert_after_cf_list(&if_stmt->else_list,
1533 &jump->instr);
1534 block = then_block;
1535 } else {
1536 /* Conventional if statement */
1537 assert(block->merge_op == SpvOpSelectionMerge);
1538 struct vtn_block *merge_block =
1539 vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
1540
1541 struct exec_list *old_list = b->nb.cf_node_list;
1542
1543 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->then_list);
1544 vtn_walk_blocks(b, then_block, break_block, cont_block, merge_block);
1545
1546 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->else_list);
1547 vtn_walk_blocks(b, else_block, break_block, cont_block, merge_block);
1548
1549 nir_builder_insert_after_cf_list(&b->nb, old_list);
1550 block = merge_block;
1551 continue;
1552 }
1553
1554 /* If we got here then we inserted a predicated break or continue
1555 * above and we need to handle the other case. We already set
1556 * `block` above to indicate what block to visit after the
1557 * predicated break.
1558 */
1559
1560 /* It's possible that the other branch is also a break/continue.
1561 * If it is, we handle that here.
1562 */
1563 if (block == break_block) {
1564 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1565 nir_jump_break);
1566 nir_builder_instr_insert(&b->nb, &jump->instr);
1567
1568 return;
1569 } else if (block == cont_block) {
1570 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1571 nir_jump_continue);
1572 nir_builder_instr_insert(&b->nb, &jump->instr);
1573
1574 return;
1575 }
1576
1577 /* If we got here then there was a predicated break/continue but
1578 * the other half of the if has stuff in it. `block` was already
1579 * set above so there is nothing left for us to do.
1580 */
1581 continue;
1582 }
1583
1584 case SpvOpReturn: {
1585 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1586 nir_jump_return);
1587 nir_builder_instr_insert(&b->nb, &jump->instr);
1588 return;
1589 }
1590
1591 case SpvOpKill: {
1592 nir_intrinsic_instr *discard =
1593 nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
1594 nir_builder_instr_insert(&b->nb, &discard->instr);
1595 return;
1596 }
1597
1598 case SpvOpSwitch:
1599 case SpvOpReturnValue:
1600 case SpvOpUnreachable:
1601 default:
1602 unreachable("Unhandled opcode");
1603 }
1604 }
1605 }
1606
1607 nir_shader *
1608 spirv_to_nir(const uint32_t *words, size_t word_count,
1609 const nir_shader_compiler_options *options)
1610 {
1611 const uint32_t *word_end = words + word_count;
1612
1613 /* Handle the SPIR-V header (first 4 dwords) */
1614 assert(word_count > 5);
1615
1616 assert(words[0] == SpvMagicNumber);
1617 assert(words[1] == 99);
1618 /* words[2] == generator magic */
1619 unsigned value_id_bound = words[3];
1620 assert(words[4] == 0);
1621
1622 words+= 5;
1623
1624 nir_shader *shader = nir_shader_create(NULL, options);
1625
1626 /* Initialize the stn_builder object */
1627 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
1628 b->shader = shader;
1629 b->value_id_bound = value_id_bound;
1630 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
1631 exec_list_make_empty(&b->functions);
1632
1633 /* Handle all the preamble instructions */
1634 words = vtn_foreach_instruction(b, words, word_end,
1635 vtn_handle_preamble_instruction);
1636
1637 /* Do a very quick CFG analysis pass */
1638 vtn_foreach_instruction(b, words, word_end,
1639 vtn_handle_first_cfg_pass_instruction);
1640
1641 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
1642 b->impl = nir_function_impl_create(func->overload);
1643 nir_builder_init(&b->nb, b->impl);
1644 nir_builder_insert_after_cf_list(&b->nb, &b->impl->body);
1645 vtn_walk_blocks(b, func->start_block, NULL, NULL, NULL);
1646 }
1647
1648 ralloc_free(b);
1649
1650 return shader;
1651 }