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 const struct glsl_type
*sampled_type
=
261 vtn_value(b
, args
[0], vtn_value_type_type
)->type
;
263 assert(glsl_type_is_vector_or_scalar(sampled_type
));
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;
274 unreachable("Invalid SPIR-V Sampler dimension");
277 /* TODO: Handle the various texture image/filter options */
280 bool is_array
= args
[3];
281 bool is_shadow
= args
[4];
283 assert(args
[5] == 0 && "FIXME: Handl multi-sampled textures");
285 return glsl_sampler_type(dim
, is_shadow
, is_array
,
286 glsl_get_base_type(sampled_type
));
289 case SpvOpTypeRuntimeArray
:
290 case SpvOpTypeOpaque
:
292 case SpvOpTypeDeviceEvent
:
293 case SpvOpTypeReserveId
:
297 unreachable("Unhandled opcode");
302 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
303 const uint32_t *w
, unsigned count
)
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
);
309 case SpvOpConstantTrue
:
310 assert(val
->type
== glsl_bool_type());
311 val
->constant
->value
.u
[0] = NIR_TRUE
;
313 case SpvOpConstantFalse
:
314 assert(val
->type
== glsl_bool_type());
315 val
->constant
->value
.u
[0] = NIR_FALSE
;
318 assert(glsl_type_is_scalar(val
->type
));
319 val
->constant
->value
.u
[0] = w
[3];
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
;
327 switch (glsl_get_base_type(val
->type
)) {
330 case GLSL_TYPE_FLOAT
:
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
];
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];
347 case GLSL_TYPE_STRUCT
:
348 case GLSL_TYPE_ARRAY
:
349 ralloc_steal(val
->constant
, elems
);
350 val
->constant
->elements
= elems
;
354 unreachable("Unsupported type for constants");
360 unreachable("Unhandled opcode");
365 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
,
366 const struct vtn_decoration
*dec
, void *void_var
)
368 assert(val
->value_type
== vtn_value_type_deref
);
369 assert(val
->deref
->deref
.child
== NULL
);
370 assert(val
->deref
->var
== void_var
);
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
;
381 case SpvDecorationNoperspective
:
382 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
384 case SpvDecorationFlat
:
385 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
387 case SpvDecorationCentroid
:
388 var
->data
.centroid
= true;
390 case SpvDecorationSample
:
391 var
->data
.sample
= true;
393 case SpvDecorationInvariant
:
394 var
->data
.invariant
= true;
396 case SpvDecorationConstant
:
397 assert(var
->constant_initializer
!= NULL
);
398 var
->data
.read_only
= true;
400 case SpvDecorationNonwritable
:
401 var
->data
.read_only
= true;
403 case SpvDecorationLocation
:
404 var
->data
.explicit_location
= true;
405 var
->data
.location
= dec
->literals
[0];
407 case SpvDecorationComponent
:
408 var
->data
.location_frac
= dec
->literals
[0];
410 case SpvDecorationIndex
:
411 var
->data
.explicit_index
= true;
412 var
->data
.index
= dec
->literals
[0];
414 case SpvDecorationBinding
:
415 var
->data
.explicit_binding
= true;
416 var
->data
.binding
= dec
->literals
[0];
418 case SpvDecorationDescriptorSet
:
419 var
->data
.descriptor_set
= dec
->literals
[0];
421 case SpvDecorationBuiltIn
:
422 var
->data
.mode
= nir_var_system_value
;
423 var
->data
.read_only
= true;
424 switch ((SpvBuiltIn
)dec
->literals
[0]) {
425 case SpvBuiltInFrontFacing
:
426 var
->data
.location
= SYSTEM_VALUE_FRONT_FACE
;
428 case SpvBuiltInVertexId
:
429 var
->data
.location
= SYSTEM_VALUE_VERTEX_ID
;
431 case SpvBuiltInInstanceId
:
432 var
->data
.location
= SYSTEM_VALUE_INSTANCE_ID
;
434 case SpvBuiltInSampleId
:
435 var
->data
.location
= SYSTEM_VALUE_SAMPLE_ID
;
437 case SpvBuiltInSamplePosition
:
438 var
->data
.location
= SYSTEM_VALUE_SAMPLE_POS
;
440 case SpvBuiltInSampleMask
:
441 var
->data
.location
= SYSTEM_VALUE_SAMPLE_MASK_IN
;
443 case SpvBuiltInInvocationId
:
444 var
->data
.location
= SYSTEM_VALUE_INVOCATION_ID
;
446 case SpvBuiltInPrimitiveId
:
447 case SpvBuiltInPosition
:
448 case SpvBuiltInPointSize
:
449 case SpvBuiltInClipVertex
:
450 case SpvBuiltInClipDistance
:
451 case SpvBuiltInCullDistance
:
452 case SpvBuiltInLayer
:
453 case SpvBuiltInViewportIndex
:
454 case SpvBuiltInTessLevelOuter
:
455 case SpvBuiltInTessLevelInner
:
456 case SpvBuiltInTessCoord
:
457 case SpvBuiltInPatchVertices
:
458 case SpvBuiltInFragCoord
:
459 case SpvBuiltInPointCoord
:
460 case SpvBuiltInFragColor
:
461 case SpvBuiltInFragDepth
:
462 case SpvBuiltInHelperInvocation
:
463 case SpvBuiltInNumWorkgroups
:
464 case SpvBuiltInWorkgroupSize
:
465 case SpvBuiltInWorkgroupId
:
466 case SpvBuiltInLocalInvocationId
:
467 case SpvBuiltInGlobalInvocationId
:
468 case SpvBuiltInLocalInvocationIndex
:
469 case SpvBuiltInWorkDim
:
470 case SpvBuiltInGlobalSize
:
471 case SpvBuiltInEnqueuedWorkgroupSize
:
472 case SpvBuiltInGlobalOffset
:
473 case SpvBuiltInGlobalLinearId
:
474 case SpvBuiltInWorkgroupLinearId
:
475 case SpvBuiltInSubgroupSize
:
476 case SpvBuiltInSubgroupMaxSize
:
477 case SpvBuiltInNumSubgroups
:
478 case SpvBuiltInNumEnqueuedSubgroups
:
479 case SpvBuiltInSubgroupId
:
480 case SpvBuiltInSubgroupLocalInvocationId
:
481 unreachable("Unhandled builtin enum");
484 case SpvDecorationNoStaticUse
:
485 /* This can safely be ignored */
487 case SpvDecorationBlock
:
488 case SpvDecorationBufferBlock
:
489 case SpvDecorationRowMajor
:
490 case SpvDecorationColMajor
:
491 case SpvDecorationGLSLShared
:
492 case SpvDecorationGLSLStd140
:
493 case SpvDecorationGLSLStd430
:
494 case SpvDecorationGLSLPacked
:
495 case SpvDecorationPatch
:
496 case SpvDecorationRestrict
:
497 case SpvDecorationAliased
:
498 case SpvDecorationVolatile
:
499 case SpvDecorationCoherent
:
500 case SpvDecorationNonreadable
:
501 case SpvDecorationUniform
:
502 /* This is really nice but we have no use for it right now. */
503 case SpvDecorationCPacked
:
504 case SpvDecorationSaturatedConversion
:
505 case SpvDecorationStream
:
506 case SpvDecorationOffset
:
507 case SpvDecorationAlignment
:
508 case SpvDecorationXfbBuffer
:
509 case SpvDecorationStride
:
510 case SpvDecorationFuncParamAttr
:
511 case SpvDecorationFPRoundingMode
:
512 case SpvDecorationFPFastMathMode
:
513 case SpvDecorationLinkageAttributes
:
514 case SpvDecorationSpecId
:
516 unreachable("Unhandled variable decoration");
521 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
522 const uint32_t *w
, unsigned count
)
525 case SpvOpVariable
: {
526 const struct glsl_type
*type
=
527 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
528 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
530 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
533 var
->name
= ralloc_strdup(var
, val
->name
);
535 switch ((SpvStorageClass
)w
[3]) {
536 case SpvStorageClassUniform
:
537 case SpvStorageClassUniformConstant
:
538 var
->data
.mode
= nir_var_uniform
;
539 var
->data
.read_only
= true;
541 case SpvStorageClassInput
:
542 var
->data
.mode
= nir_var_shader_in
;
543 var
->data
.read_only
= true;
545 case SpvStorageClassOutput
:
546 var
->data
.mode
= nir_var_shader_out
;
548 case SpvStorageClassPrivateGlobal
:
549 var
->data
.mode
= nir_var_global
;
551 case SpvStorageClassFunction
:
552 var
->data
.mode
= nir_var_local
;
554 case SpvStorageClassWorkgroupLocal
:
555 case SpvStorageClassWorkgroupGlobal
:
556 case SpvStorageClassGeneric
:
557 case SpvStorageClassPrivate
:
558 case SpvStorageClassAtomicCounter
:
560 unreachable("Unhandled variable storage class");
565 var
->constant_initializer
=
566 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
569 val
->deref
= nir_deref_var_create(b
, var
);
571 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
573 switch (var
->data
.mode
) {
574 case nir_var_shader_in
:
575 exec_list_push_tail(&b
->shader
->inputs
, &var
->node
);
577 case nir_var_shader_out
:
578 exec_list_push_tail(&b
->shader
->outputs
, &var
->node
);
581 exec_list_push_tail(&b
->shader
->globals
, &var
->node
);
584 exec_list_push_tail(&b
->impl
->locals
, &var
->node
);
586 case nir_var_uniform
:
587 exec_list_push_tail(&b
->shader
->uniforms
, &var
->node
);
589 case nir_var_system_value
:
590 exec_list_push_tail(&b
->shader
->system_values
, &var
->node
);
596 case SpvOpAccessChain
:
597 case SpvOpInBoundsAccessChain
: {
598 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
599 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
600 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
602 nir_deref
*tail
= &val
->deref
->deref
;
606 for (unsigned i
= 0; i
< count
- 4; i
++) {
607 assert(w
[i
+ 4] < b
->value_id_bound
);
608 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
610 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
614 case GLSL_TYPE_FLOAT
:
615 case GLSL_TYPE_DOUBLE
:
617 case GLSL_TYPE_ARRAY
: {
618 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
619 if (base_type
== GLSL_TYPE_ARRAY
) {
620 deref_arr
->deref
.type
= glsl_get_array_element(tail
->type
);
621 } else if (glsl_type_is_matrix(tail
->type
)) {
622 deref_arr
->deref
.type
= glsl_get_column_type(tail
->type
);
624 assert(glsl_type_is_vector(tail
->type
));
625 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
628 if (idx_val
->value_type
== vtn_value_type_constant
) {
629 unsigned idx
= idx_val
->constant
->value
.u
[0];
630 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
631 deref_arr
->base_offset
= idx
;
633 assert(idx_val
->value_type
== vtn_value_type_ssa
);
634 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
635 deref_arr
->base_offset
= 0;
636 deref_arr
->indirect
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
638 tail
->child
= &deref_arr
->deref
;
642 case GLSL_TYPE_STRUCT
: {
643 assert(idx_val
->value_type
== vtn_value_type_constant
);
644 unsigned idx
= idx_val
->constant
->value
.u
[0];
645 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
646 deref_struct
->deref
.type
= glsl_get_struct_field(tail
->type
, idx
);
647 tail
->child
= &deref_struct
->deref
;
651 unreachable("Invalid type for deref");
658 case SpvOpCopyMemory
: {
659 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
660 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
662 nir_intrinsic_instr
*copy
=
663 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
664 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
665 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
667 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
672 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
673 const struct glsl_type
*src_type
= nir_deref_tail(&src
->deref
)->type
;
675 if (glsl_get_base_type(src_type
) == GLSL_TYPE_SAMPLER
) {
676 vtn_push_value(b
, w
[2], vtn_value_type_deref
)->deref
= src
;
680 assert(glsl_type_is_vector_or_scalar(src_type
));
681 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
683 nir_intrinsic_instr
*load
=
684 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
685 load
->variables
[0] = nir_deref_as_var(nir_copy_deref(load
, &src
->deref
));
686 load
->num_components
= glsl_get_vector_elements(src_type
);
687 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
,
690 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
691 val
->type
= src_type
;
693 if (src
->var
->data
.mode
== nir_var_uniform
&&
694 glsl_get_base_type(src_type
) == GLSL_TYPE_BOOL
) {
695 /* Uniform boolean loads need to be fixed up since they're defined
696 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
698 val
->ssa
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
700 val
->ssa
= &load
->dest
.ssa
;
706 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
707 const struct glsl_type
*dest_type
= nir_deref_tail(&dest
->deref
)->type
;
708 struct vtn_value
*src_val
= vtn_untyped_value(b
, w
[2]);
709 if (src_val
->value_type
== vtn_value_type_ssa
) {
710 assert(glsl_type_is_vector_or_scalar(dest_type
));
711 nir_intrinsic_instr
*store
=
712 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
713 store
->src
[0] = nir_src_for_ssa(src_val
->ssa
);
714 store
->variables
[0] = nir_deref_as_var(nir_copy_deref(store
, &dest
->deref
));
715 store
->num_components
= glsl_get_vector_elements(dest_type
);
717 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
719 assert(src_val
->value_type
== vtn_value_type_constant
);
721 nir_variable
*const_tmp
= rzalloc(b
->shader
, nir_variable
);
722 const_tmp
->type
= dest_type
;
723 const_tmp
->name
= "const_temp";
724 const_tmp
->data
.mode
= nir_var_local
;
725 const_tmp
->data
.read_only
= true;
726 exec_list_push_tail(&b
->impl
->locals
, &const_tmp
->node
);
728 nir_intrinsic_instr
*copy
=
729 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
730 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
731 copy
->variables
[1] = nir_deref_var_create(copy
, const_tmp
);
733 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
738 case SpvOpVariableArray
:
739 case SpvOpCopyMemorySized
:
740 case SpvOpArrayLength
:
741 case SpvOpImagePointer
:
743 unreachable("Unhandled opcode");
748 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
749 const uint32_t *w
, unsigned count
)
751 unreachable("Unhandled opcode");
755 vtn_tex_src(struct vtn_builder
*b
, unsigned index
, nir_tex_src_type type
)
758 src
.src
= nir_src_for_ssa(vtn_value(b
, index
, vtn_value_type_ssa
)->ssa
);
764 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
765 const uint32_t *w
, unsigned count
)
767 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
768 nir_deref_var
*sampler
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
770 nir_tex_src srcs
[8]; /* 8 should be enough */
771 nir_tex_src
*p
= srcs
;
773 unsigned coord_components
= 0;
775 case SpvOpTextureSample
:
776 case SpvOpTextureSampleDref
:
777 case SpvOpTextureSampleLod
:
778 case SpvOpTextureSampleProj
:
779 case SpvOpTextureSampleGrad
:
780 case SpvOpTextureSampleOffset
:
781 case SpvOpTextureSampleProjLod
:
782 case SpvOpTextureSampleProjGrad
:
783 case SpvOpTextureSampleLodOffset
:
784 case SpvOpTextureSampleProjOffset
:
785 case SpvOpTextureSampleGradOffset
:
786 case SpvOpTextureSampleProjLodOffset
:
787 case SpvOpTextureSampleProjGradOffset
:
788 case SpvOpTextureFetchTexelLod
:
789 case SpvOpTextureFetchTexelOffset
:
790 case SpvOpTextureFetchSample
:
791 case SpvOpTextureFetchTexel
:
792 case SpvOpTextureGather
:
793 case SpvOpTextureGatherOffset
:
794 case SpvOpTextureGatherOffsets
:
795 case SpvOpTextureQueryLod
:
796 /* All these types have the coordinate as their first real argument */
797 coord_components
= glsl_get_vector_elements(b
->values
[w
[4]].type
);
798 p
->src
= nir_src_for_ssa(vtn_ssa_value(b
, w
[4]));
799 p
->src_type
= nir_tex_src_coord
;
808 case SpvOpTextureSample
:
809 texop
= nir_texop_tex
;
812 texop
= nir_texop_txb
;
813 *p
++ = vtn_tex_src(b
, w
[5], nir_tex_src_bias
);
817 case SpvOpTextureSampleDref
:
818 case SpvOpTextureSampleLod
:
819 case SpvOpTextureSampleProj
:
820 case SpvOpTextureSampleGrad
:
821 case SpvOpTextureSampleOffset
:
822 case SpvOpTextureSampleProjLod
:
823 case SpvOpTextureSampleProjGrad
:
824 case SpvOpTextureSampleLodOffset
:
825 case SpvOpTextureSampleProjOffset
:
826 case SpvOpTextureSampleGradOffset
:
827 case SpvOpTextureSampleProjLodOffset
:
828 case SpvOpTextureSampleProjGradOffset
:
829 case SpvOpTextureFetchTexelLod
:
830 case SpvOpTextureFetchTexelOffset
:
831 case SpvOpTextureFetchSample
:
832 case SpvOpTextureFetchTexel
:
833 case SpvOpTextureGather
:
834 case SpvOpTextureGatherOffset
:
835 case SpvOpTextureGatherOffsets
:
836 case SpvOpTextureQuerySizeLod
:
837 case SpvOpTextureQuerySize
:
838 case SpvOpTextureQueryLod
:
839 case SpvOpTextureQueryLevels
:
840 case SpvOpTextureQuerySamples
:
842 unreachable("Unhandled opcode");
845 nir_tex_instr
*instr
= nir_tex_instr_create(b
->shader
, p
- srcs
);
847 const struct glsl_type
*sampler_type
= nir_deref_tail(&sampler
->deref
)->type
;
848 instr
->sampler_dim
= glsl_get_sampler_dim(sampler_type
);
850 switch (glsl_get_sampler_result_type(sampler_type
)) {
851 case GLSL_TYPE_FLOAT
: instr
->dest_type
= nir_type_float
; break;
852 case GLSL_TYPE_INT
: instr
->dest_type
= nir_type_int
; break;
853 case GLSL_TYPE_UINT
: instr
->dest_type
= nir_type_unsigned
; break;
854 case GLSL_TYPE_BOOL
: instr
->dest_type
= nir_type_bool
; break;
856 unreachable("Invalid base type for sampler result");
860 memcpy(instr
->src
, srcs
, instr
->num_srcs
* sizeof(*instr
->src
));
861 instr
->coord_components
= coord_components
;
862 instr
->is_array
= glsl_sampler_type_is_array(sampler_type
);
863 instr
->is_shadow
= glsl_sampler_type_is_shadow(sampler_type
);
865 instr
->sampler
= nir_deref_as_var(nir_copy_deref(instr
, &sampler
->deref
));
867 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 4, NULL
);
868 val
->ssa
= &instr
->dest
.ssa
;
870 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
874 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
875 const uint32_t *w
, unsigned count
)
877 unreachable("Matrix math not handled");
881 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
882 const uint32_t *w
, unsigned count
)
884 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
885 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
887 /* Collect the various SSA sources */
888 unsigned num_inputs
= count
- 3;
890 for (unsigned i
= 0; i
< num_inputs
; i
++)
891 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3]);
893 /* Indicates that the first two arguments should be swapped. This is
894 * used for implementing greater-than and less-than-or-equal.
900 /* Basic ALU operations */
901 case SpvOpSNegate
: op
= nir_op_ineg
; break;
902 case SpvOpFNegate
: op
= nir_op_fneg
; break;
903 case SpvOpNot
: op
= nir_op_inot
; break;
906 switch (src
[0]->num_components
) {
907 case 1: op
= nir_op_imov
; break;
908 case 2: op
= nir_op_bany2
; break;
909 case 3: op
= nir_op_bany3
; break;
910 case 4: op
= nir_op_bany4
; break;
915 switch (src
[0]->num_components
) {
916 case 1: op
= nir_op_imov
; break;
917 case 2: op
= nir_op_ball2
; break;
918 case 3: op
= nir_op_ball3
; break;
919 case 4: op
= nir_op_ball4
; break;
923 case SpvOpIAdd
: op
= nir_op_iadd
; break;
924 case SpvOpFAdd
: op
= nir_op_fadd
; break;
925 case SpvOpISub
: op
= nir_op_isub
; break;
926 case SpvOpFSub
: op
= nir_op_fsub
; break;
927 case SpvOpIMul
: op
= nir_op_imul
; break;
928 case SpvOpFMul
: op
= nir_op_fmul
; break;
929 case SpvOpUDiv
: op
= nir_op_udiv
; break;
930 case SpvOpSDiv
: op
= nir_op_idiv
; break;
931 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
932 case SpvOpUMod
: op
= nir_op_umod
; break;
933 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
934 case SpvOpFMod
: op
= nir_op_fmod
; break;
937 assert(src
[0]->num_components
== src
[1]->num_components
);
938 switch (src
[0]->num_components
) {
939 case 1: op
= nir_op_fmul
; break;
940 case 2: op
= nir_op_fdot2
; break;
941 case 3: op
= nir_op_fdot3
; break;
942 case 4: op
= nir_op_fdot4
; break;
946 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
947 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
948 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
949 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
950 case SpvOpLogicalXor
: op
= nir_op_ixor
; break;
951 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
952 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
953 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
954 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
955 case SpvOpSelect
: op
= nir_op_bcsel
; break;
956 case SpvOpIEqual
: op
= nir_op_ieq
; break;
958 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
959 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
960 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
961 case SpvOpINotEqual
: op
= nir_op_ine
; break;
962 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
963 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
964 case SpvOpULessThan
: op
= nir_op_ult
; break;
965 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
966 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
967 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
968 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
969 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
970 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
971 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
972 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
973 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
974 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
975 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
976 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
977 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
978 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
979 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
982 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
983 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
984 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
985 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
986 case SpvOpBitcast
: op
= nir_op_imov
; break;
989 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
996 case SpvOpDPdx
: op
= nir_op_fddx
; break;
997 case SpvOpDPdy
: op
= nir_op_fddy
; break;
998 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
999 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
1000 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
1001 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
1003 val
->ssa
= nir_fadd(&b
->nb
,
1004 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
1005 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
1007 case SpvOpFwidthFine
:
1008 val
->ssa
= nir_fadd(&b
->nb
,
1009 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
1010 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
1012 case SpvOpFwidthCoarse
:
1013 val
->ssa
= nir_fadd(&b
->nb
,
1014 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
1015 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
1018 case SpvOpVectorTimesScalar
:
1019 /* The builder will take care of splatting for us. */
1020 val
->ssa
= nir_fmul(&b
->nb
, src
[0], src
[1]);
1025 unreachable("No NIR equivalent");
1031 case SpvOpSignBitSet
:
1032 case SpvOpLessOrGreater
:
1034 case SpvOpUnordered
:
1036 unreachable("Unhandled opcode");
1040 nir_ssa_def
*tmp
= src
[0];
1045 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
1046 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
1047 glsl_get_vector_elements(val
->type
), val
->name
);
1048 val
->ssa
= &instr
->dest
.dest
.ssa
;
1050 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
1051 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
1053 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
1057 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1058 const uint32_t *w
, unsigned count
)
1062 case SpvOpSourceExtension
:
1063 case SpvOpCompileFlag
:
1064 case SpvOpExtension
:
1065 /* Unhandled, but these are for debug so that's ok. */
1068 case SpvOpExtInstImport
:
1069 vtn_handle_extension(b
, opcode
, w
, count
);
1072 case SpvOpMemoryModel
:
1073 assert(w
[1] == SpvAddressingModelLogical
);
1074 assert(w
[2] == SpvMemoryModelGLSL450
);
1077 case SpvOpEntryPoint
:
1078 assert(b
->entry_point
== NULL
);
1079 b
->entry_point
= &b
->values
[w
[2]];
1080 b
->execution_model
= w
[1];
1083 case SpvOpExecutionMode
:
1084 unreachable("Execution modes not yet implemented");
1088 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
1089 vtn_string_literal(b
, &w
[2], count
- 2);
1093 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
1096 case SpvOpMemberName
:
1101 break; /* Ignored for now */
1103 case SpvOpDecorationGroup
:
1105 case SpvOpMemberDecorate
:
1106 case SpvOpGroupDecorate
:
1107 case SpvOpGroupMemberDecorate
:
1108 vtn_handle_decoration(b
, opcode
, w
, count
);
1114 case SpvOpTypeFloat
:
1115 case SpvOpTypeVector
:
1116 case SpvOpTypeMatrix
:
1117 case SpvOpTypeSampler
:
1118 case SpvOpTypeArray
:
1119 case SpvOpTypeRuntimeArray
:
1120 case SpvOpTypeStruct
:
1121 case SpvOpTypeOpaque
:
1122 case SpvOpTypePointer
:
1123 case SpvOpTypeFunction
:
1124 case SpvOpTypeEvent
:
1125 case SpvOpTypeDeviceEvent
:
1126 case SpvOpTypeReserveId
:
1127 case SpvOpTypeQueue
:
1129 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
1130 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
1133 case SpvOpConstantTrue
:
1134 case SpvOpConstantFalse
:
1136 case SpvOpConstantComposite
:
1137 case SpvOpConstantSampler
:
1138 case SpvOpConstantNullPointer
:
1139 case SpvOpConstantNullObject
:
1140 case SpvOpSpecConstantTrue
:
1141 case SpvOpSpecConstantFalse
:
1142 case SpvOpSpecConstant
:
1143 case SpvOpSpecConstantComposite
:
1144 vtn_handle_constant(b
, opcode
, w
, count
);
1148 vtn_handle_variables(b
, opcode
, w
, count
);
1152 return false; /* End of preamble */
1159 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1160 const uint32_t *w
, unsigned count
)
1163 case SpvOpFunction
: {
1164 assert(b
->func
== NULL
);
1165 b
->func
= rzalloc(b
, struct vtn_function
);
1167 const struct glsl_type
*result_type
=
1168 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1169 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
1170 const struct glsl_type
*func_type
=
1171 vtn_value(b
, w
[4], vtn_value_type_type
)->type
;
1173 assert(glsl_get_function_return_type(func_type
) == result_type
);
1175 nir_function
*func
=
1176 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
1178 nir_function_overload
*overload
= nir_function_overload_create(func
);
1179 overload
->num_params
= glsl_get_length(func_type
);
1180 overload
->params
= ralloc_array(overload
, nir_parameter
,
1181 overload
->num_params
);
1182 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
1183 const struct glsl_function_param
*param
=
1184 glsl_get_function_param(func_type
, i
);
1185 overload
->params
[i
].type
= param
->type
;
1188 overload
->params
[i
].param_type
= nir_parameter_inout
;
1190 overload
->params
[i
].param_type
= nir_parameter_in
;
1194 overload
->params
[i
].param_type
= nir_parameter_out
;
1196 assert(!"Parameter is neither in nor out");
1200 b
->func
->overload
= overload
;
1204 case SpvOpFunctionEnd
:
1208 case SpvOpFunctionParameter
:
1209 break; /* Does nothing */
1212 assert(b
->block
== NULL
);
1213 b
->block
= rzalloc(b
, struct vtn_block
);
1214 b
->block
->label
= w
;
1215 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
1217 if (b
->func
->start_block
== NULL
) {
1218 /* This is the first block encountered for this function. In this
1219 * case, we set the start block and add it to the list of
1220 * implemented functions that we'll walk later.
1222 b
->func
->start_block
= b
->block
;
1223 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
1229 case SpvOpBranchConditional
:
1233 case SpvOpReturnValue
:
1234 case SpvOpUnreachable
:
1236 b
->block
->branch
= w
;
1240 case SpvOpSelectionMerge
:
1241 case SpvOpLoopMerge
:
1242 assert(b
->block
&& b
->block
->merge_op
== SpvOpNop
);
1243 b
->block
->merge_op
= opcode
;
1244 b
->block
->merge_block_id
= w
[1];
1248 /* Continue on as per normal */
1256 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1257 const uint32_t *w
, unsigned count
)
1261 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1262 assert(block
->block
== NULL
);
1264 struct exec_node
*list_tail
= exec_list_get_tail(b
->nb
.cf_node_list
);
1265 nir_cf_node
*tail_node
= exec_node_data(nir_cf_node
, list_tail
, node
);
1266 assert(tail_node
->type
== nir_cf_node_block
);
1267 block
->block
= nir_cf_node_as_block(tail_node
);
1271 case SpvOpLoopMerge
:
1272 case SpvOpSelectionMerge
:
1273 /* This is handled by cfg pre-pass and walk_blocks */
1277 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
1281 vtn_handle_extension(b
, opcode
, w
, count
);
1285 case SpvOpVariableArray
:
1288 case SpvOpCopyMemory
:
1289 case SpvOpCopyMemorySized
:
1290 case SpvOpAccessChain
:
1291 case SpvOpInBoundsAccessChain
:
1292 case SpvOpArrayLength
:
1293 case SpvOpImagePointer
:
1294 vtn_handle_variables(b
, opcode
, w
, count
);
1297 case SpvOpFunctionCall
:
1298 vtn_handle_function_call(b
, opcode
, w
, count
);
1301 case SpvOpTextureSample
:
1302 case SpvOpTextureSampleDref
:
1303 case SpvOpTextureSampleLod
:
1304 case SpvOpTextureSampleProj
:
1305 case SpvOpTextureSampleGrad
:
1306 case SpvOpTextureSampleOffset
:
1307 case SpvOpTextureSampleProjLod
:
1308 case SpvOpTextureSampleProjGrad
:
1309 case SpvOpTextureSampleLodOffset
:
1310 case SpvOpTextureSampleProjOffset
:
1311 case SpvOpTextureSampleGradOffset
:
1312 case SpvOpTextureSampleProjLodOffset
:
1313 case SpvOpTextureSampleProjGradOffset
:
1314 case SpvOpTextureFetchTexelLod
:
1315 case SpvOpTextureFetchTexelOffset
:
1316 case SpvOpTextureFetchSample
:
1317 case SpvOpTextureFetchTexel
:
1318 case SpvOpTextureGather
:
1319 case SpvOpTextureGatherOffset
:
1320 case SpvOpTextureGatherOffsets
:
1321 case SpvOpTextureQuerySizeLod
:
1322 case SpvOpTextureQuerySize
:
1323 case SpvOpTextureQueryLod
:
1324 case SpvOpTextureQueryLevels
:
1325 case SpvOpTextureQuerySamples
:
1326 vtn_handle_texture(b
, opcode
, w
, count
);
1334 case SpvOpConvertFToU
:
1335 case SpvOpConvertFToS
:
1336 case SpvOpConvertSToF
:
1337 case SpvOpConvertUToF
:
1341 case SpvOpConvertPtrToU
:
1342 case SpvOpConvertUToPtr
:
1343 case SpvOpPtrCastToGeneric
:
1344 case SpvOpGenericCastToPtr
:
1350 case SpvOpSignBitSet
:
1351 case SpvOpLessOrGreater
:
1353 case SpvOpUnordered
:
1368 case SpvOpVectorTimesScalar
:
1370 case SpvOpShiftRightLogical
:
1371 case SpvOpShiftRightArithmetic
:
1372 case SpvOpShiftLeftLogical
:
1373 case SpvOpLogicalOr
:
1374 case SpvOpLogicalXor
:
1375 case SpvOpLogicalAnd
:
1376 case SpvOpBitwiseOr
:
1377 case SpvOpBitwiseXor
:
1378 case SpvOpBitwiseAnd
:
1381 case SpvOpFOrdEqual
:
1382 case SpvOpFUnordEqual
:
1383 case SpvOpINotEqual
:
1384 case SpvOpFOrdNotEqual
:
1385 case SpvOpFUnordNotEqual
:
1386 case SpvOpULessThan
:
1387 case SpvOpSLessThan
:
1388 case SpvOpFOrdLessThan
:
1389 case SpvOpFUnordLessThan
:
1390 case SpvOpUGreaterThan
:
1391 case SpvOpSGreaterThan
:
1392 case SpvOpFOrdGreaterThan
:
1393 case SpvOpFUnordGreaterThan
:
1394 case SpvOpULessThanEqual
:
1395 case SpvOpSLessThanEqual
:
1396 case SpvOpFOrdLessThanEqual
:
1397 case SpvOpFUnordLessThanEqual
:
1398 case SpvOpUGreaterThanEqual
:
1399 case SpvOpSGreaterThanEqual
:
1400 case SpvOpFOrdGreaterThanEqual
:
1401 case SpvOpFUnordGreaterThanEqual
:
1407 case SpvOpFwidthFine
:
1408 case SpvOpDPdxCoarse
:
1409 case SpvOpDPdyCoarse
:
1410 case SpvOpFwidthCoarse
:
1411 vtn_handle_alu(b
, opcode
, w
, count
);
1414 case SpvOpTranspose
:
1415 case SpvOpOuterProduct
:
1416 case SpvOpMatrixTimesScalar
:
1417 case SpvOpVectorTimesMatrix
:
1418 case SpvOpMatrixTimesVector
:
1419 case SpvOpMatrixTimesMatrix
:
1420 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
1424 unreachable("Unhandled opcode");
1431 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
1432 struct vtn_block
*break_block
, struct vtn_block
*cont_block
,
1433 struct vtn_block
*end_block
)
1435 struct vtn_block
*block
= start
;
1436 while (block
!= end_block
) {
1437 if (block
->block
!= NULL
) {
1438 /* We've already visited this block once before so this is a
1439 * back-edge. Back-edges are only allowed to point to a loop
1442 assert(block
== cont_block
);
1446 if (block
->merge_op
== SpvOpLoopMerge
) {
1447 /* This is the jump into a loop. */
1449 break_block
= vtn_value(b
, block
->merge_block_id
,
1450 vtn_value_type_block
)->block
;
1452 nir_loop
*loop
= nir_loop_create(b
->shader
);
1453 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &loop
->cf_node
);
1455 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1457 /* Reset the merge_op to prerevent infinite recursion */
1458 block
->merge_op
= SpvOpNop
;
1460 nir_builder_insert_after_cf_list(&b
->nb
, &loop
->body
);
1461 vtn_walk_blocks(b
, block
, break_block
, cont_block
, NULL
);
1463 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1464 block
= break_block
;
1468 const uint32_t *w
= block
->branch
;
1469 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
1472 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
1473 vtn_handle_body_instruction
);
1475 switch (branch_op
) {
1477 struct vtn_block
*branch_block
=
1478 vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1480 if (branch_block
== break_block
) {
1481 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1483 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1486 } else if (branch_block
== cont_block
) {
1487 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1489 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1492 } else if (branch_block
== end_block
) {
1495 block
= branch_block
;
1500 case SpvOpBranchConditional
: {
1501 /* Gather up the branch blocks */
1502 struct vtn_block
*then_block
=
1503 vtn_value(b
, w
[2], vtn_value_type_block
)->block
;
1504 struct vtn_block
*else_block
=
1505 vtn_value(b
, w
[3], vtn_value_type_block
)->block
;
1507 nir_if
*if_stmt
= nir_if_create(b
->shader
);
1508 if_stmt
->condition
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
1509 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &if_stmt
->cf_node
);
1511 if (then_block
== break_block
) {
1512 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1514 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
1517 } else if (else_block
== break_block
) {
1518 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1520 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
1523 } else if (then_block
== cont_block
) {
1524 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1526 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
1529 } else if (else_block
== cont_block
) {
1530 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1532 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
1536 /* Conventional if statement */
1537 assert(block
->merge_op
== SpvOpSelectionMerge
);
1538 struct vtn_block
*merge_block
=
1539 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
1541 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1543 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->then_list
);
1544 vtn_walk_blocks(b
, then_block
, break_block
, cont_block
, merge_block
);
1546 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->else_list
);
1547 vtn_walk_blocks(b
, else_block
, break_block
, cont_block
, merge_block
);
1549 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1550 block
= merge_block
;
1554 /* If we got here then we inserted a predicated break or continue
1555 * above and we need to handle the other case. We already set
1556 * `block` above to indicate what block to visit after the
1560 /* It's possible that the other branch is also a break/continue.
1561 * If it is, we handle that here.
1563 if (block
== break_block
) {
1564 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1566 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1569 } else if (block
== cont_block
) {
1570 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1572 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1577 /* If we got here then there was a predicated break/continue but
1578 * the other half of the if has stuff in it. `block` was already
1579 * set above so there is nothing left for us to do.
1585 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1587 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1592 nir_intrinsic_instr
*discard
=
1593 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_discard
);
1594 nir_builder_instr_insert(&b
->nb
, &discard
->instr
);
1599 case SpvOpReturnValue
:
1600 case SpvOpUnreachable
:
1602 unreachable("Unhandled opcode");
1608 spirv_to_nir(const uint32_t *words
, size_t word_count
,
1609 const nir_shader_compiler_options
*options
)
1611 const uint32_t *word_end
= words
+ word_count
;
1613 /* Handle the SPIR-V header (first 4 dwords) */
1614 assert(word_count
> 5);
1616 assert(words
[0] == SpvMagicNumber
);
1617 assert(words
[1] == 99);
1618 /* words[2] == generator magic */
1619 unsigned value_id_bound
= words
[3];
1620 assert(words
[4] == 0);
1624 nir_shader
*shader
= nir_shader_create(NULL
, options
);
1626 /* Initialize the stn_builder object */
1627 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
1629 b
->value_id_bound
= value_id_bound
;
1630 b
->values
= ralloc_array(b
, struct vtn_value
, value_id_bound
);
1631 exec_list_make_empty(&b
->functions
);
1633 /* Handle all the preamble instructions */
1634 words
= vtn_foreach_instruction(b
, words
, word_end
,
1635 vtn_handle_preamble_instruction
);
1637 /* Do a very quick CFG analysis pass */
1638 vtn_foreach_instruction(b
, words
, word_end
,
1639 vtn_handle_first_cfg_pass_instruction
);
1641 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
1642 b
->impl
= nir_function_impl_create(func
->overload
);
1643 nir_builder_init(&b
->nb
, b
->impl
);
1644 nir_builder_insert_after_cf_list(&b
->nb
, &b
->impl
->body
);
1645 vtn_walk_blocks(b
, func
->start_block
, NULL
, NULL
, NULL
);