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"
30 #include "nir_control_flow.h"
32 static struct vtn_ssa_value
*
33 vtn_const_ssa_value(struct vtn_builder
*b
, nir_constant
*constant
,
34 const struct glsl_type
*type
)
36 struct hash_entry
*entry
= _mesa_hash_table_search(b
->const_table
, constant
);
41 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
44 switch (glsl_get_base_type(type
)) {
49 case GLSL_TYPE_DOUBLE
:
50 if (glsl_type_is_vector_or_scalar(type
)) {
51 unsigned num_components
= glsl_get_vector_elements(val
->type
);
52 nir_load_const_instr
*load
=
53 nir_load_const_instr_create(b
->shader
, num_components
);
55 for (unsigned i
= 0; i
< num_components
; i
++)
56 load
->value
.u
[i
] = constant
->value
.u
[i
];
58 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
59 val
->def
= &load
->def
;
61 assert(glsl_type_is_matrix(type
));
62 unsigned rows
= glsl_get_vector_elements(val
->type
);
63 unsigned columns
= glsl_get_matrix_columns(val
->type
);
64 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, columns
);
66 for (unsigned i
= 0; i
< columns
; i
++) {
67 struct vtn_ssa_value
*col_val
= rzalloc(b
, struct vtn_ssa_value
);
68 col_val
->type
= glsl_get_column_type(val
->type
);
69 nir_load_const_instr
*load
=
70 nir_load_const_instr_create(b
->shader
, rows
);
72 for (unsigned j
= 0; j
< rows
; j
++)
73 load
->value
.u
[j
] = constant
->value
.u
[rows
* i
+ j
];
75 nir_instr_insert_before_cf_list(&b
->impl
->body
, &load
->instr
);
76 col_val
->def
= &load
->def
;
78 val
->elems
[i
] = col_val
;
83 case GLSL_TYPE_ARRAY
: {
84 unsigned elems
= glsl_get_length(val
->type
);
85 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
86 const struct glsl_type
*elem_type
= glsl_get_array_element(val
->type
);
87 for (unsigned i
= 0; i
< elems
; i
++)
88 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
93 case GLSL_TYPE_STRUCT
: {
94 unsigned elems
= glsl_get_length(val
->type
);
95 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
96 for (unsigned i
= 0; i
< elems
; i
++) {
97 const struct glsl_type
*elem_type
=
98 glsl_get_struct_field(val
->type
, i
);
99 val
->elems
[i
] = vtn_const_ssa_value(b
, constant
->elements
[i
],
106 unreachable("bad constant type");
112 struct vtn_ssa_value
*
113 vtn_ssa_value(struct vtn_builder
*b
, uint32_t value_id
)
115 struct vtn_value
*val
= vtn_untyped_value(b
, value_id
);
116 switch (val
->value_type
) {
117 case vtn_value_type_constant
:
118 return vtn_const_ssa_value(b
, val
->constant
, val
->const_type
);
120 case vtn_value_type_ssa
:
123 unreachable("Invalid type for an SSA value");
128 vtn_string_literal(struct vtn_builder
*b
, const uint32_t *words
,
131 return ralloc_strndup(b
, (char *)words
, word_count
* sizeof(*words
));
134 static const uint32_t *
135 vtn_foreach_instruction(struct vtn_builder
*b
, const uint32_t *start
,
136 const uint32_t *end
, vtn_instruction_handler handler
)
138 const uint32_t *w
= start
;
140 SpvOp opcode
= w
[0] & SpvOpCodeMask
;
141 unsigned count
= w
[0] >> SpvWordCountShift
;
142 assert(count
>= 1 && w
+ count
<= end
);
144 if (!handler(b
, opcode
, w
, count
))
154 vtn_handle_extension(struct vtn_builder
*b
, SpvOp opcode
,
155 const uint32_t *w
, unsigned count
)
158 case SpvOpExtInstImport
: {
159 struct vtn_value
*val
= vtn_push_value(b
, w
[1], vtn_value_type_extension
);
160 if (strcmp((const char *)&w
[2], "GLSL.std.450") == 0) {
161 val
->ext_handler
= vtn_handle_glsl450_instruction
;
163 assert(!"Unsupported extension");
169 struct vtn_value
*val
= vtn_value(b
, w
[3], vtn_value_type_extension
);
170 bool handled
= val
->ext_handler(b
, w
[4], w
, count
);
177 unreachable("Unhandled opcode");
182 _foreach_decoration_helper(struct vtn_builder
*b
,
183 struct vtn_value
*base_value
,
185 struct vtn_value
*value
,
186 vtn_decoration_foreach_cb cb
, void *data
)
188 int new_member
= member
;
190 for (struct vtn_decoration
*dec
= value
->decoration
; dec
; dec
= dec
->next
) {
191 if (dec
->member
>= 0) {
192 assert(member
== -1);
193 new_member
= dec
->member
;
197 assert(dec
->group
->value_type
== vtn_value_type_decoration_group
);
198 _foreach_decoration_helper(b
, base_value
, new_member
, dec
->group
,
201 cb(b
, base_value
, new_member
, dec
, data
);
206 /** Iterates (recursively if needed) over all of the decorations on a value
208 * This function iterates over all of the decorations applied to a given
209 * value. If it encounters a decoration group, it recurses into the group
210 * and iterates over all of those decorations as well.
213 vtn_foreach_decoration(struct vtn_builder
*b
, struct vtn_value
*value
,
214 vtn_decoration_foreach_cb cb
, void *data
)
216 _foreach_decoration_helper(b
, value
, -1, value
, cb
, data
);
220 vtn_handle_decoration(struct vtn_builder
*b
, SpvOp opcode
,
221 const uint32_t *w
, unsigned count
)
223 const uint32_t *w_end
= w
+ count
;
224 const uint32_t target
= w
[1];
229 case SpvOpDecorationGroup
:
230 vtn_push_value(b
, target
, vtn_value_type_undef
);
233 case SpvOpMemberDecorate
:
236 case SpvOpDecorate
: {
237 struct vtn_value
*val
= &b
->values
[target
];
239 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
240 dec
->member
= member
;
241 dec
->decoration
= *(w
++);
244 /* Link into the list */
245 dec
->next
= val
->decoration
;
246 val
->decoration
= dec
;
250 case SpvOpGroupMemberDecorate
:
253 case SpvOpGroupDecorate
: {
254 struct vtn_value
*group
= &b
->values
[target
];
255 assert(group
->value_type
== vtn_value_type_decoration_group
);
257 for (; w
< w_end
; w
++) {
258 struct vtn_value
*val
= &b
->values
[*w
];
259 struct vtn_decoration
*dec
= rzalloc(b
, struct vtn_decoration
);
260 dec
->member
= member
;
263 /* Link into the list */
264 dec
->next
= val
->decoration
;
265 val
->decoration
= dec
;
271 unreachable("Unhandled opcode");
275 struct member_decoration_ctx
{
276 struct glsl_struct_field
*fields
;
277 struct vtn_type
*type
;
280 /* does a shallow copy of a vtn_type */
282 static struct vtn_type
*
283 vtn_type_copy(struct vtn_builder
*b
, struct vtn_type
*src
)
285 struct vtn_type
*dest
= ralloc(b
, struct vtn_type
);
286 dest
->type
= src
->type
;
287 dest
->is_builtin
= src
->is_builtin
;
289 dest
->builtin
= src
->builtin
;
291 if (!glsl_type_is_vector_or_scalar(src
->type
)) {
292 switch (glsl_get_base_type(src
->type
)) {
293 case GLSL_TYPE_ARRAY
:
294 dest
->array_element
= src
->array_element
;
295 dest
->stride
= src
->stride
;
301 case GLSL_TYPE_FLOAT
:
302 case GLSL_TYPE_DOUBLE
:
304 dest
->row_major
= src
->row_major
;
305 dest
->stride
= src
->stride
;
308 case GLSL_TYPE_STRUCT
: {
309 unsigned elems
= glsl_get_length(src
->type
);
311 dest
->members
= ralloc_array(b
, struct vtn_type
*, elems
);
312 memcpy(dest
->members
, src
->members
, elems
* sizeof(struct vtn_type
*));
314 dest
->offsets
= ralloc_array(b
, unsigned, elems
);
315 memcpy(dest
->offsets
, src
->offsets
, elems
* sizeof(unsigned));
320 unreachable("unhandled type");
328 struct_member_decoration_cb(struct vtn_builder
*b
,
329 struct vtn_value
*val
, int member
,
330 const struct vtn_decoration
*dec
, void *void_ctx
)
332 struct member_decoration_ctx
*ctx
= void_ctx
;
337 switch (dec
->decoration
) {
338 case SpvDecorationRelaxedPrecision
:
339 break; /* FIXME: Do nothing with this for now. */
340 case SpvDecorationSmooth
:
341 ctx
->fields
[member
].interpolation
= INTERP_QUALIFIER_SMOOTH
;
343 case SpvDecorationNoPerspective
:
344 ctx
->fields
[member
].interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
346 case SpvDecorationFlat
:
347 ctx
->fields
[member
].interpolation
= INTERP_QUALIFIER_FLAT
;
349 case SpvDecorationCentroid
:
350 ctx
->fields
[member
].centroid
= true;
352 case SpvDecorationSample
:
353 ctx
->fields
[member
].sample
= true;
355 case SpvDecorationLocation
:
356 ctx
->fields
[member
].location
= dec
->literals
[0];
358 case SpvDecorationBuiltIn
:
359 ctx
->type
->members
[member
] = vtn_type_copy(b
,
360 ctx
->type
->members
[member
]);
361 ctx
->type
->members
[member
]->is_builtin
= true;
362 ctx
->type
->members
[member
]->builtin
= dec
->literals
[0];
363 ctx
->type
->builtin_block
= true;
365 case SpvDecorationOffset
:
366 ctx
->type
->offsets
[member
] = dec
->literals
[0];
368 case SpvDecorationMatrixStride
:
369 ctx
->type
->members
[member
]->stride
= dec
->literals
[0];
371 case SpvDecorationColMajor
:
372 break; /* Nothing to do here. Column-major is the default. */
374 unreachable("Unhandled member decoration");
379 type_decoration_cb(struct vtn_builder
*b
,
380 struct vtn_value
*val
, int member
,
381 const struct vtn_decoration
*dec
, void *ctx
)
383 struct vtn_type
*type
= val
->type
;
388 switch (dec
->decoration
) {
389 case SpvDecorationArrayStride
:
390 type
->stride
= dec
->literals
[0];
392 case SpvDecorationBlock
:
395 case SpvDecorationBufferBlock
:
396 type
->buffer_block
= true;
398 case SpvDecorationGLSLShared
:
399 case SpvDecorationGLSLPacked
:
400 /* Ignore these, since we get explicit offsets anyways */
403 case SpvDecorationStream
:
404 assert(dec
->literals
[0] == 0);
408 unreachable("Unhandled type decoration");
413 translate_image_format(SpvImageFormat format
)
416 case SpvImageFormatUnknown
: return 0; /* GL_NONE */
417 case SpvImageFormatRgba32f
: return 0x8814; /* GL_RGBA32F */
418 case SpvImageFormatRgba16f
: return 0x881A; /* GL_RGBA16F */
419 case SpvImageFormatR32f
: return 0x822E; /* GL_R32F */
420 case SpvImageFormatRgba8
: return 0x8058; /* GL_RGBA8 */
421 case SpvImageFormatRgba8Snorm
: return 0x8F97; /* GL_RGBA8_SNORM */
422 case SpvImageFormatRg32f
: return 0x8230; /* GL_RG32F */
423 case SpvImageFormatRg16f
: return 0x822F; /* GL_RG16F */
424 case SpvImageFormatR11fG11fB10f
: return 0x8C3A; /* GL_R11F_G11F_B10F */
425 case SpvImageFormatR16f
: return 0x822D; /* GL_R16F */
426 case SpvImageFormatRgba16
: return 0x805B; /* GL_RGBA16 */
427 case SpvImageFormatRgb10A2
: return 0x8059; /* GL_RGB10_A2 */
428 case SpvImageFormatRg16
: return 0x822C; /* GL_RG16 */
429 case SpvImageFormatRg8
: return 0x822B; /* GL_RG8 */
430 case SpvImageFormatR16
: return 0x822A; /* GL_R16 */
431 case SpvImageFormatR8
: return 0x8229; /* GL_R8 */
432 case SpvImageFormatRgba16Snorm
: return 0x8F9B; /* GL_RGBA16_SNORM */
433 case SpvImageFormatRg16Snorm
: return 0x8F99; /* GL_RG16_SNORM */
434 case SpvImageFormatRg8Snorm
: return 0x8F95; /* GL_RG8_SNORM */
435 case SpvImageFormatR16Snorm
: return 0x8F98; /* GL_R16_SNORM */
436 case SpvImageFormatR8Snorm
: return 0x8F94; /* GL_R8_SNORM */
437 case SpvImageFormatRgba32i
: return 0x8D82; /* GL_RGBA32I */
438 case SpvImageFormatRgba16i
: return 0x8D88; /* GL_RGBA16I */
439 case SpvImageFormatRgba8i
: return 0x8D8E; /* GL_RGBA8I */
440 case SpvImageFormatR32i
: return 0x8235; /* GL_R32I */
441 case SpvImageFormatRg32i
: return 0x823B; /* GL_RG32I */
442 case SpvImageFormatRg16i
: return 0x8239; /* GL_RG16I */
443 case SpvImageFormatRg8i
: return 0x8237; /* GL_RG8I */
444 case SpvImageFormatR16i
: return 0x8233; /* GL_R16I */
445 case SpvImageFormatR8i
: return 0x8231; /* GL_R8I */
446 case SpvImageFormatRgba32ui
: return 0x8D70; /* GL_RGBA32UI */
447 case SpvImageFormatRgba16ui
: return 0x8D76; /* GL_RGBA16UI */
448 case SpvImageFormatRgba8ui
: return 0x8D7C; /* GL_RGBA8UI */
449 case SpvImageFormatR32ui
: return 0x8236; /* GL_R32UI */
450 case SpvImageFormatRgb10a2ui
: return 0x906F; /* GL_RGB10_A2UI */
451 case SpvImageFormatRg32ui
: return 0x823C; /* GL_RG32UI */
452 case SpvImageFormatRg16ui
: return 0x823A; /* GL_RG16UI */
453 case SpvImageFormatRg8ui
: return 0x8238; /* GL_RG8UI */
454 case SpvImageFormatR16ui
: return 0x823A; /* GL_RG16UI */
455 case SpvImageFormatR8ui
: return 0x8232; /* GL_R8UI */
457 assert(!"Invalid image format");
463 vtn_handle_type(struct vtn_builder
*b
, SpvOp opcode
,
464 const uint32_t *w
, unsigned count
)
466 struct vtn_value
*val
= vtn_push_value(b
, w
[1], vtn_value_type_type
);
468 val
->type
= rzalloc(b
, struct vtn_type
);
469 val
->type
->is_builtin
= false;
473 val
->type
->type
= glsl_void_type();
476 val
->type
->type
= glsl_bool_type();
479 val
->type
->type
= glsl_int_type();
482 val
->type
->type
= glsl_float_type();
485 case SpvOpTypeVector
: {
486 const struct glsl_type
*base
=
487 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
488 unsigned elems
= w
[3];
490 assert(glsl_type_is_scalar(base
));
491 val
->type
->type
= glsl_vector_type(glsl_get_base_type(base
), elems
);
495 case SpvOpTypeMatrix
: {
496 struct vtn_type
*base
=
497 vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
498 unsigned columns
= w
[3];
500 assert(glsl_type_is_vector(base
->type
));
501 val
->type
->type
= glsl_matrix_type(glsl_get_base_type(base
->type
),
502 glsl_get_vector_elements(base
->type
),
504 val
->type
->array_element
= base
;
505 val
->type
->row_major
= false;
506 val
->type
->stride
= 0;
510 case SpvOpTypeArray
: {
511 struct vtn_type
*array_element
=
512 vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
513 val
->type
->type
= glsl_array_type(array_element
->type
, w
[3]);
514 val
->type
->array_element
= array_element
;
515 val
->type
->stride
= 0;
519 case SpvOpTypeStruct
: {
520 unsigned num_fields
= count
- 2;
521 val
->type
->members
= ralloc_array(b
, struct vtn_type
*, num_fields
);
522 val
->type
->offsets
= ralloc_array(b
, unsigned, num_fields
);
524 NIR_VLA(struct glsl_struct_field
, fields
, count
);
525 for (unsigned i
= 0; i
< num_fields
; i
++) {
526 /* TODO: Handle decorators */
527 val
->type
->members
[i
] =
528 vtn_value(b
, w
[i
+ 2], vtn_value_type_type
)->type
;
529 fields
[i
].type
= val
->type
->members
[i
]->type
;
530 fields
[i
].name
= ralloc_asprintf(b
, "field%d", i
);
531 fields
[i
].location
= -1;
532 fields
[i
].interpolation
= 0;
533 fields
[i
].centroid
= 0;
534 fields
[i
].sample
= 0;
535 fields
[i
].matrix_layout
= 2;
538 struct member_decoration_ctx ctx
= {
543 vtn_foreach_decoration(b
, val
, struct_member_decoration_cb
, &ctx
);
545 const char *name
= val
->name
? val
->name
: "struct";
547 val
->type
->type
= glsl_struct_type(fields
, num_fields
, name
);
551 case SpvOpTypeFunction
: {
552 const struct glsl_type
*return_type
=
553 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
554 NIR_VLA(struct glsl_function_param
, params
, count
- 3);
555 for (unsigned i
= 0; i
< count
- 3; i
++) {
556 params
[i
].type
= vtn_value(b
, w
[i
+ 3], vtn_value_type_type
)->type
->type
;
560 params
[i
].out
= true;
562 val
->type
->type
= glsl_function_type(return_type
, params
, count
- 3);
566 case SpvOpTypePointer
:
567 /* FIXME: For now, we'll just do the really lame thing and return
568 * the same type. The validator should ensure that the proper number
569 * of dereferences happen
571 val
->type
= vtn_value(b
, w
[3], vtn_value_type_type
)->type
;
574 case SpvOpTypeImage
: {
575 const struct glsl_type
*sampled_type
=
576 vtn_value(b
, w
[2], vtn_value_type_type
)->type
->type
;
578 assert(glsl_type_is_vector_or_scalar(sampled_type
));
580 enum glsl_sampler_dim dim
;
581 switch ((SpvDim
)w
[3]) {
582 case SpvDim1D
: dim
= GLSL_SAMPLER_DIM_1D
; break;
583 case SpvDim2D
: dim
= GLSL_SAMPLER_DIM_2D
; break;
584 case SpvDim3D
: dim
= GLSL_SAMPLER_DIM_3D
; break;
585 case SpvDimCube
: dim
= GLSL_SAMPLER_DIM_CUBE
; break;
586 case SpvDimRect
: dim
= GLSL_SAMPLER_DIM_RECT
; break;
587 case SpvDimBuffer
: dim
= GLSL_SAMPLER_DIM_BUF
; break;
589 unreachable("Invalid SPIR-V Sampler dimension");
592 bool is_shadow
= w
[4];
593 bool is_array
= w
[5];
594 bool multisampled
= w
[6];
595 unsigned sampled
= w
[7];
596 SpvImageFormat format
= w
[8];
598 assert(!multisampled
&& "FIXME: Handl multi-sampled textures");
600 val
->type
->image_format
= translate_image_format(format
);
603 val
->type
->type
= glsl_sampler_type(dim
, is_shadow
, is_array
,
604 glsl_get_base_type(sampled_type
));
605 } else if (sampled
== 2) {
608 val
->type
->type
= glsl_image_type(dim
, is_array
,
609 glsl_get_base_type(sampled_type
));
611 assert(!"We need to know if the image will be sampled");
616 case SpvOpTypeSampledImage
:
617 val
->type
= vtn_value(b
, w
[2], vtn_value_type_type
)->type
;
620 case SpvOpTypeRuntimeArray
:
621 case SpvOpTypeOpaque
:
623 case SpvOpTypeDeviceEvent
:
624 case SpvOpTypeReserveId
:
628 unreachable("Unhandled opcode");
631 vtn_foreach_decoration(b
, val
, type_decoration_cb
, NULL
);
635 vtn_handle_constant(struct vtn_builder
*b
, SpvOp opcode
,
636 const uint32_t *w
, unsigned count
)
638 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_constant
);
639 val
->const_type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
640 val
->constant
= ralloc(b
, nir_constant
);
642 case SpvOpConstantTrue
:
643 assert(val
->const_type
== glsl_bool_type());
644 val
->constant
->value
.u
[0] = NIR_TRUE
;
646 case SpvOpConstantFalse
:
647 assert(val
->const_type
== glsl_bool_type());
648 val
->constant
->value
.u
[0] = NIR_FALSE
;
651 assert(glsl_type_is_scalar(val
->const_type
));
652 val
->constant
->value
.u
[0] = w
[3];
654 case SpvOpConstantComposite
: {
655 unsigned elem_count
= count
- 3;
656 nir_constant
**elems
= ralloc_array(b
, nir_constant
*, elem_count
);
657 for (unsigned i
= 0; i
< elem_count
; i
++)
658 elems
[i
] = vtn_value(b
, w
[i
+ 3], vtn_value_type_constant
)->constant
;
660 switch (glsl_get_base_type(val
->const_type
)) {
663 case GLSL_TYPE_FLOAT
:
665 if (glsl_type_is_matrix(val
->const_type
)) {
666 unsigned rows
= glsl_get_vector_elements(val
->const_type
);
667 assert(glsl_get_matrix_columns(val
->const_type
) == elem_count
);
668 for (unsigned i
= 0; i
< elem_count
; i
++)
669 for (unsigned j
= 0; j
< rows
; j
++)
670 val
->constant
->value
.u
[rows
* i
+ j
] = elems
[i
]->value
.u
[j
];
672 assert(glsl_type_is_vector(val
->const_type
));
673 assert(glsl_get_vector_elements(val
->const_type
) == elem_count
);
674 for (unsigned i
= 0; i
< elem_count
; i
++)
675 val
->constant
->value
.u
[i
] = elems
[i
]->value
.u
[0];
680 case GLSL_TYPE_STRUCT
:
681 case GLSL_TYPE_ARRAY
:
682 ralloc_steal(val
->constant
, elems
);
683 val
->constant
->elements
= elems
;
687 unreachable("Unsupported type for constants");
693 unreachable("Unhandled opcode");
698 set_mode_system_value(nir_variable_mode
*mode
)
700 assert(*mode
== nir_var_system_value
|| *mode
== nir_var_shader_in
);
701 *mode
= nir_var_system_value
;
705 validate_per_vertex_mode(struct vtn_builder
*b
, nir_variable_mode mode
)
707 switch (b
->shader
->stage
) {
708 case MESA_SHADER_VERTEX
:
709 assert(mode
== nir_var_shader_out
);
711 case MESA_SHADER_GEOMETRY
:
712 assert(mode
== nir_var_shader_out
|| mode
== nir_var_shader_in
);
715 assert(!"Invalid shader stage");
720 vtn_get_builtin_location(struct vtn_builder
*b
,
721 SpvBuiltIn builtin
, int *location
,
722 nir_variable_mode
*mode
)
725 case SpvBuiltInPosition
:
726 *location
= VARYING_SLOT_POS
;
727 validate_per_vertex_mode(b
, *mode
);
729 case SpvBuiltInPointSize
:
730 *location
= VARYING_SLOT_PSIZ
;
731 validate_per_vertex_mode(b
, *mode
);
733 case SpvBuiltInClipDistance
:
734 *location
= VARYING_SLOT_CLIP_DIST0
; /* XXX CLIP_DIST1? */
735 validate_per_vertex_mode(b
, *mode
);
737 case SpvBuiltInCullDistance
:
738 /* XXX figure this out */
739 unreachable("unhandled builtin");
740 case SpvBuiltInVertexId
:
741 /* Vulkan defines VertexID to be zero-based and reserves the new
742 * builtin keyword VertexIndex to indicate the non-zero-based value.
744 *location
= SYSTEM_VALUE_VERTEX_ID_ZERO_BASE
;
745 set_mode_system_value(mode
);
747 case SpvBuiltInInstanceId
:
748 *location
= SYSTEM_VALUE_INSTANCE_ID
;
749 set_mode_system_value(mode
);
751 case SpvBuiltInPrimitiveId
:
752 *location
= VARYING_SLOT_PRIMITIVE_ID
;
753 *mode
= nir_var_shader_out
;
755 case SpvBuiltInInvocationId
:
756 *location
= SYSTEM_VALUE_INVOCATION_ID
;
757 set_mode_system_value(mode
);
759 case SpvBuiltInLayer
:
760 *location
= VARYING_SLOT_LAYER
;
761 *mode
= nir_var_shader_out
;
763 case SpvBuiltInTessLevelOuter
:
764 case SpvBuiltInTessLevelInner
:
765 case SpvBuiltInTessCoord
:
766 case SpvBuiltInPatchVertices
:
767 unreachable("no tessellation support");
768 case SpvBuiltInFragCoord
:
769 *location
= VARYING_SLOT_POS
;
770 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
771 assert(*mode
== nir_var_shader_in
);
773 case SpvBuiltInPointCoord
:
774 *location
= VARYING_SLOT_PNTC
;
775 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
776 assert(*mode
== nir_var_shader_in
);
778 case SpvBuiltInFrontFacing
:
779 *location
= VARYING_SLOT_FACE
;
780 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
781 assert(*mode
== nir_var_shader_in
);
783 case SpvBuiltInSampleId
:
784 *location
= SYSTEM_VALUE_SAMPLE_ID
;
785 set_mode_system_value(mode
);
787 case SpvBuiltInSamplePosition
:
788 *location
= SYSTEM_VALUE_SAMPLE_POS
;
789 set_mode_system_value(mode
);
791 case SpvBuiltInSampleMask
:
792 *location
= SYSTEM_VALUE_SAMPLE_MASK_IN
; /* XXX out? */
793 set_mode_system_value(mode
);
795 case SpvBuiltInFragColor
:
796 *location
= FRAG_RESULT_COLOR
;
797 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
798 assert(*mode
== nir_var_shader_out
);
800 case SpvBuiltInFragDepth
:
801 *location
= FRAG_RESULT_DEPTH
;
802 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
803 assert(*mode
== nir_var_shader_out
);
805 case SpvBuiltInNumWorkgroups
:
806 case SpvBuiltInWorkgroupSize
:
807 /* these are constants, need to be handled specially */
808 unreachable("unsupported builtin");
810 case SpvBuiltInGlobalInvocationId
:
811 case SpvBuiltInLocalInvocationIndex
:
812 /* these are computed values, need to be handled specially */
813 unreachable("unsupported builtin");
814 case SpvBuiltInWorkgroupId
:
815 *location
= SYSTEM_VALUE_WORK_GROUP_ID
;
816 set_mode_system_value(mode
);
818 case SpvBuiltInLocalInvocationId
:
819 *location
= SYSTEM_VALUE_LOCAL_INVOCATION_ID
;
820 set_mode_system_value(mode
);
822 case SpvBuiltInHelperInvocation
:
824 unreachable("unsupported builtin");
829 var_decoration_cb(struct vtn_builder
*b
, struct vtn_value
*val
, int member
,
830 const struct vtn_decoration
*dec
, void *void_var
)
832 assert(val
->value_type
== vtn_value_type_deref
);
833 assert(val
->deref
->deref
.child
== NULL
);
834 assert(val
->deref
->var
== void_var
);
836 nir_variable
*var
= void_var
;
837 switch (dec
->decoration
) {
838 case SpvDecorationRelaxedPrecision
:
839 break; /* FIXME: Do nothing with this for now. */
840 case SpvDecorationSmooth
:
841 var
->data
.interpolation
= INTERP_QUALIFIER_SMOOTH
;
843 case SpvDecorationNoPerspective
:
844 var
->data
.interpolation
= INTERP_QUALIFIER_NOPERSPECTIVE
;
846 case SpvDecorationFlat
:
847 var
->data
.interpolation
= INTERP_QUALIFIER_FLAT
;
849 case SpvDecorationCentroid
:
850 var
->data
.centroid
= true;
852 case SpvDecorationSample
:
853 var
->data
.sample
= true;
855 case SpvDecorationInvariant
:
856 var
->data
.invariant
= true;
858 case SpvDecorationConstant
:
859 assert(var
->constant_initializer
!= NULL
);
860 var
->data
.read_only
= true;
862 case SpvDecorationNonWritable
:
863 var
->data
.read_only
= true;
865 case SpvDecorationLocation
:
866 var
->data
.location
= dec
->literals
[0];
868 case SpvDecorationComponent
:
869 var
->data
.location_frac
= dec
->literals
[0];
871 case SpvDecorationIndex
:
872 var
->data
.explicit_index
= true;
873 var
->data
.index
= dec
->literals
[0];
875 case SpvDecorationBinding
:
876 var
->data
.explicit_binding
= true;
877 var
->data
.binding
= dec
->literals
[0];
879 case SpvDecorationDescriptorSet
:
880 var
->data
.descriptor_set
= dec
->literals
[0];
882 case SpvDecorationBuiltIn
: {
883 SpvBuiltIn builtin
= dec
->literals
[0];
885 nir_variable_mode mode
= var
->data
.mode
;
886 vtn_get_builtin_location(b
, builtin
, &var
->data
.location
, &mode
);
887 var
->data
.explicit_location
= true;
888 var
->data
.mode
= mode
;
889 if (mode
== nir_var_shader_in
|| mode
== nir_var_system_value
)
890 var
->data
.read_only
= true;
892 if (builtin
== SpvBuiltInFragCoord
|| builtin
== SpvBuiltInSamplePosition
)
893 var
->data
.origin_upper_left
= b
->origin_upper_left
;
895 if (mode
== nir_var_shader_out
)
896 b
->builtins
[dec
->literals
[0]].out
= var
;
898 b
->builtins
[dec
->literals
[0]].in
= var
;
901 case SpvDecorationRowMajor
:
902 case SpvDecorationColMajor
:
903 case SpvDecorationGLSLShared
:
904 case SpvDecorationPatch
:
905 case SpvDecorationRestrict
:
906 case SpvDecorationAliased
:
907 case SpvDecorationVolatile
:
908 case SpvDecorationCoherent
:
909 case SpvDecorationNonReadable
:
910 case SpvDecorationUniform
:
911 /* This is really nice but we have no use for it right now. */
912 case SpvDecorationCPacked
:
913 case SpvDecorationSaturatedConversion
:
914 case SpvDecorationStream
:
915 case SpvDecorationOffset
:
916 case SpvDecorationXfbBuffer
:
917 case SpvDecorationFuncParamAttr
:
918 case SpvDecorationFPRoundingMode
:
919 case SpvDecorationFPFastMathMode
:
920 case SpvDecorationLinkageAttributes
:
921 case SpvDecorationSpecId
:
924 unreachable("Unhandled variable decoration");
928 static nir_variable
*
929 get_builtin_variable(struct vtn_builder
*b
,
930 nir_variable_mode mode
,
931 const struct glsl_type
*type
,
935 if (mode
== nir_var_shader_out
)
936 var
= b
->builtins
[builtin
].out
;
938 var
= b
->builtins
[builtin
].in
;
942 vtn_get_builtin_location(b
, builtin
, &location
, &mode
);
944 var
= nir_variable_create(b
->shader
, mode
, type
, "builtin");
946 var
->data
.location
= location
;
947 var
->data
.explicit_location
= true;
949 if (builtin
== SpvBuiltInFragCoord
|| builtin
== SpvBuiltInSamplePosition
)
950 var
->data
.origin_upper_left
= b
->origin_upper_left
;
952 if (mode
== nir_var_shader_out
)
953 b
->builtins
[builtin
].out
= var
;
955 b
->builtins
[builtin
].in
= var
;
961 static struct vtn_ssa_value
*
962 _vtn_variable_load(struct vtn_builder
*b
,
963 nir_deref_var
*src_deref
, nir_deref
*src_deref_tail
)
965 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
966 val
->type
= src_deref_tail
->type
;
968 /* The deref tail may contain a deref to select a component of a vector (in
969 * other words, it might not be an actual tail) so we have to save it away
970 * here since we overwrite it later.
972 nir_deref
*old_child
= src_deref_tail
->child
;
974 if (glsl_type_is_vector_or_scalar(val
->type
)) {
975 /* Terminate the deref chain in case there is one more link to pick
976 * off a component of the vector.
978 src_deref_tail
->child
= NULL
;
980 nir_intrinsic_instr
*load
=
981 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_load_var
);
983 nir_deref_as_var(nir_copy_deref(load
, &src_deref
->deref
));
984 load
->num_components
= glsl_get_vector_elements(val
->type
);
985 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
, NULL
);
987 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
989 if (src_deref
->var
->data
.mode
== nir_var_uniform
&&
990 glsl_get_base_type(val
->type
) == GLSL_TYPE_BOOL
) {
991 /* Uniform boolean loads need to be fixed up since they're defined
992 * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
994 val
->def
= nir_ine(&b
->nb
, &load
->dest
.ssa
, nir_imm_int(&b
->nb
, 0));
996 val
->def
= &load
->dest
.ssa
;
998 } else if (glsl_get_base_type(val
->type
) == GLSL_TYPE_ARRAY
||
999 glsl_type_is_matrix(val
->type
)) {
1000 unsigned elems
= glsl_get_length(val
->type
);
1001 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1003 nir_deref_array
*deref
= nir_deref_array_create(b
);
1004 deref
->deref_array_type
= nir_deref_array_type_direct
;
1005 deref
->deref
.type
= glsl_get_array_element(val
->type
);
1006 src_deref_tail
->child
= &deref
->deref
;
1007 for (unsigned i
= 0; i
< elems
; i
++) {
1008 deref
->base_offset
= i
;
1009 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
1012 assert(glsl_get_base_type(val
->type
) == GLSL_TYPE_STRUCT
);
1013 unsigned elems
= glsl_get_length(val
->type
);
1014 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1016 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
1017 src_deref_tail
->child
= &deref
->deref
;
1018 for (unsigned i
= 0; i
< elems
; i
++) {
1020 deref
->deref
.type
= glsl_get_struct_field(val
->type
, i
);
1021 val
->elems
[i
] = _vtn_variable_load(b
, src_deref
, &deref
->deref
);
1025 src_deref_tail
->child
= old_child
;
1031 _vtn_variable_store(struct vtn_builder
*b
,
1032 nir_deref_var
*dest_deref
, nir_deref
*dest_deref_tail
,
1033 struct vtn_ssa_value
*src
)
1035 nir_deref
*old_child
= dest_deref_tail
->child
;
1037 if (glsl_type_is_vector_or_scalar(src
->type
)) {
1038 /* Terminate the deref chain in case there is one more link to pick
1039 * off a component of the vector.
1041 dest_deref_tail
->child
= NULL
;
1043 nir_intrinsic_instr
*store
=
1044 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_store_var
);
1045 store
->variables
[0] =
1046 nir_deref_as_var(nir_copy_deref(store
, &dest_deref
->deref
));
1047 store
->num_components
= glsl_get_vector_elements(src
->type
);
1048 store
->src
[0] = nir_src_for_ssa(src
->def
);
1050 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
1051 } else if (glsl_get_base_type(src
->type
) == GLSL_TYPE_ARRAY
||
1052 glsl_type_is_matrix(src
->type
)) {
1053 unsigned elems
= glsl_get_length(src
->type
);
1055 nir_deref_array
*deref
= nir_deref_array_create(b
);
1056 deref
->deref_array_type
= nir_deref_array_type_direct
;
1057 deref
->deref
.type
= glsl_get_array_element(src
->type
);
1058 dest_deref_tail
->child
= &deref
->deref
;
1059 for (unsigned i
= 0; i
< elems
; i
++) {
1060 deref
->base_offset
= i
;
1061 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
1064 assert(glsl_get_base_type(src
->type
) == GLSL_TYPE_STRUCT
);
1065 unsigned elems
= glsl_get_length(src
->type
);
1067 nir_deref_struct
*deref
= nir_deref_struct_create(b
, 0);
1068 dest_deref_tail
->child
= &deref
->deref
;
1069 for (unsigned i
= 0; i
< elems
; i
++) {
1071 deref
->deref
.type
= glsl_get_struct_field(src
->type
, i
);
1072 _vtn_variable_store(b
, dest_deref
, &deref
->deref
, src
->elems
[i
]);
1076 dest_deref_tail
->child
= old_child
;
1079 static nir_ssa_def
*
1080 nir_vulkan_resource_index(nir_builder
*b
, unsigned set
, unsigned binding
,
1081 nir_variable_mode mode
, nir_ssa_def
*array_index
)
1083 if (array_index
== NULL
)
1084 array_index
= nir_imm_int(b
, 0);
1086 nir_intrinsic_instr
*instr
=
1087 nir_intrinsic_instr_create(b
->shader
,
1088 nir_intrinsic_vulkan_resource_index
);
1089 instr
->src
[0] = nir_src_for_ssa(array_index
);
1090 instr
->const_index
[0] = set
;
1091 instr
->const_index
[1] = binding
;
1092 instr
->const_index
[2] = mode
;
1094 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 1, NULL
);
1095 nir_builder_instr_insert(b
, &instr
->instr
);
1097 return &instr
->dest
.ssa
;
1100 static struct vtn_ssa_value
*
1101 _vtn_block_load(struct vtn_builder
*b
, nir_intrinsic_op op
,
1102 unsigned set
, unsigned binding
, nir_variable_mode mode
,
1103 nir_ssa_def
*index
, unsigned offset
, nir_ssa_def
*indirect
,
1104 struct vtn_type
*type
)
1106 struct vtn_ssa_value
*val
= ralloc(b
, struct vtn_ssa_value
);
1107 val
->type
= type
->type
;
1108 val
->transposed
= NULL
;
1109 if (glsl_type_is_vector_or_scalar(type
->type
)) {
1110 nir_intrinsic_instr
*load
= nir_intrinsic_instr_create(b
->shader
, op
);
1111 load
->num_components
= glsl_get_vector_elements(type
->type
);
1112 load
->const_index
[0] = offset
;
1115 case nir_intrinsic_load_ubo_indirect
:
1116 case nir_intrinsic_load_ssbo_indirect
:
1117 load
->src
[1] = nir_src_for_ssa(indirect
);
1119 case nir_intrinsic_load_ubo
:
1120 case nir_intrinsic_load_ssbo
: {
1121 nir_ssa_def
*res_index
= nir_vulkan_resource_index(&b
->nb
,
1124 load
->src
[0] = nir_src_for_ssa(res_index
);
1128 case nir_intrinsic_load_push_constant
:
1129 break; /* Nothing to do */
1130 case nir_intrinsic_load_push_constant_indirect
:
1131 load
->src
[0] = nir_src_for_ssa(indirect
);
1135 unreachable("Invalid block load intrinsic");
1138 nir_ssa_dest_init(&load
->instr
, &load
->dest
, load
->num_components
, NULL
);
1139 nir_builder_instr_insert(&b
->nb
, &load
->instr
);
1140 val
->def
= &load
->dest
.ssa
;
1142 unsigned elems
= glsl_get_length(type
->type
);
1143 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1144 if (glsl_type_is_struct(type
->type
)) {
1145 for (unsigned i
= 0; i
< elems
; i
++) {
1146 val
->elems
[i
] = _vtn_block_load(b
, op
, set
, binding
, mode
, index
,
1147 offset
+ type
->offsets
[i
],
1148 indirect
, type
->members
[i
]);
1151 for (unsigned i
= 0; i
< elems
; i
++) {
1152 val
->elems
[i
] = _vtn_block_load(b
, op
, set
, binding
, mode
, index
,
1153 offset
+ i
* type
->stride
,
1154 indirect
, type
->array_element
);
1163 vtn_block_get_offset(struct vtn_builder
*b
, nir_deref_var
*src
,
1164 struct vtn_type
**type
, nir_deref
*src_tail
,
1165 nir_ssa_def
**index
,
1166 unsigned *offset
, nir_ssa_def
**indirect
)
1168 nir_deref
*deref
= &src
->deref
;
1170 if (deref
->child
->deref_type
== nir_deref_type_array
) {
1171 deref
= deref
->child
;
1172 *type
= (*type
)->array_element
;
1173 nir_deref_array
*deref_array
= nir_deref_as_array(deref
);
1174 *index
= nir_imm_int(&b
->nb
, deref_array
->base_offset
);
1176 if (deref_array
->deref_array_type
== nir_deref_array_type_indirect
)
1177 *index
= nir_iadd(&b
->nb
, *index
, deref_array
->indirect
.ssa
);
1179 *index
= nir_imm_int(&b
->nb
, 0);
1184 while (deref
!= src_tail
) {
1185 deref
= deref
->child
;
1186 switch (deref
->deref_type
) {
1187 case nir_deref_type_array
: {
1188 nir_deref_array
*deref_array
= nir_deref_as_array(deref
);
1189 if (deref_array
->deref_array_type
== nir_deref_array_type_direct
) {
1190 *offset
+= (*type
)->stride
* deref_array
->base_offset
;
1192 nir_ssa_def
*off
= nir_imul(&b
->nb
, deref_array
->indirect
.ssa
,
1193 nir_imm_int(&b
->nb
, (*type
)->stride
));
1194 *indirect
= *indirect
? nir_iadd(&b
->nb
, *indirect
, off
) : off
;
1196 *type
= (*type
)->array_element
;
1200 case nir_deref_type_struct
: {
1201 nir_deref_struct
*deref_struct
= nir_deref_as_struct(deref
);
1202 *offset
+= (*type
)->offsets
[deref_struct
->index
];
1203 *type
= (*type
)->members
[deref_struct
->index
];
1208 unreachable("unknown deref type");
1213 static struct vtn_ssa_value
*
1214 vtn_block_load(struct vtn_builder
*b
, nir_deref_var
*src
,
1215 struct vtn_type
*type
, nir_deref
*src_tail
)
1219 nir_ssa_def
*indirect
;
1220 vtn_block_get_offset(b
, src
, &type
, src_tail
, &index
, &offset
, &indirect
);
1222 nir_intrinsic_op op
;
1223 if (src
->var
->data
.mode
== nir_var_uniform
) {
1224 if (src
->var
->data
.descriptor_set
>= 0) {
1226 assert(src
->var
->data
.binding
>= 0);
1228 op
= indirect
? nir_intrinsic_load_ubo_indirect
1229 : nir_intrinsic_load_ubo
;
1231 /* Push constant load */
1232 assert(src
->var
->data
.descriptor_set
== -1 &&
1233 src
->var
->data
.binding
== -1);
1235 op
= indirect
? nir_intrinsic_load_push_constant_indirect
1236 : nir_intrinsic_load_push_constant
;
1239 assert(src
->var
->data
.mode
== nir_var_shader_storage
);
1240 op
= indirect
? nir_intrinsic_load_ssbo_indirect
1241 : nir_intrinsic_load_ssbo
;
1244 return _vtn_block_load(b
, op
, src
->var
->data
.descriptor_set
,
1245 src
->var
->data
.binding
, src
->var
->data
.mode
,
1246 index
, offset
, indirect
, type
);
1250 * Gets the NIR-level deref tail, which may have as a child an array deref
1251 * selecting which component due to OpAccessChain supporting per-component
1252 * indexing in SPIR-V.
1256 get_deref_tail(nir_deref_var
*deref
)
1258 nir_deref
*cur
= &deref
->deref
;
1259 while (!glsl_type_is_vector_or_scalar(cur
->type
) && cur
->child
)
1265 static nir_ssa_def
*vtn_vector_extract(struct vtn_builder
*b
,
1266 nir_ssa_def
*src
, unsigned index
);
1268 static nir_ssa_def
*vtn_vector_extract_dynamic(struct vtn_builder
*b
,
1270 nir_ssa_def
*index
);
1273 variable_is_external_block(nir_variable
*var
)
1275 return var
->interface_type
&&
1276 glsl_type_is_struct(var
->interface_type
) &&
1277 (var
->data
.mode
== nir_var_uniform
||
1278 var
->data
.mode
== nir_var_shader_storage
);
1281 static struct vtn_ssa_value
*
1282 vtn_variable_load(struct vtn_builder
*b
, nir_deref_var
*src
,
1283 struct vtn_type
*src_type
)
1285 nir_deref
*src_tail
= get_deref_tail(src
);
1287 struct vtn_ssa_value
*val
;
1288 if (variable_is_external_block(src
->var
))
1289 val
= vtn_block_load(b
, src
, src_type
, src_tail
);
1291 val
= _vtn_variable_load(b
, src
, src_tail
);
1293 if (src_tail
->child
) {
1294 nir_deref_array
*vec_deref
= nir_deref_as_array(src_tail
->child
);
1295 assert(vec_deref
->deref
.child
== NULL
);
1296 val
->type
= vec_deref
->deref
.type
;
1297 if (vec_deref
->deref_array_type
== nir_deref_array_type_direct
)
1298 val
->def
= vtn_vector_extract(b
, val
->def
, vec_deref
->base_offset
);
1300 val
->def
= vtn_vector_extract_dynamic(b
, val
->def
,
1301 vec_deref
->indirect
.ssa
);
1308 _vtn_block_store(struct vtn_builder
*b
, nir_intrinsic_op op
,
1309 struct vtn_ssa_value
*src
, unsigned set
, unsigned binding
,
1310 nir_variable_mode mode
, nir_ssa_def
*index
, unsigned offset
,
1311 nir_ssa_def
*indirect
, struct vtn_type
*type
)
1313 assert(src
->type
== type
->type
);
1314 if (glsl_type_is_vector_or_scalar(type
->type
)) {
1315 nir_intrinsic_instr
*store
= nir_intrinsic_instr_create(b
->shader
, op
);
1316 store
->num_components
= glsl_get_vector_elements(type
->type
);
1317 store
->const_index
[0] = offset
;
1318 store
->const_index
[1] = (1 << store
->num_components
) - 1;
1319 store
->src
[0] = nir_src_for_ssa(src
->def
);
1321 nir_ssa_def
*res_index
= nir_vulkan_resource_index(&b
->nb
,
1324 store
->src
[1] = nir_src_for_ssa(res_index
);
1326 if (op
== nir_intrinsic_store_ssbo_indirect
)
1327 store
->src
[2] = nir_src_for_ssa(indirect
);
1329 nir_builder_instr_insert(&b
->nb
, &store
->instr
);
1331 unsigned elems
= glsl_get_length(type
->type
);
1332 if (glsl_type_is_struct(type
->type
)) {
1333 for (unsigned i
= 0; i
< elems
; i
++) {
1334 _vtn_block_store(b
, op
, src
->elems
[i
], set
, binding
, mode
,
1335 index
, offset
+ type
->offsets
[i
], indirect
,
1339 for (unsigned i
= 0; i
< elems
; i
++) {
1340 _vtn_block_store(b
, op
, src
->elems
[i
], set
, binding
, mode
,
1341 index
, offset
+ i
* type
->stride
, indirect
,
1342 type
->array_element
);
1349 vtn_block_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1350 nir_deref_var
*dest
, struct vtn_type
*type
,
1351 nir_deref
*dest_tail
)
1355 nir_ssa_def
*indirect
;
1356 vtn_block_get_offset(b
, dest
, &type
, dest_tail
, &index
, &offset
, &indirect
);
1358 nir_intrinsic_op op
= indirect
? nir_intrinsic_store_ssbo_indirect
1359 : nir_intrinsic_store_ssbo
;
1361 return _vtn_block_store(b
, op
, src
, dest
->var
->data
.descriptor_set
,
1362 dest
->var
->data
.binding
, dest
->var
->data
.mode
,
1363 index
, offset
, indirect
, type
);
1366 static nir_ssa_def
* vtn_vector_insert(struct vtn_builder
*b
,
1367 nir_ssa_def
*src
, nir_ssa_def
*insert
,
1370 static nir_ssa_def
* vtn_vector_insert_dynamic(struct vtn_builder
*b
,
1372 nir_ssa_def
*insert
,
1373 nir_ssa_def
*index
);
1375 vtn_variable_store(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
1376 nir_deref_var
*dest
, struct vtn_type
*dest_type
)
1378 nir_deref
*dest_tail
= get_deref_tail(dest
);
1379 if (variable_is_external_block(dest
->var
)) {
1380 assert(dest
->var
->data
.mode
== nir_var_shader_storage
);
1381 vtn_block_store(b
, src
, dest
, dest_type
, dest_tail
);
1383 if (dest_tail
->child
) {
1384 struct vtn_ssa_value
*val
= _vtn_variable_load(b
, dest
, dest_tail
);
1385 nir_deref_array
*deref
= nir_deref_as_array(dest_tail
->child
);
1386 assert(deref
->deref
.child
== NULL
);
1387 if (deref
->deref_array_type
== nir_deref_array_type_direct
)
1388 val
->def
= vtn_vector_insert(b
, val
->def
, src
->def
,
1389 deref
->base_offset
);
1391 val
->def
= vtn_vector_insert_dynamic(b
, val
->def
, src
->def
,
1392 deref
->indirect
.ssa
);
1393 _vtn_variable_store(b
, dest
, dest_tail
, val
);
1395 _vtn_variable_store(b
, dest
, dest_tail
, src
);
1401 vtn_variable_copy(struct vtn_builder
*b
, nir_deref_var
*src
,
1402 nir_deref_var
*dest
, struct vtn_type
*type
)
1404 nir_deref
*src_tail
= get_deref_tail(src
);
1406 if (src_tail
->child
|| src
->var
->interface_type
) {
1407 assert(get_deref_tail(dest
)->child
);
1408 struct vtn_ssa_value
*val
= vtn_variable_load(b
, src
, type
);
1409 vtn_variable_store(b
, val
, dest
, type
);
1411 nir_intrinsic_instr
*copy
=
1412 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_copy_var
);
1413 copy
->variables
[0] = nir_deref_as_var(nir_copy_deref(copy
, &dest
->deref
));
1414 copy
->variables
[1] = nir_deref_as_var(nir_copy_deref(copy
, &src
->deref
));
1416 nir_builder_instr_insert(&b
->nb
, ©
->instr
);
1420 /* Tries to compute the size of an interface block based on the strides and
1421 * offsets that are provided to us in the SPIR-V source.
1424 vtn_type_block_size(struct vtn_type
*type
)
1426 enum glsl_base_type base_type
= glsl_get_base_type(type
->type
);
1427 switch (base_type
) {
1428 case GLSL_TYPE_UINT
:
1430 case GLSL_TYPE_FLOAT
:
1431 case GLSL_TYPE_BOOL
:
1432 case GLSL_TYPE_DOUBLE
: {
1433 unsigned cols
= type
->row_major
? glsl_get_vector_elements(type
->type
) :
1434 glsl_get_matrix_columns(type
->type
);
1436 assert(type
->stride
> 0);
1437 return type
->stride
* cols
;
1438 } else if (base_type
== GLSL_TYPE_DOUBLE
) {
1439 return glsl_get_vector_elements(type
->type
) * 8;
1441 return glsl_get_vector_elements(type
->type
) * 4;
1445 case GLSL_TYPE_STRUCT
:
1446 case GLSL_TYPE_INTERFACE
: {
1448 unsigned num_fields
= glsl_get_length(type
->type
);
1449 for (unsigned f
= 0; f
< num_fields
; f
++) {
1450 unsigned field_end
= type
->offsets
[f
] +
1451 vtn_type_block_size(type
->members
[f
]);
1452 size
= MAX2(size
, field_end
);
1457 case GLSL_TYPE_ARRAY
:
1458 assert(type
->stride
> 0);
1459 assert(glsl_get_length(type
->type
) > 0);
1460 return type
->stride
* glsl_get_length(type
->type
);
1463 assert(!"Invalid block type");
1469 is_interface_type(struct vtn_type
*type
)
1471 return type
->block
|| type
->buffer_block
||
1472 glsl_type_is_sampler(type
->type
) ||
1473 glsl_type_is_image(type
->type
);
1477 vtn_handle_variables(struct vtn_builder
*b
, SpvOp opcode
,
1478 const uint32_t *w
, unsigned count
)
1481 case SpvOpVariable
: {
1482 struct vtn_type
*type
=
1483 vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
1484 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
1486 nir_variable
*var
= rzalloc(b
->shader
, nir_variable
);
1488 var
->type
= type
->type
;
1489 var
->name
= ralloc_strdup(var
, val
->name
);
1491 struct vtn_type
*interface_type
;
1492 if (is_interface_type(type
)) {
1493 interface_type
= type
;
1494 } else if (glsl_type_is_array(type
->type
) &&
1495 is_interface_type(type
->array_element
)) {
1496 interface_type
= type
->array_element
;
1498 interface_type
= NULL
;
1502 var
->interface_type
= interface_type
->type
;
1504 switch ((SpvStorageClass
)w
[3]) {
1505 case SpvStorageClassUniform
:
1506 case SpvStorageClassUniformConstant
:
1507 if (interface_type
&& interface_type
->buffer_block
) {
1508 var
->data
.mode
= nir_var_shader_storage
;
1509 b
->shader
->info
.num_ssbos
++;
1511 /* UBO's and samplers */
1512 var
->data
.mode
= nir_var_uniform
;
1513 var
->data
.read_only
= true;
1514 if (interface_type
) {
1515 if (glsl_type_is_image(interface_type
->type
)) {
1516 b
->shader
->info
.num_images
++;
1517 var
->data
.image
.format
= interface_type
->image_format
;
1518 } else if (glsl_type_is_sampler(interface_type
->type
)) {
1519 b
->shader
->info
.num_textures
++;
1521 assert(glsl_type_is_struct(interface_type
->type
));
1522 b
->shader
->info
.num_ubos
++;
1527 case SpvStorageClassPushConstant
:
1528 assert(interface_type
&& interface_type
->block
);
1529 var
->data
.mode
= nir_var_uniform
;
1530 var
->data
.read_only
= true;
1531 var
->data
.descriptor_set
= -1;
1532 var
->data
.binding
= -1;
1534 /* We have exactly one push constant block */
1535 assert(b
->shader
->num_uniforms
== 0);
1536 b
->shader
->num_uniforms
= vtn_type_block_size(type
);
1538 case SpvStorageClassInput
:
1539 var
->data
.mode
= nir_var_shader_in
;
1540 var
->data
.read_only
= true;
1542 case SpvStorageClassOutput
:
1543 var
->data
.mode
= nir_var_shader_out
;
1545 case SpvStorageClassPrivateGlobal
:
1546 var
->data
.mode
= nir_var_global
;
1548 case SpvStorageClassFunction
:
1549 var
->data
.mode
= nir_var_local
;
1551 case SpvStorageClassWorkgroupLocal
:
1552 case SpvStorageClassWorkgroupGlobal
:
1553 case SpvStorageClassGeneric
:
1554 case SpvStorageClassAtomicCounter
:
1556 unreachable("Unhandled variable storage class");
1561 var
->constant_initializer
=
1562 vtn_value(b
, w
[4], vtn_value_type_constant
)->constant
;
1565 val
->deref
= nir_deref_var_create(b
, var
);
1566 val
->deref_type
= type
;
1568 /* We handle decorations first because decorations might give us
1569 * location information. We use the data.explicit_location field to
1570 * note that the location provided is the "final" location. If
1571 * data.explicit_location == false, this means that it's relative to
1572 * whatever the base location is.
1574 vtn_foreach_decoration(b
, val
, var_decoration_cb
, var
);
1576 if (!var
->data
.explicit_location
) {
1577 if (b
->execution_model
== SpvExecutionModelFragment
&&
1578 var
->data
.mode
== nir_var_shader_out
) {
1579 var
->data
.location
+= FRAG_RESULT_DATA0
;
1580 } else if (b
->execution_model
== SpvExecutionModelVertex
&&
1581 var
->data
.mode
== nir_var_shader_in
) {
1582 var
->data
.location
+= VERT_ATTRIB_GENERIC0
;
1583 } else if (var
->data
.mode
== nir_var_shader_in
||
1584 var
->data
.mode
== nir_var_shader_out
) {
1585 var
->data
.location
+= VARYING_SLOT_VAR0
;
1589 /* Interface block variables aren't actually going to be referenced
1590 * by the generated NIR, so we don't put them in the list
1592 if (interface_type
&& glsl_type_is_struct(interface_type
->type
))
1595 if (var
->data
.mode
== nir_var_local
) {
1596 nir_function_impl_add_variable(b
->impl
, var
);
1598 nir_shader_add_variable(b
->shader
, var
);
1604 case SpvOpAccessChain
:
1605 case SpvOpInBoundsAccessChain
: {
1606 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_deref
);
1607 nir_deref_var
*base
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
1608 val
->deref
= nir_deref_as_var(nir_copy_deref(b
, &base
->deref
));
1609 struct vtn_type
*deref_type
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1611 nir_deref
*tail
= &val
->deref
->deref
;
1615 for (unsigned i
= 0; i
< count
- 4; i
++) {
1616 assert(w
[i
+ 4] < b
->value_id_bound
);
1617 struct vtn_value
*idx_val
= &b
->values
[w
[i
+ 4]];
1619 enum glsl_base_type base_type
= glsl_get_base_type(tail
->type
);
1620 switch (base_type
) {
1621 case GLSL_TYPE_UINT
:
1623 case GLSL_TYPE_FLOAT
:
1624 case GLSL_TYPE_DOUBLE
:
1625 case GLSL_TYPE_BOOL
:
1626 case GLSL_TYPE_ARRAY
: {
1627 nir_deref_array
*deref_arr
= nir_deref_array_create(b
);
1628 if (base_type
== GLSL_TYPE_ARRAY
||
1629 glsl_type_is_matrix(tail
->type
)) {
1630 deref_type
= deref_type
->array_element
;
1632 assert(glsl_type_is_vector(tail
->type
));
1633 deref_type
= ralloc(b
, struct vtn_type
);
1634 deref_type
->type
= glsl_scalar_type(base_type
);
1637 deref_arr
->deref
.type
= deref_type
->type
;
1639 if (idx_val
->value_type
== vtn_value_type_constant
) {
1640 unsigned idx
= idx_val
->constant
->value
.u
[0];
1641 deref_arr
->deref_array_type
= nir_deref_array_type_direct
;
1642 deref_arr
->base_offset
= idx
;
1644 assert(idx_val
->value_type
== vtn_value_type_ssa
);
1645 assert(glsl_type_is_scalar(idx_val
->ssa
->type
));
1646 deref_arr
->deref_array_type
= nir_deref_array_type_indirect
;
1647 deref_arr
->base_offset
= 0;
1648 deref_arr
->indirect
= nir_src_for_ssa(idx_val
->ssa
->def
);
1650 tail
->child
= &deref_arr
->deref
;
1654 case GLSL_TYPE_STRUCT
: {
1655 assert(idx_val
->value_type
== vtn_value_type_constant
);
1656 unsigned idx
= idx_val
->constant
->value
.u
[0];
1657 deref_type
= deref_type
->members
[idx
];
1658 nir_deref_struct
*deref_struct
= nir_deref_struct_create(b
, idx
);
1659 deref_struct
->deref
.type
= deref_type
->type
;
1660 tail
->child
= &deref_struct
->deref
;
1664 unreachable("Invalid type for deref");
1667 if (deref_type
->is_builtin
) {
1668 /* If we encounter a builtin, we throw away the ress of the
1669 * access chain, jump to the builtin, and keep building.
1671 const struct glsl_type
*builtin_type
= deref_type
->type
;
1673 nir_deref_array
*per_vertex_deref
= NULL
;
1674 if (glsl_type_is_array(base
->var
->type
)) {
1675 /* This builtin is a per-vertex builtin */
1676 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
1677 assert(base
->var
->data
.mode
== nir_var_shader_in
);
1678 builtin_type
= glsl_array_type(builtin_type
,
1679 b
->shader
->info
.gs
.vertices_in
);
1681 /* The first non-var deref should be an array deref. */
1682 assert(val
->deref
->deref
.child
->deref_type
==
1683 nir_deref_type_array
);
1684 per_vertex_deref
= nir_deref_as_array(val
->deref
->deref
.child
);
1687 nir_variable
*builtin
= get_builtin_variable(b
,
1688 base
->var
->data
.mode
,
1690 deref_type
->builtin
);
1691 val
->deref
= nir_deref_var_create(b
, builtin
);
1693 if (per_vertex_deref
) {
1694 /* Since deref chains start at the variable, we can just
1695 * steal that link and use it.
1697 val
->deref
->deref
.child
= &per_vertex_deref
->deref
;
1698 per_vertex_deref
->deref
.child
= NULL
;
1699 per_vertex_deref
->deref
.type
=
1700 glsl_get_array_element(builtin_type
);
1702 tail
= &per_vertex_deref
->deref
;
1704 tail
= &val
->deref
->deref
;
1711 /* For uniform blocks, we don't resolve the access chain until we
1712 * actually access the variable, so we need to keep around the original
1713 * type of the variable.
1716 if (variable_is_external_block(base
->var
))
1717 val
->deref_type
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1719 val
->deref_type
= deref_type
;
1725 case SpvOpCopyMemory
: {
1726 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
1727 nir_deref_var
*src
= vtn_value(b
, w
[2], vtn_value_type_deref
)->deref
;
1728 struct vtn_type
*type
=
1729 vtn_value(b
, w
[1], vtn_value_type_deref
)->deref_type
;
1731 vtn_variable_copy(b
, src
, dest
, type
);
1736 nir_deref_var
*src
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
1737 struct vtn_type
*src_type
=
1738 vtn_value(b
, w
[3], vtn_value_type_deref
)->deref_type
;
1740 if (src
->var
->interface_type
&&
1741 (glsl_type_is_sampler(src
->var
->interface_type
) ||
1742 glsl_type_is_image(src
->var
->interface_type
))) {
1743 vtn_push_value(b
, w
[2], vtn_value_type_deref
)->deref
= src
;
1747 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1748 val
->ssa
= vtn_variable_load(b
, src
, src_type
);
1753 nir_deref_var
*dest
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
1754 struct vtn_type
*dest_type
=
1755 vtn_value(b
, w
[1], vtn_value_type_deref
)->deref_type
;
1756 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[2]);
1757 vtn_variable_store(b
, src
, dest
, dest_type
);
1761 case SpvOpCopyMemorySized
:
1762 case SpvOpArrayLength
:
1764 unreachable("Unhandled opcode");
1769 vtn_handle_function_call(struct vtn_builder
*b
, SpvOp opcode
,
1770 const uint32_t *w
, unsigned count
)
1772 unreachable("Unhandled opcode");
1775 static struct vtn_ssa_value
*
1776 vtn_create_ssa_value(struct vtn_builder
*b
, const struct glsl_type
*type
)
1778 struct vtn_ssa_value
*val
= rzalloc(b
, struct vtn_ssa_value
);
1781 if (!glsl_type_is_vector_or_scalar(type
)) {
1782 unsigned elems
= glsl_get_length(type
);
1783 val
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
1784 for (unsigned i
= 0; i
< elems
; i
++) {
1785 const struct glsl_type
*child_type
;
1787 switch (glsl_get_base_type(type
)) {
1789 case GLSL_TYPE_UINT
:
1790 case GLSL_TYPE_BOOL
:
1791 case GLSL_TYPE_FLOAT
:
1792 case GLSL_TYPE_DOUBLE
:
1793 child_type
= glsl_get_column_type(type
);
1795 case GLSL_TYPE_ARRAY
:
1796 child_type
= glsl_get_array_element(type
);
1798 case GLSL_TYPE_STRUCT
:
1799 child_type
= glsl_get_struct_field(type
, i
);
1802 unreachable("unkown base type");
1805 val
->elems
[i
] = vtn_create_ssa_value(b
, child_type
);
1813 vtn_tex_src(struct vtn_builder
*b
, unsigned index
, nir_tex_src_type type
)
1816 src
.src
= nir_src_for_ssa(vtn_ssa_value(b
, index
)->def
);
1817 src
.src_type
= type
;
1822 vtn_handle_texture(struct vtn_builder
*b
, SpvOp opcode
,
1823 const uint32_t *w
, unsigned count
)
1825 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
1826 nir_deref_var
*sampler
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
1828 nir_tex_src srcs
[8]; /* 8 should be enough */
1829 nir_tex_src
*p
= srcs
;
1833 unsigned coord_components
= 0;
1835 case SpvOpImageSampleImplicitLod
:
1836 case SpvOpImageSampleExplicitLod
:
1837 case SpvOpImageSampleDrefImplicitLod
:
1838 case SpvOpImageSampleDrefExplicitLod
:
1839 case SpvOpImageSampleProjImplicitLod
:
1840 case SpvOpImageSampleProjExplicitLod
:
1841 case SpvOpImageSampleProjDrefImplicitLod
:
1842 case SpvOpImageSampleProjDrefExplicitLod
:
1843 case SpvOpImageFetch
:
1844 case SpvOpImageGather
:
1845 case SpvOpImageDrefGather
:
1846 case SpvOpImageQueryLod
: {
1847 /* All these types have the coordinate as their first real argument */
1848 struct vtn_ssa_value
*coord
= vtn_ssa_value(b
, w
[idx
++]);
1849 coord_components
= glsl_get_vector_elements(coord
->type
);
1850 p
->src
= nir_src_for_ssa(coord
->def
);
1851 p
->src_type
= nir_tex_src_coord
;
1860 /* These all have an explicit depth value as their next source */
1862 case SpvOpImageSampleDrefImplicitLod
:
1863 case SpvOpImageSampleDrefExplicitLod
:
1864 case SpvOpImageSampleProjDrefImplicitLod
:
1865 case SpvOpImageSampleProjDrefExplicitLod
:
1866 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_comparitor
);
1872 /* Figure out the base texture operation */
1875 case SpvOpImageSampleImplicitLod
:
1876 case SpvOpImageSampleDrefImplicitLod
:
1877 case SpvOpImageSampleProjImplicitLod
:
1878 case SpvOpImageSampleProjDrefImplicitLod
:
1879 texop
= nir_texop_tex
;
1882 case SpvOpImageSampleExplicitLod
:
1883 case SpvOpImageSampleDrefExplicitLod
:
1884 case SpvOpImageSampleProjExplicitLod
:
1885 case SpvOpImageSampleProjDrefExplicitLod
:
1886 texop
= nir_texop_txl
;
1889 case SpvOpImageFetch
:
1890 texop
= nir_texop_txf
;
1893 case SpvOpImageGather
:
1894 case SpvOpImageDrefGather
:
1895 texop
= nir_texop_tg4
;
1898 case SpvOpImageQuerySizeLod
:
1899 case SpvOpImageQuerySize
:
1900 texop
= nir_texop_txs
;
1903 case SpvOpImageQueryLod
:
1904 texop
= nir_texop_lod
;
1907 case SpvOpImageQueryLevels
:
1908 texop
= nir_texop_query_levels
;
1911 case SpvOpImageQuerySamples
:
1913 unreachable("Unhandled opcode");
1916 /* Now we need to handle some number of optional arguments */
1918 uint32_t operands
= w
[idx
++];
1920 if (operands
& SpvImageOperandsBiasMask
) {
1921 assert(texop
== nir_texop_tex
);
1922 texop
= nir_texop_txb
;
1923 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_bias
);
1926 if (operands
& SpvImageOperandsLodMask
) {
1927 assert(texop
== nir_texop_txl
|| texop
== nir_texop_txf
||
1928 texop
== nir_texop_txs
);
1929 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_lod
);
1932 if (operands
& SpvImageOperandsGradMask
) {
1933 assert(texop
== nir_texop_tex
);
1934 texop
= nir_texop_txd
;
1935 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ddx
);
1936 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ddy
);
1939 if (operands
& SpvImageOperandsOffsetMask
||
1940 operands
& SpvImageOperandsConstOffsetMask
)
1941 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_offset
);
1943 if (operands
& SpvImageOperandsConstOffsetsMask
)
1944 assert(!"Constant offsets to texture gather not yet implemented");
1946 if (operands
& SpvImageOperandsSampleMask
) {
1947 assert(texop
== nir_texop_txf
);
1948 texop
= nir_texop_txf_ms
;
1949 (*p
++) = vtn_tex_src(b
, w
[idx
++], nir_tex_src_ms_index
);
1952 /* We should have now consumed exactly all of the arguments */
1953 assert(idx
== count
);
1955 nir_tex_instr
*instr
= nir_tex_instr_create(b
->shader
, p
- srcs
);
1957 const struct glsl_type
*sampler_type
= nir_deref_tail(&sampler
->deref
)->type
;
1958 instr
->sampler_dim
= glsl_get_sampler_dim(sampler_type
);
1960 switch (glsl_get_sampler_result_type(sampler_type
)) {
1961 case GLSL_TYPE_FLOAT
: instr
->dest_type
= nir_type_float
; break;
1962 case GLSL_TYPE_INT
: instr
->dest_type
= nir_type_int
; break;
1963 case GLSL_TYPE_UINT
: instr
->dest_type
= nir_type_unsigned
; break;
1964 case GLSL_TYPE_BOOL
: instr
->dest_type
= nir_type_bool
; break;
1966 unreachable("Invalid base type for sampler result");
1970 memcpy(instr
->src
, srcs
, instr
->num_srcs
* sizeof(*instr
->src
));
1971 instr
->coord_components
= coord_components
;
1972 instr
->is_array
= glsl_sampler_type_is_array(sampler_type
);
1973 instr
->is_shadow
= glsl_sampler_type_is_shadow(sampler_type
);
1975 instr
->sampler
= nir_deref_as_var(nir_copy_deref(instr
, &sampler
->deref
));
1977 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
, 4, NULL
);
1978 val
->ssa
= vtn_create_ssa_value(b
, glsl_vector_type(GLSL_TYPE_FLOAT
, 4));
1979 val
->ssa
->def
= &instr
->dest
.ssa
;
1981 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
1984 static nir_ssa_def
*
1985 get_image_coord(struct vtn_builder
*b
, uint32_t value
)
1987 struct vtn_ssa_value
*coord
= vtn_ssa_value(b
, value
);
1989 /* The image_load_store intrinsics assume a 4-dim coordinate */
1990 unsigned dim
= glsl_get_vector_elements(coord
->type
);
1991 unsigned swizzle
[4];
1992 for (unsigned i
= 0; i
< 4; i
++)
1993 swizzle
[i
] = MIN2(i
, dim
- 1);
1995 return nir_swizzle(&b
->nb
, coord
->def
, swizzle
, 4, false);
1999 vtn_handle_image(struct vtn_builder
*b
, SpvOp opcode
,
2000 const uint32_t *w
, unsigned count
)
2002 /* Just get this one out of the way */
2003 if (opcode
== SpvOpImageTexelPointer
) {
2004 struct vtn_value
*val
=
2005 vtn_push_value(b
, w
[2], vtn_value_type_image_pointer
);
2006 val
->image
= ralloc(b
, struct vtn_image_pointer
);
2008 val
->image
->deref
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
2009 val
->image
->coord
= get_image_coord(b
, w
[4]);
2010 val
->image
->sample
= vtn_ssa_value(b
, w
[5])->def
;
2014 struct vtn_image_pointer image
;
2017 case SpvOpAtomicExchange
:
2018 case SpvOpAtomicCompareExchange
:
2019 case SpvOpAtomicCompareExchangeWeak
:
2020 case SpvOpAtomicIIncrement
:
2021 case SpvOpAtomicIDecrement
:
2022 case SpvOpAtomicIAdd
:
2023 case SpvOpAtomicISub
:
2024 case SpvOpAtomicSMin
:
2025 case SpvOpAtomicUMin
:
2026 case SpvOpAtomicSMax
:
2027 case SpvOpAtomicUMax
:
2028 case SpvOpAtomicAnd
:
2030 case SpvOpAtomicXor
:
2031 image
= *vtn_value(b
, w
[3], vtn_value_type_image_pointer
)->image
;
2034 case SpvOpImageRead
:
2035 image
.deref
= vtn_value(b
, w
[3], vtn_value_type_deref
)->deref
;
2036 image
.coord
= get_image_coord(b
, w
[4]);
2038 if (count
> 5 && (w
[5] & SpvImageOperandsSampleMask
)) {
2039 assert(w
[5] == SpvImageOperandsSampleMask
);
2040 image
.sample
= vtn_ssa_value(b
, w
[6])->def
;
2042 image
.sample
= nir_ssa_undef(&b
->nb
, 1);
2046 case SpvOpImageWrite
:
2047 image
.deref
= vtn_value(b
, w
[1], vtn_value_type_deref
)->deref
;
2048 image
.coord
= get_image_coord(b
, w
[2]);
2052 if (count
> 4 && (w
[4] & SpvImageOperandsSampleMask
)) {
2053 assert(w
[4] == SpvImageOperandsSampleMask
);
2054 image
.sample
= vtn_ssa_value(b
, w
[5])->def
;
2056 image
.sample
= nir_ssa_undef(&b
->nb
, 1);
2060 unreachable("Invalid image opcode");
2063 nir_intrinsic_op op
;
2065 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
2067 OP(ImageWrite
, store
)
2068 OP(AtomicExchange
, atomic_exchange
)
2069 OP(AtomicCompareExchange
, atomic_comp_swap
)
2070 OP(AtomicIIncrement
, atomic_add
)
2071 OP(AtomicIDecrement
, atomic_add
)
2072 OP(AtomicIAdd
, atomic_add
)
2073 OP(AtomicISub
, atomic_add
)
2074 OP(AtomicSMin
, atomic_min
)
2075 OP(AtomicUMin
, atomic_min
)
2076 OP(AtomicSMax
, atomic_max
)
2077 OP(AtomicUMax
, atomic_max
)
2078 OP(AtomicAnd
, atomic_and
)
2079 OP(AtomicOr
, atomic_or
)
2080 OP(AtomicXor
, atomic_xor
)
2083 unreachable("Invalid image opcode");
2086 nir_intrinsic_instr
*intrin
= nir_intrinsic_instr_create(b
->shader
, op
);
2087 intrin
->variables
[0] =
2088 nir_deref_as_var(nir_copy_deref(&intrin
->instr
, &image
.deref
->deref
));
2089 intrin
->src
[0] = nir_src_for_ssa(image
.coord
);
2090 intrin
->src
[1] = nir_src_for_ssa(image
.sample
);
2093 case SpvOpImageRead
:
2095 case SpvOpImageWrite
:
2096 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[3])->def
);
2098 case SpvOpAtomicIIncrement
:
2099 intrin
->src
[2] = nir_src_for_ssa(nir_imm_int(&b
->nb
, 1));
2101 case SpvOpAtomicIDecrement
:
2102 intrin
->src
[2] = nir_src_for_ssa(nir_imm_int(&b
->nb
, -1));
2105 case SpvOpAtomicExchange
:
2106 case SpvOpAtomicIAdd
:
2107 case SpvOpAtomicSMin
:
2108 case SpvOpAtomicUMin
:
2109 case SpvOpAtomicSMax
:
2110 case SpvOpAtomicUMax
:
2111 case SpvOpAtomicAnd
:
2113 case SpvOpAtomicXor
:
2114 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[6])->def
);
2117 case SpvOpAtomicCompareExchange
:
2118 intrin
->src
[2] = nir_src_for_ssa(vtn_ssa_value(b
, w
[7])->def
);
2119 intrin
->src
[3] = nir_src_for_ssa(vtn_ssa_value(b
, w
[6])->def
);
2122 case SpvOpAtomicISub
:
2123 intrin
->src
[2] = nir_src_for_ssa(nir_ineg(&b
->nb
, vtn_ssa_value(b
, w
[6])->def
));
2127 unreachable("Invalid image opcode");
2130 if (opcode
!= SpvOpImageWrite
) {
2131 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2132 struct vtn_type
*type
= vtn_value(b
, w
[1], vtn_value_type_type
)->type
;
2133 nir_ssa_dest_init(&intrin
->instr
, &intrin
->dest
,
2134 glsl_get_vector_elements(type
->type
), NULL
);
2135 val
->ssa
= vtn_create_ssa_value(b
, type
->type
);
2136 val
->ssa
->def
= &intrin
->dest
.ssa
;
2139 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
2142 static nir_alu_instr
*
2143 create_vec(void *mem_ctx
, unsigned num_components
)
2146 switch (num_components
) {
2147 case 1: op
= nir_op_fmov
; break;
2148 case 2: op
= nir_op_vec2
; break;
2149 case 3: op
= nir_op_vec3
; break;
2150 case 4: op
= nir_op_vec4
; break;
2151 default: unreachable("bad vector size");
2154 nir_alu_instr
*vec
= nir_alu_instr_create(mem_ctx
, op
);
2155 nir_ssa_dest_init(&vec
->instr
, &vec
->dest
.dest
, num_components
, NULL
);
2156 vec
->dest
.write_mask
= (1 << num_components
) - 1;
2161 static struct vtn_ssa_value
*
2162 vtn_transpose(struct vtn_builder
*b
, struct vtn_ssa_value
*src
)
2164 if (src
->transposed
)
2165 return src
->transposed
;
2167 struct vtn_ssa_value
*dest
=
2168 vtn_create_ssa_value(b
, glsl_transposed_type(src
->type
));
2170 for (unsigned i
= 0; i
< glsl_get_matrix_columns(dest
->type
); i
++) {
2171 nir_alu_instr
*vec
= create_vec(b
, glsl_get_matrix_columns(src
->type
));
2172 if (glsl_type_is_vector_or_scalar(src
->type
)) {
2173 vec
->src
[0].src
= nir_src_for_ssa(src
->def
);
2174 vec
->src
[0].swizzle
[0] = i
;
2176 for (unsigned j
= 0; j
< glsl_get_matrix_columns(src
->type
); j
++) {
2177 vec
->src
[j
].src
= nir_src_for_ssa(src
->elems
[j
]->def
);
2178 vec
->src
[j
].swizzle
[0] = i
;
2181 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2182 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
2185 dest
->transposed
= src
;
2191 * Normally, column vectors in SPIR-V correspond to a single NIR SSA
2192 * definition. But for matrix multiplies, we want to do one routine for
2193 * multiplying a matrix by a matrix and then pretend that vectors are matrices
2194 * with one column. So we "wrap" these things, and unwrap the result before we
2198 static struct vtn_ssa_value
*
2199 vtn_wrap_matrix(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
2204 if (glsl_type_is_matrix(val
->type
))
2207 struct vtn_ssa_value
*dest
= rzalloc(b
, struct vtn_ssa_value
);
2208 dest
->type
= val
->type
;
2209 dest
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, 1);
2210 dest
->elems
[0] = val
;
2215 static struct vtn_ssa_value
*
2216 vtn_unwrap_matrix(struct vtn_ssa_value
*val
)
2218 if (glsl_type_is_matrix(val
->type
))
2221 return val
->elems
[0];
2224 static struct vtn_ssa_value
*
2225 vtn_matrix_multiply(struct vtn_builder
*b
,
2226 struct vtn_ssa_value
*_src0
, struct vtn_ssa_value
*_src1
)
2229 struct vtn_ssa_value
*src0
= vtn_wrap_matrix(b
, _src0
);
2230 struct vtn_ssa_value
*src1
= vtn_wrap_matrix(b
, _src1
);
2231 struct vtn_ssa_value
*src0_transpose
= vtn_wrap_matrix(b
, _src0
->transposed
);
2232 struct vtn_ssa_value
*src1_transpose
= vtn_wrap_matrix(b
, _src1
->transposed
);
2234 unsigned src0_rows
= glsl_get_vector_elements(src0
->type
);
2235 unsigned src0_columns
= glsl_get_matrix_columns(src0
->type
);
2236 unsigned src1_columns
= glsl_get_matrix_columns(src1
->type
);
2238 struct vtn_ssa_value
*dest
=
2239 vtn_create_ssa_value(b
, glsl_matrix_type(glsl_get_base_type(src0
->type
),
2240 src0_rows
, src1_columns
));
2242 dest
= vtn_wrap_matrix(b
, dest
);
2244 bool transpose_result
= false;
2245 if (src0_transpose
&& src1_transpose
) {
2246 /* transpose(A) * transpose(B) = transpose(B * A) */
2247 src1
= src0_transpose
;
2248 src0
= src1_transpose
;
2249 src0_transpose
= NULL
;
2250 src1_transpose
= NULL
;
2251 transpose_result
= true;
2254 if (src0_transpose
&& !src1_transpose
&&
2255 glsl_get_base_type(src0
->type
) == GLSL_TYPE_FLOAT
) {
2256 /* We already have the rows of src0 and the columns of src1 available,
2257 * so we can just take the dot product of each row with each column to
2261 for (unsigned i
= 0; i
< src1_columns
; i
++) {
2262 nir_alu_instr
*vec
= create_vec(b
, src0_rows
);
2263 for (unsigned j
= 0; j
< src0_rows
; j
++) {
2265 nir_src_for_ssa(nir_fdot(&b
->nb
, src0_transpose
->elems
[j
]->def
,
2266 src1
->elems
[i
]->def
));
2269 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2270 dest
->elems
[i
]->def
= &vec
->dest
.dest
.ssa
;
2273 /* We don't handle the case where src1 is transposed but not src0, since
2274 * the general case only uses individual components of src1 so the
2275 * optimizer should chew through the transpose we emitted for src1.
2278 for (unsigned i
= 0; i
< src1_columns
; i
++) {
2279 /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
2280 dest
->elems
[i
]->def
=
2281 nir_fmul(&b
->nb
, src0
->elems
[0]->def
,
2282 vtn_vector_extract(b
, src1
->elems
[i
]->def
, 0));
2283 for (unsigned j
= 1; j
< src0_columns
; j
++) {
2284 dest
->elems
[i
]->def
=
2285 nir_fadd(&b
->nb
, dest
->elems
[i
]->def
,
2286 nir_fmul(&b
->nb
, src0
->elems
[j
]->def
,
2287 vtn_vector_extract(b
,
2288 src1
->elems
[i
]->def
, j
)));
2293 dest
= vtn_unwrap_matrix(dest
);
2295 if (transpose_result
)
2296 dest
= vtn_transpose(b
, dest
);
2301 static struct vtn_ssa_value
*
2302 vtn_mat_times_scalar(struct vtn_builder
*b
,
2303 struct vtn_ssa_value
*mat
,
2304 nir_ssa_def
*scalar
)
2306 struct vtn_ssa_value
*dest
= vtn_create_ssa_value(b
, mat
->type
);
2307 for (unsigned i
= 0; i
< glsl_get_matrix_columns(mat
->type
); i
++) {
2308 if (glsl_get_base_type(mat
->type
) == GLSL_TYPE_FLOAT
)
2309 dest
->elems
[i
]->def
= nir_fmul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
2311 dest
->elems
[i
]->def
= nir_imul(&b
->nb
, mat
->elems
[i
]->def
, scalar
);
2318 vtn_handle_matrix_alu(struct vtn_builder
*b
, SpvOp opcode
,
2319 const uint32_t *w
, unsigned count
)
2321 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2324 case SpvOpTranspose
: {
2325 struct vtn_ssa_value
*src
= vtn_ssa_value(b
, w
[3]);
2326 val
->ssa
= vtn_transpose(b
, src
);
2330 case SpvOpOuterProduct
: {
2331 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
2332 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
2334 val
->ssa
= vtn_matrix_multiply(b
, src0
, vtn_transpose(b
, src1
));
2338 case SpvOpMatrixTimesScalar
: {
2339 struct vtn_ssa_value
*mat
= vtn_ssa_value(b
, w
[3]);
2340 struct vtn_ssa_value
*scalar
= vtn_ssa_value(b
, w
[4]);
2342 if (mat
->transposed
) {
2343 val
->ssa
= vtn_transpose(b
, vtn_mat_times_scalar(b
, mat
->transposed
,
2346 val
->ssa
= vtn_mat_times_scalar(b
, mat
, scalar
->def
);
2351 case SpvOpVectorTimesMatrix
:
2352 case SpvOpMatrixTimesVector
:
2353 case SpvOpMatrixTimesMatrix
: {
2354 struct vtn_ssa_value
*src0
= vtn_ssa_value(b
, w
[3]);
2355 struct vtn_ssa_value
*src1
= vtn_ssa_value(b
, w
[4]);
2357 val
->ssa
= vtn_matrix_multiply(b
, src0
, src1
);
2361 default: unreachable("unknown matrix opcode");
2366 vtn_handle_alu(struct vtn_builder
*b
, SpvOp opcode
,
2367 const uint32_t *w
, unsigned count
)
2369 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2370 const struct glsl_type
*type
=
2371 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
2372 val
->ssa
= vtn_create_ssa_value(b
, type
);
2374 /* Collect the various SSA sources */
2375 unsigned num_inputs
= count
- 3;
2376 nir_ssa_def
*src
[4];
2377 for (unsigned i
= 0; i
< num_inputs
; i
++)
2378 src
[i
] = vtn_ssa_value(b
, w
[i
+ 3])->def
;
2380 /* Indicates that the first two arguments should be swapped. This is
2381 * used for implementing greater-than and less-than-or-equal.
2387 /* Basic ALU operations */
2388 case SpvOpSNegate
: op
= nir_op_ineg
; break;
2389 case SpvOpFNegate
: op
= nir_op_fneg
; break;
2390 case SpvOpNot
: op
= nir_op_inot
; break;
2393 switch (src
[0]->num_components
) {
2394 case 1: op
= nir_op_imov
; break;
2395 case 2: op
= nir_op_bany2
; break;
2396 case 3: op
= nir_op_bany3
; break;
2397 case 4: op
= nir_op_bany4
; break;
2402 switch (src
[0]->num_components
) {
2403 case 1: op
= nir_op_imov
; break;
2404 case 2: op
= nir_op_ball2
; break;
2405 case 3: op
= nir_op_ball3
; break;
2406 case 4: op
= nir_op_ball4
; break;
2410 case SpvOpIAdd
: op
= nir_op_iadd
; break;
2411 case SpvOpFAdd
: op
= nir_op_fadd
; break;
2412 case SpvOpISub
: op
= nir_op_isub
; break;
2413 case SpvOpFSub
: op
= nir_op_fsub
; break;
2414 case SpvOpIMul
: op
= nir_op_imul
; break;
2415 case SpvOpFMul
: op
= nir_op_fmul
; break;
2416 case SpvOpUDiv
: op
= nir_op_udiv
; break;
2417 case SpvOpSDiv
: op
= nir_op_idiv
; break;
2418 case SpvOpFDiv
: op
= nir_op_fdiv
; break;
2419 case SpvOpUMod
: op
= nir_op_umod
; break;
2420 case SpvOpSMod
: op
= nir_op_umod
; break; /* FIXME? */
2421 case SpvOpFMod
: op
= nir_op_fmod
; break;
2424 assert(src
[0]->num_components
== src
[1]->num_components
);
2425 switch (src
[0]->num_components
) {
2426 case 1: op
= nir_op_fmul
; break;
2427 case 2: op
= nir_op_fdot2
; break;
2428 case 3: op
= nir_op_fdot3
; break;
2429 case 4: op
= nir_op_fdot4
; break;
2433 case SpvOpShiftRightLogical
: op
= nir_op_ushr
; break;
2434 case SpvOpShiftRightArithmetic
: op
= nir_op_ishr
; break;
2435 case SpvOpShiftLeftLogical
: op
= nir_op_ishl
; break;
2436 case SpvOpLogicalOr
: op
= nir_op_ior
; break;
2437 case SpvOpLogicalEqual
: op
= nir_op_ieq
; break;
2438 case SpvOpLogicalNotEqual
: op
= nir_op_ine
; break;
2439 case SpvOpLogicalAnd
: op
= nir_op_iand
; break;
2440 case SpvOpBitwiseOr
: op
= nir_op_ior
; break;
2441 case SpvOpBitwiseXor
: op
= nir_op_ixor
; break;
2442 case SpvOpBitwiseAnd
: op
= nir_op_iand
; break;
2443 case SpvOpSelect
: op
= nir_op_bcsel
; break;
2444 case SpvOpIEqual
: op
= nir_op_ieq
; break;
2446 /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
2447 case SpvOpFOrdEqual
: op
= nir_op_feq
; break;
2448 case SpvOpFUnordEqual
: op
= nir_op_feq
; break;
2449 case SpvOpINotEqual
: op
= nir_op_ine
; break;
2450 case SpvOpFOrdNotEqual
: op
= nir_op_fne
; break;
2451 case SpvOpFUnordNotEqual
: op
= nir_op_fne
; break;
2452 case SpvOpULessThan
: op
= nir_op_ult
; break;
2453 case SpvOpSLessThan
: op
= nir_op_ilt
; break;
2454 case SpvOpFOrdLessThan
: op
= nir_op_flt
; break;
2455 case SpvOpFUnordLessThan
: op
= nir_op_flt
; break;
2456 case SpvOpUGreaterThan
: op
= nir_op_ult
; swap
= true; break;
2457 case SpvOpSGreaterThan
: op
= nir_op_ilt
; swap
= true; break;
2458 case SpvOpFOrdGreaterThan
: op
= nir_op_flt
; swap
= true; break;
2459 case SpvOpFUnordGreaterThan
: op
= nir_op_flt
; swap
= true; break;
2460 case SpvOpULessThanEqual
: op
= nir_op_uge
; swap
= true; break;
2461 case SpvOpSLessThanEqual
: op
= nir_op_ige
; swap
= true; break;
2462 case SpvOpFOrdLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
2463 case SpvOpFUnordLessThanEqual
: op
= nir_op_fge
; swap
= true; break;
2464 case SpvOpUGreaterThanEqual
: op
= nir_op_uge
; break;
2465 case SpvOpSGreaterThanEqual
: op
= nir_op_ige
; break;
2466 case SpvOpFOrdGreaterThanEqual
: op
= nir_op_fge
; break;
2467 case SpvOpFUnordGreaterThanEqual
:op
= nir_op_fge
; break;
2470 case SpvOpConvertFToU
: op
= nir_op_f2u
; break;
2471 case SpvOpConvertFToS
: op
= nir_op_f2i
; break;
2472 case SpvOpConvertSToF
: op
= nir_op_i2f
; break;
2473 case SpvOpConvertUToF
: op
= nir_op_u2f
; break;
2474 case SpvOpBitcast
: op
= nir_op_imov
; break;
2477 op
= nir_op_imov
; /* TODO: NIR is 32-bit only; these are no-ops. */
2484 case SpvOpDPdx
: op
= nir_op_fddx
; break;
2485 case SpvOpDPdy
: op
= nir_op_fddy
; break;
2486 case SpvOpDPdxFine
: op
= nir_op_fddx_fine
; break;
2487 case SpvOpDPdyFine
: op
= nir_op_fddy_fine
; break;
2488 case SpvOpDPdxCoarse
: op
= nir_op_fddx_coarse
; break;
2489 case SpvOpDPdyCoarse
: op
= nir_op_fddy_coarse
; break;
2491 val
->ssa
->def
= nir_fadd(&b
->nb
,
2492 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[0])),
2493 nir_fabs(&b
->nb
, nir_fddx(&b
->nb
, src
[1])));
2495 case SpvOpFwidthFine
:
2496 val
->ssa
->def
= nir_fadd(&b
->nb
,
2497 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[0])),
2498 nir_fabs(&b
->nb
, nir_fddx_fine(&b
->nb
, src
[1])));
2500 case SpvOpFwidthCoarse
:
2501 val
->ssa
->def
= nir_fadd(&b
->nb
,
2502 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[0])),
2503 nir_fabs(&b
->nb
, nir_fddx_coarse(&b
->nb
, src
[1])));
2506 case SpvOpVectorTimesScalar
:
2507 /* The builder will take care of splatting for us. */
2508 val
->ssa
->def
= nir_fmul(&b
->nb
, src
[0], src
[1]);
2513 unreachable("No NIR equivalent");
2519 case SpvOpSignBitSet
:
2520 case SpvOpLessOrGreater
:
2522 case SpvOpUnordered
:
2524 unreachable("Unhandled opcode");
2528 nir_ssa_def
*tmp
= src
[0];
2533 nir_alu_instr
*instr
= nir_alu_instr_create(b
->shader
, op
);
2534 nir_ssa_dest_init(&instr
->instr
, &instr
->dest
.dest
,
2535 glsl_get_vector_elements(type
), val
->name
);
2536 instr
->dest
.write_mask
= (1 << glsl_get_vector_elements(type
)) - 1;
2537 val
->ssa
->def
= &instr
->dest
.dest
.ssa
;
2539 for (unsigned i
= 0; i
< nir_op_infos
[op
].num_inputs
; i
++)
2540 instr
->src
[i
].src
= nir_src_for_ssa(src
[i
]);
2542 nir_builder_instr_insert(&b
->nb
, &instr
->instr
);
2545 static nir_ssa_def
*
2546 vtn_vector_extract(struct vtn_builder
*b
, nir_ssa_def
*src
, unsigned index
)
2548 unsigned swiz
[4] = { index
};
2549 return nir_swizzle(&b
->nb
, src
, swiz
, 1, true);
2553 static nir_ssa_def
*
2554 vtn_vector_insert(struct vtn_builder
*b
, nir_ssa_def
*src
, nir_ssa_def
*insert
,
2557 nir_alu_instr
*vec
= create_vec(b
->shader
, src
->num_components
);
2559 for (unsigned i
= 0; i
< src
->num_components
; i
++) {
2561 vec
->src
[i
].src
= nir_src_for_ssa(insert
);
2563 vec
->src
[i
].src
= nir_src_for_ssa(src
);
2564 vec
->src
[i
].swizzle
[0] = i
;
2568 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2570 return &vec
->dest
.dest
.ssa
;
2573 static nir_ssa_def
*
2574 vtn_vector_extract_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
2577 nir_ssa_def
*dest
= vtn_vector_extract(b
, src
, 0);
2578 for (unsigned i
= 1; i
< src
->num_components
; i
++)
2579 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
2580 vtn_vector_extract(b
, src
, i
), dest
);
2585 static nir_ssa_def
*
2586 vtn_vector_insert_dynamic(struct vtn_builder
*b
, nir_ssa_def
*src
,
2587 nir_ssa_def
*insert
, nir_ssa_def
*index
)
2589 nir_ssa_def
*dest
= vtn_vector_insert(b
, src
, insert
, 0);
2590 for (unsigned i
= 1; i
< src
->num_components
; i
++)
2591 dest
= nir_bcsel(&b
->nb
, nir_ieq(&b
->nb
, index
, nir_imm_int(&b
->nb
, i
)),
2592 vtn_vector_insert(b
, src
, insert
, i
), dest
);
2597 static nir_ssa_def
*
2598 vtn_vector_shuffle(struct vtn_builder
*b
, unsigned num_components
,
2599 nir_ssa_def
*src0
, nir_ssa_def
*src1
,
2600 const uint32_t *indices
)
2602 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
2604 nir_ssa_undef_instr
*undef
= nir_ssa_undef_instr_create(b
->shader
, 1);
2605 nir_builder_instr_insert(&b
->nb
, &undef
->instr
);
2607 for (unsigned i
= 0; i
< num_components
; i
++) {
2608 uint32_t index
= indices
[i
];
2609 if (index
== 0xffffffff) {
2610 vec
->src
[i
].src
= nir_src_for_ssa(&undef
->def
);
2611 } else if (index
< src0
->num_components
) {
2612 vec
->src
[i
].src
= nir_src_for_ssa(src0
);
2613 vec
->src
[i
].swizzle
[0] = index
;
2615 vec
->src
[i
].src
= nir_src_for_ssa(src1
);
2616 vec
->src
[i
].swizzle
[0] = index
- src0
->num_components
;
2620 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2622 return &vec
->dest
.dest
.ssa
;
2626 * Concatentates a number of vectors/scalars together to produce a vector
2628 static nir_ssa_def
*
2629 vtn_vector_construct(struct vtn_builder
*b
, unsigned num_components
,
2630 unsigned num_srcs
, nir_ssa_def
**srcs
)
2632 nir_alu_instr
*vec
= create_vec(b
->shader
, num_components
);
2634 unsigned dest_idx
= 0;
2635 for (unsigned i
= 0; i
< num_srcs
; i
++) {
2636 nir_ssa_def
*src
= srcs
[i
];
2637 for (unsigned j
= 0; j
< src
->num_components
; j
++) {
2638 vec
->src
[dest_idx
].src
= nir_src_for_ssa(src
);
2639 vec
->src
[dest_idx
].swizzle
[0] = j
;
2644 nir_builder_instr_insert(&b
->nb
, &vec
->instr
);
2646 return &vec
->dest
.dest
.ssa
;
2649 static struct vtn_ssa_value
*
2650 vtn_composite_copy(void *mem_ctx
, struct vtn_ssa_value
*src
)
2652 struct vtn_ssa_value
*dest
= rzalloc(mem_ctx
, struct vtn_ssa_value
);
2653 dest
->type
= src
->type
;
2655 if (glsl_type_is_vector_or_scalar(src
->type
)) {
2656 dest
->def
= src
->def
;
2658 unsigned elems
= glsl_get_length(src
->type
);
2660 dest
->elems
= ralloc_array(mem_ctx
, struct vtn_ssa_value
*, elems
);
2661 for (unsigned i
= 0; i
< elems
; i
++)
2662 dest
->elems
[i
] = vtn_composite_copy(mem_ctx
, src
->elems
[i
]);
2668 static struct vtn_ssa_value
*
2669 vtn_composite_insert(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
2670 struct vtn_ssa_value
*insert
, const uint32_t *indices
,
2671 unsigned num_indices
)
2673 struct vtn_ssa_value
*dest
= vtn_composite_copy(b
, src
);
2675 struct vtn_ssa_value
*cur
= dest
;
2677 for (i
= 0; i
< num_indices
- 1; i
++) {
2678 cur
= cur
->elems
[indices
[i
]];
2681 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
2682 /* According to the SPIR-V spec, OpCompositeInsert may work down to
2683 * the component granularity. In that case, the last index will be
2684 * the index to insert the scalar into the vector.
2687 cur
->def
= vtn_vector_insert(b
, cur
->def
, insert
->def
, indices
[i
]);
2689 cur
->elems
[indices
[i
]] = insert
;
2695 static struct vtn_ssa_value
*
2696 vtn_composite_extract(struct vtn_builder
*b
, struct vtn_ssa_value
*src
,
2697 const uint32_t *indices
, unsigned num_indices
)
2699 struct vtn_ssa_value
*cur
= src
;
2700 for (unsigned i
= 0; i
< num_indices
; i
++) {
2701 if (glsl_type_is_vector_or_scalar(cur
->type
)) {
2702 assert(i
== num_indices
- 1);
2703 /* According to the SPIR-V spec, OpCompositeExtract may work down to
2704 * the component granularity. The last index will be the index of the
2705 * vector to extract.
2708 struct vtn_ssa_value
*ret
= rzalloc(b
, struct vtn_ssa_value
);
2709 ret
->type
= glsl_scalar_type(glsl_get_base_type(cur
->type
));
2710 ret
->def
= vtn_vector_extract(b
, cur
->def
, indices
[i
]);
2719 vtn_handle_composite(struct vtn_builder
*b
, SpvOp opcode
,
2720 const uint32_t *w
, unsigned count
)
2722 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2723 const struct glsl_type
*type
=
2724 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
2725 val
->ssa
= vtn_create_ssa_value(b
, type
);
2728 case SpvOpVectorExtractDynamic
:
2729 val
->ssa
->def
= vtn_vector_extract_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
2730 vtn_ssa_value(b
, w
[4])->def
);
2733 case SpvOpVectorInsertDynamic
:
2734 val
->ssa
->def
= vtn_vector_insert_dynamic(b
, vtn_ssa_value(b
, w
[3])->def
,
2735 vtn_ssa_value(b
, w
[4])->def
,
2736 vtn_ssa_value(b
, w
[5])->def
);
2739 case SpvOpVectorShuffle
:
2740 val
->ssa
->def
= vtn_vector_shuffle(b
, glsl_get_vector_elements(type
),
2741 vtn_ssa_value(b
, w
[3])->def
,
2742 vtn_ssa_value(b
, w
[4])->def
,
2746 case SpvOpCompositeConstruct
: {
2747 unsigned elems
= count
- 3;
2748 if (glsl_type_is_vector_or_scalar(type
)) {
2749 nir_ssa_def
*srcs
[4];
2750 for (unsigned i
= 0; i
< elems
; i
++)
2751 srcs
[i
] = vtn_ssa_value(b
, w
[3 + i
])->def
;
2753 vtn_vector_construct(b
, glsl_get_vector_elements(type
),
2756 val
->ssa
->elems
= ralloc_array(b
, struct vtn_ssa_value
*, elems
);
2757 for (unsigned i
= 0; i
< elems
; i
++)
2758 val
->ssa
->elems
[i
] = vtn_ssa_value(b
, w
[3 + i
]);
2762 case SpvOpCompositeExtract
:
2763 val
->ssa
= vtn_composite_extract(b
, vtn_ssa_value(b
, w
[3]),
2767 case SpvOpCompositeInsert
:
2768 val
->ssa
= vtn_composite_insert(b
, vtn_ssa_value(b
, w
[4]),
2769 vtn_ssa_value(b
, w
[3]),
2773 case SpvOpCopyObject
:
2774 val
->ssa
= vtn_composite_copy(b
, vtn_ssa_value(b
, w
[3]));
2778 unreachable("unknown composite operation");
2783 vtn_handle_barrier(struct vtn_builder
*b
, SpvOp opcode
,
2784 const uint32_t *w
, unsigned count
)
2786 nir_intrinsic_op intrinsic_op
;
2788 case SpvOpEmitVertex
:
2789 case SpvOpEmitStreamVertex
:
2790 intrinsic_op
= nir_intrinsic_emit_vertex
;
2792 case SpvOpEndPrimitive
:
2793 case SpvOpEndStreamPrimitive
:
2794 intrinsic_op
= nir_intrinsic_end_primitive
;
2796 case SpvOpMemoryBarrier
:
2797 intrinsic_op
= nir_intrinsic_memory_barrier
;
2799 case SpvOpControlBarrier
:
2801 unreachable("unknown barrier instruction");
2804 nir_intrinsic_instr
*intrin
=
2805 nir_intrinsic_instr_create(b
->shader
, intrinsic_op
);
2807 if (opcode
== SpvOpEmitStreamVertex
|| opcode
== SpvOpEndStreamPrimitive
)
2808 intrin
->const_index
[0] = w
[1];
2810 nir_builder_instr_insert(&b
->nb
, &intrin
->instr
);
2814 vtn_phi_node_init(struct vtn_builder
*b
, struct vtn_ssa_value
*val
)
2816 if (glsl_type_is_vector_or_scalar(val
->type
)) {
2817 nir_phi_instr
*phi
= nir_phi_instr_create(b
->shader
);
2818 nir_ssa_dest_init(&phi
->instr
, &phi
->dest
,
2819 glsl_get_vector_elements(val
->type
), NULL
);
2820 exec_list_make_empty(&phi
->srcs
);
2821 nir_builder_instr_insert(&b
->nb
, &phi
->instr
);
2822 val
->def
= &phi
->dest
.ssa
;
2824 unsigned elems
= glsl_get_length(val
->type
);
2825 for (unsigned i
= 0; i
< elems
; i
++)
2826 vtn_phi_node_init(b
, val
->elems
[i
]);
2830 static struct vtn_ssa_value
*
2831 vtn_phi_node_create(struct vtn_builder
*b
, const struct glsl_type
*type
)
2833 struct vtn_ssa_value
*val
= vtn_create_ssa_value(b
, type
);
2834 vtn_phi_node_init(b
, val
);
2839 vtn_handle_phi_first_pass(struct vtn_builder
*b
, const uint32_t *w
)
2841 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_ssa
);
2842 const struct glsl_type
*type
=
2843 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
2844 val
->ssa
= vtn_phi_node_create(b
, type
);
2848 vtn_phi_node_add_src(struct vtn_ssa_value
*phi
, const nir_block
*pred
,
2849 struct vtn_ssa_value
*val
)
2851 assert(phi
->type
== val
->type
);
2852 if (glsl_type_is_vector_or_scalar(phi
->type
)) {
2853 nir_phi_instr
*phi_instr
= nir_instr_as_phi(phi
->def
->parent_instr
);
2854 nir_phi_src
*src
= ralloc(phi_instr
, nir_phi_src
);
2855 src
->pred
= (nir_block
*) pred
;
2856 src
->src
= nir_src_for_ssa(val
->def
);
2857 exec_list_push_tail(&phi_instr
->srcs
, &src
->node
);
2859 unsigned elems
= glsl_get_length(phi
->type
);
2860 for (unsigned i
= 0; i
< elems
; i
++)
2861 vtn_phi_node_add_src(phi
->elems
[i
], pred
, val
->elems
[i
]);
2865 static struct vtn_ssa_value
*
2866 vtn_get_phi_node_src(struct vtn_builder
*b
, nir_block
*block
,
2867 const struct glsl_type
*type
, const uint32_t *w
,
2870 struct hash_entry
*entry
= _mesa_hash_table_search(b
->block_table
, block
);
2872 struct vtn_block
*spv_block
= entry
->data
;
2873 for (unsigned off
= 4; off
< count
; off
+= 2) {
2874 if (spv_block
== vtn_value(b
, w
[off
], vtn_value_type_block
)->block
) {
2875 return vtn_ssa_value(b
, w
[off
- 1]);
2880 b
->nb
.cursor
= nir_before_block(block
);
2881 struct vtn_ssa_value
*phi
= vtn_phi_node_create(b
, type
);
2883 struct set_entry
*entry2
;
2884 set_foreach(block
->predecessors
, entry2
) {
2885 nir_block
*pred
= (nir_block
*) entry2
->key
;
2886 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, type
, w
,
2888 vtn_phi_node_add_src(phi
, pred
, val
);
2895 vtn_handle_phi_second_pass(struct vtn_builder
*b
, SpvOp opcode
,
2896 const uint32_t *w
, unsigned count
)
2898 if (opcode
== SpvOpLabel
) {
2899 b
->block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
2903 if (opcode
!= SpvOpPhi
)
2906 struct vtn_ssa_value
*phi
= vtn_value(b
, w
[2], vtn_value_type_ssa
)->ssa
;
2908 struct set_entry
*entry
;
2909 set_foreach(b
->block
->block
->predecessors
, entry
) {
2910 nir_block
*pred
= (nir_block
*) entry
->key
;
2912 struct vtn_ssa_value
*val
= vtn_get_phi_node_src(b
, pred
, phi
->type
, w
,
2914 vtn_phi_node_add_src(phi
, pred
, val
);
2921 gl_primitive_from_spv_execution_mode(SpvExecutionMode mode
)
2924 case SpvExecutionModeInputPoints
:
2925 case SpvExecutionModeOutputPoints
:
2926 return 0; /* GL_POINTS */
2927 case SpvExecutionModeInputLines
:
2928 return 1; /* GL_LINES */
2929 case SpvExecutionModeInputLinesAdjacency
:
2930 return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
2931 case SpvExecutionModeInputTriangles
:
2932 return 4; /* GL_TRIANGLES */
2933 case SpvExecutionModeInputTrianglesAdjacency
:
2934 return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
2935 case SpvExecutionModeInputQuads
:
2936 return 7; /* GL_QUADS */
2937 case SpvExecutionModeInputIsolines
:
2938 return 0x8E7A; /* GL_ISOLINES */
2939 case SpvExecutionModeOutputLineStrip
:
2940 return 3; /* GL_LINE_STRIP */
2941 case SpvExecutionModeOutputTriangleStrip
:
2942 return 5; /* GL_TRIANGLE_STRIP */
2944 assert(!"Invalid primitive type");
2950 vertices_in_from_spv_execution_mode(SpvExecutionMode mode
)
2953 case SpvExecutionModeInputPoints
:
2955 case SpvExecutionModeInputLines
:
2957 case SpvExecutionModeInputLinesAdjacency
:
2959 case SpvExecutionModeInputTriangles
:
2961 case SpvExecutionModeInputTrianglesAdjacency
:
2964 assert(!"Invalid GS input mode");
2970 vtn_handle_preamble_instruction(struct vtn_builder
*b
, SpvOp opcode
,
2971 const uint32_t *w
, unsigned count
)
2975 case SpvOpSourceExtension
:
2976 case SpvOpExtension
:
2977 /* Unhandled, but these are for debug so that's ok. */
2980 case SpvOpCapability
:
2981 switch ((SpvCapability
)w
[1]) {
2982 case SpvCapabilityMatrix
:
2983 case SpvCapabilityShader
:
2984 /* All shaders support these */
2986 case SpvCapabilityGeometry
:
2987 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
2990 assert(!"Unsupported capability");
2994 case SpvOpExtInstImport
:
2995 vtn_handle_extension(b
, opcode
, w
, count
);
2998 case SpvOpMemoryModel
:
2999 assert(w
[1] == SpvAddressingModelLogical
);
3000 assert(w
[2] == SpvMemoryModelGLSL450
);
3003 case SpvOpEntryPoint
:
3004 assert(b
->entry_point
== NULL
);
3005 b
->entry_point
= &b
->values
[w
[2]];
3006 b
->execution_model
= w
[1];
3009 case SpvOpExecutionMode
:
3010 assert(b
->entry_point
== &b
->values
[w
[1]]);
3012 SpvExecutionMode mode
= w
[2];
3014 case SpvExecutionModeOriginUpperLeft
:
3015 case SpvExecutionModeOriginLowerLeft
:
3016 b
->origin_upper_left
= (mode
== SpvExecutionModeOriginUpperLeft
);
3019 case SpvExecutionModeEarlyFragmentTests
:
3020 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3021 b
->shader
->info
.fs
.early_fragment_tests
= true;
3024 case SpvExecutionModeInvocations
:
3025 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3026 b
->shader
->info
.gs
.invocations
= w
[3];
3029 case SpvExecutionModeDepthReplacing
:
3030 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3031 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_ANY
;
3033 case SpvExecutionModeDepthGreater
:
3034 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3035 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_GREATER
;
3037 case SpvExecutionModeDepthLess
:
3038 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3039 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_LESS
;
3041 case SpvExecutionModeDepthUnchanged
:
3042 assert(b
->shader
->stage
== MESA_SHADER_FRAGMENT
);
3043 b
->shader
->info
.fs
.depth_layout
= FRAG_DEPTH_LAYOUT_UNCHANGED
;
3046 case SpvExecutionModeLocalSize
:
3047 assert(b
->shader
->stage
== MESA_SHADER_COMPUTE
);
3048 b
->shader
->info
.cs
.local_size
[0] = w
[3];
3049 b
->shader
->info
.cs
.local_size
[1] = w
[4];
3050 b
->shader
->info
.cs
.local_size
[2] = w
[5];
3052 case SpvExecutionModeLocalSizeHint
:
3053 break; /* Nothing do do with this */
3055 case SpvExecutionModeOutputVertices
:
3056 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3057 b
->shader
->info
.gs
.vertices_out
= w
[3];
3060 case SpvExecutionModeInputPoints
:
3061 case SpvExecutionModeInputLines
:
3062 case SpvExecutionModeInputLinesAdjacency
:
3063 case SpvExecutionModeInputTriangles
:
3064 case SpvExecutionModeInputTrianglesAdjacency
:
3065 case SpvExecutionModeInputQuads
:
3066 case SpvExecutionModeInputIsolines
:
3067 if (b
->shader
->stage
== MESA_SHADER_GEOMETRY
) {
3068 b
->shader
->info
.gs
.vertices_in
=
3069 vertices_in_from_spv_execution_mode(mode
);
3071 assert(!"Tesselation shaders not yet supported");
3075 case SpvExecutionModeOutputPoints
:
3076 case SpvExecutionModeOutputLineStrip
:
3077 case SpvExecutionModeOutputTriangleStrip
:
3078 assert(b
->shader
->stage
== MESA_SHADER_GEOMETRY
);
3079 b
->shader
->info
.gs
.output_primitive
=
3080 gl_primitive_from_spv_execution_mode(mode
);
3083 case SpvExecutionModeSpacingEqual
:
3084 case SpvExecutionModeSpacingFractionalEven
:
3085 case SpvExecutionModeSpacingFractionalOdd
:
3086 case SpvExecutionModeVertexOrderCw
:
3087 case SpvExecutionModeVertexOrderCcw
:
3088 case SpvExecutionModePointMode
:
3089 assert(!"TODO: Add tessellation metadata");
3092 case SpvExecutionModePixelCenterInteger
:
3093 case SpvExecutionModeXfb
:
3094 assert(!"Unhandled execution mode");
3097 case SpvExecutionModeVecTypeHint
:
3098 case SpvExecutionModeContractionOff
:
3099 case SpvExecutionModeIndependentForwardProgress
:
3105 vtn_push_value(b
, w
[1], vtn_value_type_string
)->str
=
3106 vtn_string_literal(b
, &w
[2], count
- 2);
3110 b
->values
[w
[1]].name
= vtn_string_literal(b
, &w
[2], count
- 2);
3113 case SpvOpMemberName
:
3118 break; /* Ignored for now */
3120 case SpvOpDecorationGroup
:
3122 case SpvOpMemberDecorate
:
3123 case SpvOpGroupDecorate
:
3124 case SpvOpGroupMemberDecorate
:
3125 vtn_handle_decoration(b
, opcode
, w
, count
);
3131 case SpvOpTypeFloat
:
3132 case SpvOpTypeVector
:
3133 case SpvOpTypeMatrix
:
3134 case SpvOpTypeImage
:
3135 case SpvOpTypeSampler
:
3136 case SpvOpTypeSampledImage
:
3137 case SpvOpTypeArray
:
3138 case SpvOpTypeRuntimeArray
:
3139 case SpvOpTypeStruct
:
3140 case SpvOpTypeOpaque
:
3141 case SpvOpTypePointer
:
3142 case SpvOpTypeFunction
:
3143 case SpvOpTypeEvent
:
3144 case SpvOpTypeDeviceEvent
:
3145 case SpvOpTypeReserveId
:
3146 case SpvOpTypeQueue
:
3148 vtn_handle_type(b
, opcode
, w
, count
);
3151 case SpvOpConstantTrue
:
3152 case SpvOpConstantFalse
:
3154 case SpvOpConstantComposite
:
3155 case SpvOpConstantSampler
:
3156 case SpvOpSpecConstantTrue
:
3157 case SpvOpSpecConstantFalse
:
3158 case SpvOpSpecConstant
:
3159 case SpvOpSpecConstantComposite
:
3160 vtn_handle_constant(b
, opcode
, w
, count
);
3164 vtn_handle_variables(b
, opcode
, w
, count
);
3168 return false; /* End of preamble */
3175 vtn_handle_first_cfg_pass_instruction(struct vtn_builder
*b
, SpvOp opcode
,
3176 const uint32_t *w
, unsigned count
)
3179 case SpvOpFunction
: {
3180 assert(b
->func
== NULL
);
3181 b
->func
= rzalloc(b
, struct vtn_function
);
3183 const struct glsl_type
*result_type
=
3184 vtn_value(b
, w
[1], vtn_value_type_type
)->type
->type
;
3185 struct vtn_value
*val
= vtn_push_value(b
, w
[2], vtn_value_type_function
);
3186 const struct glsl_type
*func_type
=
3187 vtn_value(b
, w
[4], vtn_value_type_type
)->type
->type
;
3189 assert(glsl_get_function_return_type(func_type
) == result_type
);
3191 nir_function
*func
=
3192 nir_function_create(b
->shader
, ralloc_strdup(b
->shader
, val
->name
));
3194 nir_function_overload
*overload
= nir_function_overload_create(func
);
3195 overload
->num_params
= glsl_get_length(func_type
);
3196 overload
->params
= ralloc_array(overload
, nir_parameter
,
3197 overload
->num_params
);
3198 for (unsigned i
= 0; i
< overload
->num_params
; i
++) {
3199 const struct glsl_function_param
*param
=
3200 glsl_get_function_param(func_type
, i
);
3201 overload
->params
[i
].type
= param
->type
;
3204 overload
->params
[i
].param_type
= nir_parameter_inout
;
3206 overload
->params
[i
].param_type
= nir_parameter_in
;
3210 overload
->params
[i
].param_type
= nir_parameter_out
;
3212 assert(!"Parameter is neither in nor out");
3216 b
->func
->overload
= overload
;
3220 case SpvOpFunctionEnd
:
3225 case SpvOpFunctionParameter
:
3226 break; /* Does nothing */
3229 assert(b
->block
== NULL
);
3230 b
->block
= rzalloc(b
, struct vtn_block
);
3231 b
->block
->label
= w
;
3232 vtn_push_value(b
, w
[1], vtn_value_type_block
)->block
= b
->block
;
3234 if (b
->func
->start_block
== NULL
) {
3235 /* This is the first block encountered for this function. In this
3236 * case, we set the start block and add it to the list of
3237 * implemented functions that we'll walk later.
3239 b
->func
->start_block
= b
->block
;
3240 exec_list_push_tail(&b
->functions
, &b
->func
->node
);
3246 case SpvOpBranchConditional
:
3250 case SpvOpReturnValue
:
3251 case SpvOpUnreachable
:
3253 b
->block
->branch
= w
;
3257 case SpvOpSelectionMerge
:
3258 case SpvOpLoopMerge
:
3259 assert(b
->block
&& b
->block
->merge_op
== SpvOpNop
);
3260 b
->block
->merge_op
= opcode
;
3261 b
->block
->merge_block_id
= w
[1];
3265 /* Continue on as per normal */
3273 vtn_handle_body_instruction(struct vtn_builder
*b
, SpvOp opcode
,
3274 const uint32_t *w
, unsigned count
)
3278 struct vtn_block
*block
= vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
3279 assert(block
->block
== NULL
);
3281 block
->block
= nir_cursor_current_block(b
->nb
.cursor
);
3285 case SpvOpLoopMerge
:
3286 case SpvOpSelectionMerge
:
3287 /* This is handled by cfg pre-pass and walk_blocks */
3291 vtn_push_value(b
, w
[2], vtn_value_type_undef
);
3295 vtn_handle_extension(b
, opcode
, w
, count
);
3301 case SpvOpCopyMemory
:
3302 case SpvOpCopyMemorySized
:
3303 case SpvOpAccessChain
:
3304 case SpvOpInBoundsAccessChain
:
3305 case SpvOpArrayLength
:
3306 vtn_handle_variables(b
, opcode
, w
, count
);
3309 case SpvOpFunctionCall
:
3310 vtn_handle_function_call(b
, opcode
, w
, count
);
3313 case SpvOpImageSampleImplicitLod
:
3314 case SpvOpImageSampleExplicitLod
:
3315 case SpvOpImageSampleDrefImplicitLod
:
3316 case SpvOpImageSampleDrefExplicitLod
:
3317 case SpvOpImageSampleProjImplicitLod
:
3318 case SpvOpImageSampleProjExplicitLod
:
3319 case SpvOpImageSampleProjDrefImplicitLod
:
3320 case SpvOpImageSampleProjDrefExplicitLod
:
3321 case SpvOpImageFetch
:
3322 case SpvOpImageGather
:
3323 case SpvOpImageDrefGather
:
3324 case SpvOpImageQuerySizeLod
:
3325 case SpvOpImageQuerySize
:
3326 case SpvOpImageQueryLod
:
3327 case SpvOpImageQueryLevels
:
3328 case SpvOpImageQuerySamples
:
3329 vtn_handle_texture(b
, opcode
, w
, count
);
3332 case SpvOpImageRead
:
3333 case SpvOpImageWrite
:
3334 case SpvOpImageTexelPointer
:
3335 vtn_handle_image(b
, opcode
, w
, count
);
3338 case SpvOpAtomicExchange
:
3339 case SpvOpAtomicCompareExchange
:
3340 case SpvOpAtomicCompareExchangeWeak
:
3341 case SpvOpAtomicIIncrement
:
3342 case SpvOpAtomicIDecrement
:
3343 case SpvOpAtomicIAdd
:
3344 case SpvOpAtomicISub
:
3345 case SpvOpAtomicSMin
:
3346 case SpvOpAtomicUMin
:
3347 case SpvOpAtomicSMax
:
3348 case SpvOpAtomicUMax
:
3349 case SpvOpAtomicAnd
:
3351 case SpvOpAtomicXor
: {
3352 struct vtn_value
*pointer
= vtn_untyped_value(b
, w
[3]);
3353 if (pointer
->value_type
== vtn_value_type_image_pointer
) {
3354 vtn_handle_image(b
, opcode
, w
, count
);
3356 assert(!"Atomic buffers not yet implemented");
3365 case SpvOpConvertFToU
:
3366 case SpvOpConvertFToS
:
3367 case SpvOpConvertSToF
:
3368 case SpvOpConvertUToF
:
3372 case SpvOpConvertPtrToU
:
3373 case SpvOpConvertUToPtr
:
3374 case SpvOpPtrCastToGeneric
:
3375 case SpvOpGenericCastToPtr
:
3381 case SpvOpSignBitSet
:
3382 case SpvOpLessOrGreater
:
3384 case SpvOpUnordered
:
3399 case SpvOpVectorTimesScalar
:
3401 case SpvOpShiftRightLogical
:
3402 case SpvOpShiftRightArithmetic
:
3403 case SpvOpShiftLeftLogical
:
3404 case SpvOpLogicalOr
:
3405 case SpvOpLogicalEqual
:
3406 case SpvOpLogicalNotEqual
:
3407 case SpvOpLogicalAnd
:
3408 case SpvOpBitwiseOr
:
3409 case SpvOpBitwiseXor
:
3410 case SpvOpBitwiseAnd
:
3413 case SpvOpFOrdEqual
:
3414 case SpvOpFUnordEqual
:
3415 case SpvOpINotEqual
:
3416 case SpvOpFOrdNotEqual
:
3417 case SpvOpFUnordNotEqual
:
3418 case SpvOpULessThan
:
3419 case SpvOpSLessThan
:
3420 case SpvOpFOrdLessThan
:
3421 case SpvOpFUnordLessThan
:
3422 case SpvOpUGreaterThan
:
3423 case SpvOpSGreaterThan
:
3424 case SpvOpFOrdGreaterThan
:
3425 case SpvOpFUnordGreaterThan
:
3426 case SpvOpULessThanEqual
:
3427 case SpvOpSLessThanEqual
:
3428 case SpvOpFOrdLessThanEqual
:
3429 case SpvOpFUnordLessThanEqual
:
3430 case SpvOpUGreaterThanEqual
:
3431 case SpvOpSGreaterThanEqual
:
3432 case SpvOpFOrdGreaterThanEqual
:
3433 case SpvOpFUnordGreaterThanEqual
:
3439 case SpvOpFwidthFine
:
3440 case SpvOpDPdxCoarse
:
3441 case SpvOpDPdyCoarse
:
3442 case SpvOpFwidthCoarse
:
3443 vtn_handle_alu(b
, opcode
, w
, count
);
3446 case SpvOpTranspose
:
3447 case SpvOpOuterProduct
:
3448 case SpvOpMatrixTimesScalar
:
3449 case SpvOpVectorTimesMatrix
:
3450 case SpvOpMatrixTimesVector
:
3451 case SpvOpMatrixTimesMatrix
:
3452 vtn_handle_matrix_alu(b
, opcode
, w
, count
);
3455 case SpvOpVectorExtractDynamic
:
3456 case SpvOpVectorInsertDynamic
:
3457 case SpvOpVectorShuffle
:
3458 case SpvOpCompositeConstruct
:
3459 case SpvOpCompositeExtract
:
3460 case SpvOpCompositeInsert
:
3461 case SpvOpCopyObject
:
3462 vtn_handle_composite(b
, opcode
, w
, count
);
3466 vtn_handle_phi_first_pass(b
, w
);
3469 case SpvOpEmitVertex
:
3470 case SpvOpEndPrimitive
:
3471 case SpvOpEmitStreamVertex
:
3472 case SpvOpEndStreamPrimitive
:
3473 case SpvOpControlBarrier
:
3474 case SpvOpMemoryBarrier
:
3475 vtn_handle_barrier(b
, opcode
, w
, count
);
3479 unreachable("Unhandled opcode");
3486 vtn_walk_blocks(struct vtn_builder
*b
, struct vtn_block
*start
,
3487 struct vtn_block
*break_block
, struct vtn_block
*cont_block
,
3488 struct vtn_block
*end_block
)
3490 struct vtn_block
*block
= start
;
3491 while (block
!= end_block
) {
3492 if (block
->merge_op
== SpvOpLoopMerge
) {
3493 /* This is the jump into a loop. */
3494 struct vtn_block
*new_cont_block
= block
;
3495 struct vtn_block
*new_break_block
=
3496 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
3498 nir_loop
*loop
= nir_loop_create(b
->shader
);
3499 nir_cf_node_insert(b
->nb
.cursor
, &loop
->cf_node
);
3501 /* Reset the merge_op to prerevent infinite recursion */
3502 block
->merge_op
= SpvOpNop
;
3504 b
->nb
.cursor
= nir_after_cf_list(&loop
->body
);
3505 vtn_walk_blocks(b
, block
, new_break_block
, new_cont_block
, NULL
);
3507 b
->nb
.cursor
= nir_after_cf_node(&loop
->cf_node
);
3508 block
= new_break_block
;
3512 const uint32_t *w
= block
->branch
;
3513 SpvOp branch_op
= w
[0] & SpvOpCodeMask
;
3516 vtn_foreach_instruction(b
, block
->label
, block
->branch
,
3517 vtn_handle_body_instruction
);
3519 nir_block
*cur_block
= nir_cursor_current_block(b
->nb
.cursor
);
3520 assert(cur_block
== block
->block
);
3521 _mesa_hash_table_insert(b
->block_table
, cur_block
, block
);
3523 switch (branch_op
) {
3525 struct vtn_block
*branch_block
=
3526 vtn_value(b
, w
[1], vtn_value_type_block
)->block
;
3528 if (branch_block
== break_block
) {
3529 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3531 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
3534 } else if (branch_block
== cont_block
) {
3535 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3537 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
3540 } else if (branch_block
== end_block
) {
3541 /* We're branching to the merge block of an if, since for loops
3542 * and functions end_block == NULL, so we're done here.
3546 /* We're branching to another block, and according to the rules,
3547 * we can only branch to another block with one predecessor (so
3548 * we're the only one jumping to it) so we can just process it
3551 block
= branch_block
;
3556 case SpvOpBranchConditional
: {
3557 /* Gather up the branch blocks */
3558 struct vtn_block
*then_block
=
3559 vtn_value(b
, w
[2], vtn_value_type_block
)->block
;
3560 struct vtn_block
*else_block
=
3561 vtn_value(b
, w
[3], vtn_value_type_block
)->block
;
3563 nir_if
*if_stmt
= nir_if_create(b
->shader
);
3564 if_stmt
->condition
= nir_src_for_ssa(vtn_ssa_value(b
, w
[1])->def
);
3565 nir_cf_node_insert(b
->nb
.cursor
, &if_stmt
->cf_node
);
3567 if (then_block
== break_block
) {
3568 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3570 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
3573 } else if (else_block
== break_block
) {
3574 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3576 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
3579 } else if (then_block
== cont_block
) {
3580 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3582 nir_instr_insert_after_cf_list(&if_stmt
->then_list
,
3585 } else if (else_block
== cont_block
) {
3586 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3588 nir_instr_insert_after_cf_list(&if_stmt
->else_list
,
3592 /* According to the rules we're branching to two blocks that don't
3593 * have any other predecessors, so we can handle this as a
3596 assert(block
->merge_op
== SpvOpSelectionMerge
);
3597 struct vtn_block
*merge_block
=
3598 vtn_value(b
, block
->merge_block_id
, vtn_value_type_block
)->block
;
3600 b
->nb
.cursor
= nir_after_cf_list(&if_stmt
->then_list
);
3601 vtn_walk_blocks(b
, then_block
, break_block
, cont_block
, merge_block
);
3603 b
->nb
.cursor
= nir_after_cf_list(&if_stmt
->else_list
);
3604 vtn_walk_blocks(b
, else_block
, break_block
, cont_block
, merge_block
);
3606 b
->nb
.cursor
= nir_after_cf_node(&if_stmt
->cf_node
);
3607 block
= merge_block
;
3611 /* If we got here then we inserted a predicated break or continue
3612 * above and we need to handle the other case. We already set
3613 * `block` above to indicate what block to visit after the
3617 /* It's possible that the other branch is also a break/continue.
3618 * If it is, we handle that here.
3620 if (block
== break_block
) {
3621 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3623 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
3626 } else if (block
== cont_block
) {
3627 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3629 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
3634 /* If we got here then there was a predicated break/continue but
3635 * the other half of the if has stuff in it. `block` was already
3636 * set above so there is nothing left for us to do.
3642 nir_jump_instr
*jump
= nir_jump_instr_create(b
->shader
,
3644 nir_builder_instr_insert(&b
->nb
, &jump
->instr
);
3649 nir_intrinsic_instr
*discard
=
3650 nir_intrinsic_instr_create(b
->shader
, nir_intrinsic_discard
);
3651 nir_builder_instr_insert(&b
->nb
, &discard
->instr
);
3656 case SpvOpReturnValue
:
3657 case SpvOpUnreachable
:
3659 unreachable("Unhandled opcode");
3665 spirv_to_nir(const uint32_t *words
, size_t word_count
,
3666 gl_shader_stage stage
,
3667 const nir_shader_compiler_options
*options
)
3669 const uint32_t *word_end
= words
+ word_count
;
3671 /* Handle the SPIR-V header (first 4 dwords) */
3672 assert(word_count
> 5);
3674 assert(words
[0] == SpvMagicNumber
);
3675 assert(words
[1] == 99);
3676 /* words[2] == generator magic */
3677 unsigned value_id_bound
= words
[3];
3678 assert(words
[4] == 0);
3682 nir_shader
*shader
= nir_shader_create(NULL
, stage
, options
);
3684 /* Initialize the stn_builder object */
3685 struct vtn_builder
*b
= rzalloc(NULL
, struct vtn_builder
);
3687 b
->value_id_bound
= value_id_bound
;
3688 b
->values
= rzalloc_array(b
, struct vtn_value
, value_id_bound
);
3689 exec_list_make_empty(&b
->functions
);
3691 /* XXX: We shouldn't need these defaults */
3692 if (b
->shader
->stage
== MESA_SHADER_GEOMETRY
) {
3693 b
->shader
->info
.gs
.vertices_in
= 3;
3694 b
->shader
->info
.gs
.output_primitive
= 4; /* GL_TRIANGLES */
3697 /* Handle all the preamble instructions */
3698 words
= vtn_foreach_instruction(b
, words
, word_end
,
3699 vtn_handle_preamble_instruction
);
3701 /* Do a very quick CFG analysis pass */
3702 vtn_foreach_instruction(b
, words
, word_end
,
3703 vtn_handle_first_cfg_pass_instruction
);
3705 foreach_list_typed(struct vtn_function
, func
, node
, &b
->functions
) {
3706 b
->impl
= nir_function_impl_create(func
->overload
);
3707 b
->const_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
3708 _mesa_key_pointer_equal
);
3709 b
->block_table
= _mesa_hash_table_create(b
, _mesa_hash_pointer
,
3710 _mesa_key_pointer_equal
);
3711 nir_builder_init(&b
->nb
, b
->impl
);
3712 b
->nb
.cursor
= nir_after_cf_list(&b
->impl
->body
);
3713 vtn_walk_blocks(b
, func
->start_block
, NULL
, NULL
, NULL
);
3714 vtn_foreach_instruction(b
, func
->start_block
->label
, func
->end
,
3715 vtn_handle_phi_second_pass
);
3718 /* Because we can still have output reads in NIR, we need to lower
3719 * outputs to temporaries before we are truely finished.
3721 nir_lower_outputs_to_temporaries(shader
);