2 * Copyright © 2015 Intel Corporation
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:
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
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
24 * Jason Ekstrand (jason@jlekstrand.net)
28 #include "spirv_to_nir_private.h"
32 vtn_ssa_value(struct vtn_builder
*b
, uint32_t value_id
)
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
);
42 for (unsigned i
= 0; i
< num_components
; i
++)
43 load
->value
.u
[0] = val
->constant
->value
.u
[0];
45 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
49 case vtn_value_type_ssa
:
52 unreachable("Invalid type for an SSA value");
57 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
60 return ralloc_strndup(b
, (char *)words
, word_count
* sizeof(*words
));
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
)
67 const uint32_t *w
= start
;
69 SpvOp opcode
= w
[0] & SpvOpCodeMask
;
70 unsigned count
= w
[0] >> SpvWordCountShift
;
71 assert(count
>= 1 && w
+ count
<= end
);
73 if (!handler(b
, opcode
, w
, count
))
83 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
84 const uint32_t *w
, unsigned count
)
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
;
92 assert(!"Unsupported extension");
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
);
106 unreachable("Unhandled opcode");
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
)
116 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
118 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
119 _foreach_decoration_helper(b
, base_value
, dec
->group
, cb
, data
);
121 cb(b
, base_value
, dec
, data
);
126 /** Iterates (recursively if needed) over all of the decorations on a value
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.
133 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
134 vtn_decoration_foreach_cb cb
, void *data
)
136 _foreach_decoration_helper(b
, value
, value
, cb
, data
);
140 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
141 const uint32_t *w
, unsigned count
)
144 case SpvOpDecorationGroup
:
145 vtn_push_value(b
, w
[1], vtn_value_type_undef
);
148 case SpvOpDecorate
: {
149 struct vtn_value
*val
= &b
->values
[w
[1]];
151 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
152 dec
->decoration
= w
[2];
153 dec
->literals
= &w
[3];
155 /* Link into the list */
156 dec
->next
= val
->decoration
;
157 val
->decoration
= dec
;
161 case SpvOpGroupDecorate
: {
162 struct vtn_value
*group
= &b
->values
[w
[1]];
163 assert(group
->value_type
== vtn_value_type_decoration_group
);
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
);
170 /* Link into the list */
171 dec
->next
= val
->decoration
;
172 val
->decoration
= dec
;
177 case SpvOpGroupMemberDecorate
:
178 assert(!"Bad instruction. Khronos Bug #13513");
182 unreachable("Unhandled opcode");
186 static const struct glsl_type
*
187 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
188 const uint32_t *args
, unsigned count
)
192 return glsl_void_type();
194 return glsl_bool_type();
196 return glsl_int_type();
198 return glsl_float_type();
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];
205 assert(glsl_type_is_scalar(base
));
206 return glsl_vector_type(glsl_get_base_type(base
), elems
);
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];
214 assert(glsl_type_is_vector(base
));
215 return glsl_matrix_type(glsl_get_base_type(base
),
216 glsl_get_vector_elements(base
),
221 return glsl_array_type(b
->values
[args
[0]].type
, args
[1]);
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;
236 return glsl_struct_type(fields
, count
, "struct");
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
;
246 params
[i
- 1].in
= true;
247 params
[i
- 1].out
= true;
249 return glsl_function_type(return_type
, params
, count
- 1);
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
257 return vtn_value(b
, args
[1], vtn_value_type_type
)->type
;
259 case SpvOpTypeSampler
:
260 case SpvOpTypeRuntimeArray
:
261 case SpvOpTypeOpaque
:
263 case SpvOpTypeDeviceEvent
:
264 case SpvOpTypeReserveId
:
268 unreachable("Unhandled opcode");
273 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
274 const uint32_t *w
, unsigned count
)
276 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_constant
);
277 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
278 val
->constant
= ralloc(b
, nir_constant
);
280 case SpvOpConstantTrue
:
281 assert(val
->type
== glsl_bool_type());
282 val
->constant
->value
.u
[0] = NIR_TRUE
;
284 case SpvOpConstantFalse
:
285 assert(val
->type
== glsl_bool_type());
286 val
->constant
->value
.u
[0] = NIR_FALSE
;
289 assert(glsl_type_is_scalar(val
->type
));
290 val
->constant
->value
.u
[0] = w
[3];
292 case SpvOpConstantComposite
: {
293 unsigned elem_count
= count
- 3;
294 nir_constant
**elems
= ralloc_array(b
, nir_constant
*, elem_count
);
295 for (unsigned i
= 0; i
< elem_count
; i
++)
296 elems
[i
] = vtn_value(b
, w
[i
+ 3], vtn_value_type_constant
)->constant
;
298 switch (glsl_get_base_type(val
->type
)) {
301 case GLSL_TYPE_FLOAT
:
303 if (glsl_type_is_matrix(val
->type
)) {
304 unsigned rows
= glsl_get_vector_elements(val
->type
);
305 assert(glsl_get_matrix_columns(val
->type
) == elem_count
);
306 for (unsigned i
= 0; i
< elem_count
; i
++)
307 for (unsigned j
= 0; j
< rows
; j
++)
308 val
->constant
->value
.u
[rows
* i
+ j
] = elems
[i
]->value
.u
[j
];
310 assert(glsl_type_is_vector(val
->type
));
311 assert(glsl_get_vector_elements(val
->type
) == elem_count
);
312 for (unsigned i
= 0; i
< elem_count
; i
++)
313 val
->constant
->value
.u
[i
] = elems
[i
]->value
.u
[0];
318 case GLSL_TYPE_STRUCT
:
319 case GLSL_TYPE_ARRAY
:
320 ralloc_steal(val
->constant
, elems
);
321 val
->constant
->elements
= elems
;
325 unreachable("Unsupported type for constants");
331 unreachable("Unhandled opcode");
336 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
,
337 const struct vtn_decoration
*dec
, void *void_var
)
339 assert(val
->value_type
== vtn_value_type_deref
);
340 assert(val
->deref
->deref
.child
== NULL
);
341 assert(val
->deref
->var
== void_var
);
343 nir_variable
*var
= void_var
;
344 switch (dec
->decoration
) {
345 case SpvDecorationPrecisionLow
:
346 case SpvDecorationPrecisionMedium
:
347 case SpvDecorationPrecisionHigh
:
348 break; /* FIXME: Do nothing with these for now. */
349 case SpvDecorationSmooth
:
350 var
->data
.interpolation
= INTERP_QUALIFIER_SMOOTH
;
352 case SpvDecorationNoperspective
:
353 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
355 case SpvDecorationFlat
:
356 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
358 case SpvDecorationCentroid
:
359 var
->data
.centroid
= true;
361 case SpvDecorationSample
:
362 var
->data
.sample
= true;
364 case SpvDecorationInvariant
:
365 var
->data
.invariant
= true;
367 case SpvDecorationConstant
:
368 assert(var
->constant_initializer
!= NULL
);
369 var
->data
.read_only
= true;
371 case SpvDecorationNonwritable
:
372 var
->data
.read_only
= true;
374 case SpvDecorationLocation
:
375 var
->data
.explicit_location
= true;
376 var
->data
.location
= dec
->literals
[0];
378 case SpvDecorationComponent
:
379 var
->data
.location_frac
= dec
->literals
[0];
381 case SpvDecorationIndex
:
382 var
->data
.explicit_index
= true;
383 var
->data
.index
= dec
->literals
[0];
385 case SpvDecorationBinding
:
386 var
->data
.explicit_binding
= true;
387 var
->data
.binding
= dec
->literals
[0];
389 case SpvDecorationBlock
:
390 case SpvDecorationBufferBlock
:
391 case SpvDecorationRowMajor
:
392 case SpvDecorationColMajor
:
393 case SpvDecorationGLSLShared
:
394 case SpvDecorationGLSLStd140
:
395 case SpvDecorationGLSLStd430
:
396 case SpvDecorationGLSLPacked
:
397 case SpvDecorationPatch
:
398 case SpvDecorationRestrict
:
399 case SpvDecorationAliased
:
400 case SpvDecorationVolatile
:
401 case SpvDecorationCoherent
:
402 case SpvDecorationNonreadable
:
403 case SpvDecorationUniform
:
404 /* This is really nice but we have no use for it right now. */
405 case SpvDecorationNoStaticUse
:
406 case SpvDecorationCPacked
:
407 case SpvDecorationSaturatedConversion
:
408 case SpvDecorationStream
:
409 case SpvDecorationDescriptorSet
:
410 case SpvDecorationOffset
:
411 case SpvDecorationAlignment
:
412 case SpvDecorationXfbBuffer
:
413 case SpvDecorationStride
:
414 case SpvDecorationBuiltIn
:
415 case SpvDecorationFuncParamAttr
:
416 case SpvDecorationFPRoundingMode
:
417 case SpvDecorationFPFastMathMode
:
418 case SpvDecorationLinkageAttributes
:
419 case SpvDecorationSpecId
:
421 unreachable("Unhandled variable decoration");
426 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
427 const uint32_t *w
, unsigned count
)
430 case SpvOpVariable
: {
431 const struct glsl_type
*type
=
432 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
433 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
435 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
438 var
->name
= ralloc_strdup(var
, val
->name
);
440 switch ((SpvStorageClass
)w
[3]) {
441 case SpvStorageClassUniformConstant
:
442 var
->data
.mode
= nir_var_uniform
;
443 var
->data
.read_only
= true;
445 case SpvStorageClassInput
:
446 var
->data
.mode
= nir_var_shader_in
;
447 var
->data
.read_only
= true;
449 case SpvStorageClassOutput
:
450 var
->data
.mode
= nir_var_shader_out
;
452 case SpvStorageClassPrivateGlobal
:
453 var
->data
.mode
= nir_var_global
;
455 case SpvStorageClassFunction
:
456 var
->data
.mode
= nir_var_local
;
458 case SpvStorageClassUniform
:
459 case SpvStorageClassWorkgroupLocal
:
460 case SpvStorageClassWorkgroupGlobal
:
461 case SpvStorageClassGeneric
:
462 case SpvStorageClassPrivate
:
463 case SpvStorageClassAtomicCounter
:
465 unreachable("Unhandled variable storage class");
470 var
->constant_initializer
=
471 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
474 if (var
->data
.mode
== nir_var_local
) {
475 exec_list_push_tail(&b
->impl
->locals
, &var
->node
);
477 exec_list_push_tail(&b
->shader
->globals
, &var
->node
);
480 val
->deref
= nir_deref_var_create(b
->shader
, var
);
482 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
486 case SpvOpAccessChain
:
487 case SpvOpInBoundsAccessChain
: {
488 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
489 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
490 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
492 nir_deref
*tail
= &val
->deref
->deref
;
496 for (unsigned i
= 0; i
< count
- 4; i
++) {
497 assert(w
[i
+ 4] < b
->value_id_bound
);
498 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
500 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
504 case GLSL_TYPE_FLOAT
:
505 case GLSL_TYPE_DOUBLE
:
507 case GLSL_TYPE_ARRAY
: {
508 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
509 if (base_type
== GLSL_TYPE_ARRAY
) {
510 deref_arr
->deref
.type
= glsl_get_array_element(tail
->type
);
511 } else if (glsl_type_is_matrix(tail
->type
)) {
512 deref_arr
->deref
.type
= glsl_get_column_type(tail
->type
);
514 assert(glsl_type_is_vector(tail
->type
));
515 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
518 if (idx_val
->value_type
== vtn_value_type_constant
) {
519 unsigned idx
= idx_val
->constant
->value
.u
[0];
520 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
521 deref_arr
->base_offset
= idx
;
523 assert(idx_val
->value_type
== vtn_value_type_ssa
);
524 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
525 deref_arr
->base_offset
= 0;
526 deref_arr
->indirect
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
528 tail
->child
= &deref_arr
->deref
;
532 case GLSL_TYPE_STRUCT
: {
533 assert(idx_val
->value_type
== vtn_value_type_constant
);
534 unsigned idx
= idx_val
->constant
->value
.u
[0];
535 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
536 deref_struct
->deref
.type
= glsl_get_struct_field(tail
->type
, idx
);
537 tail
->child
= &deref_struct
->deref
;
541 unreachable("Invalid type for deref");
548 case SpvOpCopyMemory
: {
549 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
550 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
552 nir_intrinsic_instr
*copy
=
553 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
554 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
555 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
557 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
562 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
563 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
564 const struct glsl_type
*src_type
= nir_deref_tail(&src
->deref
)->type
;
565 assert(glsl_type_is_vector_or_scalar(src_type
));
567 nir_intrinsic_instr
*load
=
568 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
569 load
->variables
[0] = nir_deref_as_var(nir_copy_deref(load
, &src
->deref
));
570 load
->num_components
= glsl_get_vector_elements(src_type
);
571 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
,
574 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
575 val
->type
= src_type
;
576 val
->ssa
= &load
->dest
.ssa
;
581 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
582 const struct glsl_type
*dest_type
= nir_deref_tail(&dest
->deref
)->type
;
583 struct vtn_value
*src_val
= vtn_untyped_value(b
, w
[2]);
584 if (src_val
->value_type
== vtn_value_type_ssa
) {
585 assert(glsl_type_is_vector_or_scalar(dest_type
));
586 nir_intrinsic_instr
*store
=
587 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
588 store
->src
[0] = nir_src_for_ssa(src_val
->ssa
);
589 store
->variables
[0] = nir_deref_as_var(nir_copy_deref(store
, &dest
->deref
));
590 store
->num_components
= glsl_get_vector_elements(dest_type
);
592 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
594 assert(src_val
->value_type
== vtn_value_type_constant
);
596 nir_variable
*const_tmp
= rzalloc(b
->shader
, nir_variable
);
597 const_tmp
->type
= dest_type
;
598 const_tmp
->name
= "const_temp";
599 const_tmp
->data
.mode
= nir_var_local
;
600 const_tmp
->data
.read_only
= true;
601 exec_list_push_tail(&b
->impl
->locals
, &const_tmp
->node
);
603 nir_intrinsic_instr
*copy
=
604 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
605 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
606 copy
->variables
[1] = nir_deref_var_create(copy
, const_tmp
);
608 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
613 case SpvOpVariableArray
:
614 case SpvOpCopyMemorySized
:
615 case SpvOpArrayLength
:
616 case SpvOpImagePointer
:
618 unreachable("Unhandled opcode");
623 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
624 const uint32_t *w
, unsigned count
)
626 unreachable("Unhandled opcode");
630 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
631 const uint32_t *w
, unsigned count
)
633 unreachable("Unhandled opcode");
637 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
638 const uint32_t *w
, unsigned count
)
640 unreachable("Matrix math not handled");
644 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
645 const uint32_t *w
, unsigned count
)
647 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
648 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
650 /* Collect the various SSA sources */
651 unsigned num_inputs
= count
- 3;
653 for (unsigned i
= 0; i
< num_inputs
; i
++)
654 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3]);
656 /* Indicates that the first two arguments should be swapped. This is
657 * used for implementing greater-than and less-than-or-equal.
663 /* Basic ALU operations */
664 case SpvOpSNegate
: op
= nir_op_ineg
; break;
665 case SpvOpFNegate
: op
= nir_op_fneg
; break;
666 case SpvOpNot
: op
= nir_op_inot
; break;
669 switch (src
[0]->num_components
) {
670 case 1: op
= nir_op_imov
; break;
671 case 2: op
= nir_op_bany2
; break;
672 case 3: op
= nir_op_bany3
; break;
673 case 4: op
= nir_op_bany4
; break;
678 switch (src
[0]->num_components
) {
679 case 1: op
= nir_op_imov
; break;
680 case 2: op
= nir_op_ball2
; break;
681 case 3: op
= nir_op_ball3
; break;
682 case 4: op
= nir_op_ball4
; break;
686 case SpvOpIAdd
: op
= nir_op_iadd
; break;
687 case SpvOpFAdd
: op
= nir_op_fadd
; break;
688 case SpvOpISub
: op
= nir_op_isub
; break;
689 case SpvOpFSub
: op
= nir_op_fsub
; break;
690 case SpvOpIMul
: op
= nir_op_imul
; break;
691 case SpvOpFMul
: op
= nir_op_fmul
; break;
692 case SpvOpUDiv
: op
= nir_op_udiv
; break;
693 case SpvOpSDiv
: op
= nir_op_idiv
; break;
694 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
695 case SpvOpUMod
: op
= nir_op_umod
; break;
696 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
697 case SpvOpFMod
: op
= nir_op_fmod
; break;
700 assert(src
[0]->num_components
== src
[1]->num_components
);
701 switch (src
[0]->num_components
) {
702 case 1: op
= nir_op_fmul
; break;
703 case 2: op
= nir_op_fdot2
; break;
704 case 3: op
= nir_op_fdot3
; break;
705 case 4: op
= nir_op_fdot4
; break;
709 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
710 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
711 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
712 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
713 case SpvOpLogicalXor
: op
= nir_op_ixor
; break;
714 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
715 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
716 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
717 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
718 case SpvOpSelect
: op
= nir_op_bcsel
; break;
719 case SpvOpIEqual
: op
= nir_op_ieq
; break;
721 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
722 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
723 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
724 case SpvOpINotEqual
: op
= nir_op_ine
; break;
725 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
726 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
727 case SpvOpULessThan
: op
= nir_op_ult
; break;
728 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
729 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
730 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
731 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
732 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
733 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
734 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
735 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
736 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
737 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
738 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
739 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
740 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
741 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
742 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
745 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
746 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
747 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
748 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
749 case SpvOpBitcast
: op
= nir_op_imov
; break;
752 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
759 case SpvOpDPdx
: op
= nir_op_fddx
; break;
760 case SpvOpDPdy
: op
= nir_op_fddy
; break;
761 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
762 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
763 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
764 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
766 val
->ssa
= nir_fadd(&b
->nb
,
767 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
768 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
770 case SpvOpFwidthFine
:
771 val
->ssa
= nir_fadd(&b
->nb
,
772 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
773 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
775 case SpvOpFwidthCoarse
:
776 val
->ssa
= nir_fadd(&b
->nb
,
777 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
778 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
781 case SpvOpVectorTimesScalar
:
782 /* The builder will take care of splatting for us. */
783 val
->ssa
= nir_fmul(&b
->nb
, src
[0], src
[1]);
788 unreachable("No NIR equivalent");
794 case SpvOpSignBitSet
:
795 case SpvOpLessOrGreater
:
799 unreachable("Unhandled opcode");
803 nir_ssa_def
*tmp
= src
[0];
808 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
809 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
810 glsl_get_vector_elements(val
->type
), val
->name
);
811 val
->ssa
= &instr
->dest
.dest
.ssa
;
813 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
814 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
816 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
820 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
821 const uint32_t *w
, unsigned count
)
825 case SpvOpSourceExtension
:
826 case SpvOpCompileFlag
:
828 /* Unhandled, but these are for debug so that's ok. */
831 case SpvOpExtInstImport
:
832 vtn_handle_extension(b
, opcode
, w
, count
);
835 case SpvOpMemoryModel
:
836 assert(w
[1] == SpvAddressingModelLogical
);
837 assert(w
[2] == SpvMemoryModelGLSL450
);
840 case SpvOpEntryPoint
:
841 assert(b
->entry_point
== NULL
);
842 b
->entry_point
= &b
->values
[w
[2]];
843 b
->execution_model
= w
[1];
846 case SpvOpExecutionMode
:
847 unreachable("Execution modes not yet implemented");
851 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
852 vtn_string_literal(b
, &w
[2], count
- 2);
856 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
859 case SpvOpMemberName
:
864 break; /* Ignored for now */
866 case SpvOpDecorationGroup
:
868 case SpvOpMemberDecorate
:
869 case SpvOpGroupDecorate
:
870 case SpvOpGroupMemberDecorate
:
871 vtn_handle_decoration(b
, opcode
, w
, count
);
878 case SpvOpTypeVector
:
879 case SpvOpTypeMatrix
:
880 case SpvOpTypeSampler
:
882 case SpvOpTypeRuntimeArray
:
883 case SpvOpTypeStruct
:
884 case SpvOpTypeOpaque
:
885 case SpvOpTypePointer
:
886 case SpvOpTypeFunction
:
888 case SpvOpTypeDeviceEvent
:
889 case SpvOpTypeReserveId
:
892 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
893 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
896 case SpvOpConstantTrue
:
897 case SpvOpConstantFalse
:
899 case SpvOpConstantComposite
:
900 case SpvOpConstantSampler
:
901 case SpvOpConstantNullPointer
:
902 case SpvOpConstantNullObject
:
903 case SpvOpSpecConstantTrue
:
904 case SpvOpSpecConstantFalse
:
905 case SpvOpSpecConstant
:
906 case SpvOpSpecConstantComposite
:
907 vtn_handle_constant(b
, opcode
, w
, count
);
911 vtn_handle_variables(b
, opcode
, w
, count
);
915 return false; /* End of preamble */
922 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
923 const uint32_t *w
, unsigned count
)
926 case SpvOpFunction
: {
927 assert(b
->func
== NULL
);
928 b
->func
= rzalloc(b
, struct vtn_function
);
930 const struct glsl_type
*result_type
=
931 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
932 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
933 const struct glsl_type
*func_type
=
934 vtn_value(b
, w
[4], vtn_value_type_type
)->type
;
936 assert(glsl_get_function_return_type(func_type
) == result_type
);
939 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
941 nir_function_overload
*overload
= nir_function_overload_create(func
);
942 overload
->num_params
= glsl_get_length(func_type
);
943 overload
->params
= ralloc_array(overload
, nir_parameter
,
944 overload
->num_params
);
945 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
946 const struct glsl_function_param
*param
=
947 glsl_get_function_param(func_type
, i
);
948 overload
->params
[i
].type
= param
->type
;
951 overload
->params
[i
].param_type
= nir_parameter_inout
;
953 overload
->params
[i
].param_type
= nir_parameter_in
;
957 overload
->params
[i
].param_type
= nir_parameter_out
;
959 assert(!"Parameter is neither in nor out");
963 b
->func
->overload
= overload
;
967 case SpvOpFunctionEnd
:
971 case SpvOpFunctionParameter
:
972 break; /* Does nothing */
975 assert(b
->block
== NULL
);
976 b
->block
= rzalloc(b
, struct vtn_block
);
978 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
980 if (b
->func
->start_block
== NULL
) {
981 /* This is the first block encountered for this function. In this
982 * case, we set the start block and add it to the list of
983 * implemented functions that we'll walk later.
985 b
->func
->start_block
= b
->block
;
986 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
992 case SpvOpBranchConditional
:
996 case SpvOpReturnValue
:
997 case SpvOpUnreachable
:
999 b
->block
->branch
= w
;
1004 /* Continue on as per normal */
1012 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1013 const uint32_t *w
, unsigned count
)
1017 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1018 struct exec_node
*list_tail
= exec_list_get_tail(b
->nb
.cf_node_list
);
1019 nir_cf_node
*tail_node
= exec_node_data(nir_cf_node
, list_tail
, node
);
1020 assert(tail_node
->type
== nir_cf_node_block
);
1021 block
->block
= nir_cf_node_as_block(tail_node
);
1022 assert(exec_list_is_empty(&block
->block
->instr_list
));
1026 case SpvOpLoopMerge
:
1027 case SpvOpSelectionMerge
:
1028 assert(b
->merge_block
== NULL
);
1029 /* TODO: Selection Control */
1030 b
->merge_block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1034 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
1038 vtn_handle_extension(b
, opcode
, w
, count
);
1042 case SpvOpVariableArray
:
1045 case SpvOpCopyMemory
:
1046 case SpvOpCopyMemorySized
:
1047 case SpvOpAccessChain
:
1048 case SpvOpInBoundsAccessChain
:
1049 case SpvOpArrayLength
:
1050 case SpvOpImagePointer
:
1051 vtn_handle_variables(b
, opcode
, w
, count
);
1054 case SpvOpFunctionCall
:
1055 vtn_handle_function_call(b
, opcode
, w
, count
);
1058 case SpvOpTextureSample
:
1059 case SpvOpTextureSampleDref
:
1060 case SpvOpTextureSampleLod
:
1061 case SpvOpTextureSampleProj
:
1062 case SpvOpTextureSampleGrad
:
1063 case SpvOpTextureSampleOffset
:
1064 case SpvOpTextureSampleProjLod
:
1065 case SpvOpTextureSampleProjGrad
:
1066 case SpvOpTextureSampleLodOffset
:
1067 case SpvOpTextureSampleProjOffset
:
1068 case SpvOpTextureSampleGradOffset
:
1069 case SpvOpTextureSampleProjLodOffset
:
1070 case SpvOpTextureSampleProjGradOffset
:
1071 case SpvOpTextureFetchTexelLod
:
1072 case SpvOpTextureFetchTexelOffset
:
1073 case SpvOpTextureFetchSample
:
1074 case SpvOpTextureFetchTexel
:
1075 case SpvOpTextureGather
:
1076 case SpvOpTextureGatherOffset
:
1077 case SpvOpTextureGatherOffsets
:
1078 case SpvOpTextureQuerySizeLod
:
1079 case SpvOpTextureQuerySize
:
1080 case SpvOpTextureQueryLod
:
1081 case SpvOpTextureQueryLevels
:
1082 case SpvOpTextureQuerySamples
:
1083 vtn_handle_texture(b
, opcode
, w
, count
);
1091 case SpvOpConvertFToU
:
1092 case SpvOpConvertFToS
:
1093 case SpvOpConvertSToF
:
1094 case SpvOpConvertUToF
:
1098 case SpvOpConvertPtrToU
:
1099 case SpvOpConvertUToPtr
:
1100 case SpvOpPtrCastToGeneric
:
1101 case SpvOpGenericCastToPtr
:
1107 case SpvOpSignBitSet
:
1108 case SpvOpLessOrGreater
:
1110 case SpvOpUnordered
:
1125 case SpvOpVectorTimesScalar
:
1127 case SpvOpShiftRightLogical
:
1128 case SpvOpShiftRightArithmetic
:
1129 case SpvOpShiftLeftLogical
:
1130 case SpvOpLogicalOr
:
1131 case SpvOpLogicalXor
:
1132 case SpvOpLogicalAnd
:
1133 case SpvOpBitwiseOr
:
1134 case SpvOpBitwiseXor
:
1135 case SpvOpBitwiseAnd
:
1138 case SpvOpFOrdEqual
:
1139 case SpvOpFUnordEqual
:
1140 case SpvOpINotEqual
:
1141 case SpvOpFOrdNotEqual
:
1142 case SpvOpFUnordNotEqual
:
1143 case SpvOpULessThan
:
1144 case SpvOpSLessThan
:
1145 case SpvOpFOrdLessThan
:
1146 case SpvOpFUnordLessThan
:
1147 case SpvOpUGreaterThan
:
1148 case SpvOpSGreaterThan
:
1149 case SpvOpFOrdGreaterThan
:
1150 case SpvOpFUnordGreaterThan
:
1151 case SpvOpULessThanEqual
:
1152 case SpvOpSLessThanEqual
:
1153 case SpvOpFOrdLessThanEqual
:
1154 case SpvOpFUnordLessThanEqual
:
1155 case SpvOpUGreaterThanEqual
:
1156 case SpvOpSGreaterThanEqual
:
1157 case SpvOpFOrdGreaterThanEqual
:
1158 case SpvOpFUnordGreaterThanEqual
:
1164 case SpvOpFwidthFine
:
1165 case SpvOpDPdxCoarse
:
1166 case SpvOpDPdyCoarse
:
1167 case SpvOpFwidthCoarse
:
1168 vtn_handle_alu(b
, opcode
, w
, count
);
1171 case SpvOpTranspose
:
1172 case SpvOpOuterProduct
:
1173 case SpvOpMatrixTimesScalar
:
1174 case SpvOpVectorTimesMatrix
:
1175 case SpvOpMatrixTimesVector
:
1176 case SpvOpMatrixTimesMatrix
:
1177 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
1181 unreachable("Unhandled opcode");
1188 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
1189 struct vtn_block
*end
)
1191 struct vtn_block
*block
= start
;
1192 while (block
!= end
) {
1193 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
1194 vtn_handle_body_instruction
);
1196 const uint32_t *w
= block
->branch
;
1197 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
1198 switch (branch_op
) {
1200 assert(vtn_value(b
, w
[1], vtn_value_type_block
)->block
== end
);
1204 case SpvOpBranchConditional
: {
1205 /* Gather up the branch blocks */
1206 struct vtn_block
*then_block
=
1207 vtn_value(b
, w
[2], vtn_value_type_block
)->block
;
1208 struct vtn_block
*else_block
=
1209 vtn_value(b
, w
[3], vtn_value_type_block
)->block
;
1210 struct vtn_block
*merge_block
= b
->merge_block
;
1212 nir_if
*if_stmt
= nir_if_create(b
->shader
);
1213 if_stmt
->condition
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
1214 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &if_stmt
->cf_node
);
1216 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1218 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->then_list
);
1219 vtn_walk_blocks(b
, then_block
, merge_block
);
1221 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->else_list
);
1222 vtn_walk_blocks(b
, else_block
, merge_block
);
1224 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1225 block
= merge_block
;
1232 case SpvOpReturnValue
:
1233 case SpvOpUnreachable
:
1235 unreachable("Unhandled opcode");
1241 spirv_to_nir(const uint32_t *words
, size_t word_count
,
1242 const nir_shader_compiler_options
*options
)
1244 const uint32_t *word_end
= words
+ word_count
;
1246 /* Handle the SPIR-V header (first 4 dwords) */
1247 assert(word_count
> 5);
1249 assert(words
[0] == SpvMagicNumber
);
1250 assert(words
[1] == 99);
1251 /* words[2] == generator magic */
1252 unsigned value_id_bound
= words
[3];
1253 assert(words
[4] == 0);
1257 nir_shader
*shader
= nir_shader_create(NULL
, options
);
1259 /* Initialize the stn_builder object */
1260 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
1262 b
->value_id_bound
= value_id_bound
;
1263 b
->values
= ralloc_array(b
, struct vtn_value
, value_id_bound
);
1264 exec_list_make_empty(&b
->functions
);
1266 /* Handle all the preamble instructions */
1267 words
= vtn_foreach_instruction(b
, words
, word_end
,
1268 vtn_handle_preamble_instruction
);
1270 /* Do a very quick CFG analysis pass */
1271 vtn_foreach_instruction(b
, words
, word_end
,
1272 vtn_handle_first_cfg_pass_instruction
);
1274 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
1275 b
->impl
= nir_function_impl_create(func
->overload
);
1276 nir_builder_init(&b
->nb
, b
->impl
);
1277 nir_builder_insert_after_cf_list(&b
->nb
, &b
->impl
->body
);
1278 vtn_walk_blocks(b
, func
->start_block
, NULL
);