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 SpvDecorationBlock
:
419 case SpvDecorationBufferBlock
:
420 case SpvDecorationRowMajor
:
421 case SpvDecorationColMajor
:
422 case SpvDecorationGLSLShared
:
423 case SpvDecorationGLSLStd140
:
424 case SpvDecorationGLSLStd430
:
425 case SpvDecorationGLSLPacked
:
426 case SpvDecorationPatch
:
427 case SpvDecorationRestrict
:
428 case SpvDecorationAliased
:
429 case SpvDecorationVolatile
:
430 case SpvDecorationCoherent
:
431 case SpvDecorationNonreadable
:
432 case SpvDecorationUniform
:
433 /* This is really nice but we have no use for it right now. */
434 case SpvDecorationNoStaticUse
:
435 case SpvDecorationCPacked
:
436 case SpvDecorationSaturatedConversion
:
437 case SpvDecorationStream
:
438 case SpvDecorationDescriptorSet
:
439 case SpvDecorationOffset
:
440 case SpvDecorationAlignment
:
441 case SpvDecorationXfbBuffer
:
442 case SpvDecorationStride
:
443 case SpvDecorationBuiltIn
:
444 case SpvDecorationFuncParamAttr
:
445 case SpvDecorationFPRoundingMode
:
446 case SpvDecorationFPFastMathMode
:
447 case SpvDecorationLinkageAttributes
:
448 case SpvDecorationSpecId
:
450 unreachable("Unhandled variable decoration");
455 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
456 const uint32_t *w
, unsigned count
)
459 case SpvOpVariable
: {
460 const struct glsl_type
*type
=
461 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
462 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
464 nir_variable
*var
= ralloc(b
->shader
, nir_variable
);
467 var
->name
= ralloc_strdup(var
, val
->name
);
469 switch ((SpvStorageClass
)w
[3]) {
470 case SpvStorageClassUniformConstant
:
471 var
->data
.mode
= nir_var_uniform
;
472 var
->data
.read_only
= true;
474 case SpvStorageClassInput
:
475 var
->data
.mode
= nir_var_shader_in
;
476 var
->data
.read_only
= true;
478 case SpvStorageClassOutput
:
479 var
->data
.mode
= nir_var_shader_out
;
481 case SpvStorageClassPrivateGlobal
:
482 var
->data
.mode
= nir_var_global
;
484 case SpvStorageClassFunction
:
485 var
->data
.mode
= nir_var_local
;
487 case SpvStorageClassUniform
:
488 case SpvStorageClassWorkgroupLocal
:
489 case SpvStorageClassWorkgroupGlobal
:
490 case SpvStorageClassGeneric
:
491 case SpvStorageClassPrivate
:
492 case SpvStorageClassAtomicCounter
:
494 unreachable("Unhandled variable storage class");
499 var
->constant_initializer
=
500 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
503 if (var
->data
.mode
== nir_var_local
) {
504 exec_list_push_tail(&b
->impl
->locals
, &var
->node
);
506 exec_list_push_tail(&b
->shader
->globals
, &var
->node
);
509 val
->deref
= nir_deref_var_create(b
->shader
, var
);
511 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
515 case SpvOpAccessChain
:
516 case SpvOpInBoundsAccessChain
: {
517 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
518 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
519 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
521 nir_deref
*tail
= &val
->deref
->deref
;
525 for (unsigned i
= 0; i
< count
- 4; i
++) {
526 assert(w
[i
+ 4] < b
->value_id_bound
);
527 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
529 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
533 case GLSL_TYPE_FLOAT
:
534 case GLSL_TYPE_DOUBLE
:
536 case GLSL_TYPE_ARRAY
: {
537 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
538 if (base_type
== GLSL_TYPE_ARRAY
) {
539 deref_arr
->deref
.type
= glsl_get_array_element(tail
->type
);
540 } else if (glsl_type_is_matrix(tail
->type
)) {
541 deref_arr
->deref
.type
= glsl_get_column_type(tail
->type
);
543 assert(glsl_type_is_vector(tail
->type
));
544 deref_arr
->deref
.type
= glsl_scalar_type(base_type
);
547 if (idx_val
->value_type
== vtn_value_type_constant
) {
548 unsigned idx
= idx_val
->constant
->value
.u
[0];
549 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
550 deref_arr
->base_offset
= idx
;
552 assert(idx_val
->value_type
== vtn_value_type_ssa
);
553 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
554 deref_arr
->base_offset
= 0;
555 deref_arr
->indirect
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
557 tail
->child
= &deref_arr
->deref
;
561 case GLSL_TYPE_STRUCT
: {
562 assert(idx_val
->value_type
== vtn_value_type_constant
);
563 unsigned idx
= idx_val
->constant
->value
.u
[0];
564 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
565 deref_struct
->deref
.type
= glsl_get_struct_field(tail
->type
, idx
);
566 tail
->child
= &deref_struct
->deref
;
570 unreachable("Invalid type for deref");
577 case SpvOpCopyMemory
: {
578 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
579 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
581 nir_intrinsic_instr
*copy
=
582 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
583 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
584 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
586 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
591 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
592 const struct glsl_type
*src_type
= nir_deref_tail(&src
->deref
)->type
;
594 if (glsl_get_base_type(src_type
) == GLSL_TYPE_SAMPLER
) {
595 vtn_push_value(b
, w
[2], vtn_value_type_deref
)->deref
= src
;
599 assert(glsl_type_is_vector_or_scalar(src_type
));
600 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
602 nir_intrinsic_instr
*load
=
603 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
604 load
->variables
[0] = nir_deref_as_var(nir_copy_deref(load
, &src
->deref
));
605 load
->num_components
= glsl_get_vector_elements(src_type
);
606 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
,
609 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
610 val
->type
= src_type
;
612 if (src
->var
->data
.mode
== nir_var_uniform
&&
613 glsl_get_base_type(src_type
) == GLSL_TYPE_BOOL
) {
614 /* Uniform boolean loads need to be fixed up since they're defined
615 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
617 val
->ssa
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
619 val
->ssa
= &load
->dest
.ssa
;
625 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
626 const struct glsl_type
*dest_type
= nir_deref_tail(&dest
->deref
)->type
;
627 struct vtn_value
*src_val
= vtn_untyped_value(b
, w
[2]);
628 if (src_val
->value_type
== vtn_value_type_ssa
) {
629 assert(glsl_type_is_vector_or_scalar(dest_type
));
630 nir_intrinsic_instr
*store
=
631 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
632 store
->src
[0] = nir_src_for_ssa(src_val
->ssa
);
633 store
->variables
[0] = nir_deref_as_var(nir_copy_deref(store
, &dest
->deref
));
634 store
->num_components
= glsl_get_vector_elements(dest_type
);
636 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
638 assert(src_val
->value_type
== vtn_value_type_constant
);
640 nir_variable
*const_tmp
= rzalloc(b
->shader
, nir_variable
);
641 const_tmp
->type
= dest_type
;
642 const_tmp
->name
= "const_temp";
643 const_tmp
->data
.mode
= nir_var_local
;
644 const_tmp
->data
.read_only
= true;
645 exec_list_push_tail(&b
->impl
->locals
, &const_tmp
->node
);
647 nir_intrinsic_instr
*copy
=
648 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
649 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
650 copy
->variables
[1] = nir_deref_var_create(copy
, const_tmp
);
652 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
657 case SpvOpVariableArray
:
658 case SpvOpCopyMemorySized
:
659 case SpvOpArrayLength
:
660 case SpvOpImagePointer
:
662 unreachable("Unhandled opcode");
667 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
668 const uint32_t *w
, unsigned count
)
670 unreachable("Unhandled opcode");
674 vtn_tex_src(struct vtn_builder
*b
, unsigned index
, nir_tex_src_type type
)
677 src
.src
= nir_src_for_ssa(vtn_value(b
, index
, vtn_value_type_ssa
)->ssa
);
683 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
684 const uint32_t *w
, unsigned count
)
686 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
687 nir_deref_var
*sampler
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
689 nir_tex_src srcs
[8]; /* 8 should be enough */
690 nir_tex_src
*p
= srcs
;
692 unsigned coord_components
= 0;
694 case SpvOpTextureSample
:
695 case SpvOpTextureSampleDref
:
696 case SpvOpTextureSampleLod
:
697 case SpvOpTextureSampleProj
:
698 case SpvOpTextureSampleGrad
:
699 case SpvOpTextureSampleOffset
:
700 case SpvOpTextureSampleProjLod
:
701 case SpvOpTextureSampleProjGrad
:
702 case SpvOpTextureSampleLodOffset
:
703 case SpvOpTextureSampleProjOffset
:
704 case SpvOpTextureSampleGradOffset
:
705 case SpvOpTextureSampleProjLodOffset
:
706 case SpvOpTextureSampleProjGradOffset
:
707 case SpvOpTextureFetchTexelLod
:
708 case SpvOpTextureFetchTexelOffset
:
709 case SpvOpTextureFetchSample
:
710 case SpvOpTextureFetchTexel
:
711 case SpvOpTextureGather
:
712 case SpvOpTextureGatherOffset
:
713 case SpvOpTextureGatherOffsets
:
714 case SpvOpTextureQueryLod
: {
715 /* All these types have the coordinate as their first real argument */
716 struct vtn_value
*coord
= vtn_value(b
, w
[4], vtn_value_type_ssa
);
717 coord_components
= glsl_get_vector_elements(coord
->type
);
718 p
->src
= nir_src_for_ssa(coord
->ssa
);
719 p
->src_type
= nir_tex_src_coord
;
729 case SpvOpTextureSample
:
730 texop
= nir_texop_tex
;
733 texop
= nir_texop_txb
;
734 *p
++ = vtn_tex_src(b
, w
[5], nir_tex_src_bias
);
738 case SpvOpTextureSampleDref
:
739 case SpvOpTextureSampleLod
:
740 case SpvOpTextureSampleProj
:
741 case SpvOpTextureSampleGrad
:
742 case SpvOpTextureSampleOffset
:
743 case SpvOpTextureSampleProjLod
:
744 case SpvOpTextureSampleProjGrad
:
745 case SpvOpTextureSampleLodOffset
:
746 case SpvOpTextureSampleProjOffset
:
747 case SpvOpTextureSampleGradOffset
:
748 case SpvOpTextureSampleProjLodOffset
:
749 case SpvOpTextureSampleProjGradOffset
:
750 case SpvOpTextureFetchTexelLod
:
751 case SpvOpTextureFetchTexelOffset
:
752 case SpvOpTextureFetchSample
:
753 case SpvOpTextureFetchTexel
:
754 case SpvOpTextureGather
:
755 case SpvOpTextureGatherOffset
:
756 case SpvOpTextureGatherOffsets
:
757 case SpvOpTextureQuerySizeLod
:
758 case SpvOpTextureQuerySize
:
759 case SpvOpTextureQueryLod
:
760 case SpvOpTextureQueryLevels
:
761 case SpvOpTextureQuerySamples
:
763 unreachable("Unhandled opcode");
766 nir_tex_instr
*instr
= nir_tex_instr_create(b
->shader
, p
- srcs
);
768 const struct glsl_type
*sampler_type
= nir_deref_tail(&sampler
->deref
)->type
;
769 instr
->sampler_dim
= glsl_get_sampler_dim(sampler_type
);
771 switch (glsl_get_sampler_result_type(sampler_type
)) {
772 case GLSL_TYPE_FLOAT
: instr
->dest_type
= nir_type_float
; break;
773 case GLSL_TYPE_INT
: instr
->dest_type
= nir_type_int
; break;
774 case GLSL_TYPE_UINT
: instr
->dest_type
= nir_type_unsigned
; break;
775 case GLSL_TYPE_BOOL
: instr
->dest_type
= nir_type_bool
; break;
777 unreachable("Invalid base type for sampler result");
781 memcpy(instr
->src
, srcs
, instr
->num_srcs
* sizeof(*instr
->src
));
782 instr
->coord_components
= coord_components
;
783 instr
->is_array
= glsl_sampler_type_is_array(sampler_type
);
784 instr
->is_shadow
= glsl_sampler_type_is_shadow(sampler_type
);
786 instr
->sampler
= sampler
;
788 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 4, NULL
);
789 val
->ssa
= &instr
->dest
.ssa
;
791 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
795 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
796 const uint32_t *w
, unsigned count
)
798 unreachable("Matrix math not handled");
802 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
803 const uint32_t *w
, unsigned count
)
805 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
806 val
->type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
808 /* Collect the various SSA sources */
809 unsigned num_inputs
= count
- 3;
811 for (unsigned i
= 0; i
< num_inputs
; i
++)
812 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3]);
814 /* Indicates that the first two arguments should be swapped. This is
815 * used for implementing greater-than and less-than-or-equal.
821 /* Basic ALU operations */
822 case SpvOpSNegate
: op
= nir_op_ineg
; break;
823 case SpvOpFNegate
: op
= nir_op_fneg
; break;
824 case SpvOpNot
: op
= nir_op_inot
; break;
827 switch (src
[0]->num_components
) {
828 case 1: op
= nir_op_imov
; break;
829 case 2: op
= nir_op_bany2
; break;
830 case 3: op
= nir_op_bany3
; break;
831 case 4: op
= nir_op_bany4
; break;
836 switch (src
[0]->num_components
) {
837 case 1: op
= nir_op_imov
; break;
838 case 2: op
= nir_op_ball2
; break;
839 case 3: op
= nir_op_ball3
; break;
840 case 4: op
= nir_op_ball4
; break;
844 case SpvOpIAdd
: op
= nir_op_iadd
; break;
845 case SpvOpFAdd
: op
= nir_op_fadd
; break;
846 case SpvOpISub
: op
= nir_op_isub
; break;
847 case SpvOpFSub
: op
= nir_op_fsub
; break;
848 case SpvOpIMul
: op
= nir_op_imul
; break;
849 case SpvOpFMul
: op
= nir_op_fmul
; break;
850 case SpvOpUDiv
: op
= nir_op_udiv
; break;
851 case SpvOpSDiv
: op
= nir_op_idiv
; break;
852 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
853 case SpvOpUMod
: op
= nir_op_umod
; break;
854 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
855 case SpvOpFMod
: op
= nir_op_fmod
; break;
858 assert(src
[0]->num_components
== src
[1]->num_components
);
859 switch (src
[0]->num_components
) {
860 case 1: op
= nir_op_fmul
; break;
861 case 2: op
= nir_op_fdot2
; break;
862 case 3: op
= nir_op_fdot3
; break;
863 case 4: op
= nir_op_fdot4
; break;
867 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
868 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
869 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
870 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
871 case SpvOpLogicalXor
: op
= nir_op_ixor
; break;
872 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
873 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
874 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
875 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
876 case SpvOpSelect
: op
= nir_op_bcsel
; break;
877 case SpvOpIEqual
: op
= nir_op_ieq
; break;
879 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
880 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
881 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
882 case SpvOpINotEqual
: op
= nir_op_ine
; break;
883 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
884 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
885 case SpvOpULessThan
: op
= nir_op_ult
; break;
886 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
887 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
888 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
889 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
890 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
891 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
892 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
893 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
894 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
895 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
896 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
897 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
898 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
899 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
900 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
903 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
904 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
905 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
906 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
907 case SpvOpBitcast
: op
= nir_op_imov
; break;
910 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
917 case SpvOpDPdx
: op
= nir_op_fddx
; break;
918 case SpvOpDPdy
: op
= nir_op_fddy
; break;
919 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
920 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
921 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
922 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
924 val
->ssa
= nir_fadd(&b
->nb
,
925 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
926 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
928 case SpvOpFwidthFine
:
929 val
->ssa
= nir_fadd(&b
->nb
,
930 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
931 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
933 case SpvOpFwidthCoarse
:
934 val
->ssa
= nir_fadd(&b
->nb
,
935 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
936 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
939 case SpvOpVectorTimesScalar
:
940 /* The builder will take care of splatting for us. */
941 val
->ssa
= nir_fmul(&b
->nb
, src
[0], src
[1]);
946 unreachable("No NIR equivalent");
952 case SpvOpSignBitSet
:
953 case SpvOpLessOrGreater
:
957 unreachable("Unhandled opcode");
961 nir_ssa_def
*tmp
= src
[0];
966 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
967 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
968 glsl_get_vector_elements(val
->type
), val
->name
);
969 val
->ssa
= &instr
->dest
.dest
.ssa
;
971 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
972 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
974 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
978 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
979 const uint32_t *w
, unsigned count
)
983 case SpvOpSourceExtension
:
984 case SpvOpCompileFlag
:
986 /* Unhandled, but these are for debug so that's ok. */
989 case SpvOpExtInstImport
:
990 vtn_handle_extension(b
, opcode
, w
, count
);
993 case SpvOpMemoryModel
:
994 assert(w
[1] == SpvAddressingModelLogical
);
995 assert(w
[2] == SpvMemoryModelGLSL450
);
998 case SpvOpEntryPoint
:
999 assert(b
->entry_point
== NULL
);
1000 b
->entry_point
= &b
->values
[w
[2]];
1001 b
->execution_model
= w
[1];
1004 case SpvOpExecutionMode
:
1005 unreachable("Execution modes not yet implemented");
1009 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
1010 vtn_string_literal(b
, &w
[2], count
- 2);
1014 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
1017 case SpvOpMemberName
:
1022 break; /* Ignored for now */
1024 case SpvOpDecorationGroup
:
1026 case SpvOpMemberDecorate
:
1027 case SpvOpGroupDecorate
:
1028 case SpvOpGroupMemberDecorate
:
1029 vtn_handle_decoration(b
, opcode
, w
, count
);
1035 case SpvOpTypeFloat
:
1036 case SpvOpTypeVector
:
1037 case SpvOpTypeMatrix
:
1038 case SpvOpTypeSampler
:
1039 case SpvOpTypeArray
:
1040 case SpvOpTypeRuntimeArray
:
1041 case SpvOpTypeStruct
:
1042 case SpvOpTypeOpaque
:
1043 case SpvOpTypePointer
:
1044 case SpvOpTypeFunction
:
1045 case SpvOpTypeEvent
:
1046 case SpvOpTypeDeviceEvent
:
1047 case SpvOpTypeReserveId
:
1048 case SpvOpTypeQueue
:
1050 vtn_push_value(b
, w
[1], vtn_value_type_type
)->type
=
1051 vtn_handle_type(b
, opcode
, &w
[2], count
- 2);
1054 case SpvOpConstantTrue
:
1055 case SpvOpConstantFalse
:
1057 case SpvOpConstantComposite
:
1058 case SpvOpConstantSampler
:
1059 case SpvOpConstantNullPointer
:
1060 case SpvOpConstantNullObject
:
1061 case SpvOpSpecConstantTrue
:
1062 case SpvOpSpecConstantFalse
:
1063 case SpvOpSpecConstant
:
1064 case SpvOpSpecConstantComposite
:
1065 vtn_handle_constant(b
, opcode
, w
, count
);
1069 vtn_handle_variables(b
, opcode
, w
, count
);
1073 return false; /* End of preamble */
1080 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1081 const uint32_t *w
, unsigned count
)
1084 case SpvOpFunction
: {
1085 assert(b
->func
== NULL
);
1086 b
->func
= rzalloc(b
, struct vtn_function
);
1088 const struct glsl_type
*result_type
=
1089 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1090 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
1091 const struct glsl_type
*func_type
=
1092 vtn_value(b
, w
[4], vtn_value_type_type
)->type
;
1094 assert(glsl_get_function_return_type(func_type
) == result_type
);
1096 nir_function
*func
=
1097 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
1099 nir_function_overload
*overload
= nir_function_overload_create(func
);
1100 overload
->num_params
= glsl_get_length(func_type
);
1101 overload
->params
= ralloc_array(overload
, nir_parameter
,
1102 overload
->num_params
);
1103 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
1104 const struct glsl_function_param
*param
=
1105 glsl_get_function_param(func_type
, i
);
1106 overload
->params
[i
].type
= param
->type
;
1109 overload
->params
[i
].param_type
= nir_parameter_inout
;
1111 overload
->params
[i
].param_type
= nir_parameter_in
;
1115 overload
->params
[i
].param_type
= nir_parameter_out
;
1117 assert(!"Parameter is neither in nor out");
1121 b
->func
->overload
= overload
;
1125 case SpvOpFunctionEnd
:
1129 case SpvOpFunctionParameter
:
1130 break; /* Does nothing */
1133 assert(b
->block
== NULL
);
1134 b
->block
= rzalloc(b
, struct vtn_block
);
1135 b
->block
->label
= w
;
1136 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
1138 if (b
->func
->start_block
== NULL
) {
1139 /* This is the first block encountered for this function. In this
1140 * case, we set the start block and add it to the list of
1141 * implemented functions that we'll walk later.
1143 b
->func
->start_block
= b
->block
;
1144 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
1150 case SpvOpBranchConditional
:
1154 case SpvOpReturnValue
:
1155 case SpvOpUnreachable
:
1157 b
->block
->branch
= w
;
1161 case SpvOpSelectionMerge
:
1162 case SpvOpLoopMerge
:
1163 assert(b
->block
&& b
->block
->merge_op
== SpvOpNop
);
1164 b
->block
->merge_op
= opcode
;
1165 b
->block
->merge_block_id
= w
[1];
1169 /* Continue on as per normal */
1177 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
1178 const uint32_t *w
, unsigned count
)
1182 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1183 assert(block
->block
== NULL
);
1185 struct exec_node
*list_tail
= exec_list_get_tail(b
->nb
.cf_node_list
);
1186 nir_cf_node
*tail_node
= exec_node_data(nir_cf_node
, list_tail
, node
);
1187 assert(tail_node
->type
== nir_cf_node_block
);
1188 block
->block
= nir_cf_node_as_block(tail_node
);
1192 case SpvOpLoopMerge
:
1193 case SpvOpSelectionMerge
:
1194 /* This is handled by cfg pre-pass and walk_blocks */
1198 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
1202 vtn_handle_extension(b
, opcode
, w
, count
);
1206 case SpvOpVariableArray
:
1209 case SpvOpCopyMemory
:
1210 case SpvOpCopyMemorySized
:
1211 case SpvOpAccessChain
:
1212 case SpvOpInBoundsAccessChain
:
1213 case SpvOpArrayLength
:
1214 case SpvOpImagePointer
:
1215 vtn_handle_variables(b
, opcode
, w
, count
);
1218 case SpvOpFunctionCall
:
1219 vtn_handle_function_call(b
, opcode
, w
, count
);
1222 case SpvOpTextureSample
:
1223 case SpvOpTextureSampleDref
:
1224 case SpvOpTextureSampleLod
:
1225 case SpvOpTextureSampleProj
:
1226 case SpvOpTextureSampleGrad
:
1227 case SpvOpTextureSampleOffset
:
1228 case SpvOpTextureSampleProjLod
:
1229 case SpvOpTextureSampleProjGrad
:
1230 case SpvOpTextureSampleLodOffset
:
1231 case SpvOpTextureSampleProjOffset
:
1232 case SpvOpTextureSampleGradOffset
:
1233 case SpvOpTextureSampleProjLodOffset
:
1234 case SpvOpTextureSampleProjGradOffset
:
1235 case SpvOpTextureFetchTexelLod
:
1236 case SpvOpTextureFetchTexelOffset
:
1237 case SpvOpTextureFetchSample
:
1238 case SpvOpTextureFetchTexel
:
1239 case SpvOpTextureGather
:
1240 case SpvOpTextureGatherOffset
:
1241 case SpvOpTextureGatherOffsets
:
1242 case SpvOpTextureQuerySizeLod
:
1243 case SpvOpTextureQuerySize
:
1244 case SpvOpTextureQueryLod
:
1245 case SpvOpTextureQueryLevels
:
1246 case SpvOpTextureQuerySamples
:
1247 vtn_handle_texture(b
, opcode
, w
, count
);
1255 case SpvOpConvertFToU
:
1256 case SpvOpConvertFToS
:
1257 case SpvOpConvertSToF
:
1258 case SpvOpConvertUToF
:
1262 case SpvOpConvertPtrToU
:
1263 case SpvOpConvertUToPtr
:
1264 case SpvOpPtrCastToGeneric
:
1265 case SpvOpGenericCastToPtr
:
1271 case SpvOpSignBitSet
:
1272 case SpvOpLessOrGreater
:
1274 case SpvOpUnordered
:
1289 case SpvOpVectorTimesScalar
:
1291 case SpvOpShiftRightLogical
:
1292 case SpvOpShiftRightArithmetic
:
1293 case SpvOpShiftLeftLogical
:
1294 case SpvOpLogicalOr
:
1295 case SpvOpLogicalXor
:
1296 case SpvOpLogicalAnd
:
1297 case SpvOpBitwiseOr
:
1298 case SpvOpBitwiseXor
:
1299 case SpvOpBitwiseAnd
:
1302 case SpvOpFOrdEqual
:
1303 case SpvOpFUnordEqual
:
1304 case SpvOpINotEqual
:
1305 case SpvOpFOrdNotEqual
:
1306 case SpvOpFUnordNotEqual
:
1307 case SpvOpULessThan
:
1308 case SpvOpSLessThan
:
1309 case SpvOpFOrdLessThan
:
1310 case SpvOpFUnordLessThan
:
1311 case SpvOpUGreaterThan
:
1312 case SpvOpSGreaterThan
:
1313 case SpvOpFOrdGreaterThan
:
1314 case SpvOpFUnordGreaterThan
:
1315 case SpvOpULessThanEqual
:
1316 case SpvOpSLessThanEqual
:
1317 case SpvOpFOrdLessThanEqual
:
1318 case SpvOpFUnordLessThanEqual
:
1319 case SpvOpUGreaterThanEqual
:
1320 case SpvOpSGreaterThanEqual
:
1321 case SpvOpFOrdGreaterThanEqual
:
1322 case SpvOpFUnordGreaterThanEqual
:
1328 case SpvOpFwidthFine
:
1329 case SpvOpDPdxCoarse
:
1330 case SpvOpDPdyCoarse
:
1331 case SpvOpFwidthCoarse
:
1332 vtn_handle_alu(b
, opcode
, w
, count
);
1335 case SpvOpTranspose
:
1336 case SpvOpOuterProduct
:
1337 case SpvOpMatrixTimesScalar
:
1338 case SpvOpVectorTimesMatrix
:
1339 case SpvOpMatrixTimesVector
:
1340 case SpvOpMatrixTimesMatrix
:
1341 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
1345 unreachable("Unhandled opcode");
1352 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
1353 struct vtn_block
*break_block
, struct vtn_block
*cont_block
,
1354 struct vtn_block
*end_block
)
1356 struct vtn_block
*block
= start
;
1357 while (block
!= end_block
) {
1358 if (block
->merge_op
== SpvOpLoopMerge
) {
1359 /* This is the jump into a loop. */
1360 struct vtn_block
*new_cont_block
= block
;
1361 struct vtn_block
*new_break_block
=
1362 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
1364 nir_loop
*loop
= nir_loop_create(b
->shader
);
1365 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &loop
->cf_node
);
1367 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1369 /* Reset the merge_op to prerevent infinite recursion */
1370 block
->merge_op
= SpvOpNop
;
1372 nir_builder_insert_after_cf_list(&b
->nb
, &loop
->body
);
1373 vtn_walk_blocks(b
, block
, new_break_block
, new_cont_block
, NULL
);
1375 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1376 block
= break_block
;
1380 const uint32_t *w
= block
->branch
;
1381 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
1384 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
1385 vtn_handle_body_instruction
);
1387 switch (branch_op
) {
1389 struct vtn_block
*branch_block
=
1390 vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
1392 if (branch_block
== break_block
) {
1393 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1395 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1398 } else if (branch_block
== cont_block
) {
1399 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1401 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1404 } else if (branch_block
== end_block
) {
1405 /* We're branching to the merge block of an if, since for loops
1406 * and functions end_block == NULL, so we're done here.
1410 /* We're branching to another block, and according to the rules,
1411 * we can only branch to another block with one predecessor (so
1412 * we're the only one jumping to it) so we can just process it
1415 block
= branch_block
;
1420 case SpvOpBranchConditional
: {
1421 /* Gather up the branch blocks */
1422 struct vtn_block
*then_block
=
1423 vtn_value(b
, w
[2], vtn_value_type_block
)->block
;
1424 struct vtn_block
*else_block
=
1425 vtn_value(b
, w
[3], vtn_value_type_block
)->block
;
1427 nir_if
*if_stmt
= nir_if_create(b
->shader
);
1428 if_stmt
->condition
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1]));
1429 nir_cf_node_insert_end(b
->nb
.cf_node_list
, &if_stmt
->cf_node
);
1431 if (then_block
== break_block
) {
1432 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1434 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
1437 } else if (else_block
== break_block
) {
1438 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1440 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
1443 } else if (then_block
== cont_block
) {
1444 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1446 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
1449 } else if (else_block
== cont_block
) {
1450 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1452 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
1456 /* According to the rules we're branching to two blocks that don't
1457 * have any other predecessors, so we can handle this as a
1460 assert(block
->merge_op
== SpvOpSelectionMerge
);
1461 struct vtn_block
*merge_block
=
1462 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
1464 struct exec_list
*old_list
= b
->nb
.cf_node_list
;
1466 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->then_list
);
1467 vtn_walk_blocks(b
, then_block
, break_block
, cont_block
, merge_block
);
1469 nir_builder_insert_after_cf_list(&b
->nb
, &if_stmt
->else_list
);
1470 vtn_walk_blocks(b
, else_block
, break_block
, cont_block
, merge_block
);
1472 nir_builder_insert_after_cf_list(&b
->nb
, old_list
);
1473 block
= merge_block
;
1477 /* If we got here then we inserted a predicated break or continue
1478 * above and we need to handle the other case. We already set
1479 * `block` above to indicate what block to visit after the
1483 /* It's possible that the other branch is also a break/continue.
1484 * If it is, we handle that here.
1486 if (block
== break_block
) {
1487 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1489 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1492 } else if (block
== cont_block
) {
1493 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1495 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1500 /* If we got here then there was a predicated break/continue but
1501 * the other half of the if has stuff in it. `block` was already
1502 * set above so there is nothing left for us to do.
1508 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
1510 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
1515 nir_intrinsic_instr
*discard
=
1516 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_discard
);
1517 nir_builder_instr_insert(&b
->nb
, &discard
->instr
);
1522 case SpvOpReturnValue
:
1523 case SpvOpUnreachable
:
1525 unreachable("Unhandled opcode");
1531 spirv_to_nir(const uint32_t *words
, size_t word_count
,
1532 const nir_shader_compiler_options
*options
)
1534 const uint32_t *word_end
= words
+ word_count
;
1536 /* Handle the SPIR-V header (first 4 dwords) */
1537 assert(word_count
> 5);
1539 assert(words
[0] == SpvMagicNumber
);
1540 assert(words
[1] == 99);
1541 /* words[2] == generator magic */
1542 unsigned value_id_bound
= words
[3];
1543 assert(words
[4] == 0);
1547 nir_shader
*shader
= nir_shader_create(NULL
, options
);
1549 /* Initialize the stn_builder object */
1550 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
1552 b
->value_id_bound
= value_id_bound
;
1553 b
->values
= ralloc_array(b
, struct vtn_value
, value_id_bound
);
1554 exec_list_make_empty(&b
->functions
);
1556 /* Handle all the preamble instructions */
1557 words
= vtn_foreach_instruction(b
, words
, word_end
,
1558 vtn_handle_preamble_instruction
);
1560 /* Do a very quick CFG analysis pass */
1561 vtn_foreach_instruction(b
, words
, word_end
,
1562 vtn_handle_first_cfg_pass_instruction
);
1564 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
1565 b
->impl
= nir_function_impl_create(func
->overload
);
1566 nir_builder_init(&b
->nb
, b
->impl
);
1567 nir_builder_insert_after_cf_list(&b
->nb
, &b
->impl
->body
);
1568 vtn_walk_blocks(b
, func
->start_block
, NULL
, NULL
, NULL
);