979df2019e0159c2232f1c7c06081dd325f92c92
[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 SpvDecorationBlock:
419 case SpvDecorationBufferBlock:
420 case SpvDecorationRowMajor:
421 case SpvDecorationColMajor:
422 case SpvDecorationGLSLShared:
423 case SpvDecorationGLSLStd140:
424 case SpvDecorationGLSLStd430:
425 case SpvDecorationGLSLPacked:
426 case SpvDecorationPatch:
427 case SpvDecorationRestrict:
428 case SpvDecorationAliased:
429 case SpvDecorationVolatile:
430 case SpvDecorationCoherent:
431 case SpvDecorationNonreadable:
432 case SpvDecorationUniform:
433 /* This is really nice but we have no use for it right now. */
434 case SpvDecorationNoStaticUse:
435 case SpvDecorationCPacked:
436 case SpvDecorationSaturatedConversion:
437 case SpvDecorationStream:
438 case SpvDecorationDescriptorSet:
439 case SpvDecorationOffset:
440 case SpvDecorationAlignment:
441 case SpvDecorationXfbBuffer:
442 case SpvDecorationStride:
443 case SpvDecorationBuiltIn:
444 case SpvDecorationFuncParamAttr:
445 case SpvDecorationFPRoundingMode:
446 case SpvDecorationFPFastMathMode:
447 case SpvDecorationLinkageAttributes:
448 case SpvDecorationSpecId:
449 default:
450 unreachable("Unhandled variable decoration");
451 }
452 }
453
454 static void
455 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
456 const uint32_t *w, unsigned count)
457 {
458 switch (opcode) {
459 case SpvOpVariable: {
460 const struct glsl_type *type =
461 vtn_value(b, w[1], vtn_value_type_type)->type;
462 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
463
464 nir_variable *var = ralloc(b->shader, nir_variable);
465
466 var->type = type;
467 var->name = ralloc_strdup(var, val->name);
468
469 switch ((SpvStorageClass)w[3]) {
470 case SpvStorageClassUniformConstant:
471 var->data.mode = nir_var_uniform;
472 var->data.read_only = true;
473 break;
474 case SpvStorageClassInput:
475 var->data.mode = nir_var_shader_in;
476 var->data.read_only = true;
477 break;
478 case SpvStorageClassOutput:
479 var->data.mode = nir_var_shader_out;
480 break;
481 case SpvStorageClassPrivateGlobal:
482 var->data.mode = nir_var_global;
483 break;
484 case SpvStorageClassFunction:
485 var->data.mode = nir_var_local;
486 break;
487 case SpvStorageClassUniform:
488 case SpvStorageClassWorkgroupLocal:
489 case SpvStorageClassWorkgroupGlobal:
490 case SpvStorageClassGeneric:
491 case SpvStorageClassPrivate:
492 case SpvStorageClassAtomicCounter:
493 default:
494 unreachable("Unhandled variable storage class");
495 }
496
497 if (count > 4) {
498 assert(count == 5);
499 var->constant_initializer =
500 vtn_value(b, w[4], vtn_value_type_constant)->constant;
501 }
502
503 if (var->data.mode == nir_var_local) {
504 exec_list_push_tail(&b->impl->locals, &var->node);
505 } else {
506 exec_list_push_tail(&b->shader->globals, &var->node);
507 }
508
509 val->deref = nir_deref_var_create(b->shader, var);
510
511 vtn_foreach_decoration(b, val, var_decoration_cb, var);
512 break;
513 }
514
515 case SpvOpAccessChain:
516 case SpvOpInBoundsAccessChain: {
517 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
518 nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
519 val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
520
521 nir_deref *tail = &val->deref->deref;
522 while (tail->child)
523 tail = tail->child;
524
525 for (unsigned i = 0; i < count - 4; i++) {
526 assert(w[i + 4] < b->value_id_bound);
527 struct vtn_value *idx_val = &b->values[w[i + 4]];
528
529 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
530 switch (base_type) {
531 case GLSL_TYPE_UINT:
532 case GLSL_TYPE_INT:
533 case GLSL_TYPE_FLOAT:
534 case GLSL_TYPE_DOUBLE:
535 case GLSL_TYPE_BOOL:
536 case GLSL_TYPE_ARRAY: {
537 nir_deref_array *deref_arr = nir_deref_array_create(b);
538 if (base_type == GLSL_TYPE_ARRAY) {
539 deref_arr->deref.type = glsl_get_array_element(tail->type);
540 } else if (glsl_type_is_matrix(tail->type)) {
541 deref_arr->deref.type = glsl_get_column_type(tail->type);
542 } else {
543 assert(glsl_type_is_vector(tail->type));
544 deref_arr->deref.type = glsl_scalar_type(base_type);
545 }
546
547 if (idx_val->value_type == vtn_value_type_constant) {
548 unsigned idx = idx_val->constant->value.u[0];
549 deref_arr->deref_array_type = nir_deref_array_type_direct;
550 deref_arr->base_offset = idx;
551 } else {
552 assert(idx_val->value_type == vtn_value_type_ssa);
553 deref_arr->deref_array_type = nir_deref_array_type_indirect;
554 deref_arr->base_offset = 0;
555 deref_arr->indirect = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
556 }
557 tail->child = &deref_arr->deref;
558 break;
559 }
560
561 case GLSL_TYPE_STRUCT: {
562 assert(idx_val->value_type == vtn_value_type_constant);
563 unsigned idx = idx_val->constant->value.u[0];
564 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
565 deref_struct->deref.type = glsl_get_struct_field(tail->type, idx);
566 tail->child = &deref_struct->deref;
567 break;
568 }
569 default:
570 unreachable("Invalid type for deref");
571 }
572 tail = tail->child;
573 }
574 break;
575 }
576
577 case SpvOpCopyMemory: {
578 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
579 nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
580
581 nir_intrinsic_instr *copy =
582 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
583 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
584 copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
585
586 nir_builder_instr_insert(&b->nb, &copy->instr);
587 break;
588 }
589
590 case SpvOpLoad: {
591 nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
592 const struct glsl_type *src_type = nir_deref_tail(&src->deref)->type;
593
594 if (glsl_get_base_type(src_type) == GLSL_TYPE_SAMPLER) {
595 vtn_push_value(b, w[2], vtn_value_type_deref)->deref = src;
596 return;
597 }
598
599 assert(glsl_type_is_vector_or_scalar(src_type));
600 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
601
602 nir_intrinsic_instr *load =
603 nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
604 load->variables[0] = nir_deref_as_var(nir_copy_deref(load, &src->deref));
605 load->num_components = glsl_get_vector_elements(src_type);
606 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components,
607 val->name);
608
609 nir_builder_instr_insert(&b->nb, &load->instr);
610 val->type = src_type;
611
612 if (src->var->data.mode == nir_var_uniform &&
613 glsl_get_base_type(src_type) == GLSL_TYPE_BOOL) {
614 /* Uniform boolean loads need to be fixed up since they're defined
615 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
616 */
617 val->ssa = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
618 } else {
619 val->ssa = &load->dest.ssa;
620 }
621 break;
622 }
623
624 case SpvOpStore: {
625 nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
626 const struct glsl_type *dest_type = nir_deref_tail(&dest->deref)->type;
627 struct vtn_value *src_val = vtn_untyped_value(b, w[2]);
628 if (src_val->value_type == vtn_value_type_ssa) {
629 assert(glsl_type_is_vector_or_scalar(dest_type));
630 nir_intrinsic_instr *store =
631 nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
632 store->src[0] = nir_src_for_ssa(src_val->ssa);
633 store->variables[0] = nir_deref_as_var(nir_copy_deref(store, &dest->deref));
634 store->num_components = glsl_get_vector_elements(dest_type);
635
636 nir_builder_instr_insert(&b->nb, &store->instr);
637 } else {
638 assert(src_val->value_type == vtn_value_type_constant);
639
640 nir_variable *const_tmp = rzalloc(b->shader, nir_variable);
641 const_tmp->type = dest_type;
642 const_tmp->name = "const_temp";
643 const_tmp->data.mode = nir_var_local;
644 const_tmp->data.read_only = true;
645 exec_list_push_tail(&b->impl->locals, &const_tmp->node);
646
647 nir_intrinsic_instr *copy =
648 nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
649 copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
650 copy->variables[1] = nir_deref_var_create(copy, const_tmp);
651
652 nir_builder_instr_insert(&b->nb, &copy->instr);
653 }
654 break;
655 }
656
657 case SpvOpVariableArray:
658 case SpvOpCopyMemorySized:
659 case SpvOpArrayLength:
660 case SpvOpImagePointer:
661 default:
662 unreachable("Unhandled opcode");
663 }
664 }
665
666 static void
667 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
668 const uint32_t *w, unsigned count)
669 {
670 unreachable("Unhandled opcode");
671 }
672
673 static nir_tex_src
674 vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
675 {
676 nir_tex_src src;
677 src.src = nir_src_for_ssa(vtn_value(b, index, vtn_value_type_ssa)->ssa);
678 src.src_type = type;
679 return src;
680 }
681
682 static void
683 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
684 const uint32_t *w, unsigned count)
685 {
686 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
687 nir_deref_var *sampler = vtn_value(b, w[3], vtn_value_type_deref)->deref;
688
689 nir_tex_src srcs[8]; /* 8 should be enough */
690 nir_tex_src *p = srcs;
691
692 unsigned coord_components = 0;
693 switch (opcode) {
694 case SpvOpTextureSample:
695 case SpvOpTextureSampleDref:
696 case SpvOpTextureSampleLod:
697 case SpvOpTextureSampleProj:
698 case SpvOpTextureSampleGrad:
699 case SpvOpTextureSampleOffset:
700 case SpvOpTextureSampleProjLod:
701 case SpvOpTextureSampleProjGrad:
702 case SpvOpTextureSampleLodOffset:
703 case SpvOpTextureSampleProjOffset:
704 case SpvOpTextureSampleGradOffset:
705 case SpvOpTextureSampleProjLodOffset:
706 case SpvOpTextureSampleProjGradOffset:
707 case SpvOpTextureFetchTexelLod:
708 case SpvOpTextureFetchTexelOffset:
709 case SpvOpTextureFetchSample:
710 case SpvOpTextureFetchTexel:
711 case SpvOpTextureGather:
712 case SpvOpTextureGatherOffset:
713 case SpvOpTextureGatherOffsets:
714 case SpvOpTextureQueryLod: {
715 /* All these types have the coordinate as their first real argument */
716 struct vtn_value *coord = vtn_value(b, w[4], vtn_value_type_ssa);
717 coord_components = glsl_get_vector_elements(coord->type);
718 p->src = nir_src_for_ssa(coord->ssa);
719 p->src_type = nir_tex_src_coord;
720 p++;
721 break;
722 }
723 default:
724 break;
725 }
726
727 nir_texop texop;
728 switch (opcode) {
729 case SpvOpTextureSample:
730 texop = nir_texop_tex;
731
732 if (count == 6) {
733 texop = nir_texop_txb;
734 *p++ = vtn_tex_src(b, w[5], nir_tex_src_bias);
735 }
736 break;
737
738 case SpvOpTextureSampleDref:
739 case SpvOpTextureSampleLod:
740 case SpvOpTextureSampleProj:
741 case SpvOpTextureSampleGrad:
742 case SpvOpTextureSampleOffset:
743 case SpvOpTextureSampleProjLod:
744 case SpvOpTextureSampleProjGrad:
745 case SpvOpTextureSampleLodOffset:
746 case SpvOpTextureSampleProjOffset:
747 case SpvOpTextureSampleGradOffset:
748 case SpvOpTextureSampleProjLodOffset:
749 case SpvOpTextureSampleProjGradOffset:
750 case SpvOpTextureFetchTexelLod:
751 case SpvOpTextureFetchTexelOffset:
752 case SpvOpTextureFetchSample:
753 case SpvOpTextureFetchTexel:
754 case SpvOpTextureGather:
755 case SpvOpTextureGatherOffset:
756 case SpvOpTextureGatherOffsets:
757 case SpvOpTextureQuerySizeLod:
758 case SpvOpTextureQuerySize:
759 case SpvOpTextureQueryLod:
760 case SpvOpTextureQueryLevels:
761 case SpvOpTextureQuerySamples:
762 default:
763 unreachable("Unhandled opcode");
764 }
765
766 nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
767
768 const struct glsl_type *sampler_type = nir_deref_tail(&sampler->deref)->type;
769 instr->sampler_dim = glsl_get_sampler_dim(sampler_type);
770
771 switch (glsl_get_sampler_result_type(sampler_type)) {
772 case GLSL_TYPE_FLOAT: instr->dest_type = nir_type_float; break;
773 case GLSL_TYPE_INT: instr->dest_type = nir_type_int; break;
774 case GLSL_TYPE_UINT: instr->dest_type = nir_type_unsigned; break;
775 case GLSL_TYPE_BOOL: instr->dest_type = nir_type_bool; break;
776 default:
777 unreachable("Invalid base type for sampler result");
778 }
779
780 instr->op = texop;
781 memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
782 instr->coord_components = coord_components;
783 instr->is_array = glsl_sampler_type_is_array(sampler_type);
784 instr->is_shadow = glsl_sampler_type_is_shadow(sampler_type);
785
786 instr->sampler = sampler;
787
788 nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
789 val->ssa = &instr->dest.ssa;
790
791 nir_builder_instr_insert(&b->nb, &instr->instr);
792 }
793
794 static void
795 vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
796 const uint32_t *w, unsigned count)
797 {
798 unreachable("Matrix math not handled");
799 }
800
801 static void
802 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
803 const uint32_t *w, unsigned count)
804 {
805 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
806 val->type = vtn_value(b, w[1], vtn_value_type_type)->type;
807
808 /* Collect the various SSA sources */
809 unsigned num_inputs = count - 3;
810 nir_ssa_def *src[4];
811 for (unsigned i = 0; i < num_inputs; i++)
812 src[i] = vtn_ssa_value(b, w[i + 3]);
813
814 /* Indicates that the first two arguments should be swapped. This is
815 * used for implementing greater-than and less-than-or-equal.
816 */
817 bool swap = false;
818
819 nir_op op;
820 switch (opcode) {
821 /* Basic ALU operations */
822 case SpvOpSNegate: op = nir_op_ineg; break;
823 case SpvOpFNegate: op = nir_op_fneg; break;
824 case SpvOpNot: op = nir_op_inot; break;
825
826 case SpvOpAny:
827 switch (src[0]->num_components) {
828 case 1: op = nir_op_imov; break;
829 case 2: op = nir_op_bany2; break;
830 case 3: op = nir_op_bany3; break;
831 case 4: op = nir_op_bany4; break;
832 }
833 break;
834
835 case SpvOpAll:
836 switch (src[0]->num_components) {
837 case 1: op = nir_op_imov; break;
838 case 2: op = nir_op_ball2; break;
839 case 3: op = nir_op_ball3; break;
840 case 4: op = nir_op_ball4; break;
841 }
842 break;
843
844 case SpvOpIAdd: op = nir_op_iadd; break;
845 case SpvOpFAdd: op = nir_op_fadd; break;
846 case SpvOpISub: op = nir_op_isub; break;
847 case SpvOpFSub: op = nir_op_fsub; break;
848 case SpvOpIMul: op = nir_op_imul; break;
849 case SpvOpFMul: op = nir_op_fmul; break;
850 case SpvOpUDiv: op = nir_op_udiv; break;
851 case SpvOpSDiv: op = nir_op_idiv; break;
852 case SpvOpFDiv: op = nir_op_fdiv; break;
853 case SpvOpUMod: op = nir_op_umod; break;
854 case SpvOpSMod: op = nir_op_umod; break; /* FIXME? */
855 case SpvOpFMod: op = nir_op_fmod; break;
856
857 case SpvOpDot:
858 assert(src[0]->num_components == src[1]->num_components);
859 switch (src[0]->num_components) {
860 case 1: op = nir_op_fmul; break;
861 case 2: op = nir_op_fdot2; break;
862 case 3: op = nir_op_fdot3; break;
863 case 4: op = nir_op_fdot4; break;
864 }
865 break;
866
867 case SpvOpShiftRightLogical: op = nir_op_ushr; break;
868 case SpvOpShiftRightArithmetic: op = nir_op_ishr; break;
869 case SpvOpShiftLeftLogical: op = nir_op_ishl; break;
870 case SpvOpLogicalOr: op = nir_op_ior; break;
871 case SpvOpLogicalXor: op = nir_op_ixor; break;
872 case SpvOpLogicalAnd: op = nir_op_iand; break;
873 case SpvOpBitwiseOr: op = nir_op_ior; break;
874 case SpvOpBitwiseXor: op = nir_op_ixor; break;
875 case SpvOpBitwiseAnd: op = nir_op_iand; break;
876 case SpvOpSelect: op = nir_op_bcsel; break;
877 case SpvOpIEqual: op = nir_op_ieq; break;
878
879 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
880 case SpvOpFOrdEqual: op = nir_op_feq; break;
881 case SpvOpFUnordEqual: op = nir_op_feq; break;
882 case SpvOpINotEqual: op = nir_op_ine; break;
883 case SpvOpFOrdNotEqual: op = nir_op_fne; break;
884 case SpvOpFUnordNotEqual: op = nir_op_fne; break;
885 case SpvOpULessThan: op = nir_op_ult; break;
886 case SpvOpSLessThan: op = nir_op_ilt; break;
887 case SpvOpFOrdLessThan: op = nir_op_flt; break;
888 case SpvOpFUnordLessThan: op = nir_op_flt; break;
889 case SpvOpUGreaterThan: op = nir_op_ult; swap = true; break;
890 case SpvOpSGreaterThan: op = nir_op_ilt; swap = true; break;
891 case SpvOpFOrdGreaterThan: op = nir_op_flt; swap = true; break;
892 case SpvOpFUnordGreaterThan: op = nir_op_flt; swap = true; break;
893 case SpvOpULessThanEqual: op = nir_op_uge; swap = true; break;
894 case SpvOpSLessThanEqual: op = nir_op_ige; swap = true; break;
895 case SpvOpFOrdLessThanEqual: op = nir_op_fge; swap = true; break;
896 case SpvOpFUnordLessThanEqual: op = nir_op_fge; swap = true; break;
897 case SpvOpUGreaterThanEqual: op = nir_op_uge; break;
898 case SpvOpSGreaterThanEqual: op = nir_op_ige; break;
899 case SpvOpFOrdGreaterThanEqual: op = nir_op_fge; break;
900 case SpvOpFUnordGreaterThanEqual:op = nir_op_fge; break;
901
902 /* Conversions: */
903 case SpvOpConvertFToU: op = nir_op_f2u; break;
904 case SpvOpConvertFToS: op = nir_op_f2i; break;
905 case SpvOpConvertSToF: op = nir_op_i2f; break;
906 case SpvOpConvertUToF: op = nir_op_u2f; break;
907 case SpvOpBitcast: op = nir_op_imov; break;
908 case SpvOpUConvert:
909 case SpvOpSConvert:
910 op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
911 break;
912 case SpvOpFConvert:
913 op = nir_op_fmov;
914 break;
915
916 /* Derivatives: */
917 case SpvOpDPdx: op = nir_op_fddx; break;
918 case SpvOpDPdy: op = nir_op_fddy; break;
919 case SpvOpDPdxFine: op = nir_op_fddx_fine; break;
920 case SpvOpDPdyFine: op = nir_op_fddy_fine; break;
921 case SpvOpDPdxCoarse: op = nir_op_fddx_coarse; break;
922 case SpvOpDPdyCoarse: op = nir_op_fddy_coarse; break;
923 case SpvOpFwidth:
924 val->ssa = nir_fadd(&b->nb,
925 nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
926 nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
927 return;
928 case SpvOpFwidthFine:
929 val->ssa = nir_fadd(&b->nb,
930 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
931 nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
932 return;
933 case SpvOpFwidthCoarse:
934 val->ssa = nir_fadd(&b->nb,
935 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
936 nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
937 return;
938
939 case SpvOpVectorTimesScalar:
940 /* The builder will take care of splatting for us. */
941 val->ssa = nir_fmul(&b->nb, src[0], src[1]);
942 return;
943
944 case SpvOpSRem:
945 case SpvOpFRem:
946 unreachable("No NIR equivalent");
947
948 case SpvOpIsNan:
949 case SpvOpIsInf:
950 case SpvOpIsFinite:
951 case SpvOpIsNormal:
952 case SpvOpSignBitSet:
953 case SpvOpLessOrGreater:
954 case SpvOpOrdered:
955 case SpvOpUnordered:
956 default:
957 unreachable("Unhandled opcode");
958 }
959
960 if (swap) {
961 nir_ssa_def *tmp = src[0];
962 src[0] = src[1];
963 src[1] = tmp;
964 }
965
966 nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
967 nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
968 glsl_get_vector_elements(val->type), val->name);
969 val->ssa = &instr->dest.dest.ssa;
970
971 for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
972 instr->src[i].src = nir_src_for_ssa(src[i]);
973
974 nir_builder_instr_insert(&b->nb, &instr->instr);
975 }
976
977 static bool
978 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
979 const uint32_t *w, unsigned count)
980 {
981 switch (opcode) {
982 case SpvOpSource:
983 case SpvOpSourceExtension:
984 case SpvOpCompileFlag:
985 case SpvOpExtension:
986 /* Unhandled, but these are for debug so that's ok. */
987 break;
988
989 case SpvOpExtInstImport:
990 vtn_handle_extension(b, opcode, w, count);
991 break;
992
993 case SpvOpMemoryModel:
994 assert(w[1] == SpvAddressingModelLogical);
995 assert(w[2] == SpvMemoryModelGLSL450);
996 break;
997
998 case SpvOpEntryPoint:
999 assert(b->entry_point == NULL);
1000 b->entry_point = &b->values[w[2]];
1001 b->execution_model = w[1];
1002 break;
1003
1004 case SpvOpExecutionMode:
1005 unreachable("Execution modes not yet implemented");
1006 break;
1007
1008 case SpvOpString:
1009 vtn_push_value(b, w[1], vtn_value_type_string)->str =
1010 vtn_string_literal(b, &w[2], count - 2);
1011 break;
1012
1013 case SpvOpName:
1014 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
1015 break;
1016
1017 case SpvOpMemberName:
1018 /* TODO */
1019 break;
1020
1021 case SpvOpLine:
1022 break; /* Ignored for now */
1023
1024 case SpvOpDecorationGroup:
1025 case SpvOpDecorate:
1026 case SpvOpMemberDecorate:
1027 case SpvOpGroupDecorate:
1028 case SpvOpGroupMemberDecorate:
1029 vtn_handle_decoration(b, opcode, w, count);
1030 break;
1031
1032 case SpvOpTypeVoid:
1033 case SpvOpTypeBool:
1034 case SpvOpTypeInt:
1035 case SpvOpTypeFloat:
1036 case SpvOpTypeVector:
1037 case SpvOpTypeMatrix:
1038 case SpvOpTypeSampler:
1039 case SpvOpTypeArray:
1040 case SpvOpTypeRuntimeArray:
1041 case SpvOpTypeStruct:
1042 case SpvOpTypeOpaque:
1043 case SpvOpTypePointer:
1044 case SpvOpTypeFunction:
1045 case SpvOpTypeEvent:
1046 case SpvOpTypeDeviceEvent:
1047 case SpvOpTypeReserveId:
1048 case SpvOpTypeQueue:
1049 case SpvOpTypePipe:
1050 vtn_push_value(b, w[1], vtn_value_type_type)->type =
1051 vtn_handle_type(b, opcode, &w[2], count - 2);
1052 break;
1053
1054 case SpvOpConstantTrue:
1055 case SpvOpConstantFalse:
1056 case SpvOpConstant:
1057 case SpvOpConstantComposite:
1058 case SpvOpConstantSampler:
1059 case SpvOpConstantNullPointer:
1060 case SpvOpConstantNullObject:
1061 case SpvOpSpecConstantTrue:
1062 case SpvOpSpecConstantFalse:
1063 case SpvOpSpecConstant:
1064 case SpvOpSpecConstantComposite:
1065 vtn_handle_constant(b, opcode, w, count);
1066 break;
1067
1068 case SpvOpVariable:
1069 vtn_handle_variables(b, opcode, w, count);
1070 break;
1071
1072 default:
1073 return false; /* End of preamble */
1074 }
1075
1076 return true;
1077 }
1078
1079 static bool
1080 vtn_handle_first_cfg_pass_instruction(struct vtn_builder *b, SpvOp opcode,
1081 const uint32_t *w, unsigned count)
1082 {
1083 switch (opcode) {
1084 case SpvOpFunction: {
1085 assert(b->func == NULL);
1086 b->func = rzalloc(b, struct vtn_function);
1087
1088 const struct glsl_type *result_type =
1089 vtn_value(b, w[1], vtn_value_type_type)->type;
1090 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
1091 const struct glsl_type *func_type =
1092 vtn_value(b, w[4], vtn_value_type_type)->type;
1093
1094 assert(glsl_get_function_return_type(func_type) == result_type);
1095
1096 nir_function *func =
1097 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
1098
1099 nir_function_overload *overload = nir_function_overload_create(func);
1100 overload->num_params = glsl_get_length(func_type);
1101 overload->params = ralloc_array(overload, nir_parameter,
1102 overload->num_params);
1103 for (unsigned i = 0; i < overload->num_params; i++) {
1104 const struct glsl_function_param *param =
1105 glsl_get_function_param(func_type, i);
1106 overload->params[i].type = param->type;
1107 if (param->in) {
1108 if (param->out) {
1109 overload->params[i].param_type = nir_parameter_inout;
1110 } else {
1111 overload->params[i].param_type = nir_parameter_in;
1112 }
1113 } else {
1114 if (param->out) {
1115 overload->params[i].param_type = nir_parameter_out;
1116 } else {
1117 assert(!"Parameter is neither in nor out");
1118 }
1119 }
1120 }
1121 b->func->overload = overload;
1122 break;
1123 }
1124
1125 case SpvOpFunctionEnd:
1126 b->func = NULL;
1127 break;
1128
1129 case SpvOpFunctionParameter:
1130 break; /* Does nothing */
1131
1132 case SpvOpLabel: {
1133 assert(b->block == NULL);
1134 b->block = rzalloc(b, struct vtn_block);
1135 b->block->label = w;
1136 vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
1137
1138 if (b->func->start_block == NULL) {
1139 /* This is the first block encountered for this function. In this
1140 * case, we set the start block and add it to the list of
1141 * implemented functions that we'll walk later.
1142 */
1143 b->func->start_block = b->block;
1144 exec_list_push_tail(&b->functions, &b->func->node);
1145 }
1146 break;
1147 }
1148
1149 case SpvOpBranch:
1150 case SpvOpBranchConditional:
1151 case SpvOpSwitch:
1152 case SpvOpKill:
1153 case SpvOpReturn:
1154 case SpvOpReturnValue:
1155 case SpvOpUnreachable:
1156 assert(b->block);
1157 b->block->branch = w;
1158 b->block = NULL;
1159 break;
1160
1161 case SpvOpSelectionMerge:
1162 case SpvOpLoopMerge:
1163 assert(b->block && b->block->merge_op == SpvOpNop);
1164 b->block->merge_op = opcode;
1165 b->block->merge_block_id = w[1];
1166 break;
1167
1168 default:
1169 /* Continue on as per normal */
1170 return true;
1171 }
1172
1173 return true;
1174 }
1175
1176 static bool
1177 vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
1178 const uint32_t *w, unsigned count)
1179 {
1180 switch (opcode) {
1181 case SpvOpLabel: {
1182 struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
1183 assert(block->block == NULL);
1184
1185 struct exec_node *list_tail = exec_list_get_tail(b->nb.cf_node_list);
1186 nir_cf_node *tail_node = exec_node_data(nir_cf_node, list_tail, node);
1187 assert(tail_node->type == nir_cf_node_block);
1188 block->block = nir_cf_node_as_block(tail_node);
1189 break;
1190 }
1191
1192 case SpvOpLoopMerge:
1193 case SpvOpSelectionMerge:
1194 /* This is handled by cfg pre-pass and walk_blocks */
1195 break;
1196
1197 case SpvOpUndef:
1198 vtn_push_value(b, w[2], vtn_value_type_undef);
1199 break;
1200
1201 case SpvOpExtInst:
1202 vtn_handle_extension(b, opcode, w, count);
1203 break;
1204
1205 case SpvOpVariable:
1206 case SpvOpVariableArray:
1207 case SpvOpLoad:
1208 case SpvOpStore:
1209 case SpvOpCopyMemory:
1210 case SpvOpCopyMemorySized:
1211 case SpvOpAccessChain:
1212 case SpvOpInBoundsAccessChain:
1213 case SpvOpArrayLength:
1214 case SpvOpImagePointer:
1215 vtn_handle_variables(b, opcode, w, count);
1216 break;
1217
1218 case SpvOpFunctionCall:
1219 vtn_handle_function_call(b, opcode, w, count);
1220 break;
1221
1222 case SpvOpTextureSample:
1223 case SpvOpTextureSampleDref:
1224 case SpvOpTextureSampleLod:
1225 case SpvOpTextureSampleProj:
1226 case SpvOpTextureSampleGrad:
1227 case SpvOpTextureSampleOffset:
1228 case SpvOpTextureSampleProjLod:
1229 case SpvOpTextureSampleProjGrad:
1230 case SpvOpTextureSampleLodOffset:
1231 case SpvOpTextureSampleProjOffset:
1232 case SpvOpTextureSampleGradOffset:
1233 case SpvOpTextureSampleProjLodOffset:
1234 case SpvOpTextureSampleProjGradOffset:
1235 case SpvOpTextureFetchTexelLod:
1236 case SpvOpTextureFetchTexelOffset:
1237 case SpvOpTextureFetchSample:
1238 case SpvOpTextureFetchTexel:
1239 case SpvOpTextureGather:
1240 case SpvOpTextureGatherOffset:
1241 case SpvOpTextureGatherOffsets:
1242 case SpvOpTextureQuerySizeLod:
1243 case SpvOpTextureQuerySize:
1244 case SpvOpTextureQueryLod:
1245 case SpvOpTextureQueryLevels:
1246 case SpvOpTextureQuerySamples:
1247 vtn_handle_texture(b, opcode, w, count);
1248 break;
1249
1250 case SpvOpSNegate:
1251 case SpvOpFNegate:
1252 case SpvOpNot:
1253 case SpvOpAny:
1254 case SpvOpAll:
1255 case SpvOpConvertFToU:
1256 case SpvOpConvertFToS:
1257 case SpvOpConvertSToF:
1258 case SpvOpConvertUToF:
1259 case SpvOpUConvert:
1260 case SpvOpSConvert:
1261 case SpvOpFConvert:
1262 case SpvOpConvertPtrToU:
1263 case SpvOpConvertUToPtr:
1264 case SpvOpPtrCastToGeneric:
1265 case SpvOpGenericCastToPtr:
1266 case SpvOpBitcast:
1267 case SpvOpIsNan:
1268 case SpvOpIsInf:
1269 case SpvOpIsFinite:
1270 case SpvOpIsNormal:
1271 case SpvOpSignBitSet:
1272 case SpvOpLessOrGreater:
1273 case SpvOpOrdered:
1274 case SpvOpUnordered:
1275 case SpvOpIAdd:
1276 case SpvOpFAdd:
1277 case SpvOpISub:
1278 case SpvOpFSub:
1279 case SpvOpIMul:
1280 case SpvOpFMul:
1281 case SpvOpUDiv:
1282 case SpvOpSDiv:
1283 case SpvOpFDiv:
1284 case SpvOpUMod:
1285 case SpvOpSRem:
1286 case SpvOpSMod:
1287 case SpvOpFRem:
1288 case SpvOpFMod:
1289 case SpvOpVectorTimesScalar:
1290 case SpvOpDot:
1291 case SpvOpShiftRightLogical:
1292 case SpvOpShiftRightArithmetic:
1293 case SpvOpShiftLeftLogical:
1294 case SpvOpLogicalOr:
1295 case SpvOpLogicalXor:
1296 case SpvOpLogicalAnd:
1297 case SpvOpBitwiseOr:
1298 case SpvOpBitwiseXor:
1299 case SpvOpBitwiseAnd:
1300 case SpvOpSelect:
1301 case SpvOpIEqual:
1302 case SpvOpFOrdEqual:
1303 case SpvOpFUnordEqual:
1304 case SpvOpINotEqual:
1305 case SpvOpFOrdNotEqual:
1306 case SpvOpFUnordNotEqual:
1307 case SpvOpULessThan:
1308 case SpvOpSLessThan:
1309 case SpvOpFOrdLessThan:
1310 case SpvOpFUnordLessThan:
1311 case SpvOpUGreaterThan:
1312 case SpvOpSGreaterThan:
1313 case SpvOpFOrdGreaterThan:
1314 case SpvOpFUnordGreaterThan:
1315 case SpvOpULessThanEqual:
1316 case SpvOpSLessThanEqual:
1317 case SpvOpFOrdLessThanEqual:
1318 case SpvOpFUnordLessThanEqual:
1319 case SpvOpUGreaterThanEqual:
1320 case SpvOpSGreaterThanEqual:
1321 case SpvOpFOrdGreaterThanEqual:
1322 case SpvOpFUnordGreaterThanEqual:
1323 case SpvOpDPdx:
1324 case SpvOpDPdy:
1325 case SpvOpFwidth:
1326 case SpvOpDPdxFine:
1327 case SpvOpDPdyFine:
1328 case SpvOpFwidthFine:
1329 case SpvOpDPdxCoarse:
1330 case SpvOpDPdyCoarse:
1331 case SpvOpFwidthCoarse:
1332 vtn_handle_alu(b, opcode, w, count);
1333 break;
1334
1335 case SpvOpTranspose:
1336 case SpvOpOuterProduct:
1337 case SpvOpMatrixTimesScalar:
1338 case SpvOpVectorTimesMatrix:
1339 case SpvOpMatrixTimesVector:
1340 case SpvOpMatrixTimesMatrix:
1341 vtn_handle_matrix_alu(b, opcode, w, count);
1342 break;
1343
1344 default:
1345 unreachable("Unhandled opcode");
1346 }
1347
1348 return true;
1349 }
1350
1351 static void
1352 vtn_walk_blocks(struct vtn_builder *b, struct vtn_block *start,
1353 struct vtn_block *break_block, struct vtn_block *cont_block,
1354 struct vtn_block *end_block)
1355 {
1356 struct vtn_block *block = start;
1357 while (block != end_block) {
1358 if (block->merge_op == SpvOpLoopMerge) {
1359 /* This is the jump into a loop. */
1360 struct vtn_block *new_cont_block = block;
1361 struct vtn_block *new_break_block =
1362 vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
1363
1364 nir_loop *loop = nir_loop_create(b->shader);
1365 nir_cf_node_insert_end(b->nb.cf_node_list, &loop->cf_node);
1366
1367 struct exec_list *old_list = b->nb.cf_node_list;
1368
1369 /* Reset the merge_op to prerevent infinite recursion */
1370 block->merge_op = SpvOpNop;
1371
1372 nir_builder_insert_after_cf_list(&b->nb, &loop->body);
1373 vtn_walk_blocks(b, block, new_break_block, new_cont_block, NULL);
1374
1375 nir_builder_insert_after_cf_list(&b->nb, old_list);
1376 block = break_block;
1377 continue;
1378 }
1379
1380 const uint32_t *w = block->branch;
1381 SpvOp branch_op = w[0] & SpvOpCodeMask;
1382
1383 b->block = block;
1384 vtn_foreach_instruction(b, block->label, block->branch,
1385 vtn_handle_body_instruction);
1386
1387 switch (branch_op) {
1388 case SpvOpBranch: {
1389 struct vtn_block *branch_block =
1390 vtn_value(b, w[1], vtn_value_type_block)->block;
1391
1392 if (branch_block == break_block) {
1393 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1394 nir_jump_break);
1395 nir_builder_instr_insert(&b->nb, &jump->instr);
1396
1397 return;
1398 } else if (branch_block == cont_block) {
1399 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1400 nir_jump_continue);
1401 nir_builder_instr_insert(&b->nb, &jump->instr);
1402
1403 return;
1404 } else if (branch_block == end_block) {
1405 /* We're branching to the merge block of an if, since for loops
1406 * and functions end_block == NULL, so we're done here.
1407 */
1408 return;
1409 } else {
1410 /* We're branching to another block, and according to the rules,
1411 * we can only branch to another block with one predecessor (so
1412 * we're the only one jumping to it) so we can just process it
1413 * next.
1414 */
1415 block = branch_block;
1416 continue;
1417 }
1418 }
1419
1420 case SpvOpBranchConditional: {
1421 /* Gather up the branch blocks */
1422 struct vtn_block *then_block =
1423 vtn_value(b, w[2], vtn_value_type_block)->block;
1424 struct vtn_block *else_block =
1425 vtn_value(b, w[3], vtn_value_type_block)->block;
1426
1427 nir_if *if_stmt = nir_if_create(b->shader);
1428 if_stmt->condition = nir_src_for_ssa(vtn_ssa_value(b, w[1]));
1429 nir_cf_node_insert_end(b->nb.cf_node_list, &if_stmt->cf_node);
1430
1431 if (then_block == break_block) {
1432 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1433 nir_jump_break);
1434 nir_instr_insert_after_cf_list(&if_stmt->then_list,
1435 &jump->instr);
1436 block = else_block;
1437 } else if (else_block == break_block) {
1438 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1439 nir_jump_break);
1440 nir_instr_insert_after_cf_list(&if_stmt->else_list,
1441 &jump->instr);
1442 block = then_block;
1443 } else if (then_block == cont_block) {
1444 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1445 nir_jump_continue);
1446 nir_instr_insert_after_cf_list(&if_stmt->then_list,
1447 &jump->instr);
1448 block = else_block;
1449 } else if (else_block == cont_block) {
1450 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1451 nir_jump_continue);
1452 nir_instr_insert_after_cf_list(&if_stmt->else_list,
1453 &jump->instr);
1454 block = then_block;
1455 } else {
1456 /* According to the rules we're branching to two blocks that don't
1457 * have any other predecessors, so we can handle this as a
1458 * conventional if.
1459 */
1460 assert(block->merge_op == SpvOpSelectionMerge);
1461 struct vtn_block *merge_block =
1462 vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
1463
1464 struct exec_list *old_list = b->nb.cf_node_list;
1465
1466 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->then_list);
1467 vtn_walk_blocks(b, then_block, break_block, cont_block, merge_block);
1468
1469 nir_builder_insert_after_cf_list(&b->nb, &if_stmt->else_list);
1470 vtn_walk_blocks(b, else_block, break_block, cont_block, merge_block);
1471
1472 nir_builder_insert_after_cf_list(&b->nb, old_list);
1473 block = merge_block;
1474 continue;
1475 }
1476
1477 /* If we got here then we inserted a predicated break or continue
1478 * above and we need to handle the other case. We already set
1479 * `block` above to indicate what block to visit after the
1480 * predicated break.
1481 */
1482
1483 /* It's possible that the other branch is also a break/continue.
1484 * If it is, we handle that here.
1485 */
1486 if (block == break_block) {
1487 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1488 nir_jump_break);
1489 nir_builder_instr_insert(&b->nb, &jump->instr);
1490
1491 return;
1492 } else if (block == cont_block) {
1493 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1494 nir_jump_continue);
1495 nir_builder_instr_insert(&b->nb, &jump->instr);
1496
1497 return;
1498 }
1499
1500 /* If we got here then there was a predicated break/continue but
1501 * the other half of the if has stuff in it. `block` was already
1502 * set above so there is nothing left for us to do.
1503 */
1504 continue;
1505 }
1506
1507 case SpvOpReturn: {
1508 nir_jump_instr *jump = nir_jump_instr_create(b->shader,
1509 nir_jump_return);
1510 nir_builder_instr_insert(&b->nb, &jump->instr);
1511 return;
1512 }
1513
1514 case SpvOpKill: {
1515 nir_intrinsic_instr *discard =
1516 nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
1517 nir_builder_instr_insert(&b->nb, &discard->instr);
1518 return;
1519 }
1520
1521 case SpvOpSwitch:
1522 case SpvOpReturnValue:
1523 case SpvOpUnreachable:
1524 default:
1525 unreachable("Unhandled opcode");
1526 }
1527 }
1528 }
1529
1530 nir_shader *
1531 spirv_to_nir(const uint32_t *words, size_t word_count,
1532 const nir_shader_compiler_options *options)
1533 {
1534 const uint32_t *word_end = words + word_count;
1535
1536 /* Handle the SPIR-V header (first 4 dwords) */
1537 assert(word_count > 5);
1538
1539 assert(words[0] == SpvMagicNumber);
1540 assert(words[1] == 99);
1541 /* words[2] == generator magic */
1542 unsigned value_id_bound = words[3];
1543 assert(words[4] == 0);
1544
1545 words+= 5;
1546
1547 nir_shader *shader = nir_shader_create(NULL, options);
1548
1549 /* Initialize the stn_builder object */
1550 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
1551 b->shader = shader;
1552 b->value_id_bound = value_id_bound;
1553 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
1554 exec_list_make_empty(&b->functions);
1555
1556 /* Handle all the preamble instructions */
1557 words = vtn_foreach_instruction(b, words, word_end,
1558 vtn_handle_preamble_instruction);
1559
1560 /* Do a very quick CFG analysis pass */
1561 vtn_foreach_instruction(b, words, word_end,
1562 vtn_handle_first_cfg_pass_instruction);
1563
1564 foreach_list_typed(struct vtn_function, func, node, &b->functions) {
1565 b->impl = nir_function_impl_create(func->overload);
1566 nir_builder_init(&b->nb, b->impl);
1567 nir_builder_insert_after_cf_list(&b->nb, &b->impl->body);
1568 vtn_walk_blocks(b, func->start_block, NULL, NULL, NULL);
1569 }
1570
1571 ralloc_free(b);
1572
1573 return shader;
1574 }