2 * Copyright 2018 Collabora Ltd.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include "nir_to_spirv.h"
25 #include "spirv_builder.h"
28 #include "pipe/p_state.h"
29 #include "util/u_memory.h"
32 struct spirv_builder builder
;
36 gl_shader_stage stage
;
37 SpvId inputs
[PIPE_MAX_SHADER_INPUTS
][4];
38 SpvId outputs
[PIPE_MAX_SHADER_OUTPUTS
][4];
42 SpvId samplers
[PIPE_MAX_SAMPLERS
];
44 SpvId entry_ifaces
[PIPE_MAX_SHADER_INPUTS
* 4 + PIPE_MAX_SHADER_OUTPUTS
* 4];
45 size_t num_entry_ifaces
;
52 get_bvec_type(struct ntv_context
*ctx
, int num_components
)
54 SpvId bool_type
= spirv_builder_type_bool(&ctx
->builder
);
55 if (num_components
> 1)
56 return spirv_builder_type_vector(&ctx
->builder
, bool_type
,
59 assert(num_components
== 1);
64 get_fvec_type(struct ntv_context
*ctx
, unsigned bit_size
, unsigned num_components
)
66 assert(bit_size
== 32); // only 32-bit floats supported so far
68 SpvId float_type
= spirv_builder_type_float(&ctx
->builder
, bit_size
);
69 if (num_components
> 1)
70 return spirv_builder_type_vector(&ctx
->builder
, float_type
,
73 assert(num_components
== 1);
78 get_dest_type(struct ntv_context
*ctx
, nir_dest
*dest
)
80 return get_fvec_type(ctx
, nir_dest_bit_size(*dest
),
81 nir_dest_num_components(*dest
));
85 get_glsl_basetype(struct ntv_context
*ctx
, enum glsl_base_type type
)
89 return spirv_builder_type_float(&ctx
->builder
, 32);
92 return spirv_builder_type_int(&ctx
->builder
, 32);
95 return spirv_builder_type_uint(&ctx
->builder
, 32);
96 /* TODO: handle more types */
99 unreachable("unknown GLSL type");
104 get_glsl_type(struct ntv_context
*ctx
, const struct glsl_type
*type
)
107 if (glsl_type_is_scalar(type
))
108 return get_glsl_basetype(ctx
, glsl_get_base_type(type
));
110 if (glsl_type_is_vector(type
))
111 return spirv_builder_type_vector(&ctx
->builder
,
112 get_glsl_basetype(ctx
, glsl_get_base_type(type
)),
113 glsl_get_vector_elements(type
));
115 unreachable("we shouldn't get here, I think...");
119 emit_input(struct ntv_context
*ctx
, struct nir_variable
*var
)
121 SpvId vec_type
= get_glsl_type(ctx
, var
->type
);
122 SpvId pointer_type
= spirv_builder_type_pointer(&ctx
->builder
,
123 SpvStorageClassInput
,
125 SpvId var_id
= spirv_builder_emit_var(&ctx
->builder
, pointer_type
,
126 SpvStorageClassInput
);
129 spirv_builder_emit_name(&ctx
->builder
, var_id
, var
->name
);
131 if (ctx
->stage
== MESA_SHADER_FRAGMENT
) {
132 switch (var
->data
.location
) {
133 case VARYING_SLOT_POS
:
134 spirv_builder_emit_builtin(&ctx
->builder
, var_id
, SpvBuiltInFragCoord
);
138 spirv_builder_emit_location(&ctx
->builder
, var_id
,
139 var
->data
.driver_location
);
143 spirv_builder_emit_location(&ctx
->builder
, var_id
,
144 var
->data
.driver_location
);
147 if (var
->data
.location_frac
)
148 spirv_builder_emit_component(&ctx
->builder
, var_id
,
149 var
->data
.location_frac
);
151 if (var
->data
.interpolation
== INTERP_MODE_FLAT
)
152 spirv_builder_emit_decoration(&ctx
->builder
, var_id
, SpvDecorationFlat
);
154 assert(var
->data
.driver_location
< PIPE_MAX_SHADER_INPUTS
);
155 assert(var
->data
.location_frac
< 4);
156 assert(ctx
->inputs
[var
->data
.driver_location
][var
->data
.location_frac
] == 0);
157 ctx
->inputs
[var
->data
.driver_location
][var
->data
.location_frac
] = var_id
;
159 assert(ctx
->num_entry_ifaces
< ARRAY_SIZE(ctx
->entry_ifaces
));
160 ctx
->entry_ifaces
[ctx
->num_entry_ifaces
++] = var_id
;
164 emit_output(struct ntv_context
*ctx
, struct nir_variable
*var
)
166 SpvId vec_type
= get_glsl_type(ctx
, var
->type
);
167 SpvId pointer_type
= spirv_builder_type_pointer(&ctx
->builder
,
168 SpvStorageClassOutput
,
170 SpvId var_id
= spirv_builder_emit_var(&ctx
->builder
, pointer_type
,
171 SpvStorageClassOutput
);
173 spirv_builder_emit_name(&ctx
->builder
, var_id
, var
->name
);
176 if (ctx
->stage
== MESA_SHADER_VERTEX
) {
177 switch (var
->data
.location
) {
178 case VARYING_SLOT_POS
:
179 spirv_builder_emit_builtin(&ctx
->builder
, var_id
, SpvBuiltInPosition
);
182 case VARYING_SLOT_PSIZ
:
183 spirv_builder_emit_builtin(&ctx
->builder
, var_id
, SpvBuiltInPointSize
);
187 spirv_builder_emit_location(&ctx
->builder
, var_id
,
188 var
->data
.driver_location
- 1);
190 } else if (ctx
->stage
== MESA_SHADER_FRAGMENT
) {
191 switch (var
->data
.location
) {
192 case FRAG_RESULT_DEPTH
:
193 spirv_builder_emit_builtin(&ctx
->builder
, var_id
, SpvBuiltInFragDepth
);
197 spirv_builder_emit_location(&ctx
->builder
, var_id
,
198 var
->data
.driver_location
);
202 if (var
->data
.location_frac
)
203 spirv_builder_emit_component(&ctx
->builder
, var_id
,
204 var
->data
.location_frac
);
206 assert(var
->data
.driver_location
< PIPE_MAX_SHADER_INPUTS
);
207 assert(var
->data
.location_frac
< 4);
208 assert(ctx
->outputs
[var
->data
.driver_location
][var
->data
.location_frac
] == 0);
209 ctx
->outputs
[var
->data
.driver_location
][var
->data
.location_frac
] = var_id
;
211 assert(ctx
->num_entry_ifaces
< ARRAY_SIZE(ctx
->entry_ifaces
));
212 ctx
->entry_ifaces
[ctx
->num_entry_ifaces
++] = var_id
;
216 type_to_dim(enum glsl_sampler_dim gdim
, bool *is_ms
)
220 case GLSL_SAMPLER_DIM_1D
:
222 case GLSL_SAMPLER_DIM_2D
:
224 case GLSL_SAMPLER_DIM_RECT
:
226 case GLSL_SAMPLER_DIM_CUBE
:
228 case GLSL_SAMPLER_DIM_3D
:
230 case GLSL_SAMPLER_DIM_MS
:
234 fprintf(stderr
, "unknown sampler type %d\n", gdim
);
241 emit_sampler(struct ntv_context
*ctx
, struct nir_variable
*var
)
244 SpvDim dimension
= type_to_dim(glsl_get_sampler_dim(var
->type
), &is_ms
);
245 SpvId float_type
= spirv_builder_type_float(&ctx
->builder
, 32);
246 SpvId image_type
= spirv_builder_type_image(&ctx
->builder
, float_type
,
247 dimension
, false, glsl_sampler_type_is_array(var
->type
), is_ms
, 1,
248 SpvImageFormatUnknown
);
250 SpvId sampled_type
= spirv_builder_type_sampled_image(&ctx
->builder
,
252 SpvId pointer_type
= spirv_builder_type_pointer(&ctx
->builder
,
253 SpvStorageClassUniformConstant
,
255 SpvId var_id
= spirv_builder_emit_var(&ctx
->builder
, pointer_type
,
256 SpvStorageClassUniformConstant
);
259 spirv_builder_emit_name(&ctx
->builder
, var_id
, var
->name
);
261 assert(ctx
->num_samplers
< ARRAY_SIZE(ctx
->samplers
));
262 ctx
->samplers
[ctx
->num_samplers
++] = var_id
;
264 spirv_builder_emit_descriptor_set(&ctx
->builder
, var_id
,
265 var
->data
.descriptor_set
);
266 spirv_builder_emit_binding(&ctx
->builder
, var_id
, var
->data
.binding
);
270 emit_ubo(struct ntv_context
*ctx
, struct nir_variable
*var
)
272 uint32_t size
= glsl_count_attribute_slots(var
->type
, false);
273 SpvId vec4_type
= get_fvec_type(ctx
, 32, 4);
274 SpvId array_length
= spirv_builder_const_uint(&ctx
->builder
, 32, size
);
275 SpvId array_type
= spirv_builder_type_array(&ctx
->builder
, vec4_type
,
277 spirv_builder_emit_array_stride(&ctx
->builder
, array_type
, 16);
279 // wrap UBO-array in a struct
280 SpvId struct_type
= spirv_builder_type_struct(&ctx
->builder
, &array_type
, 1);
282 char struct_name
[100];
283 snprintf(struct_name
, sizeof(struct_name
), "struct_%s", var
->name
);
284 spirv_builder_emit_name(&ctx
->builder
, struct_type
, struct_name
);
287 spirv_builder_emit_decoration(&ctx
->builder
, struct_type
,
289 spirv_builder_emit_member_offset(&ctx
->builder
, struct_type
, 0, 0);
292 SpvId pointer_type
= spirv_builder_type_pointer(&ctx
->builder
,
293 SpvStorageClassUniform
,
296 SpvId var_id
= spirv_builder_emit_var(&ctx
->builder
, pointer_type
,
297 SpvStorageClassUniform
);
299 spirv_builder_emit_name(&ctx
->builder
, var_id
, var
->name
);
301 assert(ctx
->num_ubos
< ARRAY_SIZE(ctx
->ubos
));
302 ctx
->ubos
[ctx
->num_ubos
++] = var_id
;
304 spirv_builder_emit_descriptor_set(&ctx
->builder
, var_id
,
305 var
->data
.descriptor_set
);
306 spirv_builder_emit_binding(&ctx
->builder
, var_id
, var
->data
.binding
);
310 emit_uniform(struct ntv_context
*ctx
, struct nir_variable
*var
)
312 if (glsl_type_is_sampler(var
->type
))
313 emit_sampler(ctx
, var
);
314 else if (var
->interface_type
)
319 get_src(struct ntv_context
*ctx
, nir_src
*src
)
322 assert(src
->ssa
->index
< ctx
->num_defs
);
323 assert(ctx
->defs
[src
->ssa
->index
] != 0);
324 return ctx
->defs
[src
->ssa
->index
];
328 get_alu_src(struct ntv_context
*ctx
, nir_alu_instr
*alu
, unsigned src
)
330 assert(!alu
->src
[src
].negate
);
331 assert(!alu
->src
[src
].abs
);
333 SpvId def
= get_src(ctx
, &alu
->src
[src
].src
);
335 unsigned used_channels
= 0;
336 bool need_swizzle
= false;
337 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++) {
338 if (!nir_alu_instr_channel_used(alu
, src
, i
))
343 if (alu
->src
[src
].swizzle
[i
] != i
)
346 assert(used_channels
!= 0);
348 unsigned live_channels
= nir_src_num_components(alu
->src
[src
].src
);
349 if (used_channels
!= live_channels
)
355 int bit_size
= nir_src_bit_size(alu
->src
[src
].src
);
357 if (used_channels
== 1) {
358 SpvId result_type
= spirv_builder_type_float(&ctx
->builder
, bit_size
);
359 uint32_t indices
[] = { alu
->src
[src
].swizzle
[0] };
360 return spirv_builder_emit_composite_extract(&ctx
->builder
, result_type
,
362 ARRAY_SIZE(indices
));
363 } else if (live_channels
== 1) {
364 SpvId type
= get_fvec_type(ctx
, bit_size
, used_channels
);
366 SpvId constituents
[NIR_MAX_VEC_COMPONENTS
];
367 for (unsigned i
= 0; i
< used_channels
; ++i
)
368 constituents
[i
] = def
;
370 return spirv_builder_emit_composite_construct(&ctx
->builder
, type
,
374 uint32_t components
[NIR_MAX_VEC_COMPONENTS
];
375 size_t num_components
= 0;
376 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++) {
377 if (!nir_alu_instr_channel_used(alu
, src
, i
))
380 components
[num_components
++] = alu
->src
[src
].swizzle
[i
];
383 SpvId vecType
= get_fvec_type(ctx
, bit_size
, used_channels
);
384 return spirv_builder_emit_vector_shuffle(&ctx
->builder
, vecType
,
385 def
, def
, components
, num_components
);
390 store_ssa_def(struct ntv_context
*ctx
, nir_ssa_def
*ssa
, SpvId result
)
393 assert(ssa
->index
< ctx
->num_defs
);
394 ctx
->defs
[ssa
->index
] = result
;
398 store_dest(struct ntv_context
*ctx
, nir_dest
*dest
, SpvId result
)
400 assert(dest
->is_ssa
);
401 store_ssa_def(ctx
, &dest
->ssa
, result
);
405 store_alu_result(struct ntv_context
*ctx
, nir_alu_dest
*dest
, SpvId result
)
407 assert(!dest
->saturate
);
408 return store_dest(ctx
, &dest
->dest
, result
);
412 emit_unop(struct ntv_context
*ctx
, SpvOp op
, SpvId type
, SpvId src
)
414 return spirv_builder_emit_unop(&ctx
->builder
, op
, type
, src
);
418 emit_binop(struct ntv_context
*ctx
, SpvOp op
, SpvId type
,
419 SpvId src0
, SpvId src1
)
421 return spirv_builder_emit_binop(&ctx
->builder
, op
, type
, src0
, src1
);
425 emit_triop(struct ntv_context
*ctx
, SpvOp op
, SpvId type
,
426 SpvId src0
, SpvId src1
, SpvId src2
)
428 return spirv_builder_emit_triop(&ctx
->builder
, op
, type
, src0
, src1
, src2
);
432 emit_builtin_unop(struct ntv_context
*ctx
, enum GLSLstd450 op
, SpvId type
,
435 SpvId args
[] = { src
};
436 return spirv_builder_emit_ext_inst(&ctx
->builder
, type
, ctx
->GLSL_std_450
,
437 op
, args
, ARRAY_SIZE(args
));
441 emit_builtin_binop(struct ntv_context
*ctx
, enum GLSLstd450 op
, SpvId type
,
442 SpvId src0
, SpvId src1
)
444 SpvId args
[] = { src0
, src1
};
445 return spirv_builder_emit_ext_inst(&ctx
->builder
, type
, ctx
->GLSL_std_450
,
446 op
, args
, ARRAY_SIZE(args
));
450 get_fvec_constant(struct ntv_context
*ctx
, int bit_size
, int num_components
,
453 assert(bit_size
== 32);
455 if (num_components
> 1) {
456 SpvId components
[num_components
];
457 for (int i
= 0; i
< num_components
; i
++)
458 components
[i
] = spirv_builder_const_float(&ctx
->builder
, bit_size
,
461 SpvId type
= get_fvec_type(ctx
, bit_size
, num_components
);
462 return spirv_builder_const_composite(&ctx
->builder
, type
, components
,
466 assert(num_components
== 1);
467 return spirv_builder_const_float(&ctx
->builder
, bit_size
, values
[0]);
471 emit_alu(struct ntv_context
*ctx
, nir_alu_instr
*alu
)
473 SpvId src
[nir_op_infos
[alu
->op
].num_inputs
];
474 for (unsigned i
= 0; i
< nir_op_infos
[alu
->op
].num_inputs
; i
++)
475 src
[i
] = get_alu_src(ctx
, alu
, i
);
477 SpvId dest_type
= get_dest_type(ctx
, &alu
->dest
.dest
);
482 assert(nir_op_infos
[alu
->op
].num_inputs
== 1);
486 #define UNOP(nir_op, spirv_op) \
488 assert(nir_op_infos[alu->op].num_inputs == 1); \
489 result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
492 #define BUILTIN_UNOP(nir_op, spirv_op) \
494 assert(nir_op_infos[alu->op].num_inputs == 1); \
495 result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
498 UNOP(nir_op_fneg
, SpvOpFNegate
)
499 UNOP(nir_op_fddx
, SpvOpDPdx
)
500 UNOP(nir_op_fddy
, SpvOpDPdy
)
502 BUILTIN_UNOP(nir_op_fabs
, GLSLstd450FAbs
)
503 BUILTIN_UNOP(nir_op_fsqrt
, GLSLstd450Sqrt
)
504 BUILTIN_UNOP(nir_op_frsq
, GLSLstd450InverseSqrt
)
505 BUILTIN_UNOP(nir_op_flog2
, GLSLstd450Log2
)
506 BUILTIN_UNOP(nir_op_fexp2
, GLSLstd450Exp2
)
507 BUILTIN_UNOP(nir_op_ffract
, GLSLstd450Fract
)
508 BUILTIN_UNOP(nir_op_ffloor
, GLSLstd450Floor
)
509 BUILTIN_UNOP(nir_op_fceil
, GLSLstd450Ceil
)
510 BUILTIN_UNOP(nir_op_ftrunc
, GLSLstd450Trunc
)
511 BUILTIN_UNOP(nir_op_fround_even
, GLSLstd450RoundEven
)
512 BUILTIN_UNOP(nir_op_fsign
, GLSLstd450FSign
)
513 BUILTIN_UNOP(nir_op_fsin
, GLSLstd450Sin
)
514 BUILTIN_UNOP(nir_op_fcos
, GLSLstd450Cos
)
517 assert(nir_op_infos
[alu
->op
].num_inputs
== 1);
518 float one
[4] = { 1, 1, 1, 1 };
520 src
[0] = get_fvec_constant(ctx
, nir_dest_bit_size(alu
->dest
.dest
),
521 nir_dest_num_components(alu
->dest
.dest
),
523 result
= emit_binop(ctx
, SpvOpFDiv
, dest_type
, src
[0], src
[1]);
530 #define BINOP(nir_op, spirv_op) \
532 assert(nir_op_infos[alu->op].num_inputs == 2); \
533 result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
536 #define BUILTIN_BINOP(nir_op, spirv_op) \
538 assert(nir_op_infos[alu->op].num_inputs == 2); \
539 result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
542 BINOP(nir_op_fadd
, SpvOpFAdd
)
543 BINOP(nir_op_fsub
, SpvOpFSub
)
544 BINOP(nir_op_fmul
, SpvOpFMul
)
545 BINOP(nir_op_flt
, SpvOpFUnordLessThan
)
546 BINOP(nir_op_fge
, SpvOpFUnordGreaterThanEqual
)
548 BUILTIN_BINOP(nir_op_fmin
, GLSLstd450FMin
)
549 BUILTIN_BINOP(nir_op_fmax
, GLSLstd450FMax
)
557 assert(nir_op_infos
[alu
->op
].num_inputs
== 2);
558 result
= emit_binop(ctx
, SpvOpDot
, dest_type
, src
[0], src
[1]);
565 assert(nir_op_infos
[alu
->op
].num_inputs
== 2);
566 int num_components
= nir_dest_num_components(alu
->dest
.dest
);
567 SpvId bool_type
= get_bvec_type(ctx
, num_components
);
569 SpvId zero
= spirv_builder_const_float(&ctx
->builder
, 32, 0.0f
);
570 SpvId one
= spirv_builder_const_float(&ctx
->builder
, 32, 1.0f
);
571 if (num_components
> 1) {
572 SpvId zero_comps
[num_components
], one_comps
[num_components
];
573 for (int i
= 0; i
< num_components
; i
++) {
574 zero_comps
[i
] = zero
;
578 zero
= spirv_builder_const_composite(&ctx
->builder
, dest_type
,
579 zero_comps
, num_components
);
580 one
= spirv_builder_const_composite(&ctx
->builder
, dest_type
,
581 one_comps
, num_components
);
586 case nir_op_seq
: op
= SpvOpFOrdEqual
; break;
587 case nir_op_sne
: op
= SpvOpFOrdNotEqual
; break;
588 case nir_op_slt
: op
= SpvOpFOrdLessThan
; break;
589 case nir_op_sge
: op
= SpvOpFOrdGreaterThanEqual
; break;
590 default: unreachable("unexpected op");
593 result
= emit_binop(ctx
, op
, bool_type
, src
[0], src
[1]);
594 result
= emit_triop(ctx
, SpvOpSelect
, dest_type
, result
, one
, zero
);
599 assert(nir_op_infos
[alu
->op
].num_inputs
== 3);
600 int num_components
= nir_dest_num_components(alu
->dest
.dest
);
601 SpvId bool_type
= get_bvec_type(ctx
, num_components
);
603 float zero
[4] = { 0, 0, 0, 0 };
604 SpvId cmp
= get_fvec_constant(ctx
, nir_src_bit_size(alu
->src
[0].src
),
605 num_components
, zero
);
607 result
= emit_binop(ctx
, SpvOpFOrdGreaterThan
, bool_type
, src
[0], cmp
);
608 result
= emit_triop(ctx
, SpvOpSelect
, dest_type
, result
, src
[1], src
[2]);
615 int num_inputs
= nir_op_infos
[alu
->op
].num_inputs
;
616 assert(2 <= num_inputs
&& num_inputs
<= 4);
617 result
= spirv_builder_emit_composite_construct(&ctx
->builder
, dest_type
,
623 fprintf(stderr
, "emit_alu: not implemented (%s)\n",
624 nir_op_infos
[alu
->op
].name
);
626 unreachable("unsupported opcode");
630 store_alu_result(ctx
, &alu
->dest
, result
);
634 emit_load_const(struct ntv_context
*ctx
, nir_load_const_instr
*load_const
)
636 float values
[NIR_MAX_VEC_COMPONENTS
];
637 for (int i
= 0; i
< load_const
->def
.num_components
; ++i
)
638 values
[i
] = load_const
->value
[i
].f32
;
640 SpvId constant
= get_fvec_constant(ctx
, load_const
->def
.bit_size
,
641 load_const
->def
.num_components
,
643 store_ssa_def(ctx
, &load_const
->def
, constant
);
647 emit_load_input(struct ntv_context
*ctx
, nir_intrinsic_instr
*intr
)
649 nir_const_value
*const_offset
= nir_src_as_const_value(intr
->src
[0]);
651 SpvId type
= get_dest_type(ctx
, &intr
->dest
);
653 int driver_location
= (int)nir_intrinsic_base(intr
) + const_offset
->u32
;
654 assert(driver_location
< PIPE_MAX_SHADER_INPUTS
);
655 int location_frac
= nir_intrinsic_component(intr
);
656 assert(location_frac
< 4);
658 SpvId ptr
= ctx
->inputs
[driver_location
][location_frac
];
661 store_dest(ctx
, &intr
->dest
, spirv_builder_emit_load(&ctx
->builder
, type
, ptr
));
663 unreachable("input-addressing not yet supported");
667 emit_load_ubo(struct ntv_context
*ctx
, nir_intrinsic_instr
*intr
)
669 nir_const_value
*const_block_index
= nir_src_as_const_value(intr
->src
[0]);
670 assert(const_block_index
); // no dynamic indexing for now
671 assert(const_block_index
->u32
== 0); // we only support the default UBO for now
673 nir_const_value
*const_offset
= nir_src_as_const_value(intr
->src
[1]);
675 SpvId vec4_type
= get_fvec_type(ctx
, 32, 4);
676 SpvId pointer_type
= spirv_builder_type_pointer(&ctx
->builder
,
677 SpvStorageClassUniform
,
680 unsigned idx
= const_offset
->u32
;
681 SpvId member
= spirv_builder_const_uint(&ctx
->builder
, 32, 0);
682 SpvId offset
= spirv_builder_const_uint(&ctx
->builder
, 32, idx
);
683 SpvId offsets
[] = { member
, offset
};
684 SpvId ptr
= spirv_builder_emit_access_chain(&ctx
->builder
, pointer_type
,
685 ctx
->ubos
[0], offsets
,
686 ARRAY_SIZE(offsets
));
687 SpvId result
= spirv_builder_emit_load(&ctx
->builder
, vec4_type
, ptr
);
689 SpvId type
= get_dest_type(ctx
, &intr
->dest
);
690 unsigned num_components
= nir_dest_num_components(intr
->dest
);
691 if (num_components
== 1) {
692 uint32_t components
[] = { 0 };
693 result
= spirv_builder_emit_composite_extract(&ctx
->builder
,
697 } else if (num_components
< 4) {
698 SpvId constituents
[num_components
];
699 SpvId float_type
= spirv_builder_type_float(&ctx
->builder
, 32);
700 for (uint32_t i
= 0; i
< num_components
; ++i
)
701 constituents
[i
] = spirv_builder_emit_composite_extract(&ctx
->builder
,
706 result
= spirv_builder_emit_composite_construct(&ctx
->builder
,
712 store_dest(ctx
, &intr
->dest
, result
);
714 unreachable("uniform-addressing not yet supported");
718 emit_store_output(struct ntv_context
*ctx
, nir_intrinsic_instr
*intr
)
720 nir_const_value
*const_offset
= nir_src_as_const_value(intr
->src
[1]);
722 int driver_location
= (int)nir_intrinsic_base(intr
) + const_offset
->u32
;
723 assert(driver_location
< PIPE_MAX_SHADER_OUTPUTS
);
724 int location_frac
= nir_intrinsic_component(intr
);
725 assert(location_frac
< 4);
727 SpvId ptr
= ctx
->outputs
[driver_location
][location_frac
];
730 SpvId src
= get_src(ctx
, &intr
->src
[0]);
731 spirv_builder_emit_store(&ctx
->builder
, ptr
, src
);
733 unreachable("output-addressing not yet supported");
737 emit_intrinsic(struct ntv_context
*ctx
, nir_intrinsic_instr
*intr
)
739 switch (intr
->intrinsic
) {
740 case nir_intrinsic_load_input
:
741 emit_load_input(ctx
, intr
);
744 case nir_intrinsic_load_ubo
:
745 emit_load_ubo(ctx
, intr
);
748 case nir_intrinsic_store_output
:
749 emit_store_output(ctx
, intr
);
753 fprintf(stderr
, "emit_intrinsic: not implemented (%s)\n",
754 nir_intrinsic_infos
[intr
->intrinsic
].name
);
755 unreachable("unsupported intrinsic");
760 emit_undef(struct ntv_context
*ctx
, nir_ssa_undef_instr
*undef
)
762 SpvId type
= get_fvec_type(ctx
, undef
->def
.bit_size
,
763 undef
->def
.num_components
);
765 store_ssa_def(ctx
, &undef
->def
,
766 spirv_builder_emit_undef(&ctx
->builder
, type
));
770 emit_tex(struct ntv_context
*ctx
, nir_tex_instr
*tex
)
772 assert(tex
->op
== nir_texop_tex
);
773 assert(nir_alu_type_get_base_type(tex
->dest_type
) == nir_type_float
);
774 assert(tex
->texture_index
== tex
->sampler_index
);
776 bool has_proj
= false;
777 SpvId coord
= 0, proj
;
779 for (unsigned i
= 0; i
< tex
->num_srcs
; i
++) {
780 switch (tex
->src
[i
].src_type
) {
781 case nir_tex_src_coord
:
782 coord
= get_src(ctx
, &tex
->src
[i
].src
);
783 coord_size
= nir_src_num_components(tex
->src
[i
].src
);
786 case nir_tex_src_projector
:
788 proj
= get_src(ctx
, &tex
->src
[i
].src
);
792 fprintf(stderr
, "texture source: %d\n", tex
->src
[i
].src_type
);
793 unreachable("unknown texture source");
798 SpvDim dimension
= type_to_dim(tex
->sampler_dim
, &is_ms
);
799 SpvId float_type
= spirv_builder_type_float(&ctx
->builder
, 32);
800 SpvId image_type
= spirv_builder_type_image(&ctx
->builder
, float_type
,
801 dimension
, false, tex
->is_array
, is_ms
, 1,
802 SpvImageFormatUnknown
);
803 SpvId sampled_type
= spirv_builder_type_sampled_image(&ctx
->builder
,
806 assert(tex
->texture_index
< ctx
->num_samplers
);
807 SpvId load
= spirv_builder_emit_load(&ctx
->builder
, sampled_type
,
808 ctx
->samplers
[tex
->texture_index
]);
810 SpvId dest_type
= get_dest_type(ctx
, &tex
->dest
);
814 SpvId constituents
[coord_size
+ 1];
815 SpvId float_type
= spirv_builder_type_float(&ctx
->builder
, 32);
816 for (uint32_t i
= 0; i
< coord_size
; ++i
)
817 constituents
[i
] = spirv_builder_emit_composite_extract(&ctx
->builder
,
822 constituents
[coord_size
++] = proj
;
824 SpvId vec_type
= get_fvec_type(ctx
, 32, coord_size
);
825 SpvId merged
= spirv_builder_emit_composite_construct(&ctx
->builder
,
830 result
= spirv_builder_emit_image_sample_proj_implicit_lod(&ctx
->builder
,
835 result
= spirv_builder_emit_image_sample_implicit_lod(&ctx
->builder
,
838 spirv_builder_emit_decoration(&ctx
->builder
, result
,
839 SpvDecorationRelaxedPrecision
);
841 store_dest(ctx
, &tex
->dest
, result
);
845 emit_block(struct ntv_context
*ctx
, struct nir_block
*block
)
847 nir_foreach_instr(instr
, block
) {
848 switch (instr
->type
) {
849 case nir_instr_type_alu
:
850 emit_alu(ctx
, nir_instr_as_alu(instr
));
852 case nir_instr_type_intrinsic
:
853 emit_intrinsic(ctx
, nir_instr_as_intrinsic(instr
));
855 case nir_instr_type_load_const
:
856 emit_load_const(ctx
, nir_instr_as_load_const(instr
));
858 case nir_instr_type_ssa_undef
:
859 emit_undef(ctx
, nir_instr_as_ssa_undef(instr
));
861 case nir_instr_type_tex
:
862 emit_tex(ctx
, nir_instr_as_tex(instr
));
864 case nir_instr_type_phi
:
865 unreachable("nir_instr_type_phi not supported");
867 case nir_instr_type_jump
:
868 unreachable("nir_instr_type_jump not supported");
870 case nir_instr_type_call
:
871 unreachable("nir_instr_type_call not supported");
873 case nir_instr_type_parallel_copy
:
874 unreachable("nir_instr_type_parallel_copy not supported");
876 case nir_instr_type_deref
:
877 unreachable("nir_instr_type_deref not supported");
884 emit_cf_list(struct ntv_context
*ctx
, struct exec_list
*list
)
886 foreach_list_typed(nir_cf_node
, node
, node
, list
) {
887 switch (node
->type
) {
888 case nir_cf_node_block
:
889 emit_block(ctx
, nir_cf_node_as_block(node
));
893 unreachable("nir_cf_node_if not supported");
896 case nir_cf_node_loop
:
897 unreachable("nir_cf_node_loop not supported");
900 case nir_cf_node_function
:
901 unreachable("nir_cf_node_function not supported");
907 struct spirv_shader
*
908 nir_to_spirv(struct nir_shader
*s
)
910 struct spirv_shader
*ret
= NULL
;
912 struct ntv_context ctx
= {};
914 switch (s
->info
.stage
) {
915 case MESA_SHADER_VERTEX
:
916 case MESA_SHADER_FRAGMENT
:
917 case MESA_SHADER_COMPUTE
:
918 spirv_builder_emit_cap(&ctx
.builder
, SpvCapabilityShader
);
921 case MESA_SHADER_TESS_CTRL
:
922 case MESA_SHADER_TESS_EVAL
:
923 spirv_builder_emit_cap(&ctx
.builder
, SpvCapabilityTessellation
);
926 case MESA_SHADER_GEOMETRY
:
927 spirv_builder_emit_cap(&ctx
.builder
, SpvCapabilityGeometry
);
931 unreachable("invalid stage");
934 ctx
.stage
= s
->info
.stage
;
935 ctx
.GLSL_std_450
= spirv_builder_import(&ctx
.builder
, "GLSL.std.450");
936 spirv_builder_emit_source(&ctx
.builder
, SpvSourceLanguageGLSL
, 450);
938 spirv_builder_emit_mem_model(&ctx
.builder
, SpvAddressingModelLogical
,
939 SpvMemoryModelGLSL450
);
941 SpvExecutionModel exec_model
;
942 switch (s
->info
.stage
) {
943 case MESA_SHADER_VERTEX
:
944 exec_model
= SpvExecutionModelVertex
;
946 case MESA_SHADER_TESS_CTRL
:
947 exec_model
= SpvExecutionModelTessellationControl
;
949 case MESA_SHADER_TESS_EVAL
:
950 exec_model
= SpvExecutionModelTessellationEvaluation
;
952 case MESA_SHADER_GEOMETRY
:
953 exec_model
= SpvExecutionModelGeometry
;
955 case MESA_SHADER_FRAGMENT
:
956 exec_model
= SpvExecutionModelFragment
;
958 case MESA_SHADER_COMPUTE
:
959 exec_model
= SpvExecutionModelGLCompute
;
962 unreachable("invalid stage");
965 SpvId type_void
= spirv_builder_type_void(&ctx
.builder
);
966 SpvId type_main
= spirv_builder_type_function(&ctx
.builder
, type_void
,
968 SpvId entry_point
= spirv_builder_new_id(&ctx
.builder
);
969 SpvId label
= spirv_builder_new_id(&ctx
.builder
);
970 spirv_builder_emit_name(&ctx
.builder
, entry_point
, "main");
972 nir_foreach_variable(var
, &s
->inputs
)
973 emit_input(&ctx
, var
);
975 nir_foreach_variable(var
, &s
->outputs
)
976 emit_output(&ctx
, var
);
978 nir_foreach_variable(var
, &s
->uniforms
)
979 emit_uniform(&ctx
, var
);
981 spirv_builder_emit_entry_point(&ctx
.builder
, exec_model
, entry_point
,
982 "main", ctx
.entry_ifaces
,
983 ctx
.num_entry_ifaces
);
984 if (s
->info
.stage
== MESA_SHADER_FRAGMENT
)
985 spirv_builder_emit_exec_mode(&ctx
.builder
, entry_point
,
986 SpvExecutionModeOriginUpperLeft
);
989 spirv_builder_function(&ctx
.builder
, entry_point
, type_void
,
990 SpvFunctionControlMaskNone
,
992 spirv_builder_label(&ctx
.builder
, label
);
994 nir_function_impl
*entry
= nir_shader_get_entrypoint(s
);
996 ctx
.defs
= (SpvId
*)malloc(sizeof(SpvId
) * entry
->ssa_alloc
);
999 ctx
.num_defs
= entry
->ssa_alloc
;
1001 emit_cf_list(&ctx
, &entry
->body
);
1004 spirv_builder_return(&ctx
.builder
); // doesn't belong here, but whatevz
1005 spirv_builder_function_end(&ctx
.builder
);
1007 size_t num_words
= spirv_builder_get_num_words(&ctx
.builder
);
1009 ret
= CALLOC_STRUCT(spirv_shader
);
1013 ret
->words
= MALLOC(sizeof(uint32_t) * num_words
);
1017 ret
->num_words
= spirv_builder_get_words(&ctx
.builder
, ret
->words
, num_words
);
1018 assert(ret
->num_words
== num_words
);
1025 spirv_shader_delete(ret
);
1031 spirv_shader_delete(struct spirv_shader
*s
)