nir/spirv: Use vtn_value in the types code and fix a off-by-one error
[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 "nir_spirv.h"
29 #include "nir_vla.h"
30 #include "spirv.h"
31
32 struct vtn_decoration;
33
34 enum vtn_value_type {
35 vtn_value_type_invalid = 0,
36 vtn_value_type_undef,
37 vtn_value_type_string,
38 vtn_value_type_decoration_group,
39 vtn_value_type_type,
40 vtn_value_type_constant,
41 vtn_value_type_deref,
42 vtn_value_type_function,
43 vtn_value_type_block,
44 vtn_value_type_ssa,
45 };
46
47 struct vtn_value {
48 enum vtn_value_type value_type;
49 const char *name;
50 struct vtn_decoration *decoration;
51 union {
52 void *ptr;
53 char *str;
54 const struct glsl_type *type;
55 nir_constant *constant;
56 nir_deref_var *deref;
57 nir_function_impl *impl;
58 nir_block *block;
59 nir_ssa_def *ssa;
60 };
61 };
62
63 struct vtn_decoration {
64 struct vtn_decoration *next;
65 const uint32_t *literals;
66 struct vtn_value *group;
67 SpvDecoration decoration;
68 };
69
70 struct vtn_builder {
71 nir_shader *shader;
72 nir_function_impl *impl;
73 struct exec_list *cf_list;
74
75 unsigned value_id_bound;
76 struct vtn_value *values;
77
78 SpvExecutionModel execution_model;
79 struct vtn_value *entry_point;
80 };
81
82 static struct vtn_value *
83 vtn_push_value(struct vtn_builder *b, uint32_t value_id,
84 enum vtn_value_type value_type)
85 {
86 assert(value_id < b->value_id_bound);
87 assert(b->values[value_id].value_type == vtn_value_type_invalid);
88
89 b->values[value_id].value_type = value_type;
90
91 return &b->values[value_id];
92 }
93
94 static struct vtn_value *
95 vtn_value(struct vtn_builder *b, uint32_t value_id,
96 enum vtn_value_type value_type)
97 {
98 assert(value_id < b->value_id_bound);
99 assert(b->values[value_id].value_type == value_type);
100 return &b->values[value_id];
101 }
102
103 static char *
104 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
105 unsigned word_count)
106 {
107 return ralloc_strndup(b, (char *)words, (word_count - 2) * sizeof(*words));
108 }
109
110 static void
111 vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
112 const uint32_t *w, unsigned count)
113 {
114 switch (opcode) {
115 case SpvOpExtInstImport:
116 /* Do nothing for the moment */
117 break;
118
119 case SpvOpExtInst:
120 default:
121 unreachable("Unhandled opcode");
122 }
123 }
124
125 typedef void (*decoration_foreach_cb)(struct vtn_builder *,
126 struct vtn_value *,
127 const struct vtn_decoration *,
128 void *);
129
130 static void
131 _foreach_decoration_helper(struct vtn_builder *b,
132 struct vtn_value *base_value,
133 struct vtn_value *value,
134 decoration_foreach_cb cb, void *data)
135 {
136 for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
137 if (dec->group) {
138 assert(dec->group->value_type == vtn_value_type_decoration_group);
139 _foreach_decoration_helper(b, base_value, dec->group, cb, data);
140 } else {
141 cb(b, base_value, dec, data);
142 }
143 }
144 }
145
146 /** Iterates (recursively if needed) over all of the decorations on a value
147 *
148 * This function iterates over all of the decorations applied to a given
149 * value. If it encounters a decoration group, it recurses into the group
150 * and iterates over all of those decorations as well.
151 */
152 static void
153 vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
154 decoration_foreach_cb cb, void *data)
155 {
156 _foreach_decoration_helper(b, value, value, cb, data);
157 }
158
159 static void
160 vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
161 const uint32_t *w, unsigned count)
162 {
163 switch (opcode) {
164 case SpvOpDecorationGroup:
165 vtn_push_value(b, w[1], vtn_value_type_undef);
166 break;
167
168 case SpvOpDecorate: {
169 struct vtn_value *val = &b->values[w[1]];
170
171 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
172 dec->decoration = w[2];
173 dec->literals = &w[3];
174
175 /* Link into the list */
176 dec->next = val->decoration;
177 val->decoration = dec;
178 break;
179 }
180
181 case SpvOpGroupDecorate: {
182 struct vtn_value *group = &b->values[w[1]];
183 assert(group->value_type == vtn_value_type_decoration_group);
184
185 for (unsigned i = 2; i < count; i++) {
186 struct vtn_value *val = &b->values[w[i]];
187 struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
188 dec->group = group;
189
190 /* Link into the list */
191 dec->next = val->decoration;
192 val->decoration = dec;
193 }
194 break;
195 }
196
197 case SpvOpGroupMemberDecorate:
198 assert(!"Bad instruction. Khronos Bug #13513");
199 break;
200
201 default:
202 unreachable("Unhandled opcode");
203 }
204 }
205
206 static const struct glsl_type *
207 vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
208 const uint32_t *args, unsigned count)
209 {
210 switch (opcode) {
211 case SpvOpTypeVoid:
212 return glsl_void_type();
213 case SpvOpTypeBool:
214 return glsl_bool_type();
215 case SpvOpTypeInt:
216 return glsl_int_type();
217 case SpvOpTypeFloat:
218 return glsl_float_type();
219
220 case SpvOpTypeVector: {
221 const struct glsl_type *base =
222 vtn_value(b, args[0], vtn_value_type_type)->type;
223 unsigned elems = args[1];
224
225 assert(glsl_type_is_scalar(base));
226 return glsl_vector_type(glsl_get_base_type(base), elems);
227 }
228
229 case SpvOpTypeMatrix: {
230 const struct glsl_type *base =
231 vtn_value(b, args[0], vtn_value_type_type)->type;
232 unsigned columns = args[1];
233
234 assert(glsl_type_is_vector(base));
235 return glsl_matrix_type(glsl_get_base_type(base),
236 glsl_get_vector_elements(base),
237 columns);
238 }
239
240 case SpvOpTypeArray:
241 return glsl_array_type(b->values[args[0]].type, args[1]);
242
243 case SpvOpTypeStruct: {
244 NIR_VLA(struct glsl_struct_field, fields, count);
245 for (unsigned i = 0; i < count; i++) {
246 /* TODO: Handle decorators */
247 fields[i].type = vtn_value(b, args[i], vtn_value_type_type)->type;
248 fields[i].name = ralloc_asprintf(b, "field%d", i);
249 fields[i].location = -1;
250 fields[i].interpolation = 0;
251 fields[i].centroid = 0;
252 fields[i].sample = 0;
253 fields[i].matrix_layout = 2;
254 fields[i].stream = -1;
255 }
256 return glsl_struct_type(fields, count, "struct");
257 }
258
259 case SpvOpTypeFunction: {
260 const struct glsl_type *return_type = b->values[args[0]].type;
261 NIR_VLA(struct glsl_function_param, params, count - 1);
262 for (unsigned i = 1; i < count; i++) {
263 params[i - 1].type = vtn_value(b, args[i], vtn_value_type_type)->type;
264
265 /* FIXME: */
266 params[i - 1].in = true;
267 params[i - 1].out = true;
268 }
269 return glsl_function_type(return_type, params, count - 1);
270 }
271
272 case SpvOpTypePointer:
273 /* FIXME: For now, we'll just do the really lame thing and return
274 * the same type. The validator should ensure that the proper number
275 * of dereferences happen
276 */
277 return vtn_value(b, args[1], vtn_value_type_type)->type;
278
279 case SpvOpTypeSampler:
280 case SpvOpTypeRuntimeArray:
281 case SpvOpTypeOpaque:
282 case SpvOpTypeEvent:
283 case SpvOpTypeDeviceEvent:
284 case SpvOpTypeReserveId:
285 case SpvOpTypeQueue:
286 case SpvOpTypePipe:
287 default:
288 unreachable("Unhandled opcode");
289 }
290 }
291
292 static void
293 vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
294 const uint32_t *w, unsigned count)
295 {
296 const struct glsl_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
297 nir_constant *constant = ralloc(b, nir_constant);
298 switch (opcode) {
299 case SpvOpConstantTrue:
300 assert(type == glsl_bool_type());
301 constant->value.u[0] = NIR_TRUE;
302 break;
303 case SpvOpConstantFalse:
304 assert(type == glsl_bool_type());
305 constant->value.u[0] = NIR_FALSE;
306 break;
307 case SpvOpConstant:
308 assert(glsl_type_is_scalar(type));
309 constant->value.u[0] = w[3];
310 break;
311 case SpvOpConstantComposite: {
312 unsigned elem_count = count - 3;
313 nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
314 for (unsigned i = 0; i < elem_count; i++)
315 elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
316
317 switch (glsl_get_base_type(type)) {
318 case GLSL_TYPE_UINT:
319 case GLSL_TYPE_INT:
320 case GLSL_TYPE_FLOAT:
321 case GLSL_TYPE_BOOL:
322 if (glsl_type_is_matrix(type)) {
323 unsigned rows = glsl_get_vector_elements(type);
324 assert(glsl_get_matrix_columns(type) == elem_count);
325 for (unsigned i = 0; i < elem_count; i++)
326 for (unsigned j = 0; j < rows; j++)
327 constant->value.u[rows * i + j] = elems[i]->value.u[j];
328 } else {
329 assert(glsl_type_is_vector(type));
330 assert(glsl_get_vector_elements(type) == elem_count);
331 for (unsigned i = 0; i < elem_count; i++)
332 constant->value.u[i] = elems[i]->value.u[0];
333 }
334 ralloc_free(elems);
335 break;
336
337 case GLSL_TYPE_STRUCT:
338 case GLSL_TYPE_ARRAY:
339 constant->elements = elems;
340 break;
341
342 default:
343 unreachable("Unsupported type for constants");
344 }
345 break;
346 }
347
348 default:
349 unreachable("Unhandled opcode");
350 }
351 vtn_push_value(b, w[2], vtn_value_type_constant)->constant = constant;
352 }
353
354 static void
355 var_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
356 const struct vtn_decoration *dec, void *void_var)
357 {
358 assert(val->value_type == vtn_value_type_deref);
359 assert(val->deref->deref.child == NULL);
360 assert(val->deref->var == void_var);
361
362 nir_variable *var = void_var;
363 switch (dec->decoration) {
364 case SpvDecorationPrecisionLow:
365 case SpvDecorationPrecisionMedium:
366 case SpvDecorationPrecisionHigh:
367 break; /* FIXME: Do nothing with these for now. */
368 case SpvDecorationSmooth:
369 var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
370 break;
371 case SpvDecorationNoperspective:
372 var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
373 break;
374 case SpvDecorationFlat:
375 var->data.interpolation = INTERP_QUALIFIER_FLAT;
376 break;
377 case SpvDecorationCentroid:
378 var->data.centroid = true;
379 break;
380 case SpvDecorationSample:
381 var->data.sample = true;
382 break;
383 case SpvDecorationInvariant:
384 var->data.invariant = true;
385 break;
386 case SpvDecorationConstant:
387 assert(var->constant_initializer != NULL);
388 var->data.read_only = true;
389 break;
390 case SpvDecorationNonwritable:
391 var->data.read_only = true;
392 break;
393 case SpvDecorationLocation:
394 var->data.explicit_location = true;
395 var->data.location = dec->literals[0];
396 break;
397 case SpvDecorationComponent:
398 var->data.location_frac = dec->literals[0];
399 break;
400 case SpvDecorationIndex:
401 var->data.explicit_index = true;
402 var->data.index = dec->literals[0];
403 break;
404 case SpvDecorationBinding:
405 var->data.explicit_binding = true;
406 var->data.binding = dec->literals[0];
407 break;
408 case SpvDecorationBlock:
409 case SpvDecorationBufferBlock:
410 case SpvDecorationRowMajor:
411 case SpvDecorationColMajor:
412 case SpvDecorationGLSLShared:
413 case SpvDecorationGLSLStd140:
414 case SpvDecorationGLSLStd430:
415 case SpvDecorationGLSLPacked:
416 case SpvDecorationPatch:
417 case SpvDecorationRestrict:
418 case SpvDecorationAliased:
419 case SpvDecorationVolatile:
420 case SpvDecorationCoherent:
421 case SpvDecorationNonreadable:
422 case SpvDecorationUniform:
423 /* This is really nice but we have no use for it right now. */
424 case SpvDecorationNoStaticUse:
425 case SpvDecorationCPacked:
426 case SpvDecorationSaturatedConversion:
427 case SpvDecorationStream:
428 case SpvDecorationDescriptorSet:
429 case SpvDecorationOffset:
430 case SpvDecorationAlignment:
431 case SpvDecorationXfbBuffer:
432 case SpvDecorationStride:
433 case SpvDecorationBuiltIn:
434 case SpvDecorationFuncParamAttr:
435 case SpvDecorationFPRoundingMode:
436 case SpvDecorationFPFastMathMode:
437 case SpvDecorationLinkageAttributes:
438 case SpvDecorationSpecId:
439 default:
440 unreachable("Unhandled variable decoration");
441 }
442 }
443
444 static void
445 vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
446 const uint32_t *w, unsigned count)
447 {
448 switch (opcode) {
449 case SpvOpVariable: {
450 const struct glsl_type *type =
451 vtn_value(b, w[1], vtn_value_type_type)->type;
452 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
453
454 nir_variable *var = ralloc(b->shader, nir_variable);
455
456 var->type = type;
457 var->name = ralloc_strdup(var, val->name);
458
459 switch ((SpvStorageClass)w[3]) {
460 case SpvStorageClassUniformConstant:
461 var->data.mode = nir_var_uniform;
462 var->data.read_only = true;
463 break;
464 case SpvStorageClassInput:
465 var->data.mode = nir_var_shader_in;
466 var->data.read_only = true;
467 break;
468 case SpvStorageClassOutput:
469 var->data.mode = nir_var_shader_out;
470 break;
471 case SpvStorageClassPrivateGlobal:
472 var->data.mode = nir_var_global;
473 break;
474 case SpvStorageClassFunction:
475 var->data.mode = nir_var_local;
476 break;
477 case SpvStorageClassUniform:
478 case SpvStorageClassWorkgroupLocal:
479 case SpvStorageClassWorkgroupGlobal:
480 case SpvStorageClassGeneric:
481 case SpvStorageClassPrivate:
482 case SpvStorageClassAtomicCounter:
483 default:
484 unreachable("Unhandled variable storage class");
485 }
486
487 if (count > 4) {
488 assert(count == 5);
489 var->constant_initializer =
490 vtn_value(b, w[4], vtn_value_type_constant)->constant;
491 }
492
493 val->deref = nir_deref_var_create(b->shader, var);
494
495 vtn_foreach_decoration(b, val, var_decoration_cb, var);
496 break;
497 }
498
499 case SpvOpAccessChain:
500 case SpvOpInBoundsAccessChain: {
501 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
502 nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
503 val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
504
505 nir_deref *tail = &val->deref->deref;
506 while (tail->child)
507 tail = tail->child;
508
509 for (unsigned i = 0; i < count - 3; i++) {
510 assert(w[i + 3] < b->value_id_bound);
511 struct vtn_value *idx_val = &b->values[w[i + 3]];
512
513 enum glsl_base_type base_type = glsl_get_base_type(tail->type);
514 switch (base_type) {
515 case GLSL_TYPE_UINT:
516 case GLSL_TYPE_INT:
517 case GLSL_TYPE_FLOAT:
518 case GLSL_TYPE_DOUBLE:
519 case GLSL_TYPE_BOOL:
520 case GLSL_TYPE_ARRAY: {
521 nir_deref_array *deref_arr = nir_deref_array_create(b);
522 if (base_type == GLSL_TYPE_ARRAY) {
523 deref_arr->deref.type = glsl_get_array_element(tail->type);
524 } else if (glsl_type_is_matrix(tail->type)) {
525 deref_arr->deref.type = glsl_get_column_type(tail->type);
526 } else {
527 assert(glsl_type_is_vector(tail->type));
528 deref_arr->deref.type = glsl_scalar_type(base_type);
529 }
530
531 if (idx_val->value_type == vtn_value_type_constant) {
532 unsigned idx = idx_val->constant->value.u[0];
533 deref_arr->deref_array_type = nir_deref_array_type_direct;
534 deref_arr->base_offset = idx;
535 } else {
536 assert(idx_val->value_type == vtn_value_type_ssa);
537 deref_arr->deref_array_type = nir_deref_array_type_indirect;
538 /* TODO */
539 unreachable("Indirect array accesses not implemented");
540 }
541 tail->child = &deref_arr->deref;
542 break;
543 }
544
545 case GLSL_TYPE_STRUCT: {
546 assert(idx_val->value_type == vtn_value_type_constant);
547 unsigned idx = idx_val->constant->value.u[0];
548 nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
549 deref_struct->deref.type = glsl_get_struct_field(tail->type, idx);
550 tail->child = &deref_struct->deref;
551 break;
552 }
553 default:
554 unreachable("Invalid type for deref");
555 }
556 tail = tail->child;
557 }
558 break;
559 }
560
561 case SpvOpVariableArray:
562 case SpvOpLoad:
563 case SpvOpStore:
564 case SpvOpCopyMemory:
565 case SpvOpCopyMemorySized:
566 case SpvOpArrayLength:
567 case SpvOpImagePointer:
568 default:
569 unreachable("Unhandled opcode");
570 }
571 }
572
573 static void
574 vtn_handle_functions(struct vtn_builder *b, SpvOp opcode,
575 const uint32_t *w, unsigned count)
576 {
577 switch (opcode) {
578 case SpvOpFunction: {
579 assert(b->impl == NULL);
580
581 const struct glsl_type *result_type =
582 vtn_value(b, w[1], vtn_value_type_type)->type;
583 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
584 const struct glsl_type *func_type =
585 vtn_value(b, w[4], vtn_value_type_type)->type;
586
587 assert(glsl_get_function_return_type(func_type) == result_type);
588
589 nir_function *func =
590 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
591
592 nir_function_overload *overload = nir_function_overload_create(func);
593 overload->num_params = glsl_get_length(func_type);
594 overload->params = ralloc_array(overload, nir_parameter,
595 overload->num_params);
596 for (unsigned i = 0; i < overload->num_params; i++) {
597 const struct glsl_function_param *param =
598 glsl_get_function_param(func_type, i);
599 overload->params[i].type = param->type;
600 if (param->in) {
601 if (param->out) {
602 overload->params[i].param_type = nir_parameter_inout;
603 } else {
604 overload->params[i].param_type = nir_parameter_in;
605 }
606 } else {
607 if (param->out) {
608 overload->params[i].param_type = nir_parameter_out;
609 } else {
610 assert(!"Parameter is neither in nor out");
611 }
612 }
613 }
614
615 val->impl = b->impl = nir_function_impl_create(overload);
616 b->cf_list = &b->impl->body;
617
618 break;
619 }
620 case SpvOpFunctionEnd:
621 b->impl = NULL;
622 break;
623 case SpvOpFunctionParameter:
624 case SpvOpFunctionCall:
625 default:
626 unreachable("Unhandled opcode");
627 }
628 }
629
630 static void
631 vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
632 const uint32_t *w, unsigned count)
633 {
634 unreachable("Unhandled opcode");
635 }
636
637 static void
638 vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
639 const uint32_t *w, unsigned count)
640 {
641 unreachable("Unhandled opcode");
642 }
643
644 static void
645 vtn_handle_instruction(struct vtn_builder *b, SpvOp opcode,
646 const uint32_t *w, unsigned count)
647 {
648 switch (opcode) {
649 case SpvOpSource:
650 case SpvOpSourceExtension:
651 case SpvOpMemberName:
652 case SpvOpLine:
653 case SpvOpExtension:
654 /* Unhandled, but these are for debug so that's ok. */
655 break;
656
657 case SpvOpName:
658 b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
659 break;
660
661 case SpvOpString:
662 vtn_push_value(b, w[1], vtn_value_type_string)->str =
663 vtn_string_literal(b, &w[2], count - 2);
664 break;
665
666 case SpvOpUndef:
667 vtn_push_value(b, w[2], vtn_value_type_undef);
668 break;
669
670 case SpvOpMemoryModel:
671 assert(w[1] == SpvAddressingModelLogical);
672 assert(w[2] == SpvMemoryModelGLSL450);
673 break;
674
675 case SpvOpEntryPoint:
676 assert(b->entry_point == NULL);
677 b->entry_point = &b->values[w[2]];
678 b->execution_model = w[1];
679 break;
680
681 case SpvOpLabel: {
682 struct exec_node *list_tail = exec_list_get_tail(b->cf_list);
683 nir_cf_node *tail_node = exec_node_data(nir_cf_node, list_tail, node);
684 assert(tail_node->type == nir_cf_node_block);
685 nir_block *block = nir_cf_node_as_block(tail_node);
686
687 assert(exec_list_is_empty(&block->instr_list));
688 vtn_push_value(b, w[1], vtn_value_type_block)->block = block;
689 break;
690 }
691
692 case SpvOpExtInstImport:
693 case SpvOpExtInst:
694 vtn_handle_extension(b, opcode, w, count);
695 break;
696
697 case SpvOpTypeVoid:
698 case SpvOpTypeBool:
699 case SpvOpTypeInt:
700 case SpvOpTypeFloat:
701 case SpvOpTypeVector:
702 case SpvOpTypeMatrix:
703 case SpvOpTypeSampler:
704 case SpvOpTypeArray:
705 case SpvOpTypeRuntimeArray:
706 case SpvOpTypeStruct:
707 case SpvOpTypeOpaque:
708 case SpvOpTypePointer:
709 case SpvOpTypeFunction:
710 case SpvOpTypeEvent:
711 case SpvOpTypeDeviceEvent:
712 case SpvOpTypeReserveId:
713 case SpvOpTypeQueue:
714 case SpvOpTypePipe:
715 vtn_push_value(b, w[1], vtn_value_type_type)->type =
716 vtn_handle_type(b, opcode, &w[2], count - 2);
717 break;
718
719 case SpvOpConstantTrue:
720 case SpvOpConstantFalse:
721 case SpvOpConstant:
722 case SpvOpConstantComposite:
723 case SpvOpConstantSampler:
724 case SpvOpConstantNullPointer:
725 case SpvOpConstantNullObject:
726 case SpvOpSpecConstantTrue:
727 case SpvOpSpecConstantFalse:
728 case SpvOpSpecConstant:
729 case SpvOpSpecConstantComposite:
730 vtn_handle_constant(b, opcode, w, count);
731 break;
732
733 case SpvOpVariable:
734 case SpvOpVariableArray:
735 case SpvOpLoad:
736 case SpvOpStore:
737 case SpvOpCopyMemory:
738 case SpvOpCopyMemorySized:
739 case SpvOpAccessChain:
740 case SpvOpInBoundsAccessChain:
741 case SpvOpArrayLength:
742 case SpvOpImagePointer:
743 vtn_handle_variables(b, opcode, w, count);
744 break;
745
746 case SpvOpDecorationGroup:
747 case SpvOpDecorate:
748 case SpvOpMemberDecorate:
749 case SpvOpGroupDecorate:
750 case SpvOpGroupMemberDecorate:
751 vtn_handle_decoration(b, opcode, w, count);
752 break;
753
754 case SpvOpFunction:
755 case SpvOpFunctionEnd:
756 case SpvOpFunctionParameter:
757 case SpvOpFunctionCall:
758 vtn_handle_functions(b, opcode, w, count);
759 break;
760
761 case SpvOpTextureSample:
762 case SpvOpTextureSampleDref:
763 case SpvOpTextureSampleLod:
764 case SpvOpTextureSampleProj:
765 case SpvOpTextureSampleGrad:
766 case SpvOpTextureSampleOffset:
767 case SpvOpTextureSampleProjLod:
768 case SpvOpTextureSampleProjGrad:
769 case SpvOpTextureSampleLodOffset:
770 case SpvOpTextureSampleProjOffset:
771 case SpvOpTextureSampleGradOffset:
772 case SpvOpTextureSampleProjLodOffset:
773 case SpvOpTextureSampleProjGradOffset:
774 case SpvOpTextureFetchTexelLod:
775 case SpvOpTextureFetchTexelOffset:
776 case SpvOpTextureFetchSample:
777 case SpvOpTextureFetchTexel:
778 case SpvOpTextureGather:
779 case SpvOpTextureGatherOffset:
780 case SpvOpTextureGatherOffsets:
781 case SpvOpTextureQuerySizeLod:
782 case SpvOpTextureQuerySize:
783 case SpvOpTextureQueryLod:
784 case SpvOpTextureQueryLevels:
785 case SpvOpTextureQuerySamples:
786 vtn_handle_texture(b, opcode, w, count);
787 break;
788
789 case SpvOpSNegate:
790 case SpvOpFNegate:
791 case SpvOpNot:
792 case SpvOpAny:
793 case SpvOpAll:
794 case SpvOpConvertFToU:
795 case SpvOpConvertFToS:
796 case SpvOpConvertSToF:
797 case SpvOpConvertUToF:
798 case SpvOpUConvert:
799 case SpvOpSConvert:
800 case SpvOpFConvert:
801 case SpvOpConvertPtrToU:
802 case SpvOpConvertUToPtr:
803 case SpvOpPtrCastToGeneric:
804 case SpvOpGenericCastToPtr:
805 case SpvOpBitcast:
806 case SpvOpTranspose:
807 case SpvOpIsNan:
808 case SpvOpIsInf:
809 case SpvOpIsFinite:
810 case SpvOpIsNormal:
811 case SpvOpSignBitSet:
812 case SpvOpLessOrGreater:
813 case SpvOpOrdered:
814 case SpvOpUnordered:
815 case SpvOpIAdd:
816 case SpvOpFAdd:
817 case SpvOpISub:
818 case SpvOpFSub:
819 case SpvOpIMul:
820 case SpvOpFMul:
821 case SpvOpUDiv:
822 case SpvOpSDiv:
823 case SpvOpFDiv:
824 case SpvOpUMod:
825 case SpvOpSRem:
826 case SpvOpSMod:
827 case SpvOpFRem:
828 case SpvOpFMod:
829 case SpvOpVectorTimesScalar:
830 case SpvOpMatrixTimesScalar:
831 case SpvOpVectorTimesMatrix:
832 case SpvOpMatrixTimesVector:
833 case SpvOpMatrixTimesMatrix:
834 case SpvOpOuterProduct:
835 case SpvOpDot:
836 case SpvOpShiftRightLogical:
837 case SpvOpShiftRightArithmetic:
838 case SpvOpShiftLeftLogical:
839 case SpvOpLogicalOr:
840 case SpvOpLogicalXor:
841 case SpvOpLogicalAnd:
842 case SpvOpBitwiseOr:
843 case SpvOpBitwiseXor:
844 case SpvOpBitwiseAnd:
845 case SpvOpSelect:
846 case SpvOpIEqual:
847 case SpvOpFOrdEqual:
848 case SpvOpFUnordEqual:
849 case SpvOpINotEqual:
850 case SpvOpFOrdNotEqual:
851 case SpvOpFUnordNotEqual:
852 case SpvOpULessThan:
853 case SpvOpSLessThan:
854 case SpvOpFOrdLessThan:
855 case SpvOpFUnordLessThan:
856 case SpvOpUGreaterThan:
857 case SpvOpSGreaterThan:
858 case SpvOpFOrdGreaterThan:
859 case SpvOpFUnordGreaterThan:
860 case SpvOpULessThanEqual:
861 case SpvOpSLessThanEqual:
862 case SpvOpFOrdLessThanEqual:
863 case SpvOpFUnordLessThanEqual:
864 case SpvOpUGreaterThanEqual:
865 case SpvOpSGreaterThanEqual:
866 case SpvOpFOrdGreaterThanEqual:
867 case SpvOpFUnordGreaterThanEqual:
868 case SpvOpDPdx:
869 case SpvOpDPdy:
870 case SpvOpFwidth:
871 case SpvOpDPdxFine:
872 case SpvOpDPdyFine:
873 case SpvOpFwidthFine:
874 case SpvOpDPdxCoarse:
875 case SpvOpDPdyCoarse:
876 case SpvOpFwidthCoarse:
877 vtn_handle_alu(b, opcode, w, count);
878 break;
879
880 default:
881 unreachable("Unhandled opcode");
882 }
883 }
884
885 nir_shader *
886 spirv_to_nir(const uint32_t *words, size_t word_count,
887 const nir_shader_compiler_options *options)
888 {
889 /* Handle the SPIR-V header (first 4 dwords) */
890 assert(word_count > 5);
891
892 assert(words[0] == SpvMagicNumber);
893 assert(words[1] == 99);
894 /* words[2] == generator magic */
895 unsigned value_id_bound = words[3];
896 assert(words[4] == 0);
897
898 words+= 5;
899
900 nir_shader *shader = nir_shader_create(NULL, options);
901
902 /* Initialize the stn_builder object */
903 struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
904 b->shader = shader;
905 b->value_id_bound = value_id_bound;
906 b->values = ralloc_array(b, struct vtn_value, value_id_bound);
907
908 /* Start handling instructions */
909 const uint32_t *word_end = words + word_count;
910 while (words < word_end) {
911 SpvOp opcode = words[0] & SpvOpCodeMask;
912 unsigned count = words[0] >> SpvWordCountShift;
913 assert(words + count <= word_end);
914
915 vtn_handle_instruction(b, opcode, words, count);
916
917 words += count;
918 }
919
920 ralloc_free(b);
921
922 return shader;
923 }