1 /*
2 * Copyright 2018 Collabora Ltd.
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 */
23
24 #include "nir_to_spirv.h"
25 #include "spirv_builder.h"
26
27 #include "nir.h"
28 #include "pipe/p_state.h"
29 #include "util/u_math.h"
30 #include "util/u_memory.h"
31 #include "util/hash_table.h"
32
33 #define SLOT_UNSET ((unsigned char) -1)
34
35 struct ntv_context {
36 void *mem_ctx;
37
38 /* SPIR-V 1.4 and later requires entrypoints to list all global
39 * variables in the interface.
40 */
41 bool spirv_1_4_interfaces;
42
43 bool explicit_lod; //whether to set lod=0 for texture()
44
45 struct spirv_builder builder;
46 nir_shader *nir;
47
48 struct hash_table *glsl_types;
49 struct hash_table *bo_struct_types;
50 struct hash_table *bo_array_types;
51
52 SpvId GLSL_std_450;
53
54 gl_shader_stage stage;
55 const struct zink_shader_info *sinfo;
56
57 SpvId ubos[PIPE_MAX_CONSTANT_BUFFERS][5]; //8, 16, 32, unused, 64
58 nir_variable *ubo_vars[PIPE_MAX_CONSTANT_BUFFERS];
59
60 SpvId ssbos[5]; //8, 16, 32, unused, 64
61 nir_variable *ssbo_vars;
62
63 SpvId images[PIPE_MAX_SHADER_IMAGES];
64 struct hash_table image_types;
65 SpvId samplers[PIPE_MAX_SHADER_SAMPLER_VIEWS];
66 SpvId bindless_samplers[2];
67 SpvId cl_samplers[PIPE_MAX_SAMPLERS];
68 nir_variable *sampler_var[PIPE_MAX_SHADER_SAMPLER_VIEWS]; /* driver_location -> variable */
69 nir_variable *bindless_sampler_var[2];
70 unsigned last_sampler;
71 unsigned bindless_set_idx;
72 nir_variable *image_var[PIPE_MAX_SHADER_IMAGES]; /* driver_location -> variable */
73
74 SpvId entry_ifaces[PIPE_MAX_SHADER_INPUTS * 4 + PIPE_MAX_SHADER_OUTPUTS * 4];
75 size_t num_entry_ifaces;
76
77 SpvId *defs;
78 nir_alu_type *def_types;
79 SpvId *resident_defs;
80 size_t num_defs;
81
82 struct hash_table *vars; /* nir_variable -> SpvId */
83 unsigned outputs[VARYING_SLOT_MAX * 4];
84
85 const SpvId *block_ids;
86 size_t num_blocks;
87 bool block_started;
88 SpvId loop_break, loop_cont;
89
90 SpvId shared_block_var[5]; //8, 16, 32, unused, 64
91 SpvId shared_block_arr_type[5]; //8, 16, 32, unused, 64
92 SpvId scratch_block_var[5]; //8, 16, 32, unused, 64
93
94 SpvId front_face_var, instance_id_var, vertex_id_var,
95 primitive_id_var, invocation_id_var, // geometry
96 sample_mask_type, sample_id_var, sample_pos_var, sample_mask_in_var,
97 tess_patch_vertices_in, tess_coord_var, // tess
98 push_const_var, point_coord_var,
99 workgroup_id_var, num_workgroups_var,
100 local_invocation_id_var, global_invocation_id_var,
101 local_invocation_index_var, helper_invocation_var,
102 local_group_size_var,
103 base_vertex_var, base_instance_var, draw_id_var;
104
105 SpvId shared_mem_size;
106
107 SpvId subgroup_eq_mask_var,
108 subgroup_ge_mask_var,
109 subgroup_gt_mask_var,
110 subgroup_id_var,
111 subgroup_invocation_var,
112 subgroup_le_mask_var,
113 subgroup_lt_mask_var,
114 subgroup_size_var;
115
116 SpvId discard_func;
117 };
118
119 static SpvId
120 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
121 unsigned num_components, double value);
122
123 static SpvId
124 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
125 unsigned num_components, int64_t value);
126
127 static SpvId
128 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src);
129
130 static SpvId
131 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
132 SpvId src0, SpvId src1);
133
134 static SpvId
135 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
136 SpvId src0, SpvId src1, SpvId src2);
137
138 static bool
alu_op_is_typeless(nir_op op)139 alu_op_is_typeless(nir_op op)
140 {
141 switch (op) {
142 case nir_op_mov:
143 case nir_op_vec16:
144 case nir_op_vec2:
145 case nir_op_vec3:
146 case nir_op_vec4:
147 case nir_op_vec5:
148 case nir_op_vec8:
149 case nir_op_bcsel:
150 return true;
151 default:
152 break;
153 }
154 return false;
155 }
156
157 static nir_alu_type
get_nir_alu_type(const struct glsl_type * type)158 get_nir_alu_type(const struct glsl_type *type)
159 {
160 return nir_alu_type_get_base_type(nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(glsl_without_array_or_matrix(type))));
161 }
162
163 static nir_alu_type
164 infer_nir_alu_type_from_uses_ssa(nir_def *ssa);
165
166 static nir_alu_type
infer_nir_alu_type_from_use(nir_src * src)167 infer_nir_alu_type_from_use(nir_src *src)
168 {
169 nir_instr *instr = nir_src_parent_instr(src);
170 nir_alu_type atype = nir_type_invalid;
171 switch (instr->type) {
172 case nir_instr_type_alu: {
173 nir_alu_instr *alu = nir_instr_as_alu(instr);
174 if (alu->op == nir_op_bcsel) {
175 if (nir_srcs_equal(alu->src[0].src, *src)) {
176 /* special case: the first src in bcsel is always bool */
177 return nir_type_bool;
178 }
179 }
180 /* ignore typeless ops */
181 if (alu_op_is_typeless(alu->op)) {
182 atype = infer_nir_alu_type_from_uses_ssa(&alu->def);
183 break;
184 }
185 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++) {
186 if (!nir_srcs_equal(alu->src[i].src, *src))
187 continue;
188 atype = nir_op_infos[alu->op].input_types[i];
189 break;
190 }
191 break;
192 }
193 case nir_instr_type_tex: {
194 nir_tex_instr *tex = nir_instr_as_tex(instr);
195 for (unsigned i = 0; i < tex->num_srcs; i++) {
196 if (!nir_srcs_equal(tex->src[i].src, *src))
197 continue;
198 switch (tex->src[i].src_type) {
199 case nir_tex_src_coord:
200 case nir_tex_src_lod:
201 if (tex->op == nir_texop_txf ||
202 tex->op == nir_texop_txf_ms ||
203 tex->op == nir_texop_txs)
204 atype = nir_type_int;
205 else
206 atype = nir_type_float;
207 break;
208 case nir_tex_src_projector:
209 case nir_tex_src_bias:
210 case nir_tex_src_min_lod:
211 case nir_tex_src_comparator:
212 case nir_tex_src_ddx:
213 case nir_tex_src_ddy:
214 atype = nir_type_float;
215 break;
216 case nir_tex_src_offset:
217 case nir_tex_src_ms_index:
218 case nir_tex_src_texture_offset:
219 case nir_tex_src_sampler_offset:
220 case nir_tex_src_sampler_handle:
221 case nir_tex_src_texture_handle:
222 atype = nir_type_int;
223 break;
224 default:
225 break;
226 }
227 break;
228 }
229 break;
230 }
231 case nir_instr_type_intrinsic: {
232 if (nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_load_deref) {
233 atype = get_nir_alu_type(nir_instr_as_deref(instr)->type);
234 } else if (nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_store_deref) {
235 atype = get_nir_alu_type(nir_src_as_deref(nir_instr_as_intrinsic(instr)->src[0])->type);
236 }
237 break;
238 }
239 default:
240 break;
241 }
242 return nir_alu_type_get_base_type(atype);
243 }
244
245 static nir_alu_type
infer_nir_alu_type_from_uses_ssa(nir_def * ssa)246 infer_nir_alu_type_from_uses_ssa(nir_def *ssa)
247 {
248 nir_alu_type atype = nir_type_invalid;
249 /* try to infer a type: if it's wrong then whatever, but at least we tried */
250 nir_foreach_use_including_if(src, ssa) {
251 if (nir_src_is_if(src))
252 return nir_type_bool;
253 atype = infer_nir_alu_type_from_use(src);
254 if (atype)
255 break;
256 }
257 return atype ? atype : nir_type_uint;
258 }
259
260 static SpvId
get_bvec_type(struct ntv_context * ctx,int num_components)261 get_bvec_type(struct ntv_context *ctx, int num_components)
262 {
263 SpvId bool_type = spirv_builder_type_bool(&ctx->builder);
264 if (num_components > 1)
265 return spirv_builder_type_vector(&ctx->builder, bool_type,
266 num_components);
267
268 assert(num_components == 1);
269 return bool_type;
270 }
271
272 static SpvId
find_image_type(struct ntv_context * ctx,nir_variable * var)273 find_image_type(struct ntv_context *ctx, nir_variable *var)
274 {
275 struct hash_entry *he = _mesa_hash_table_search(&ctx->image_types, var);
276 return he ? (intptr_t)he->data : 0;
277 }
278
279 static SpvScope
get_scope(mesa_scope scope)280 get_scope(mesa_scope scope)
281 {
282 SpvScope conv[] = {
283 [SCOPE_NONE] = 0,
284 [SCOPE_INVOCATION] = SpvScopeInvocation,
285 [SCOPE_SUBGROUP] = SpvScopeSubgroup,
286 [SCOPE_SHADER_CALL] = SpvScopeShaderCallKHR,
287 [SCOPE_WORKGROUP] = SpvScopeWorkgroup,
288 [SCOPE_QUEUE_FAMILY] = SpvScopeQueueFamily,
289 [SCOPE_DEVICE] = SpvScopeDevice,
290 };
291 return conv[scope];
292 }
293
294 static SpvId
block_label(struct ntv_context * ctx,nir_block * block)295 block_label(struct ntv_context *ctx, nir_block *block)
296 {
297 assert(block->index < ctx->num_blocks);
298 return ctx->block_ids[block->index];
299 }
300
301 static void
emit_access_decorations(struct ntv_context * ctx,nir_variable * var,SpvId var_id)302 emit_access_decorations(struct ntv_context *ctx, nir_variable *var, SpvId var_id)
303 {
304 u_foreach_bit(bit, var->data.access) {
305 switch (1 << bit) {
306 case ACCESS_COHERENT:
307 /* SpvDecorationCoherent can't be used with vulkan memory model */
308 break;
309 case ACCESS_RESTRICT:
310 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationRestrict);
311 break;
312 case ACCESS_VOLATILE:
313 /* SpvDecorationVolatile can't be used with vulkan memory model */
314 break;
315 case ACCESS_NON_READABLE:
316 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonReadable);
317 break;
318 case ACCESS_NON_WRITEABLE:
319 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonWritable);
320 break;
321 case ACCESS_NON_UNIFORM:
322 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationNonUniform);
323 break;
324 case ACCESS_CAN_REORDER:
325 case ACCESS_NON_TEMPORAL:
326 /* no equivalent */
327 break;
328 default:
329 unreachable("unknown access bit");
330 }
331 }
332 /* The Simple, GLSL, and Vulkan memory models can assume that aliasing is generally
333 * not present between the memory object declarations. Specifically, the consumer
334 * is free to assume aliasing is not present between memory object declarations,
335 * unless the memory object declarations explicitly indicate they alias.
336 * ...
337 * Applying Restrict is allowed, but has no effect.
338 * ...
339 * Only those memory object declarations decorated with Aliased or AliasedPointer may alias each other.
340 *
341 * - SPIRV 2.18.2 Aliasing
342 *
343 * thus if the variable isn't marked restrict, assume it may alias
344 */
345 if (!(var->data.access & ACCESS_RESTRICT))
346 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationAliased);
347 }
348
349 static SpvOp
get_atomic_op(struct ntv_context * ctx,unsigned bit_size,nir_atomic_op op)350 get_atomic_op(struct ntv_context *ctx, unsigned bit_size, nir_atomic_op op)
351 {
352 switch (op) {
353 #define ATOMIC_FCAP(NAME) \
354 do {\
355 if (bit_size == 16) \
356 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityAtomicFloat16##NAME##EXT); \
357 if (bit_size == 32) \
358 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityAtomicFloat32##NAME##EXT); \
359 if (bit_size == 64) \
360 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityAtomicFloat64##NAME##EXT); \
361 } while (0)
362
363 case nir_atomic_op_fadd:
364 ATOMIC_FCAP(Add);
365 if (bit_size == 16)
366 spirv_builder_emit_extension(&ctx->builder, "SPV_EXT_shader_atomic_float16_add");
367 else
368 spirv_builder_emit_extension(&ctx->builder, "SPV_EXT_shader_atomic_float_add");
369 return SpvOpAtomicFAddEXT;
370 case nir_atomic_op_fmax:
371 ATOMIC_FCAP(MinMax);
372 spirv_builder_emit_extension(&ctx->builder, "SPV_EXT_shader_atomic_float_min_max");
373 return SpvOpAtomicFMaxEXT;
374 case nir_atomic_op_fmin:
375 ATOMIC_FCAP(MinMax);
376 spirv_builder_emit_extension(&ctx->builder, "SPV_EXT_shader_atomic_float_min_max");
377 return SpvOpAtomicFMinEXT;
378
379 case nir_atomic_op_iadd:
380 return SpvOpAtomicIAdd;
381 case nir_atomic_op_umin:
382 return SpvOpAtomicUMin;
383 case nir_atomic_op_imin:
384 return SpvOpAtomicSMin;
385 case nir_atomic_op_umax:
386 return SpvOpAtomicUMax;
387 case nir_atomic_op_imax:
388 return SpvOpAtomicSMax;
389 case nir_atomic_op_iand:
390 return SpvOpAtomicAnd;
391 case nir_atomic_op_ior:
392 return SpvOpAtomicOr;
393 case nir_atomic_op_ixor:
394 return SpvOpAtomicXor;
395 case nir_atomic_op_xchg:
396 return SpvOpAtomicExchange;
397 case nir_atomic_op_cmpxchg:
398 return SpvOpAtomicCompareExchange;
399 default:
400 debug_printf("%s - ", nir_intrinsic_infos[op].name);
401 unreachable("unhandled atomic op");
402 }
403 return 0;
404 }
405
406 static SpvId
emit_float_const(struct ntv_context * ctx,int bit_size,double value)407 emit_float_const(struct ntv_context *ctx, int bit_size, double value)
408 {
409 assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
410 return spirv_builder_const_float(&ctx->builder, bit_size, value);
411 }
412
413 static SpvId
emit_uint_const(struct ntv_context * ctx,int bit_size,uint64_t value)414 emit_uint_const(struct ntv_context *ctx, int bit_size, uint64_t value)
415 {
416 assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
417 return spirv_builder_const_uint(&ctx->builder, bit_size, value);
418 }
419
420 static SpvId
emit_int_const(struct ntv_context * ctx,int bit_size,int64_t value)421 emit_int_const(struct ntv_context *ctx, int bit_size, int64_t value)
422 {
423 assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
424 return spirv_builder_const_int(&ctx->builder, bit_size, value);
425 }
426
427 static SpvId
get_fvec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)428 get_fvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
429 {
430 assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
431
432 SpvId float_type = spirv_builder_type_float(&ctx->builder, bit_size);
433 if (num_components > 1)
434 return spirv_builder_type_vector(&ctx->builder, float_type,
435 num_components);
436
437 assert(num_components == 1);
438 return float_type;
439 }
440
441 static SpvId
get_ivec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)442 get_ivec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
443 {
444 assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
445
446 SpvId int_type = spirv_builder_type_int(&ctx->builder, bit_size);
447 if (num_components > 1)
448 return spirv_builder_type_vector(&ctx->builder, int_type,
449 num_components);
450
451 assert(num_components == 1);
452 return int_type;
453 }
454
455 static SpvId
get_uvec_type(struct ntv_context * ctx,unsigned bit_size,unsigned num_components)456 get_uvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
457 {
458 assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
459
460 SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bit_size);
461 if (num_components > 1)
462 return spirv_builder_type_vector(&ctx->builder, uint_type,
463 num_components);
464
465 assert(num_components == 1);
466 return uint_type;
467 }
468
469 static SpvId
get_alu_type(struct ntv_context * ctx,nir_alu_type type,unsigned num_components,unsigned bit_size)470 get_alu_type(struct ntv_context *ctx, nir_alu_type type, unsigned num_components, unsigned bit_size)
471 {
472 if (bit_size == 1)
473 return get_bvec_type(ctx, num_components);
474
475 type = nir_alu_type_get_base_type(type);
476 switch (nir_alu_type_get_base_type(type)) {
477 case nir_type_bool:
478 return get_bvec_type(ctx, num_components);
479
480 case nir_type_int:
481 return get_ivec_type(ctx, bit_size, num_components);
482
483 case nir_type_uint:
484 return get_uvec_type(ctx, bit_size, num_components);
485
486 case nir_type_float:
487 return get_fvec_type(ctx, bit_size, num_components);
488
489 default:
490 unreachable("unsupported nir_alu_type");
491 }
492 }
493
494 static SpvStorageClass
get_storage_class(struct nir_variable * var)495 get_storage_class(struct nir_variable *var)
496 {
497 switch (var->data.mode) {
498 case nir_var_function_temp:
499 return SpvStorageClassFunction;
500 case nir_var_mem_push_const:
501 return SpvStorageClassPushConstant;
502 case nir_var_shader_in:
503 return SpvStorageClassInput;
504 case nir_var_shader_out:
505 return SpvStorageClassOutput;
506 case nir_var_uniform:
507 case nir_var_image:
508 return SpvStorageClassUniformConstant;
509 case nir_var_mem_ubo:
510 return SpvStorageClassUniform;
511 case nir_var_mem_ssbo:
512 return SpvStorageClassStorageBuffer;
513 default:
514 unreachable("Unsupported nir_variable_mode");
515 }
516 return 0;
517 }
518
519 static SpvId
get_def_uvec_type(struct ntv_context * ctx,nir_def * def)520 get_def_uvec_type(struct ntv_context *ctx, nir_def *def)
521 {
522 unsigned bit_size = def->bit_size;
523 return get_uvec_type(ctx, bit_size, def->num_components);
524 }
525
526 static SpvId
get_glsl_basetype(struct ntv_context * ctx,enum glsl_base_type type)527 get_glsl_basetype(struct ntv_context *ctx, enum glsl_base_type type)
528 {
529 switch (type) {
530 case GLSL_TYPE_BOOL:
531 return spirv_builder_type_bool(&ctx->builder);
532
533 case GLSL_TYPE_FLOAT16:
534 return spirv_builder_type_float(&ctx->builder, 16);
535
536 case GLSL_TYPE_FLOAT:
537 return spirv_builder_type_float(&ctx->builder, 32);
538
539 case GLSL_TYPE_INT:
540 return spirv_builder_type_int(&ctx->builder, 32);
541
542 case GLSL_TYPE_UINT:
543 return spirv_builder_type_uint(&ctx->builder, 32);
544
545 case GLSL_TYPE_DOUBLE:
546 return spirv_builder_type_float(&ctx->builder, 64);
547
548 case GLSL_TYPE_INT64:
549 return spirv_builder_type_int(&ctx->builder, 64);
550
551 case GLSL_TYPE_UINT64:
552 return spirv_builder_type_uint(&ctx->builder, 64);
553
554 case GLSL_TYPE_UINT16:
555 return spirv_builder_type_uint(&ctx->builder, 16);
556 case GLSL_TYPE_INT16:
557 return spirv_builder_type_int(&ctx->builder, 16);
558 case GLSL_TYPE_INT8:
559 return spirv_builder_type_int(&ctx->builder, 8);
560 case GLSL_TYPE_UINT8:
561 return spirv_builder_type_uint(&ctx->builder, 8);
562
563 default:
564 unreachable("unknown GLSL type");
565 }
566 }
567
568 static SpvId
get_glsl_type(struct ntv_context * ctx,const struct glsl_type * type)569 get_glsl_type(struct ntv_context *ctx, const struct glsl_type *type)
570 {
571 assert(type);
572 if (glsl_type_is_scalar(type))
573 return get_glsl_basetype(ctx, glsl_get_base_type(type));
574
575 if (glsl_type_is_vector(type))
576 return spirv_builder_type_vector(&ctx->builder,
577 get_glsl_basetype(ctx, glsl_get_base_type(type)),
578 glsl_get_vector_elements(type));
579
580 if (glsl_type_is_matrix(type))
581 return spirv_builder_type_matrix(&ctx->builder,
582 spirv_builder_type_vector(&ctx->builder,
583 get_glsl_basetype(ctx, glsl_get_base_type(type)),
584 glsl_get_vector_elements(type)),
585 glsl_get_matrix_columns(type));
586
587 /* Aggregate types aren't cached in spirv_builder, so let's cache
588 * them here instead.
589 */
590
591 struct hash_entry *entry =
592 _mesa_hash_table_search(ctx->glsl_types, type);
593 if (entry)
594 return (SpvId)(uintptr_t)entry->data;
595
596 SpvId ret;
597 if (glsl_type_is_array(type)) {
598 SpvId element_type = get_glsl_type(ctx, glsl_get_array_element(type));
599 if (glsl_type_is_unsized_array(type))
600 ret = spirv_builder_type_runtime_array(&ctx->builder, element_type);
601 else
602 ret = spirv_builder_type_array(&ctx->builder,
603 element_type,
604 emit_uint_const(ctx, 32, glsl_get_length(type)));
605 uint32_t stride = glsl_get_explicit_stride(type);
606 if (!stride && glsl_type_is_scalar(glsl_get_array_element(type))) {
607 stride = MAX2(glsl_get_bit_size(glsl_get_array_element(type)) / 8, 1);
608 }
609 if (stride)
610 spirv_builder_emit_array_stride(&ctx->builder, ret, stride);
611 } else if (glsl_type_is_struct_or_ifc(type)) {
612 const unsigned length = glsl_get_length(type);
613
614 /* allocate some SpvId on the stack, falling back to the heap if the array is too long */
615 SpvId *types, types_stack[16];
616
617 if (length <= ARRAY_SIZE(types_stack)) {
618 types = types_stack;
619 } else {
620 types = ralloc_array_size(ctx->mem_ctx, sizeof(SpvId), length);
621 assert(types != NULL);
622 }
623
624 for (unsigned i = 0; i < glsl_get_length(type); i++)
625 types[i] = get_glsl_type(ctx, glsl_get_struct_field(type, i));
626 ret = spirv_builder_type_struct(&ctx->builder, types,
627 glsl_get_length(type));
628 for (unsigned i = 0; i < glsl_get_length(type); i++) {
629 int32_t offset = glsl_get_struct_field_offset(type, i);
630 if (offset >= 0)
631 spirv_builder_emit_member_offset(&ctx->builder, ret, i, offset);
632 }
633 } else
634 unreachable("Unhandled GLSL type");
635
636 _mesa_hash_table_insert(ctx->glsl_types, type, (void *)(uintptr_t)ret);
637 return ret;
638 }
639
640 static void
create_scratch_block(struct ntv_context * ctx,unsigned scratch_size,unsigned bit_size)641 create_scratch_block(struct ntv_context *ctx, unsigned scratch_size, unsigned bit_size)
642 {
643 unsigned idx = bit_size >> 4;
644 SpvId type = spirv_builder_type_uint(&ctx->builder, bit_size);
645 unsigned block_size = scratch_size / (bit_size / 8);
646 assert(block_size);
647 SpvId array = spirv_builder_type_array(&ctx->builder, type, emit_uint_const(ctx, 32, block_size));
648 spirv_builder_emit_array_stride(&ctx->builder, array, bit_size / 8);
649 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
650 SpvStorageClassPrivate,
651 array);
652 ctx->scratch_block_var[idx] = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassPrivate);
653 if (ctx->spirv_1_4_interfaces) {
654 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
655 ctx->entry_ifaces[ctx->num_entry_ifaces++] = ctx->scratch_block_var[idx];
656 }
657 }
658
659 static SpvId
get_scratch_block(struct ntv_context * ctx,unsigned bit_size)660 get_scratch_block(struct ntv_context *ctx, unsigned bit_size)
661 {
662 unsigned idx = bit_size >> 4;
663 if (!ctx->scratch_block_var[idx])
664 create_scratch_block(ctx, ctx->nir->scratch_size, bit_size);
665 return ctx->scratch_block_var[idx];
666 }
667
668 static void
create_shared_block(struct ntv_context * ctx,unsigned bit_size)669 create_shared_block(struct ntv_context *ctx, unsigned bit_size)
670 {
671 unsigned idx = bit_size >> 4;
672 SpvId type = spirv_builder_type_uint(&ctx->builder, bit_size);
673 SpvId array;
674
675 assert(gl_shader_stage_is_compute(ctx->nir->info.stage));
676 if (ctx->nir->info.cs.has_variable_shared_mem) {
677 assert(ctx->shared_mem_size);
678 SpvId const_shared_size = emit_uint_const(ctx, 32, ctx->nir->info.shared_size);
679 SpvId shared_mem_size = spirv_builder_emit_triop(&ctx->builder, SpvOpSpecConstantOp, spirv_builder_type_uint(&ctx->builder, 32), SpvOpIAdd, const_shared_size, ctx->shared_mem_size);
680 shared_mem_size = spirv_builder_emit_triop(&ctx->builder, SpvOpSpecConstantOp, spirv_builder_type_uint(&ctx->builder, 32), SpvOpUDiv, shared_mem_size, emit_uint_const(ctx, 32, bit_size / 8));
681 array = spirv_builder_type_array(&ctx->builder, type, shared_mem_size);
682 } else {
683 unsigned block_size = ctx->nir->info.shared_size / (bit_size / 8);
684 assert(block_size);
685 array = spirv_builder_type_array(&ctx->builder, type, emit_uint_const(ctx, 32, block_size));
686 }
687
688 ctx->shared_block_arr_type[idx] = array;
689 spirv_builder_emit_array_stride(&ctx->builder, array, bit_size / 8);
690
691 /* Create wrapper struct for Block, Offset and Aliased decorations. */
692 SpvId block = spirv_builder_type_struct(&ctx->builder, &array, 1);
693
694 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
695 SpvStorageClassWorkgroup,
696 block);
697 ctx->shared_block_var[idx] = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassWorkgroup);
698 if (ctx->spirv_1_4_interfaces) {
699 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
700 ctx->entry_ifaces[ctx->num_entry_ifaces++] = ctx->shared_block_var[idx];
701 }
702 /* Alias our shared memory blocks */
703 if (ctx->sinfo->have_workgroup_memory_explicit_layout) {
704 spirv_builder_emit_member_offset(&ctx->builder, block, 0, 0);
705 spirv_builder_emit_decoration(&ctx->builder, block, SpvDecorationBlock);
706 spirv_builder_emit_decoration(&ctx->builder, ctx->shared_block_var[idx], SpvDecorationAliased);
707 }
708 }
709
710 static SpvId
get_shared_block(struct ntv_context * ctx,unsigned bit_size)711 get_shared_block(struct ntv_context *ctx, unsigned bit_size)
712 {
713 unsigned idx = bit_size >> 4;
714 if (!ctx->shared_block_var[idx])
715 create_shared_block(ctx, bit_size);
716 if (ctx->sinfo->have_workgroup_memory_explicit_layout) {
717 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_workgroup_memory_explicit_layout");
718 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityWorkgroupMemoryExplicitLayoutKHR);
719 if (ctx->shared_block_var[0])
720 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
721 if (ctx->shared_block_var[1])
722 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
723 }
724
725 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
726 SpvStorageClassWorkgroup,
727 ctx->shared_block_arr_type[idx]);
728 SpvId zero = emit_uint_const(ctx, 32, 0);
729
730 return spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
731 ctx->shared_block_var[idx], &zero, 1);
732 }
733
734 #define HANDLE_EMIT_BUILTIN(SLOT, BUILTIN) \
735 case VARYING_SLOT_##SLOT: \
736 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltIn##BUILTIN); \
737 break
738
739
740 static SpvId
input_var_init(struct ntv_context * ctx,struct nir_variable * var)741 input_var_init(struct ntv_context *ctx, struct nir_variable *var)
742 {
743 SpvId var_type = get_glsl_type(ctx, var->type);
744 SpvStorageClass sc = get_storage_class(var);
745 if (sc == SpvStorageClassPushConstant)
746 spirv_builder_emit_decoration(&ctx->builder, var_type, SpvDecorationBlock);
747 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
748 sc, var_type);
749 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type, sc);
750
751 if (var->name)
752 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
753
754 if (var->data.mode == nir_var_mem_push_const) {
755 ctx->push_const_var = var_id;
756
757 if (ctx->spirv_1_4_interfaces) {
758 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
759 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
760 }
761 }
762 return var_id;
763 }
764
765 static void
emit_interpolation(struct ntv_context * ctx,SpvId var_id,enum glsl_interp_mode mode)766 emit_interpolation(struct ntv_context *ctx, SpvId var_id,
767 enum glsl_interp_mode mode)
768 {
769 switch (mode) {
770 case INTERP_MODE_NONE:
771 case INTERP_MODE_SMOOTH:
772 /* XXX spirv doesn't seem to have anything for this */
773 break;
774 case INTERP_MODE_FLAT:
775 spirv_builder_emit_decoration(&ctx->builder, var_id,
776 SpvDecorationFlat);
777 break;
778 case INTERP_MODE_EXPLICIT:
779 spirv_builder_emit_decoration(&ctx->builder, var_id,
780 SpvDecorationExplicitInterpAMD);
781 break;
782 case INTERP_MODE_NOPERSPECTIVE:
783 spirv_builder_emit_decoration(&ctx->builder, var_id,
784 SpvDecorationNoPerspective);
785 break;
786 default:
787 unreachable("unknown interpolation value");
788 }
789 }
790
791 static void
emit_input(struct ntv_context * ctx,struct nir_variable * var)792 emit_input(struct ntv_context *ctx, struct nir_variable *var)
793 {
794 SpvId var_id = input_var_init(ctx, var);
795 if (ctx->stage == MESA_SHADER_VERTEX)
796 spirv_builder_emit_location(&ctx->builder, var_id,
797 var->data.driver_location);
798 else if (ctx->stage == MESA_SHADER_FRAGMENT) {
799 switch (var->data.location) {
800 HANDLE_EMIT_BUILTIN(POS, FragCoord);
801 HANDLE_EMIT_BUILTIN(LAYER, Layer);
802 HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
803 HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
804 HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
805 HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
806 HANDLE_EMIT_BUILTIN(FACE, FrontFacing);
807
808 default:
809 spirv_builder_emit_location(&ctx->builder, var_id,
810 var->data.driver_location);
811 }
812 if (var->data.centroid)
813 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationCentroid);
814 else if (var->data.sample)
815 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationSample);
816 emit_interpolation(ctx, var_id, var->data.interpolation);
817 } else if (ctx->stage < MESA_SHADER_FRAGMENT) {
818 switch (var->data.location) {
819 HANDLE_EMIT_BUILTIN(POS, Position);
820 HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
821 HANDLE_EMIT_BUILTIN(LAYER, Layer);
822 HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
823 HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
824 HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
825 HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
826 HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
827
828 case VARYING_SLOT_CLIP_DIST0:
829 assert(glsl_type_is_array(var->type));
830 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
831 break;
832
833 default:
834 spirv_builder_emit_location(&ctx->builder, var_id,
835 var->data.driver_location);
836 }
837 }
838
839 if (var->data.location_frac)
840 spirv_builder_emit_component(&ctx->builder, var_id,
841 var->data.location_frac);
842
843 if (var->data.patch)
844 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationPatch);
845
846 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
847
848 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
849 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
850 }
851
852 static void
emit_output(struct ntv_context * ctx,struct nir_variable * var)853 emit_output(struct ntv_context *ctx, struct nir_variable *var)
854 {
855 SpvId var_type = get_glsl_type(ctx, var->type);
856
857 /* SampleMask is always an array in spirv */
858 if (ctx->stage == MESA_SHADER_FRAGMENT && var->data.location == FRAG_RESULT_SAMPLE_MASK)
859 ctx->sample_mask_type = var_type = spirv_builder_type_array(&ctx->builder, var_type, emit_uint_const(ctx, 32, 1));
860 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
861 SpvStorageClassOutput,
862 var_type);
863 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
864 SpvStorageClassOutput);
865 if (var->name)
866 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
867
868 if (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW) {
869 spirv_builder_emit_decoration(&ctx->builder, var_id,
870 SpvDecorationRelaxedPrecision);
871 }
872
873 if (ctx->stage != MESA_SHADER_FRAGMENT) {
874 switch (var->data.location) {
875 HANDLE_EMIT_BUILTIN(POS, Position);
876 HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
877 HANDLE_EMIT_BUILTIN(LAYER, Layer);
878 HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
879 HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
880 HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
881 HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
882 HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
883 HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
884
885 default:
886 /* non-xfb psiz output will have location -1 */
887 if (var->data.location >= 0)
888 spirv_builder_emit_location(&ctx->builder, var_id,
889 var->data.driver_location);
890 }
891 /* tcs can't do xfb */
892 if (ctx->stage != MESA_SHADER_TESS_CTRL && var->data.location >= 0) {
893 unsigned idx = var->data.location << 2 | var->data.location_frac;
894 ctx->outputs[idx] = var_id;
895 }
896 emit_interpolation(ctx, var_id, var->data.interpolation);
897 } else {
898 if (var->data.location >= FRAG_RESULT_DATA0) {
899 spirv_builder_emit_location(&ctx->builder, var_id,
900 var->data.location - FRAG_RESULT_DATA0);
901 spirv_builder_emit_index(&ctx->builder, var_id, var->data.index);
902 } else {
903 switch (var->data.location) {
904 case FRAG_RESULT_COLOR:
905 unreachable("gl_FragColor should be lowered by now");
906
907 case FRAG_RESULT_DEPTH:
908 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
909 break;
910
911 case FRAG_RESULT_SAMPLE_MASK:
912 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInSampleMask);
913 break;
914
915 case FRAG_RESULT_STENCIL:
916 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragStencilRefEXT);
917 break;
918
919 default:
920 spirv_builder_emit_location(&ctx->builder, var_id,
921 var->data.location);
922 spirv_builder_emit_index(&ctx->builder, var_id, var->data.index);
923 }
924 }
925 if (var->data.sample)
926 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationSample);
927 }
928
929 if (var->data.location_frac)
930 spirv_builder_emit_component(&ctx->builder, var_id,
931 var->data.location_frac);
932
933 if (var->data.patch)
934 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationPatch);
935
936 if (var->data.explicit_xfb_buffer && ctx->nir->xfb_info) {
937 spirv_builder_emit_offset(&ctx->builder, var_id, var->data.offset);
938 spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, var->data.xfb.buffer);
939 spirv_builder_emit_xfb_stride(&ctx->builder, var_id, var->data.xfb.stride);
940 if (var->data.stream)
941 spirv_builder_emit_stream(&ctx->builder, var_id, var->data.stream);
942 }
943
944 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
945
946 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
947 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
948 }
949
950 static void
emit_shader_temp(struct ntv_context * ctx,struct nir_variable * var)951 emit_shader_temp(struct ntv_context *ctx, struct nir_variable *var)
952 {
953 SpvId var_type = get_glsl_type(ctx, var->type);
954
955 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
956 SpvStorageClassPrivate,
957 var_type);
958 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
959 SpvStorageClassPrivate);
960 if (var->name)
961 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
962
963 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
964
965 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
966 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
967 }
968
969 static void
emit_temp(struct ntv_context * ctx,struct nir_variable * var)970 emit_temp(struct ntv_context *ctx, struct nir_variable *var)
971 {
972 SpvId var_type = get_glsl_type(ctx, var->type);
973
974 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
975 SpvStorageClassFunction,
976 var_type);
977 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
978 SpvStorageClassFunction);
979 if (var->name)
980 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
981
982 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
983 }
984
985 static SpvDim
type_to_dim(enum glsl_sampler_dim gdim,bool * is_ms)986 type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
987 {
988 *is_ms = false;
989 switch (gdim) {
990 case GLSL_SAMPLER_DIM_1D:
991 return SpvDim1D;
992 case GLSL_SAMPLER_DIM_2D:
993 return SpvDim2D;
994 case GLSL_SAMPLER_DIM_3D:
995 return SpvDim3D;
996 case GLSL_SAMPLER_DIM_CUBE:
997 return SpvDimCube;
998 case GLSL_SAMPLER_DIM_RECT:
999 return SpvDim2D;
1000 case GLSL_SAMPLER_DIM_BUF:
1001 return SpvDimBuffer;
1002 case GLSL_SAMPLER_DIM_EXTERNAL:
1003 return SpvDim2D; /* seems dodgy... */
1004 case GLSL_SAMPLER_DIM_MS:
1005 *is_ms = true;
1006 return SpvDim2D;
1007 case GLSL_SAMPLER_DIM_SUBPASS_MS:
1008 *is_ms = true;
1009 return SpvDimSubpassData;
1010 case GLSL_SAMPLER_DIM_SUBPASS:
1011 return SpvDimSubpassData;
1012 default:
1013 fprintf(stderr, "unknown sampler type %d\n", gdim);
1014 break;
1015 }
1016 return SpvDim2D;
1017 }
1018
1019 static inline SpvImageFormat
get_shader_image_format(enum pipe_format format)1020 get_shader_image_format(enum pipe_format format)
1021 {
1022 switch (format) {
1023 case PIPE_FORMAT_R32G32B32A32_FLOAT:
1024 return SpvImageFormatRgba32f;
1025 case PIPE_FORMAT_R16G16B16A16_FLOAT:
1026 return SpvImageFormatRgba16f;
1027 case PIPE_FORMAT_R32_FLOAT:
1028 return SpvImageFormatR32f;
1029 case PIPE_FORMAT_R8G8B8A8_UNORM:
1030 return SpvImageFormatRgba8;
1031 case PIPE_FORMAT_R8G8B8A8_SNORM:
1032 return SpvImageFormatRgba8Snorm;
1033 case PIPE_FORMAT_R32G32B32A32_SINT:
1034 return SpvImageFormatRgba32i;
1035 case PIPE_FORMAT_R16G16B16A16_SINT:
1036 return SpvImageFormatRgba16i;
1037 case PIPE_FORMAT_R8G8B8A8_SINT:
1038 return SpvImageFormatRgba8i;
1039 case PIPE_FORMAT_R32_SINT:
1040 return SpvImageFormatR32i;
1041 case PIPE_FORMAT_R32G32B32A32_UINT:
1042 return SpvImageFormatRgba32ui;
1043 case PIPE_FORMAT_R16G16B16A16_UINT:
1044 return SpvImageFormatRgba16ui;
1045 case PIPE_FORMAT_R8G8B8A8_UINT:
1046 return SpvImageFormatRgba8ui;
1047 case PIPE_FORMAT_R32_UINT:
1048 return SpvImageFormatR32ui;
1049 default:
1050 return SpvImageFormatUnknown;
1051 }
1052 }
1053
1054 static inline SpvImageFormat
get_extended_image_format(enum pipe_format format)1055 get_extended_image_format(enum pipe_format format)
1056 {
1057 switch (format) {
1058 case PIPE_FORMAT_R32G32_FLOAT:
1059 return SpvImageFormatRg32f;
1060 case PIPE_FORMAT_R16G16_FLOAT:
1061 return SpvImageFormatRg16f;
1062 case PIPE_FORMAT_R11G11B10_FLOAT:
1063 return SpvImageFormatR11fG11fB10f;
1064 case PIPE_FORMAT_R16_FLOAT:
1065 return SpvImageFormatR16f;
1066 case PIPE_FORMAT_R16G16B16A16_UNORM:
1067 return SpvImageFormatRgba16;
1068 case PIPE_FORMAT_R10G10B10A2_UNORM:
1069 return SpvImageFormatRgb10A2;
1070 case PIPE_FORMAT_R16G16_UNORM:
1071 return SpvImageFormatRg16;
1072 case PIPE_FORMAT_R8G8_UNORM:
1073 return SpvImageFormatRg8;
1074 case PIPE_FORMAT_R16_UNORM:
1075 return SpvImageFormatR16;
1076 case PIPE_FORMAT_R8_UNORM:
1077 return SpvImageFormatR8;
1078 case PIPE_FORMAT_R16G16B16A16_SNORM:
1079 return SpvImageFormatRgba16Snorm;
1080 case PIPE_FORMAT_R16G16_SNORM:
1081 return SpvImageFormatRg16Snorm;
1082 case PIPE_FORMAT_R8G8_SNORM:
1083 return SpvImageFormatRg8Snorm;
1084 case PIPE_FORMAT_R16_SNORM:
1085 return SpvImageFormatR16Snorm;
1086 case PIPE_FORMAT_R8_SNORM:
1087 return SpvImageFormatR8Snorm;
1088 case PIPE_FORMAT_R32G32_SINT:
1089 return SpvImageFormatRg32i;
1090 case PIPE_FORMAT_R16G16_SINT:
1091 return SpvImageFormatRg16i;
1092 case PIPE_FORMAT_R8G8_SINT:
1093 return SpvImageFormatRg8i;
1094 case PIPE_FORMAT_R16_SINT:
1095 return SpvImageFormatR16i;
1096 case PIPE_FORMAT_R8_SINT:
1097 return SpvImageFormatR8i;
1098 case PIPE_FORMAT_R10G10B10A2_UINT:
1099 return SpvImageFormatRgb10a2ui;
1100 case PIPE_FORMAT_R32G32_UINT:
1101 return SpvImageFormatRg32ui;
1102 case PIPE_FORMAT_R16G16_UINT:
1103 return SpvImageFormatRg16ui;
1104 case PIPE_FORMAT_R8G8_UINT:
1105 return SpvImageFormatRg8ui;
1106 case PIPE_FORMAT_R16_UINT:
1107 return SpvImageFormatR16ui;
1108 case PIPE_FORMAT_R8_UINT:
1109 return SpvImageFormatR8ui;
1110
1111 default:
1112 return SpvImageFormatUnknown;
1113 }
1114 }
1115
1116 static inline SpvImageFormat
get_image_format(struct ntv_context * ctx,enum pipe_format format)1117 get_image_format(struct ntv_context *ctx, enum pipe_format format)
1118 {
1119 /* always supported */
1120 if (format == PIPE_FORMAT_NONE)
1121 return SpvImageFormatUnknown;
1122
1123 SpvImageFormat ret = get_shader_image_format(format);
1124 if (ret != SpvImageFormatUnknown) {
1125 /* requires the shader-cap, but we already emit that */
1126 return ret;
1127 }
1128
1129 ret = get_extended_image_format(format);
1130 assert(ret != SpvImageFormatUnknown);
1131 spirv_builder_emit_cap(&ctx->builder,
1132 SpvCapabilityStorageImageExtendedFormats);
1133 return ret;
1134 }
1135
1136 static SpvId
get_bare_image_type(struct ntv_context * ctx,struct nir_variable * var,bool is_sampler)1137 get_bare_image_type(struct ntv_context *ctx, struct nir_variable *var, bool is_sampler)
1138 {
1139 const struct glsl_type *type = glsl_without_array(var->type);
1140
1141 bool is_ms;
1142
1143 if (var->data.fb_fetch_output) {
1144 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInputAttachment);
1145 } else if (!is_sampler && !var->data.image.format) {
1146 if (!(var->data.access & ACCESS_NON_WRITEABLE))
1147 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityStorageImageWriteWithoutFormat);
1148 if (!(var->data.access & ACCESS_NON_READABLE))
1149 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityStorageImageReadWithoutFormat);
1150 }
1151
1152 SpvDim dimension = type_to_dim(glsl_get_sampler_dim(type), &is_ms);
1153 if (dimension == SpvDim1D) {
1154 if (is_sampler)
1155 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampled1D);
1156 else
1157 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImage1D);
1158 }
1159 if (dimension == SpvDimBuffer) {
1160 if (is_sampler)
1161 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampledBuffer);
1162 else
1163 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageBuffer);
1164 }
1165
1166 bool arrayed = glsl_sampler_type_is_array(type);
1167 if (dimension == SpvDimCube && arrayed)
1168 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageCubeArray);
1169
1170 SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
1171 return spirv_builder_type_image(&ctx->builder, result_type,
1172 dimension, false,
1173 arrayed,
1174 is_ms, is_sampler ? 1 : 2,
1175 get_image_format(ctx, var->data.image.format));
1176 }
1177
1178 static SpvId
get_image_type(struct ntv_context * ctx,struct nir_variable * var,bool is_sampler,bool is_buffer)1179 get_image_type(struct ntv_context *ctx, struct nir_variable *var,
1180 bool is_sampler, bool is_buffer)
1181 {
1182 SpvId image_type = get_bare_image_type(ctx, var, is_sampler);
1183 return is_sampler && ctx->stage != MESA_SHADER_KERNEL && !is_buffer ?
1184 spirv_builder_type_sampled_image(&ctx->builder, image_type) :
1185 image_type;
1186 }
1187
1188 static SpvId
emit_image(struct ntv_context * ctx,struct nir_variable * var,SpvId image_type)1189 emit_image(struct ntv_context *ctx, struct nir_variable *var, SpvId image_type)
1190 {
1191 if (var->data.bindless)
1192 return 0;
1193 const struct glsl_type *type = glsl_without_array(var->type);
1194
1195 bool is_sampler = glsl_type_is_sampler(type);
1196 bool is_buffer = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF;
1197 SpvId var_type = is_sampler && ctx->stage != MESA_SHADER_KERNEL && !is_buffer ?
1198 spirv_builder_type_sampled_image(&ctx->builder, image_type) : image_type;
1199
1200 bool mediump = (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW);
1201
1202 int index = var->data.driver_location;
1203 assert(!find_image_type(ctx, var));
1204
1205 if (glsl_type_is_array(var->type)) {
1206 var_type = spirv_builder_type_array(&ctx->builder, var_type,
1207 emit_uint_const(ctx, 32, glsl_get_aoa_size(var->type)));
1208 spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(void*));
1209 }
1210 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1211 SpvStorageClassUniformConstant,
1212 var_type);
1213
1214 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1215 SpvStorageClassUniformConstant);
1216
1217 if (mediump) {
1218 spirv_builder_emit_decoration(&ctx->builder, var_id,
1219 SpvDecorationRelaxedPrecision);
1220 }
1221
1222 if (var->name)
1223 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
1224
1225 if (var->data.fb_fetch_output)
1226 spirv_builder_emit_input_attachment_index(&ctx->builder, var_id, var->data.index);
1227
1228 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
1229 if (is_sampler) {
1230 if (var->data.descriptor_set == ctx->bindless_set_idx) {
1231 assert(!ctx->bindless_samplers[index]);
1232 ctx->bindless_samplers[index] = var_id;
1233 } else {
1234 assert(!ctx->samplers[index]);
1235 ctx->samplers[index] = var_id;
1236 }
1237 } else {
1238 assert(!ctx->images[index]);
1239 ctx->images[index] = var_id;
1240 emit_access_decorations(ctx, var, var_id);
1241 }
1242 _mesa_hash_table_insert(&ctx->image_types, var, (void *)(intptr_t)image_type);
1243 if (ctx->spirv_1_4_interfaces) {
1244 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1245 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1246 }
1247
1248 spirv_builder_emit_descriptor_set(&ctx->builder, var_id, var->data.descriptor_set);
1249 spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
1250 return var_id;
1251 }
1252
1253 static void
emit_sampler(struct ntv_context * ctx,unsigned sampler_index,unsigned desc_set)1254 emit_sampler(struct ntv_context *ctx, unsigned sampler_index, unsigned desc_set)
1255 {
1256 SpvId type = spirv_builder_type_sampler(&ctx->builder);
1257 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1258 SpvStorageClassUniformConstant,
1259 type);
1260
1261 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1262 SpvStorageClassUniformConstant);
1263 char buf[128];
1264 snprintf(buf, sizeof(buf), "sampler_%u", sampler_index);
1265 spirv_builder_emit_name(&ctx->builder, var_id, buf);
1266 spirv_builder_emit_descriptor_set(&ctx->builder, var_id, desc_set);
1267 spirv_builder_emit_binding(&ctx->builder, var_id, sampler_index);
1268 ctx->cl_samplers[sampler_index] = var_id;
1269 if (ctx->spirv_1_4_interfaces) {
1270 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1271 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1272 }
1273
1274 }
1275
1276 static SpvId
get_sized_uint_array_type(struct ntv_context * ctx,unsigned array_size,unsigned bitsize)1277 get_sized_uint_array_type(struct ntv_context *ctx, unsigned array_size, unsigned bitsize)
1278 {
1279 SpvId array_length = emit_uint_const(ctx, 32, array_size);
1280 SpvId array_type = spirv_builder_type_array(&ctx->builder, get_uvec_type(ctx, bitsize, 1),
1281 array_length);
1282 spirv_builder_emit_array_stride(&ctx->builder, array_type, bitsize / 8);
1283 return array_type;
1284 }
1285
1286 /* get array<struct(array_type <--this one)> */
1287 static SpvId
get_bo_array_type(struct ntv_context * ctx,struct nir_variable * var)1288 get_bo_array_type(struct ntv_context *ctx, struct nir_variable *var)
1289 {
1290 struct hash_entry *he = _mesa_hash_table_search(ctx->bo_array_types, var);
1291 if (he)
1292 return (SpvId)(uintptr_t)he->data;
1293 unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(glsl_without_array(var->type), 0)));
1294 assert(bitsize);
1295 SpvId array_type;
1296 const struct glsl_type *type = glsl_without_array(var->type);
1297 const struct glsl_type *first_type = glsl_get_struct_field(type, 0);
1298 if (!glsl_type_is_unsized_array(first_type)) {
1299 uint32_t array_size = glsl_get_length(first_type);
1300 assert(array_size);
1301 return get_sized_uint_array_type(ctx, array_size, bitsize);
1302 }
1303 SpvId uint_type = spirv_builder_type_uint(&ctx->builder, bitsize);
1304 array_type = spirv_builder_type_runtime_array(&ctx->builder, uint_type);
1305 spirv_builder_emit_array_stride(&ctx->builder, array_type, bitsize / 8);
1306 return array_type;
1307 }
1308
1309 /* get array<struct(array_type) <--this one> */
1310 static SpvId
get_bo_struct_type(struct ntv_context * ctx,struct nir_variable * var)1311 get_bo_struct_type(struct ntv_context *ctx, struct nir_variable *var)
1312 {
1313 struct hash_entry *he = _mesa_hash_table_search(ctx->bo_struct_types, var);
1314 if (he)
1315 return (SpvId)(uintptr_t)he->data;
1316 const struct glsl_type *bare_type = glsl_without_array(var->type);
1317 unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(bare_type, 0)));
1318 SpvId array_type = get_bo_array_type(ctx, var);
1319 _mesa_hash_table_insert(ctx->bo_array_types, var, (void *)(uintptr_t)array_type);
1320 bool ssbo = var->data.mode == nir_var_mem_ssbo;
1321
1322 // wrap UBO-array in a struct
1323 SpvId runtime_array = 0;
1324 if (ssbo && glsl_get_length(bare_type) > 1) {
1325 const struct glsl_type *last_member = glsl_get_struct_field(bare_type, glsl_get_length(bare_type) - 1);
1326 if (glsl_type_is_unsized_array(last_member)) {
1327 runtime_array = spirv_builder_type_runtime_array(&ctx->builder, get_uvec_type(ctx, bitsize, 1));
1328 spirv_builder_emit_array_stride(&ctx->builder, runtime_array, glsl_get_explicit_stride(last_member));
1329 }
1330 }
1331 SpvId types[] = {array_type, runtime_array};
1332 SpvId struct_type = spirv_builder_type_struct(&ctx->builder, types, 1 + !!runtime_array);
1333 if (var->name) {
1334 char struct_name[100];
1335 snprintf(struct_name, sizeof(struct_name), "struct_%s", var->name);
1336 spirv_builder_emit_name(&ctx->builder, struct_type, struct_name);
1337 }
1338
1339 spirv_builder_emit_decoration(&ctx->builder, struct_type,
1340 SpvDecorationBlock);
1341 spirv_builder_emit_member_offset(&ctx->builder, struct_type, 0, 0);
1342 if (runtime_array)
1343 spirv_builder_emit_member_offset(&ctx->builder, struct_type, 1, 0);
1344
1345 return struct_type;
1346 }
1347
1348 static void
emit_bo(struct ntv_context * ctx,struct nir_variable * var,bool aliased)1349 emit_bo(struct ntv_context *ctx, struct nir_variable *var, bool aliased)
1350 {
1351 unsigned bitsize = glsl_get_bit_size(glsl_get_array_element(glsl_get_struct_field(glsl_without_array(var->type), 0)));
1352 bool ssbo = var->data.mode == nir_var_mem_ssbo;
1353 SpvId struct_type = get_bo_struct_type(ctx, var);
1354 _mesa_hash_table_insert(ctx->bo_struct_types, var, (void *)(uintptr_t)struct_type);
1355 SpvId array_length = emit_uint_const(ctx, 32, glsl_get_length(var->type));
1356 SpvId array_type = spirv_builder_type_array(&ctx->builder, struct_type, array_length);
1357 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1358 ssbo ? SpvStorageClassStorageBuffer : SpvStorageClassUniform,
1359 array_type);
1360 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
1361 ssbo ? SpvStorageClassStorageBuffer : SpvStorageClassUniform);
1362 if (var->name)
1363 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
1364
1365 if (aliased)
1366 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationAliased);
1367
1368 unsigned idx = bitsize >> 4;
1369 assert(idx < ARRAY_SIZE(ctx->ssbos));
1370 if (ssbo) {
1371 assert(!ctx->ssbos[idx]);
1372 ctx->ssbos[idx] = var_id;
1373 if (bitsize == 32)
1374 ctx->ssbo_vars = var;
1375 } else {
1376 assert(!ctx->ubos[var->data.driver_location][idx]);
1377 ctx->ubos[var->data.driver_location][idx] = var_id;
1378 ctx->ubo_vars[var->data.driver_location] = var;
1379 }
1380 if (ctx->spirv_1_4_interfaces) {
1381 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
1382 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
1383 }
1384 _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
1385
1386 spirv_builder_emit_descriptor_set(&ctx->builder, var_id, var->data.descriptor_set);
1387 spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
1388 }
1389
1390 static SpvId
get_vec_from_bit_size(struct ntv_context * ctx,uint32_t bit_size,uint32_t num_components)1391 get_vec_from_bit_size(struct ntv_context *ctx, uint32_t bit_size, uint32_t num_components)
1392 {
1393 if (bit_size == 1)
1394 return get_bvec_type(ctx, num_components);
1395 return get_uvec_type(ctx, bit_size, num_components);
1396 }
1397
1398 static SpvId
get_src_ssa(struct ntv_context * ctx,const nir_def * ssa,nir_alu_type * atype)1399 get_src_ssa(struct ntv_context *ctx, const nir_def *ssa, nir_alu_type *atype)
1400 {
1401 assert(ssa->index < ctx->num_defs);
1402 assert(ctx->defs[ssa->index] != 0);
1403 *atype = ctx->def_types[ssa->index];
1404 return ctx->defs[ssa->index];
1405 }
1406
1407 static void
init_reg(struct ntv_context * ctx,nir_intrinsic_instr * decl,nir_alu_type atype)1408 init_reg(struct ntv_context *ctx, nir_intrinsic_instr *decl, nir_alu_type atype)
1409 {
1410 unsigned index = decl->def.index;
1411 unsigned num_components = nir_intrinsic_num_components(decl);
1412 unsigned bit_size = nir_intrinsic_bit_size(decl);
1413
1414 if (ctx->defs[index])
1415 return;
1416
1417 SpvId type = get_alu_type(ctx, atype, num_components, bit_size);
1418 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
1419 SpvStorageClassFunction,
1420 type);
1421 SpvId var = spirv_builder_emit_var(&ctx->builder, pointer_type,
1422 SpvStorageClassFunction);
1423
1424 ctx->defs[index] = var;
1425 ctx->def_types[index] = nir_alu_type_get_base_type(atype);
1426 }
1427
1428 static SpvId
get_src(struct ntv_context * ctx,nir_src * src,nir_alu_type * atype)1429 get_src(struct ntv_context *ctx, nir_src *src, nir_alu_type *atype)
1430 {
1431 return get_src_ssa(ctx, src->ssa, atype);
1432 }
1433
1434 static SpvId
get_alu_src_raw(struct ntv_context * ctx,nir_alu_instr * alu,unsigned src,nir_alu_type * atype)1435 get_alu_src_raw(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src, nir_alu_type *atype)
1436 {
1437 SpvId def = get_src(ctx, &alu->src[src].src, atype);
1438
1439 unsigned used_channels = 0;
1440 bool need_swizzle = false;
1441 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
1442 if (!nir_alu_instr_channel_used(alu, src, i))
1443 continue;
1444
1445 used_channels++;
1446
1447 if (alu->src[src].swizzle[i] != i)
1448 need_swizzle = true;
1449 }
1450 assert(used_channels != 0);
1451
1452 unsigned live_channels = nir_src_num_components(alu->src[src].src);
1453 if (used_channels != live_channels)
1454 need_swizzle = true;
1455
1456 if (!need_swizzle)
1457 return def;
1458
1459 int bit_size = nir_src_bit_size(alu->src[src].src);
1460 SpvId raw_type = get_alu_type(ctx, *atype, 1, bit_size);
1461
1462 if (used_channels == 1) {
1463 uint32_t indices[] = { alu->src[src].swizzle[0] };
1464 return spirv_builder_emit_composite_extract(&ctx->builder, raw_type,
1465 def, indices,
1466 ARRAY_SIZE(indices));
1467 } else if (live_channels == 1) {
1468 SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
1469 raw_type,
1470 used_channels);
1471
1472 SpvId constituents[NIR_MAX_VEC_COMPONENTS] = {0};
1473 for (unsigned i = 0; i < used_channels; ++i)
1474 constituents[i] = def;
1475
1476 return spirv_builder_emit_composite_construct(&ctx->builder,
1477 raw_vec_type,
1478 constituents,
1479 used_channels);
1480 } else {
1481 SpvId raw_vec_type = spirv_builder_type_vector(&ctx->builder,
1482 raw_type,
1483 used_channels);
1484
1485 uint32_t components[NIR_MAX_VEC_COMPONENTS] = {0};
1486 size_t num_components = 0;
1487 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
1488 if (!nir_alu_instr_channel_used(alu, src, i))
1489 continue;
1490
1491 components[num_components++] = alu->src[src].swizzle[i];
1492 }
1493
1494 return spirv_builder_emit_vector_shuffle(&ctx->builder, raw_vec_type,
1495 def, def, components,
1496 num_components);
1497 }
1498 }
1499
1500 static void
store_ssa_def(struct ntv_context * ctx,nir_def * ssa,SpvId result,nir_alu_type atype)1501 store_ssa_def(struct ntv_context *ctx, nir_def *ssa, SpvId result, nir_alu_type atype)
1502 {
1503 assert(result != 0);
1504 assert(ssa->index < ctx->num_defs);
1505 ctx->def_types[ssa->index] = nir_alu_type_get_base_type(atype);
1506 ctx->defs[ssa->index] = result;
1507 }
1508
1509 static SpvId
emit_select(struct ntv_context * ctx,SpvId type,SpvId cond,SpvId if_true,SpvId if_false)1510 emit_select(struct ntv_context *ctx, SpvId type, SpvId cond,
1511 SpvId if_true, SpvId if_false)
1512 {
1513 return emit_triop(ctx, SpvOpSelect, type, cond, if_true, if_false);
1514 }
1515
1516 static SpvId
emit_bitcast(struct ntv_context * ctx,SpvId type,SpvId value)1517 emit_bitcast(struct ntv_context *ctx, SpvId type, SpvId value)
1518 {
1519 return emit_unop(ctx, SpvOpBitcast, type, value);
1520 }
1521
1522 static SpvId
bitcast_to_uvec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1523 bitcast_to_uvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1524 unsigned num_components)
1525 {
1526 SpvId type = get_uvec_type(ctx, bit_size, num_components);
1527 return emit_bitcast(ctx, type, value);
1528 }
1529
1530 static SpvId
bitcast_to_ivec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1531 bitcast_to_ivec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1532 unsigned num_components)
1533 {
1534 SpvId type = get_ivec_type(ctx, bit_size, num_components);
1535 return emit_bitcast(ctx, type, value);
1536 }
1537
1538 static SpvId
bitcast_to_fvec(struct ntv_context * ctx,SpvId value,unsigned bit_size,unsigned num_components)1539 bitcast_to_fvec(struct ntv_context *ctx, SpvId value, unsigned bit_size,
1540 unsigned num_components)
1541 {
1542 SpvId type = get_fvec_type(ctx, bit_size, num_components);
1543 return emit_bitcast(ctx, type, value);
1544 }
1545
1546 static SpvId
cast_src_to_type(struct ntv_context * ctx,SpvId value,nir_src src,nir_alu_type atype)1547 cast_src_to_type(struct ntv_context *ctx, SpvId value, nir_src src, nir_alu_type atype)
1548 {
1549 atype = nir_alu_type_get_base_type(atype);
1550 unsigned num_components = nir_src_num_components(src);
1551 unsigned bit_size = nir_src_bit_size(src);
1552 return emit_bitcast(ctx, get_alu_type(ctx, atype, num_components, bit_size), value);
1553 }
1554
1555 static void
store_def_raw(struct ntv_context * ctx,nir_def * def,SpvId result,nir_alu_type atype)1556 store_def_raw(struct ntv_context *ctx, nir_def *def, SpvId result, nir_alu_type atype)
1557 {
1558 store_ssa_def(ctx, def, result, atype);
1559 }
1560
1561 static void
store_def(struct ntv_context * ctx,nir_def * def,SpvId result,nir_alu_type type)1562 store_def(struct ntv_context *ctx, nir_def *def, SpvId result, nir_alu_type type)
1563 {
1564 store_def_raw(ctx, def, result, type);
1565 }
1566
1567 static SpvId
emit_unop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src)1568 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src)
1569 {
1570 return spirv_builder_emit_unop(&ctx->builder, op, type, src);
1571 }
1572
1573 static SpvId
emit_atomic(struct ntv_context * ctx,SpvId op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1574 emit_atomic(struct ntv_context *ctx, SpvId op, SpvId type, SpvId src0, SpvId src1, SpvId src2)
1575 {
1576 if (op == SpvOpAtomicLoad)
1577 return spirv_builder_emit_triop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1578 emit_uint_const(ctx, 32, 0));
1579 if (op == SpvOpAtomicCompareExchange)
1580 return spirv_builder_emit_hexop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1581 emit_uint_const(ctx, 32, 0),
1582 emit_uint_const(ctx, 32, 0),
1583 /* these params are intentionally swapped */
1584 src2, src1);
1585
1586 return spirv_builder_emit_quadop(&ctx->builder, op, type, src0, emit_uint_const(ctx, 32, SpvScopeDevice),
1587 emit_uint_const(ctx, 32, 0), src1);
1588 }
1589
1590 static SpvId
emit_binop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src0,SpvId src1)1591 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
1592 SpvId src0, SpvId src1)
1593 {
1594 return spirv_builder_emit_binop(&ctx->builder, op, type, src0, src1);
1595 }
1596
1597 static SpvId
emit_triop(struct ntv_context * ctx,SpvOp op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1598 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
1599 SpvId src0, SpvId src1, SpvId src2)
1600 {
1601 return spirv_builder_emit_triop(&ctx->builder, op, type, src0, src1, src2);
1602 }
1603
1604 static SpvId
emit_builtin_unop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src)1605 emit_builtin_unop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1606 SpvId src)
1607 {
1608 SpvId args[] = { src };
1609 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1610 op, args, ARRAY_SIZE(args));
1611 }
1612
1613 static SpvId
emit_builtin_binop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src0,SpvId src1)1614 emit_builtin_binop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1615 SpvId src0, SpvId src1)
1616 {
1617 SpvId args[] = { src0, src1 };
1618 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1619 op, args, ARRAY_SIZE(args));
1620 }
1621
1622 static SpvId
emit_builtin_triop(struct ntv_context * ctx,enum GLSLstd450 op,SpvId type,SpvId src0,SpvId src1,SpvId src2)1623 emit_builtin_triop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
1624 SpvId src0, SpvId src1, SpvId src2)
1625 {
1626 SpvId args[] = { src0, src1, src2 };
1627 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
1628 op, args, ARRAY_SIZE(args));
1629 }
1630
1631 static SpvId
get_fvec_constant(struct ntv_context * ctx,unsigned bit_size,unsigned num_components,double value)1632 get_fvec_constant(struct ntv_context *ctx, unsigned bit_size,
1633 unsigned num_components, double value)
1634 {
1635 assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
1636
1637 SpvId result = emit_float_const(ctx, bit_size, value);
1638 if (num_components == 1)
1639 return result;
1640
1641 assert(num_components > 1);
1642 SpvId components[NIR_MAX_VEC_COMPONENTS];
1643 for (int i = 0; i < num_components; i++)
1644 components[i] = result;
1645
1646 SpvId type = get_fvec_type(ctx, bit_size, num_components);
1647 return spirv_builder_const_composite(&ctx->builder, type, components,
1648 num_components);
1649 }
1650
1651 static SpvId
get_ivec_constant(struct ntv_context * ctx,unsigned bit_size,unsigned num_components,int64_t value)1652 get_ivec_constant(struct ntv_context *ctx, unsigned bit_size,
1653 unsigned num_components, int64_t value)
1654 {
1655 assert(bit_size == 8 || bit_size == 16 || bit_size == 32 || bit_size == 64);
1656
1657 SpvId result = emit_int_const(ctx, bit_size, value);
1658 if (num_components == 1)
1659 return result;
1660
1661 assert(num_components > 1);
1662 SpvId components[NIR_MAX_VEC_COMPONENTS];
1663 for (int i = 0; i < num_components; i++)
1664 components[i] = result;
1665
1666 SpvId type = get_ivec_type(ctx, bit_size, num_components);
1667 return spirv_builder_const_composite(&ctx->builder, type, components,
1668 num_components);
1669 }
1670
1671 static inline unsigned
alu_instr_src_components(const nir_alu_instr * instr,unsigned src)1672 alu_instr_src_components(const nir_alu_instr *instr, unsigned src)
1673 {
1674 if (nir_op_infos[instr->op].input_sizes[src] > 0)
1675 return nir_op_infos[instr->op].input_sizes[src];
1676
1677 return instr->def.num_components;
1678 }
1679
1680 static SpvId
get_alu_src(struct ntv_context * ctx,nir_alu_instr * alu,unsigned src,SpvId * raw_value,nir_alu_type * atype)1681 get_alu_src(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src, SpvId *raw_value, nir_alu_type *atype)
1682 {
1683 *raw_value = get_alu_src_raw(ctx, alu, src, atype);
1684
1685 unsigned num_components = alu_instr_src_components(alu, src);
1686 unsigned bit_size = nir_src_bit_size(alu->src[src].src);
1687 nir_alu_type type = alu_op_is_typeless(alu->op) ? *atype : nir_op_infos[alu->op].input_types[src];
1688 type = nir_alu_type_get_base_type(type);
1689 if (type == *atype)
1690 return *raw_value;
1691
1692 if (bit_size == 1)
1693 return *raw_value;
1694 else {
1695 switch (nir_alu_type_get_base_type(type)) {
1696 case nir_type_bool:
1697 unreachable("bool should have bit-size 1");
1698
1699 case nir_type_int:
1700 return bitcast_to_ivec(ctx, *raw_value, bit_size, num_components);
1701
1702 case nir_type_uint:
1703 return bitcast_to_uvec(ctx, *raw_value, bit_size, num_components);
1704
1705 case nir_type_float:
1706 return bitcast_to_fvec(ctx, *raw_value, bit_size, num_components);
1707
1708 default:
1709 unreachable("unknown nir_alu_type");
1710 }
1711 }
1712 }
1713
1714 static void
store_alu_result(struct ntv_context * ctx,nir_alu_instr * alu,SpvId result,nir_alu_type atype)1715 store_alu_result(struct ntv_context *ctx, nir_alu_instr *alu, SpvId result, nir_alu_type atype)
1716 {
1717 store_def(ctx, &alu->def, result, atype);
1718 }
1719
1720 static SpvId
get_def_type(struct ntv_context * ctx,nir_def * def,nir_alu_type type)1721 get_def_type(struct ntv_context *ctx, nir_def *def, nir_alu_type type)
1722 {
1723 return get_alu_type(ctx, type, def->num_components, def->bit_size);
1724 }
1725
1726 static bool
needs_derivative_control(nir_alu_instr * alu)1727 needs_derivative_control(nir_alu_instr *alu)
1728 {
1729 switch (alu->op) {
1730 case nir_op_fddx_coarse:
1731 case nir_op_fddx_fine:
1732 case nir_op_fddy_coarse:
1733 case nir_op_fddy_fine:
1734 return true;
1735
1736 default:
1737 return false;
1738 }
1739 }
1740
1741 static void
emit_alu(struct ntv_context * ctx,nir_alu_instr * alu)1742 emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
1743 {
1744 bool is_bcsel = alu->op == nir_op_bcsel;
1745 nir_alu_type stype[NIR_MAX_VEC_COMPONENTS] = {0};
1746 SpvId src[NIR_MAX_VEC_COMPONENTS];
1747 SpvId raw_src[NIR_MAX_VEC_COMPONENTS];
1748 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
1749 src[i] = get_alu_src(ctx, alu, i, &raw_src[i], &stype[i]);
1750
1751 nir_alu_type typeless_type = stype[is_bcsel];
1752 if (nir_op_infos[alu->op].num_inputs > 1 &&
1753 alu_op_is_typeless(alu->op) &&
1754 nir_src_bit_size(alu->src[is_bcsel].src) != 1) {
1755 unsigned uint_count = 0;
1756 unsigned int_count = 0;
1757 unsigned float_count = 0;
1758 for (unsigned i = is_bcsel; i < nir_op_infos[alu->op].num_inputs; i++) {
1759 if (stype[i] == nir_type_bool)
1760 break;
1761 switch (stype[i]) {
1762 case nir_type_uint:
1763 uint_count++;
1764 break;
1765 case nir_type_int:
1766 int_count++;
1767 break;
1768 case nir_type_float:
1769 float_count++;
1770 break;
1771 default:
1772 unreachable("this shouldn't happen");
1773 }
1774 }
1775 if (uint_count > int_count && uint_count > float_count)
1776 typeless_type = nir_type_uint;
1777 else if (int_count > uint_count && int_count > float_count)
1778 typeless_type = nir_type_int;
1779 else if (float_count > uint_count && float_count > int_count)
1780 typeless_type = nir_type_float;
1781 else if (float_count == uint_count || uint_count == int_count)
1782 typeless_type = nir_type_uint;
1783 else if (float_count == int_count)
1784 typeless_type = nir_type_float;
1785 else
1786 typeless_type = nir_type_uint;
1787 assert(typeless_type != nir_type_bool);
1788 for (unsigned i = is_bcsel; i < nir_op_infos[alu->op].num_inputs; i++) {
1789 unsigned num_components = alu_instr_src_components(alu, i);
1790 unsigned bit_size = nir_src_bit_size(alu->src[i].src);
1791 SpvId type = get_alu_type(ctx, typeless_type, num_components, bit_size);
1792 if (stype[i] != typeless_type) {
1793 src[i] = emit_bitcast(ctx, type, src[i]);
1794 }
1795 }
1796 }
1797
1798 unsigned bit_size = alu->def.bit_size;
1799 unsigned num_components = alu->def.num_components;
1800 nir_alu_type atype = bit_size == 1 ?
1801 nir_type_bool :
1802 (alu_op_is_typeless(alu->op) ? typeless_type : nir_op_infos[alu->op].output_type);
1803 SpvId dest_type = get_def_type(ctx, &alu->def, atype);
1804
1805 if (needs_derivative_control(alu))
1806 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDerivativeControl);
1807
1808 SpvId result = 0;
1809 switch (alu->op) {
1810 case nir_op_mov:
1811 assert(nir_op_infos[alu->op].num_inputs == 1);
1812 result = src[0];
1813 break;
1814
1815 #define UNOP(nir_op, spirv_op) \
1816 case nir_op: \
1817 assert(nir_op_infos[alu->op].num_inputs == 1); \
1818 result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
1819 break;
1820
1821 UNOP(nir_op_ineg, SpvOpSNegate)
1822 UNOP(nir_op_fneg, SpvOpFNegate)
1823 UNOP(nir_op_fddx, SpvOpDPdx)
1824 UNOP(nir_op_fddx_coarse, SpvOpDPdxCoarse)
1825 UNOP(nir_op_fddx_fine, SpvOpDPdxFine)
1826 UNOP(nir_op_fddy, SpvOpDPdy)
1827 UNOP(nir_op_fddy_coarse, SpvOpDPdyCoarse)
1828 UNOP(nir_op_fddy_fine, SpvOpDPdyFine)
1829 UNOP(nir_op_f2i8, SpvOpConvertFToS)
1830 UNOP(nir_op_f2u8, SpvOpConvertFToU)
1831 UNOP(nir_op_f2i16, SpvOpConvertFToS)
1832 UNOP(nir_op_f2u16, SpvOpConvertFToU)
1833 UNOP(nir_op_f2i32, SpvOpConvertFToS)
1834 UNOP(nir_op_f2u32, SpvOpConvertFToU)
1835 UNOP(nir_op_i2f16, SpvOpConvertSToF)
1836 UNOP(nir_op_i2f32, SpvOpConvertSToF)
1837 UNOP(nir_op_u2f16, SpvOpConvertUToF)
1838 UNOP(nir_op_u2f32, SpvOpConvertUToF)
1839 UNOP(nir_op_i2i8, SpvOpSConvert)
1840 UNOP(nir_op_i2i16, SpvOpSConvert)
1841 UNOP(nir_op_i2i32, SpvOpSConvert)
1842 UNOP(nir_op_u2u8, SpvOpUConvert)
1843 UNOP(nir_op_u2u16, SpvOpUConvert)
1844 UNOP(nir_op_u2u32, SpvOpUConvert)
1845 UNOP(nir_op_f2f16, SpvOpFConvert)
1846 UNOP(nir_op_f2f32, SpvOpFConvert)
1847 UNOP(nir_op_f2i64, SpvOpConvertFToS)
1848 UNOP(nir_op_f2u64, SpvOpConvertFToU)
1849 UNOP(nir_op_u2f64, SpvOpConvertUToF)
1850 UNOP(nir_op_i2f64, SpvOpConvertSToF)
1851 UNOP(nir_op_i2i64, SpvOpSConvert)
1852 UNOP(nir_op_u2u64, SpvOpUConvert)
1853 UNOP(nir_op_f2f64, SpvOpFConvert)
1854 UNOP(nir_op_bitfield_reverse, SpvOpBitReverse)
1855 UNOP(nir_op_bit_count, SpvOpBitCount)
1856 #undef UNOP
1857
1858 case nir_op_f2f16_rtz:
1859 assert(nir_op_infos[alu->op].num_inputs == 1);
1860 result = emit_unop(ctx, SpvOpFConvert, dest_type, src[0]);
1861 spirv_builder_emit_rounding_mode(&ctx->builder, result, SpvFPRoundingModeRTZ);
1862 break;
1863
1864 case nir_op_inot:
1865 if (bit_size == 1)
1866 result = emit_unop(ctx, SpvOpLogicalNot, dest_type, src[0]);
1867 else
1868 result = emit_unop(ctx, SpvOpNot, dest_type, src[0]);
1869 break;
1870
1871 case nir_op_b2i8:
1872 case nir_op_b2i16:
1873 case nir_op_b2i32:
1874 case nir_op_b2i64:
1875 assert(nir_op_infos[alu->op].num_inputs == 1);
1876 result = emit_select(ctx, dest_type, src[0],
1877 get_ivec_constant(ctx, bit_size, num_components, 1),
1878 get_ivec_constant(ctx, bit_size, num_components, 0));
1879 break;
1880
1881 case nir_op_b2f16:
1882 case nir_op_b2f32:
1883 case nir_op_b2f64:
1884 assert(nir_op_infos[alu->op].num_inputs == 1);
1885 result = emit_select(ctx, dest_type, src[0],
1886 get_fvec_constant(ctx, bit_size, num_components, 1),
1887 get_fvec_constant(ctx, bit_size, num_components, 0));
1888 break;
1889
1890 case nir_op_uclz:
1891 assert(nir_op_infos[alu->op].num_inputs == 1);
1892 result = emit_unop(ctx, SpvOpUCountLeadingZerosINTEL, dest_type, src[0]);
1893 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityIntegerFunctions2INTEL);
1894 spirv_builder_emit_extension(&ctx->builder, "SPV_INTEL_shader_integer_functions2");
1895 break;
1896 #define BUILTIN_UNOP(nir_op, spirv_op) \
1897 case nir_op: \
1898 assert(nir_op_infos[alu->op].num_inputs == 1); \
1899 result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
1900 break;
1901
1902 #define BUILTIN_UNOPF(nir_op, spirv_op) \
1903 case nir_op: \
1904 assert(nir_op_infos[alu->op].num_inputs == 1); \
1905 result = emit_builtin_unop(ctx, spirv_op, get_def_type(ctx, &alu->def, nir_type_float), src[0]); \
1906 atype = nir_type_float; \
1907 break;
1908
1909 BUILTIN_UNOP(nir_op_iabs, GLSLstd450SAbs)
1910 BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
1911 BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
1912 BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
1913 BUILTIN_UNOP(nir_op_flog2, GLSLstd450Log2)
1914 BUILTIN_UNOP(nir_op_fexp2, GLSLstd450Exp2)
1915 BUILTIN_UNOP(nir_op_ffract, GLSLstd450Fract)
1916 BUILTIN_UNOP(nir_op_ffloor, GLSLstd450Floor)
1917 BUILTIN_UNOP(nir_op_fceil, GLSLstd450Ceil)
1918 BUILTIN_UNOP(nir_op_ftrunc, GLSLstd450Trunc)
1919 BUILTIN_UNOP(nir_op_fround_even, GLSLstd450RoundEven)
1920 BUILTIN_UNOP(nir_op_fsign, GLSLstd450FSign)
1921 BUILTIN_UNOP(nir_op_isign, GLSLstd450SSign)
1922 BUILTIN_UNOP(nir_op_fsin, GLSLstd450Sin)
1923 BUILTIN_UNOP(nir_op_fcos, GLSLstd450Cos)
1924 BUILTIN_UNOP(nir_op_ufind_msb, GLSLstd450FindUMsb)
1925 BUILTIN_UNOP(nir_op_find_lsb, GLSLstd450FindILsb)
1926 BUILTIN_UNOP(nir_op_ifind_msb, GLSLstd450FindSMsb)
1927
1928 case nir_op_pack_half_2x16:
1929 assert(nir_op_infos[alu->op].num_inputs == 1);
1930 result = emit_builtin_unop(ctx, GLSLstd450PackHalf2x16, get_def_type(ctx, &alu->def, nir_type_uint), src[0]);
1931 break;
1932
1933 case nir_op_unpack_64_2x32:
1934 assert(nir_op_infos[alu->op].num_inputs == 1);
1935 result = emit_builtin_unop(ctx, GLSLstd450UnpackDouble2x32, get_def_type(ctx, &alu->def, nir_type_uint), src[0]);
1936 break;
1937
1938 BUILTIN_UNOPF(nir_op_unpack_half_2x16, GLSLstd450UnpackHalf2x16)
1939 BUILTIN_UNOPF(nir_op_pack_64_2x32, GLSLstd450PackDouble2x32)
1940 #undef BUILTIN_UNOP
1941 #undef BUILTIN_UNOPF
1942
1943 case nir_op_frcp:
1944 assert(nir_op_infos[alu->op].num_inputs == 1);
1945 result = emit_binop(ctx, SpvOpFDiv, dest_type,
1946 get_fvec_constant(ctx, bit_size, num_components, 1),
1947 src[0]);
1948 break;
1949
1950
1951 #define BINOP(nir_op, spirv_op) \
1952 case nir_op: \
1953 assert(nir_op_infos[alu->op].num_inputs == 2); \
1954 result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
1955 break;
1956
1957 BINOP(nir_op_iadd, SpvOpIAdd)
1958 BINOP(nir_op_isub, SpvOpISub)
1959 BINOP(nir_op_imul, SpvOpIMul)
1960 BINOP(nir_op_idiv, SpvOpSDiv)
1961 BINOP(nir_op_udiv, SpvOpUDiv)
1962 BINOP(nir_op_umod, SpvOpUMod)
1963 BINOP(nir_op_imod, SpvOpSMod)
1964 BINOP(nir_op_irem, SpvOpSRem)
1965 BINOP(nir_op_fadd, SpvOpFAdd)
1966 BINOP(nir_op_fsub, SpvOpFSub)
1967 BINOP(nir_op_fmul, SpvOpFMul)
1968 BINOP(nir_op_fdiv, SpvOpFDiv)
1969 BINOP(nir_op_fmod, SpvOpFMod)
1970 BINOP(nir_op_ilt, SpvOpSLessThan)
1971 BINOP(nir_op_ige, SpvOpSGreaterThanEqual)
1972 BINOP(nir_op_ult, SpvOpULessThan)
1973 BINOP(nir_op_uge, SpvOpUGreaterThanEqual)
1974 BINOP(nir_op_flt, SpvOpFOrdLessThan)
1975 BINOP(nir_op_fge, SpvOpFOrdGreaterThanEqual)
1976 BINOP(nir_op_frem, SpvOpFRem)
1977 #undef BINOP
1978
1979 #define BINOP_LOG(nir_op, spv_op, spv_log_op) \
1980 case nir_op: \
1981 assert(nir_op_infos[alu->op].num_inputs == 2); \
1982 if (nir_src_bit_size(alu->src[0].src) == 1) \
1983 result = emit_binop(ctx, spv_log_op, dest_type, src[0], src[1]); \
1984 else \
1985 result = emit_binop(ctx, spv_op, dest_type, src[0], src[1]); \
1986 break;
1987
1988 BINOP_LOG(nir_op_iand, SpvOpBitwiseAnd, SpvOpLogicalAnd)
1989 BINOP_LOG(nir_op_ior, SpvOpBitwiseOr, SpvOpLogicalOr)
1990 BINOP_LOG(nir_op_ieq, SpvOpIEqual, SpvOpLogicalEqual)
1991 BINOP_LOG(nir_op_ine, SpvOpINotEqual, SpvOpLogicalNotEqual)
1992 BINOP_LOG(nir_op_ixor, SpvOpBitwiseXor, SpvOpLogicalNotEqual)
1993 #undef BINOP_LOG
1994
1995 #define BINOP_SHIFT(nir_op, spirv_op) \
1996 case nir_op: { \
1997 assert(nir_op_infos[alu->op].num_inputs == 2); \
1998 int shift_bit_size = nir_src_bit_size(alu->src[1].src); \
1999 nir_alu_type shift_nir_type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[1]); \
2000 SpvId shift_type = get_alu_type(ctx, shift_nir_type, num_components, shift_bit_size); \
2001 SpvId shift_mask = get_ivec_constant(ctx, shift_bit_size, num_components, bit_size - 1); \
2002 SpvId shift_count = emit_binop(ctx, SpvOpBitwiseAnd, shift_type, src[1], shift_mask); \
2003 result = emit_binop(ctx, spirv_op, dest_type, src[0], shift_count); \
2004 break; \
2005 }
2006
2007 BINOP_SHIFT(nir_op_ishl, SpvOpShiftLeftLogical)
2008 BINOP_SHIFT(nir_op_ishr, SpvOpShiftRightArithmetic)
2009 BINOP_SHIFT(nir_op_ushr, SpvOpShiftRightLogical)
2010 #undef BINOP_SHIFT
2011
2012 #define BUILTIN_BINOP(nir_op, spirv_op) \
2013 case nir_op: \
2014 assert(nir_op_infos[alu->op].num_inputs == 2); \
2015 result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
2016 break;
2017
2018 BUILTIN_BINOP(nir_op_fmin, GLSLstd450FMin)
2019 BUILTIN_BINOP(nir_op_fmax, GLSLstd450FMax)
2020 BUILTIN_BINOP(nir_op_imin, GLSLstd450SMin)
2021 BUILTIN_BINOP(nir_op_imax, GLSLstd450SMax)
2022 BUILTIN_BINOP(nir_op_umin, GLSLstd450UMin)
2023 BUILTIN_BINOP(nir_op_umax, GLSLstd450UMax)
2024 BUILTIN_BINOP(nir_op_ldexp, GLSLstd450Ldexp)
2025 #undef BUILTIN_BINOP
2026
2027 #define INTEL_BINOP(nir_op, spirv_op) \
2028 case nir_op: \
2029 assert(nir_op_infos[alu->op].num_inputs == 2); \
2030 result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
2031 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityIntegerFunctions2INTEL); \
2032 spirv_builder_emit_extension(&ctx->builder, "SPV_INTEL_shader_integer_functions2"); \
2033 break;
2034
2035 INTEL_BINOP(nir_op_uabs_isub, SpvOpAbsISubINTEL)
2036 INTEL_BINOP(nir_op_uabs_usub, SpvOpAbsUSubINTEL)
2037 INTEL_BINOP(nir_op_iadd_sat, SpvOpIAddSatINTEL)
2038 INTEL_BINOP(nir_op_uadd_sat, SpvOpUAddSatINTEL)
2039 INTEL_BINOP(nir_op_ihadd, SpvOpIAverageINTEL)
2040 INTEL_BINOP(nir_op_uhadd, SpvOpUAverageINTEL)
2041 INTEL_BINOP(nir_op_irhadd, SpvOpIAverageRoundedINTEL)
2042 INTEL_BINOP(nir_op_urhadd, SpvOpUAverageRoundedINTEL)
2043 INTEL_BINOP(nir_op_isub_sat, SpvOpISubSatINTEL)
2044 INTEL_BINOP(nir_op_usub_sat, SpvOpUSubSatINTEL)
2045 INTEL_BINOP(nir_op_imul_32x16, SpvOpIMul32x16INTEL)
2046 INTEL_BINOP(nir_op_umul_32x16, SpvOpUMul32x16INTEL)
2047 #undef INTEL_BINOP
2048
2049 case nir_op_fdot2:
2050 case nir_op_fdot3:
2051 case nir_op_fdot4:
2052 assert(nir_op_infos[alu->op].num_inputs == 2);
2053 result = emit_binop(ctx, SpvOpDot, dest_type, src[0], src[1]);
2054 break;
2055
2056 case nir_op_fdph:
2057 case nir_op_seq:
2058 case nir_op_sne:
2059 case nir_op_slt:
2060 case nir_op_sge:
2061 unreachable("should already be lowered away");
2062
2063 case nir_op_fneu:
2064 assert(nir_op_infos[alu->op].num_inputs == 2);
2065 if (raw_src[0] == raw_src[1])
2066 result = emit_unop(ctx, SpvOpIsNan, dest_type, src[0]);
2067 else
2068 result = emit_binop(ctx, SpvOpFUnordNotEqual, dest_type, src[0], src[1]);
2069 break;
2070
2071 case nir_op_feq:
2072 assert(nir_op_infos[alu->op].num_inputs == 2);
2073 if (raw_src[0] == raw_src[1])
2074 result = emit_unop(ctx, SpvOpLogicalNot, dest_type,
2075 emit_unop(ctx, SpvOpIsNan, dest_type, src[0]));
2076 else
2077 result = emit_binop(ctx, SpvOpFOrdEqual, dest_type, src[0], src[1]);
2078 break;
2079
2080 case nir_op_flrp:
2081 assert(nir_op_infos[alu->op].num_inputs == 3);
2082 result = emit_builtin_triop(ctx, GLSLstd450FMix, dest_type,
2083 src[0], src[1], src[2]);
2084 break;
2085
2086 case nir_op_bcsel:
2087 assert(nir_op_infos[alu->op].num_inputs == 3);
2088 result = emit_select(ctx, dest_type, src[0], src[1], src[2]);
2089 break;
2090
2091 case nir_op_pack_half_2x16_split: {
2092 SpvId fvec = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, 32, 2),
2093 src, 2);
2094 result = emit_builtin_unop(ctx, GLSLstd450PackHalf2x16, dest_type, fvec);
2095 break;
2096 }
2097 case nir_op_vec2:
2098 case nir_op_vec3:
2099 case nir_op_vec4: {
2100 int num_inputs = nir_op_infos[alu->op].num_inputs;
2101 assert(2 <= num_inputs && num_inputs <= 4);
2102 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type,
2103 src, num_inputs);
2104 }
2105 break;
2106
2107 case nir_op_ubitfield_extract:
2108 assert(nir_op_infos[alu->op].num_inputs == 3);
2109 result = emit_triop(ctx, SpvOpBitFieldUExtract, dest_type, src[0], src[1], src[2]);
2110 break;
2111
2112 case nir_op_ibitfield_extract:
2113 assert(nir_op_infos[alu->op].num_inputs == 3);
2114 result = emit_triop(ctx, SpvOpBitFieldSExtract, dest_type, src[0], src[1], src[2]);
2115 break;
2116
2117 case nir_op_bitfield_insert:
2118 assert(nir_op_infos[alu->op].num_inputs == 4);
2119 result = spirv_builder_emit_quadop(&ctx->builder, SpvOpBitFieldInsert, dest_type, src[0], src[1], src[2], src[3]);
2120 break;
2121
2122 /* those are all simple bitcasts, we could do better, but it doesn't matter */
2123 case nir_op_pack_32_4x8:
2124 case nir_op_pack_32_2x16:
2125 case nir_op_pack_64_4x16:
2126 case nir_op_unpack_32_4x8:
2127 case nir_op_unpack_32_2x16:
2128 case nir_op_unpack_64_4x16: {
2129 result = emit_bitcast(ctx, dest_type, src[0]);
2130 break;
2131 }
2132
2133 case nir_op_pack_32_2x16_split:
2134 case nir_op_pack_64_2x32_split: {
2135 nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2136 if (num_components <= 2) {
2137 SpvId components[] = {src[0], src[1]};
2138 SpvId vec_type = get_alu_type(ctx, type, num_components * 2, nir_src_bit_size(alu->src[0].src));
2139 result = spirv_builder_emit_composite_construct(&ctx->builder, vec_type, components, 2);
2140 result = emit_bitcast(ctx, dest_type, result);
2141 } else {
2142 SpvId components[NIR_MAX_VEC_COMPONENTS];
2143 SpvId conv_type = get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src));
2144 SpvId vec_type = get_alu_type(ctx, type, 2, nir_src_bit_size(alu->src[0].src));
2145 SpvId dest_scalar_type = get_alu_type(ctx, nir_op_infos[alu->op].output_type, 1, bit_size);
2146 for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2147 SpvId conv[2];
2148 conv[0] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, src[0], &i, 1);
2149 conv[1] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, src[1], &i, 1);
2150 SpvId vec = spirv_builder_emit_composite_construct(&ctx->builder, vec_type, conv, 2);
2151 components[i] = emit_bitcast(ctx, dest_scalar_type, vec);
2152 }
2153 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2154 }
2155 break;
2156 }
2157
2158 case nir_op_unpack_32_2x16_split_x:
2159 case nir_op_unpack_64_2x32_split_x: {
2160 nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2161 SpvId vec_type = get_alu_type(ctx, type, 2, bit_size);
2162 unsigned idx = 0;
2163 if (num_components == 1) {
2164 SpvId vec = emit_bitcast(ctx, vec_type, src[0]);
2165 result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, vec, &idx, 1);
2166 } else {
2167 SpvId components[NIR_MAX_VEC_COMPONENTS];
2168 for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2169 SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src)), src[0], &i, 1);
2170 conv = emit_bitcast(ctx, vec_type, conv);
2171 SpvId conv_type = get_alu_type(ctx, type, 1, bit_size);
2172 components[i] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, conv, &idx, 1);
2173 }
2174 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2175 }
2176 break;
2177 }
2178
2179 case nir_op_unpack_32_2x16_split_y:
2180 case nir_op_unpack_64_2x32_split_y: {
2181 nir_alu_type type = nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[0]);
2182 SpvId vec_type = get_alu_type(ctx, type, 2, bit_size);
2183 unsigned idx = 1;
2184 if (num_components == 1) {
2185 SpvId vec = emit_bitcast(ctx, vec_type, src[0]);
2186 result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, vec, &idx, 1);
2187 } else {
2188 SpvId components[NIR_MAX_VEC_COMPONENTS];
2189 for (unsigned i = 0; i < nir_src_num_components(alu->src[0].src); i++) {
2190 SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, get_alu_type(ctx, type, 1, nir_src_bit_size(alu->src[0].src)), src[0], &i, 1);
2191 conv = emit_bitcast(ctx, vec_type, conv);
2192 SpvId conv_type = get_alu_type(ctx, type, 1, bit_size);
2193 components[i] = spirv_builder_emit_composite_extract(&ctx->builder, conv_type, conv, &idx, 1);
2194 }
2195 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, components, num_components);
2196 }
2197 break;
2198 }
2199
2200 default:
2201 fprintf(stderr, "emit_alu: not implemented (%s)\n",
2202 nir_op_infos[alu->op].name);
2203
2204 unreachable("unsupported opcode");
2205 return;
2206 }
2207 if (alu->exact)
2208 spirv_builder_emit_decoration(&ctx->builder, result, SpvDecorationNoContraction);
2209
2210 store_alu_result(ctx, alu, result, atype);
2211 }
2212
2213 static void
emit_load_const(struct ntv_context * ctx,nir_load_const_instr * load_const)2214 emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const)
2215 {
2216 unsigned bit_size = load_const->def.bit_size;
2217 unsigned num_components = load_const->def.num_components;
2218
2219 SpvId components[NIR_MAX_VEC_COMPONENTS];
2220 nir_alu_type atype;
2221 if (bit_size == 1) {
2222 atype = nir_type_bool;
2223 for (int i = 0; i < num_components; i++)
2224 components[i] = spirv_builder_const_bool(&ctx->builder,
2225 load_const->value[i].b);
2226 } else {
2227 atype = infer_nir_alu_type_from_uses_ssa(&load_const->def);
2228 for (int i = 0; i < num_components; i++) {
2229 switch (atype) {
2230 case nir_type_uint: {
2231 uint64_t tmp = nir_const_value_as_uint(load_const->value[i], bit_size);
2232 components[i] = emit_uint_const(ctx, bit_size, tmp);
2233 break;
2234 }
2235 case nir_type_int: {
2236 int64_t tmp = nir_const_value_as_int(load_const->value[i], bit_size);
2237 components[i] = emit_int_const(ctx, bit_size, tmp);
2238 break;
2239 }
2240 case nir_type_float: {
2241 double tmp = nir_const_value_as_float(load_const->value[i], bit_size);
2242 components[i] = emit_float_const(ctx, bit_size, tmp);
2243 break;
2244 }
2245 default:
2246 unreachable("this shouldn't happen!");
2247 }
2248 }
2249 }
2250
2251 if (num_components > 1) {
2252 SpvId type = get_alu_type(ctx, atype, num_components, bit_size);
2253 SpvId value = spirv_builder_const_composite(&ctx->builder,
2254 type, components,
2255 num_components);
2256 store_ssa_def(ctx, &load_const->def, value, atype);
2257 } else {
2258 assert(num_components == 1);
2259 store_ssa_def(ctx, &load_const->def, components[0], atype);
2260 }
2261 }
2262
2263 static void
emit_discard(struct ntv_context * ctx,nir_intrinsic_instr * intr)2264 emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2265 {
2266 assert(ctx->discard_func);
2267 SpvId type_void = spirv_builder_type_void(&ctx->builder);
2268 spirv_builder_function_call(&ctx->builder, type_void,
2269 ctx->discard_func, NULL, 0);
2270 }
2271
2272 static void
emit_load_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2273 emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2274 {
2275 nir_alu_type atype;
2276 SpvId ptr = get_src(ctx, intr->src, &atype);
2277
2278 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2279 SpvId type;
2280 if (glsl_type_is_image(deref->type)) {
2281 nir_variable *var = nir_deref_instr_get_variable(deref);
2282 const struct glsl_type *gtype = glsl_without_array(var->type);
2283 type = get_image_type(ctx, var,
2284 glsl_type_is_sampler(gtype),
2285 glsl_get_sampler_dim(gtype) == GLSL_SAMPLER_DIM_BUF);
2286 atype = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(gtype));
2287 } else {
2288 type = get_glsl_type(ctx, deref->type);
2289 atype = get_nir_alu_type(deref->type);
2290 }
2291 SpvId result;
2292
2293 if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2294 result = emit_atomic(ctx, SpvOpAtomicLoad, type, ptr, 0, 0);
2295 else
2296 result = spirv_builder_emit_load(&ctx->builder, type, ptr);
2297 store_def(ctx, &intr->def, result, atype);
2298 }
2299
2300 static void
emit_store_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2301 emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2302 {
2303 nir_alu_type ptype, stype;
2304 SpvId ptr = get_src(ctx, &intr->src[0], &ptype);
2305 SpvId src = get_src(ctx, &intr->src[1], &stype);
2306
2307 const struct glsl_type *gtype = nir_src_as_deref(intr->src[0])->type;
2308 SpvId type = get_glsl_type(ctx, gtype);
2309 nir_variable *var = nir_intrinsic_get_var(intr, 0);
2310 unsigned wrmask = nir_intrinsic_write_mask(intr);
2311 if (!glsl_type_is_scalar(gtype) &&
2312 wrmask != BITFIELD_MASK(glsl_type_is_array(gtype) ? glsl_get_aoa_size(gtype) : glsl_get_vector_elements(gtype))) {
2313 /* no idea what we do if this fails */
2314 assert(glsl_type_is_array(gtype) || glsl_type_is_vector(gtype));
2315
2316 /* this is a partial write, so we have to loop and do a per-component write */
2317 SpvId result_type;
2318 SpvId member_type;
2319 if (glsl_type_is_vector(gtype)) {
2320 result_type = get_glsl_basetype(ctx, glsl_get_base_type(gtype));
2321 member_type = get_alu_type(ctx, stype, 1, glsl_get_bit_size(gtype));
2322 } else
2323 member_type = result_type = get_glsl_type(ctx, glsl_get_array_element(gtype));
2324 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2325 get_storage_class(var),
2326 result_type);
2327 for (unsigned i = 0; i < 4; i++)
2328 if (wrmask & BITFIELD_BIT(i)) {
2329 SpvId idx = emit_uint_const(ctx, 32, i);
2330 SpvId val = spirv_builder_emit_composite_extract(&ctx->builder, member_type, src, &i, 1);
2331 if (stype != ptype)
2332 val = emit_bitcast(ctx, result_type, val);
2333 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2334 ptr, &idx, 1);
2335 spirv_builder_emit_store(&ctx->builder, member, val);
2336 }
2337 return;
2338
2339 }
2340 SpvId result;
2341 if (ctx->stage == MESA_SHADER_FRAGMENT &&
2342 var->data.mode == nir_var_shader_out &&
2343 var->data.location == FRAG_RESULT_SAMPLE_MASK) {
2344 src = emit_bitcast(ctx, type, src);
2345 /* SampleMask is always an array in spirv, so we need to construct it into one */
2346 result = spirv_builder_emit_composite_construct(&ctx->builder, ctx->sample_mask_type, &src, 1);
2347 } else {
2348 if (ptype == stype)
2349 result = src;
2350 else
2351 result = emit_bitcast(ctx, type, src);
2352 }
2353 if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2354 spirv_builder_emit_atomic_store(&ctx->builder, ptr, SpvScopeDevice, 0, result);
2355 else
2356 spirv_builder_emit_store(&ctx->builder, ptr, result);
2357 }
2358
2359 static void
emit_load_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2360 emit_load_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2361 {
2362 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2363 unsigned num_components = intr->def.num_components;
2364 unsigned bit_size = intr->def.bit_size;
2365 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2366 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2367 SpvStorageClassWorkgroup,
2368 uint_type);
2369 nir_alu_type atype;
2370 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2371 if (atype == nir_type_float)
2372 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2373 SpvId constituents[NIR_MAX_VEC_COMPONENTS];
2374 SpvId shared_block = get_shared_block(ctx, bit_size);
2375 /* need to convert array -> vec */
2376 for (unsigned i = 0; i < num_components; i++) {
2377 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2378 shared_block, &offset, 1);
2379 constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
2380 offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, 1));
2381 }
2382 SpvId result;
2383 if (num_components > 1)
2384 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
2385 else
2386 result = constituents[0];
2387 store_def(ctx, &intr->def, result, nir_type_uint);
2388 }
2389
2390 static void
emit_store_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2391 emit_store_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2392 {
2393 nir_alu_type atype;
2394 SpvId src = get_src(ctx, &intr->src[0], &atype);
2395
2396 unsigned wrmask = nir_intrinsic_write_mask(intr);
2397 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2398 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2399 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2400 SpvStorageClassWorkgroup,
2401 uint_type);
2402 nir_alu_type otype;
2403 SpvId offset = get_src(ctx, &intr->src[1], &otype);
2404 if (otype == nir_type_float)
2405 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2406 SpvId shared_block = get_shared_block(ctx, bit_size);
2407 /* this is a partial write, so we have to loop and do a per-component write */
2408 u_foreach_bit(i, wrmask) {
2409 SpvId shared_offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, i));
2410 SpvId val = src;
2411 if (nir_src_num_components(intr->src[0]) != 1)
2412 val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &i, 1);
2413 if (atype != nir_type_uint)
2414 val = emit_bitcast(ctx, get_alu_type(ctx, nir_type_uint, 1, bit_size), val);
2415 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2416 shared_block, &shared_offset, 1);
2417 spirv_builder_emit_store(&ctx->builder, member, val);
2418 }
2419 }
2420
2421 static void
emit_load_scratch(struct ntv_context * ctx,nir_intrinsic_instr * intr)2422 emit_load_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2423 {
2424 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2425 unsigned num_components = intr->def.num_components;
2426 unsigned bit_size = intr->def.bit_size;
2427 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2428 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2429 SpvStorageClassPrivate,
2430 uint_type);
2431 nir_alu_type atype;
2432 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2433 if (atype != nir_type_uint)
2434 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2435 SpvId constituents[NIR_MAX_VEC_COMPONENTS];
2436 SpvId scratch_block = get_scratch_block(ctx, bit_size);
2437 /* need to convert array -> vec */
2438 for (unsigned i = 0; i < num_components; i++) {
2439 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2440 scratch_block, &offset, 1);
2441 constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
2442 offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, 1));
2443 }
2444 SpvId result;
2445 if (num_components > 1)
2446 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
2447 else
2448 result = constituents[0];
2449 store_def(ctx, &intr->def, result, nir_type_uint);
2450 }
2451
2452 static void
emit_store_scratch(struct ntv_context * ctx,nir_intrinsic_instr * intr)2453 emit_store_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2454 {
2455 nir_alu_type atype;
2456 SpvId src = get_src(ctx, &intr->src[0], &atype);
2457
2458 unsigned wrmask = nir_intrinsic_write_mask(intr);
2459 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2460 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2461 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2462 SpvStorageClassPrivate,
2463 uint_type);
2464 nir_alu_type otype;
2465 SpvId offset = get_src(ctx, &intr->src[1], &otype);
2466 if (otype != nir_type_uint)
2467 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[1]), 1);
2468 SpvId scratch_block = get_scratch_block(ctx, bit_size);
2469 /* this is a partial write, so we have to loop and do a per-component write */
2470 u_foreach_bit(i, wrmask) {
2471 SpvId scratch_offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, i));
2472 SpvId val = src;
2473 if (nir_src_num_components(intr->src[0]) != 1)
2474 val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &i, 1);
2475 if (atype != nir_type_uint)
2476 val = emit_bitcast(ctx, get_alu_type(ctx, nir_type_uint, 1, bit_size), val);
2477 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2478 scratch_block, &scratch_offset, 1);
2479 spirv_builder_emit_store(&ctx->builder, member, val);
2480 }
2481 }
2482
2483 static void
emit_load_push_const(struct ntv_context * ctx,nir_intrinsic_instr * intr)2484 emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2485 {
2486 SpvId uint_type = get_uvec_type(ctx, 32, 1);
2487 SpvId load_type = get_uvec_type(ctx, 32, 1);
2488
2489 /* number of components being loaded */
2490 unsigned num_components = intr->def.num_components;
2491 SpvId constituents[NIR_MAX_VEC_COMPONENTS * 2];
2492 SpvId result;
2493
2494 /* destination type for the load */
2495 SpvId type = get_def_uvec_type(ctx, &intr->def);
2496 SpvId one = emit_uint_const(ctx, 32, 1);
2497
2498 /* we grab a single array member at a time, so it's a pointer to a uint */
2499 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2500 SpvStorageClassPushConstant,
2501 load_type);
2502
2503 nir_alu_type atype;
2504 SpvId member = get_src(ctx, &intr->src[0], &atype);
2505 if (atype == nir_type_float)
2506 member = bitcast_to_uvec(ctx, member, nir_src_bit_size(intr->src[0]), 1);
2507 /* reuse the offset from ZINK_PUSH_CONST_OFFSET */
2508 SpvId offset = emit_uint_const(ctx, 32, nir_intrinsic_component(intr));
2509 /* OpAccessChain takes an array of indices that drill into a hierarchy based on the type:
2510 * index 0 is accessing 'base'
2511 * index 1 is accessing 'base[index 1]'
2512 *
2513 */
2514 for (unsigned i = 0; i < num_components; i++) {
2515 SpvId indices[2] = { member, offset };
2516 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2517 ctx->push_const_var, indices,
2518 ARRAY_SIZE(indices));
2519 /* load a single value into the constituents array */
2520 constituents[i] = spirv_builder_emit_load(&ctx->builder, load_type, ptr);
2521 /* increment to the next vec4 member index for the next load */
2522 offset = emit_binop(ctx, SpvOpIAdd, uint_type, offset, one);
2523 }
2524
2525 /* if loading more than 1 value, reassemble the results into the desired type,
2526 * otherwise just use the loaded result
2527 */
2528 if (num_components > 1) {
2529 result = spirv_builder_emit_composite_construct(&ctx->builder,
2530 type,
2531 constituents,
2532 num_components);
2533 } else
2534 result = constituents[0];
2535
2536 store_def(ctx, &intr->def, result, nir_type_uint);
2537 }
2538
2539 static void
emit_load_global(struct ntv_context * ctx,nir_intrinsic_instr * intr)2540 emit_load_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2541 {
2542 bool coherent = ctx->sinfo->have_vulkan_memory_model && nir_intrinsic_access(intr) & ACCESS_COHERENT;
2543 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2544 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2545 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2546 SpvStorageClassPhysicalStorageBuffer,
2547 dest_type);
2548 nir_alu_type atype;
2549 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[0], &atype));
2550 SpvId result = spirv_builder_emit_load_aligned(&ctx->builder, dest_type, ptr, intr->def.bit_size / 8, coherent);
2551 store_def(ctx, &intr->def, result, nir_type_uint);
2552 }
2553
2554 static void
emit_store_global(struct ntv_context * ctx,nir_intrinsic_instr * intr)2555 emit_store_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2556 {
2557 bool coherent = ctx->sinfo->have_vulkan_memory_model && nir_intrinsic_access(intr) & ACCESS_COHERENT;
2558 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2559 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2560 SpvId dest_type = get_uvec_type(ctx, bit_size, 1);
2561 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2562 SpvStorageClassPhysicalStorageBuffer,
2563 dest_type);
2564 nir_alu_type atype;
2565 SpvId param = get_src(ctx, &intr->src[0], &atype);
2566 if (atype != nir_type_uint)
2567 param = emit_bitcast(ctx, dest_type, param);
2568 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[1], &atype));
2569 spirv_builder_emit_store_aligned(&ctx->builder, ptr, param, bit_size / 8, coherent);
2570 }
2571
2572 static void
emit_load_reg(struct ntv_context * ctx,nir_intrinsic_instr * intr)2573 emit_load_reg(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2574 {
2575 assert(nir_intrinsic_base(intr) == 0 && "no array registers");
2576
2577 nir_intrinsic_instr *decl = nir_reg_get_decl(intr->src[0].ssa);
2578 unsigned num_components = nir_intrinsic_num_components(decl);
2579 unsigned bit_size = nir_intrinsic_bit_size(decl);
2580 unsigned index = decl->def.index;
2581 assert(index < ctx->num_defs);
2582
2583 init_reg(ctx, decl, nir_type_uint);
2584 assert(ctx->defs[index] != 0);
2585
2586 nir_alu_type atype = ctx->def_types[index];
2587 SpvId var = ctx->defs[index];
2588 SpvId type = get_alu_type(ctx, atype, num_components, bit_size);
2589 SpvId result = spirv_builder_emit_load(&ctx->builder, type, var);
2590 store_def(ctx, &intr->def, result, atype);
2591 }
2592
2593 static void
emit_store_reg(struct ntv_context * ctx,nir_intrinsic_instr * intr)2594 emit_store_reg(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2595 {
2596 nir_alu_type atype;
2597 SpvId param = get_src(ctx, &intr->src[0], &atype);
2598
2599 nir_intrinsic_instr *decl = nir_reg_get_decl(intr->src[1].ssa);
2600 unsigned index = decl->def.index;
2601 unsigned num_components = nir_intrinsic_num_components(decl);
2602 unsigned bit_size = nir_intrinsic_bit_size(decl);
2603
2604 atype = nir_alu_type_get_base_type(atype);
2605 init_reg(ctx, decl, atype);
2606 SpvId var = ctx->defs[index];
2607 nir_alu_type vtype = ctx->def_types[index];
2608 if (atype != vtype) {
2609 assert(vtype != nir_type_bool);
2610 param = emit_bitcast(ctx, get_alu_type(ctx, vtype, num_components, bit_size), param);
2611 }
2612 assert(var);
2613 spirv_builder_emit_store(&ctx->builder, var, param);
2614 }
2615
2616 static SpvId
create_builtin_var(struct ntv_context * ctx,SpvId var_type,SpvStorageClass storage_class,const char * name,SpvBuiltIn builtin)2617 create_builtin_var(struct ntv_context *ctx, SpvId var_type,
2618 SpvStorageClass storage_class,
2619 const char *name, SpvBuiltIn builtin)
2620 {
2621 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2622 storage_class,
2623 var_type);
2624 SpvId var = spirv_builder_emit_var(&ctx->builder, pointer_type,
2625 storage_class);
2626 spirv_builder_emit_name(&ctx->builder, var, name);
2627 spirv_builder_emit_builtin(&ctx->builder, var, builtin);
2628
2629 if (ctx->stage == MESA_SHADER_FRAGMENT) {
2630 switch (builtin) {
2631 case SpvBuiltInSampleId:
2632 case SpvBuiltInSubgroupLocalInvocationId:
2633 spirv_builder_emit_decoration(&ctx->builder, var, SpvDecorationFlat);
2634 break;
2635 default:
2636 break;
2637 }
2638 }
2639
2640 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
2641 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var;
2642 return var;
2643 }
2644
2645 static void
emit_load_front_face(struct ntv_context * ctx,nir_intrinsic_instr * intr)2646 emit_load_front_face(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2647 {
2648 SpvId var_type = spirv_builder_type_bool(&ctx->builder);
2649 if (!ctx->front_face_var)
2650 ctx->front_face_var = create_builtin_var(ctx, var_type,
2651 SpvStorageClassInput,
2652 "gl_FrontFacing",
2653 SpvBuiltInFrontFacing);
2654
2655 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
2656 ctx->front_face_var);
2657 assert(1 == intr->def.num_components);
2658 store_def(ctx, &intr->def, result, nir_type_bool);
2659 }
2660
2661 static void
emit_load_uint_input(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId * var_id,const char * var_name,SpvBuiltIn builtin)2662 emit_load_uint_input(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId *var_id, const char *var_name, SpvBuiltIn builtin)
2663 {
2664 SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
2665 if (!*var_id) {
2666 if (builtin == SpvBuiltInSampleMask) {
2667 /* gl_SampleMaskIn is an array[1] in spirv... */
2668 var_type = spirv_builder_type_array(&ctx->builder, var_type, emit_uint_const(ctx, 32, 1));
2669 spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(uint32_t));
2670 }
2671 *var_id = create_builtin_var(ctx, var_type,
2672 SpvStorageClassInput,
2673 var_name,
2674 builtin);
2675 }
2676
2677 SpvId load_var = *var_id;
2678 if (builtin == SpvBuiltInSampleMask) {
2679 SpvId zero = emit_uint_const(ctx, 32, 0);
2680 var_type = spirv_builder_type_uint(&ctx->builder, 32);
2681 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2682 SpvStorageClassInput,
2683 var_type);
2684 load_var = spirv_builder_emit_access_chain(&ctx->builder, pointer_type, load_var, &zero, 1);
2685 }
2686
2687 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, load_var);
2688 assert(1 == intr->def.num_components);
2689 store_def(ctx, &intr->def, result, nir_type_uint);
2690 }
2691
2692 static void
emit_load_vec_input(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId * var_id,const char * var_name,SpvBuiltIn builtin,nir_alu_type type)2693 emit_load_vec_input(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId *var_id, const char *var_name, SpvBuiltIn builtin, nir_alu_type type)
2694 {
2695 SpvId var_type;
2696
2697 switch (type) {
2698 case nir_type_bool:
2699 var_type = get_bvec_type(ctx, intr->def.num_components);
2700 break;
2701 case nir_type_int:
2702 var_type = get_ivec_type(ctx, intr->def.bit_size,
2703 intr->def.num_components);
2704 break;
2705 case nir_type_uint:
2706 var_type = get_uvec_type(ctx, intr->def.bit_size,
2707 intr->def.num_components);
2708 break;
2709 case nir_type_float:
2710 var_type = get_fvec_type(ctx, intr->def.bit_size,
2711 intr->def.num_components);
2712 break;
2713 default:
2714 unreachable("unknown type passed");
2715 }
2716 if (!*var_id)
2717 *var_id = create_builtin_var(ctx, var_type,
2718 SpvStorageClassInput,
2719 var_name,
2720 builtin);
2721
2722 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, *var_id);
2723 store_def(ctx, &intr->def, result, type);
2724 }
2725
2726 static void
emit_interpolate(struct ntv_context * ctx,nir_intrinsic_instr * intr)2727 emit_interpolate(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2728 {
2729 SpvId op;
2730 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInterpolationFunction);
2731 SpvId src1 = 0;
2732 nir_alu_type atype;
2733 switch (intr->intrinsic) {
2734 case nir_intrinsic_interp_deref_at_centroid:
2735 op = GLSLstd450InterpolateAtCentroid;
2736 break;
2737 case nir_intrinsic_interp_deref_at_sample:
2738 op = GLSLstd450InterpolateAtSample;
2739 src1 = get_src(ctx, &intr->src[1], &atype);
2740 break;
2741 case nir_intrinsic_interp_deref_at_offset:
2742 op = GLSLstd450InterpolateAtOffset;
2743 src1 = get_src(ctx, &intr->src[1], &atype);
2744 /*
2745 The offset operand must be a vector of 2 components of 32-bit floating-point type.
2746 - InterpolateAtOffset spec
2747 */
2748 if (atype != nir_type_float)
2749 src1 = emit_bitcast(ctx, get_fvec_type(ctx, 32, 2), src1);
2750 break;
2751 default:
2752 unreachable("unknown interp op");
2753 }
2754 nir_alu_type ptype;
2755 SpvId ptr = get_src(ctx, &intr->src[0], &ptype);
2756 SpvId result;
2757 const struct glsl_type *gtype = nir_src_as_deref(intr->src[0])->type;
2758 assert(ptype == get_nir_alu_type(gtype));
2759 if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid)
2760 result = emit_builtin_unop(ctx, op, get_glsl_type(ctx, gtype), ptr);
2761 else
2762 result = emit_builtin_binop(ctx, op, get_glsl_type(ctx, gtype), ptr, src1);
2763 store_def(ctx, &intr->def, result, ptype);
2764 }
2765
2766 static void
handle_atomic_op(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId ptr,SpvId param,SpvId param2,nir_alu_type type)2767 handle_atomic_op(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId ptr, SpvId param, SpvId param2, nir_alu_type type)
2768 {
2769 SpvId dest_type = get_def_type(ctx, &intr->def, type);
2770 SpvId result = emit_atomic(ctx,
2771 get_atomic_op(ctx, intr->def.bit_size, nir_intrinsic_atomic_op(intr)),
2772 dest_type, ptr, param, param2);
2773 assert(result);
2774 store_def(ctx, &intr->def, result, type);
2775 }
2776
2777 static void
emit_deref_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2778 emit_deref_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2779 {
2780 nir_alu_type atype;
2781 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2782 SpvId ptr = get_src(ctx, &intr->src[0], &atype);
2783 SpvId param = get_src(ctx, &intr->src[1], &atype);
2784 if (atype != ret_type)
2785 param = cast_src_to_type(ctx, param, intr->src[1], ret_type);
2786
2787 SpvId param2 = 0;
2788
2789 if (nir_src_bit_size(intr->src[1]) == 64)
2790 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2791
2792 if (intr->intrinsic == nir_intrinsic_deref_atomic_swap) {
2793 param2 = get_src(ctx, &intr->src[2], &atype);
2794 if (atype != ret_type)
2795 param2 = cast_src_to_type(ctx, param2, intr->src[2], ret_type);
2796 }
2797
2798 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2799 }
2800
2801 static void
emit_shared_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2802 emit_shared_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2803 {
2804 unsigned bit_size = nir_src_bit_size(intr->src[1]);
2805 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2806 nir_alu_type atype;
2807 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2808 SpvId param = get_src(ctx, &intr->src[1], &atype);
2809 if (atype != ret_type)
2810 param = cast_src_to_type(ctx, param, intr->src[1], ret_type);
2811
2812 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2813 SpvStorageClassWorkgroup,
2814 dest_type);
2815 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2816 if (atype != nir_type_uint)
2817 offset = cast_src_to_type(ctx, offset, intr->src[0], nir_type_uint);
2818 offset = emit_binop(ctx, SpvOpUDiv, get_uvec_type(ctx, 32, 1), offset, emit_uint_const(ctx, 32, bit_size / 8));
2819 SpvId shared_block = get_shared_block(ctx, bit_size);
2820 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2821 shared_block, &offset, 1);
2822 if (nir_src_bit_size(intr->src[1]) == 64)
2823 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2824 SpvId param2 = 0;
2825
2826 if (intr->intrinsic == nir_intrinsic_shared_atomic_swap) {
2827 param2 = get_src(ctx, &intr->src[2], &atype);
2828 if (atype != ret_type)
2829 param2 = cast_src_to_type(ctx, param2, intr->src[2], ret_type);
2830 }
2831
2832 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2833 }
2834
2835 static void
emit_global_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2836 emit_global_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2837 {
2838 unsigned bit_size = nir_src_bit_size(intr->src[1]);
2839 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2840 nir_alu_type atype;
2841 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2842 SpvId param = get_src(ctx, &intr->src[1], &atype);
2843
2844 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2845 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2846 SpvStorageClassPhysicalStorageBuffer,
2847 dest_type);
2848 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[0], &atype));
2849
2850 if (bit_size == 64)
2851 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2852 SpvId param2 = 0;
2853
2854 if (intr->intrinsic == nir_intrinsic_global_atomic_swap)
2855 param2 = get_src(ctx, &intr->src[2], &atype);
2856
2857 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2858 }
2859
2860 static void
emit_get_ssbo_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)2861 emit_get_ssbo_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2862 {
2863 SpvId uint_type = get_uvec_type(ctx, 32, 1);
2864 nir_variable *var = ctx->ssbo_vars;
2865 const struct glsl_type *bare_type = glsl_without_array(var->type);
2866 unsigned last_member_idx = glsl_get_length(bare_type) - 1;
2867 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2868 SpvStorageClassStorageBuffer,
2869 get_bo_struct_type(ctx, var));
2870 nir_alu_type atype;
2871 SpvId bo = get_src(ctx, &intr->src[0], &atype);
2872 if (atype == nir_type_float)
2873 bo = bitcast_to_uvec(ctx, bo, nir_src_bit_size(intr->src[0]), 1);
2874 SpvId indices[] = { bo };
2875 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2876 ctx->ssbos[2], indices,
2877 ARRAY_SIZE(indices));
2878 SpvId result = spirv_builder_emit_binop(&ctx->builder, SpvOpArrayLength, uint_type,
2879 ptr, last_member_idx);
2880 /* this is going to be converted by nir to:
2881
2882 length = (buffer_size - offset) / stride
2883
2884 * so we need to un-convert it to avoid having the calculation performed twice
2885 */
2886 const struct glsl_type *last_member = glsl_get_struct_field(bare_type, last_member_idx);
2887 /* multiply by stride */
2888 result = emit_binop(ctx, SpvOpIMul, uint_type, result, emit_uint_const(ctx, 32, glsl_get_explicit_stride(last_member)));
2889 /* get total ssbo size by adding offset */
2890 result = emit_binop(ctx, SpvOpIAdd, uint_type, result,
2891 emit_uint_const(ctx, 32,
2892 glsl_get_struct_field_offset(bare_type, last_member_idx)));
2893 store_def(ctx, &intr->def, result, nir_type_uint);
2894 }
2895
2896 static SpvId
get_image_coords(struct ntv_context * ctx,const struct glsl_type * type,nir_src * src)2897 get_image_coords(struct ntv_context *ctx, const struct glsl_type *type, nir_src *src)
2898 {
2899 uint32_t num_coords = glsl_get_sampler_coordinate_components(type);
2900 uint32_t src_components = nir_src_num_components(*src);
2901
2902 nir_alu_type atype;
2903 SpvId spv = get_src(ctx, src, &atype);
2904 if (num_coords == src_components)
2905 return spv;
2906
2907 /* need to extract the coord dimensions that the image can use */
2908 SpvId vec_type = get_alu_type(ctx, atype, num_coords, 32);
2909 if (num_coords == 1)
2910 return spirv_builder_emit_vector_extract(&ctx->builder, vec_type, spv, 0);
2911 uint32_t constituents[4];
2912 SpvId zero = atype == nir_type_uint ? emit_uint_const(ctx, nir_src_bit_size(*src), 0) : emit_float_const(ctx, nir_src_bit_size(*src), 0);
2913 assert(num_coords < ARRAY_SIZE(constituents));
2914 for (unsigned i = 0; i < num_coords; i++)
2915 constituents[i] = i < src_components ? i : zero;
2916 return spirv_builder_emit_vector_shuffle(&ctx->builder, vec_type, spv, spv, constituents, num_coords);
2917 }
2918
2919 static void
emit_image_deref_store(struct ntv_context * ctx,nir_intrinsic_instr * intr)2920 emit_image_deref_store(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2921 {
2922 nir_alu_type atype;
2923 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
2924 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2925 nir_variable *var = nir_deref_instr_get_variable(deref);
2926 SpvId img_type = find_image_type(ctx, var);
2927 const struct glsl_type *type = glsl_without_array(var->type);
2928 SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2929 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2930 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2931 SpvId texel = get_src(ctx, &intr->src[3], &atype);
2932 /* texel type must match image type */
2933 if (atype != nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(type)))
2934 texel = emit_bitcast(ctx,
2935 spirv_builder_type_vector(&ctx->builder, base_type, 4),
2936 texel);
2937 bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2938 glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2939 SpvId sample = use_sample ? get_src(ctx, &intr->src[2], &atype) : 0;
2940 assert(nir_src_bit_size(intr->src[3]) == glsl_base_type_bit_size(glsl_get_sampler_result_type(type)));
2941 spirv_builder_emit_image_write(&ctx->builder, img, coord, texel, 0, sample, 0);
2942 }
2943
2944 static SpvId
extract_sparse_load(struct ntv_context * ctx,SpvId result,SpvId dest_type,nir_def * def)2945 extract_sparse_load(struct ntv_context *ctx, SpvId result, SpvId dest_type, nir_def *def)
2946 {
2947 /* Result Type must be an OpTypeStruct with two members.
2948 * The first member’s type must be an integer type scalar.
2949 * It holds a Residency Code that can be passed to OpImageSparseTexelsResident
2950 * - OpImageSparseRead spec
2951 */
2952 uint32_t idx = 0;
2953 SpvId resident = spirv_builder_emit_composite_extract(&ctx->builder, spirv_builder_type_uint(&ctx->builder, 32), result, &idx, 1);
2954 idx = 1;
2955 /* normal vec4 return */
2956 if (def->num_components == 4)
2957 result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, result, &idx, 1);
2958 else {
2959 /* shadow */
2960 assert(def->num_components == 1);
2961 SpvId type = spirv_builder_type_float(&ctx->builder, def->bit_size);
2962 SpvId val[2];
2963 /* pad to 2 components: the upcoming is_sparse_texels_resident instr will always use the
2964 * separate residency value, but the shader still expects this return to be a vec2,
2965 * so give it a vec2
2966 */
2967 val[0] = spirv_builder_emit_composite_extract(&ctx->builder, type, result, &idx, 1);
2968 val[1] = emit_float_const(ctx, def->bit_size, 0);
2969 result = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, def->bit_size, 2), val, 2);
2970 }
2971 assert(resident != 0);
2972 assert(def->index < ctx->num_defs);
2973 ctx->resident_defs[def->index] = resident;
2974 return result;
2975 }
2976
2977 static void
emit_image_deref_load(struct ntv_context * ctx,nir_intrinsic_instr * intr)2978 emit_image_deref_load(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2979 {
2980 bool sparse = intr->intrinsic == nir_intrinsic_image_deref_sparse_load;
2981 nir_alu_type atype;
2982 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
2983 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2984 nir_variable *var = nir_deref_instr_get_variable(deref);
2985 bool mediump = (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW);
2986 SpvId img_type = find_image_type(ctx, var);
2987 const struct glsl_type *type = glsl_without_array(var->type);
2988 SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2989 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2990 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2991 bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2992 glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2993 SpvId sample = use_sample ? get_src(ctx, &intr->src[2], &atype) : 0;
2994 SpvId dest_type = spirv_builder_type_vector(&ctx->builder, base_type,
2995 intr->def.num_components);
2996 SpvId result = spirv_builder_emit_image_read(&ctx->builder,
2997 dest_type,
2998 img, coord, 0, sample, 0, sparse);
2999 if (sparse)
3000 result = extract_sparse_load(ctx, result, dest_type, &intr->def);
3001
3002 if (!sparse && mediump) {
3003 spirv_builder_emit_decoration(&ctx->builder, result,
3004 SpvDecorationRelaxedPrecision);
3005 }
3006
3007 store_def(ctx, &intr->def, result, nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(type)));
3008 }
3009
3010 static void
emit_image_deref_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)3011 emit_image_deref_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3012 {
3013 nir_alu_type atype;
3014 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3015 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3016 nir_variable *var = nir_deref_instr_get_variable(deref);
3017 SpvId img_type = find_image_type(ctx, var);
3018 const struct glsl_type *type = glsl_without_array(var->type);
3019 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
3020 unsigned num_components = glsl_get_sampler_coordinate_components(type);
3021 /* SPIRV requires 2 components for non-array cube size */
3022 if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE && !glsl_sampler_type_is_array(type))
3023 num_components = 2;
3024
3025 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3026 SpvId result = spirv_builder_emit_image_query_size(&ctx->builder, get_uvec_type(ctx, 32, num_components), img, 0);
3027 store_def(ctx, &intr->def, result, nir_type_uint);
3028 }
3029
3030 static void
emit_image_deref_samples(struct ntv_context * ctx,nir_intrinsic_instr * intr)3031 emit_image_deref_samples(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3032 {
3033 nir_alu_type atype;
3034 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3035 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3036 nir_variable *var = nir_deref_instr_get_variable(deref);
3037 SpvId img_type = find_image_type(ctx, var);
3038 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
3039
3040 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3041 SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples, get_def_type(ctx, &intr->def, nir_type_uint), img);
3042 store_def(ctx, &intr->def, result, nir_type_uint);
3043 }
3044
3045 static void
emit_image_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)3046 emit_image_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3047 {
3048 nir_alu_type atype, ptype;
3049 SpvId param = get_src(ctx, &intr->src[3], &ptype);
3050 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3051 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3052 nir_variable *var = nir_deref_instr_get_variable(deref);
3053 const struct glsl_type *type = glsl_without_array(var->type);
3054 bool is_ms;
3055 type_to_dim(glsl_get_sampler_dim(type), &is_ms);
3056 SpvId sample = is_ms ? get_src(ctx, &intr->src[2], &atype) : emit_uint_const(ctx, 32, 0);
3057 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
3058 enum glsl_base_type glsl_result_type = glsl_get_sampler_result_type(type);
3059 SpvId base_type = get_glsl_basetype(ctx, glsl_result_type);
3060 SpvId texel = spirv_builder_emit_image_texel_pointer(&ctx->builder, base_type, img_var, coord, sample);
3061 SpvId param2 = 0;
3062
3063 /* The type of Value must be the same as Result Type.
3064 * The type of the value pointed to by Pointer must be the same as Result Type.
3065 */
3066 nir_alu_type ntype = nir_get_nir_type_for_glsl_base_type(glsl_result_type);
3067 if (ptype != ntype) {
3068 SpvId cast_type = get_def_type(ctx, &intr->def, ntype);
3069 param = emit_bitcast(ctx, cast_type, param);
3070 }
3071
3072 if (intr->intrinsic == nir_intrinsic_image_deref_atomic_swap) {
3073 param2 = get_src(ctx, &intr->src[4], &ptype);
3074 if (ptype != ntype) {
3075 SpvId cast_type = get_def_type(ctx, &intr->def, ntype);
3076 param2 = emit_bitcast(ctx, cast_type, param2);
3077 }
3078 }
3079
3080 handle_atomic_op(ctx, intr, texel, param, param2, ntype);
3081 }
3082
3083 static void
emit_ballot(struct ntv_context * ctx,nir_intrinsic_instr * intr)3084 emit_ballot(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3085 {
3086 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3087 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3088 SpvId type = get_def_uvec_type(ctx, &intr->def);
3089 nir_alu_type atype;
3090 SpvId result = emit_unop(ctx, SpvOpSubgroupBallotKHR, type, get_src(ctx, &intr->src[0], &atype));
3091 store_def(ctx, &intr->def, result, nir_type_uint);
3092 }
3093
3094 static void
emit_read_first_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3095 emit_read_first_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3096 {
3097 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3098 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3099 nir_alu_type atype;
3100 SpvId src = get_src(ctx, &intr->src[0], &atype);
3101 SpvId type = get_def_type(ctx, &intr->def, atype);
3102 SpvId result = emit_unop(ctx, SpvOpSubgroupFirstInvocationKHR, type, src);
3103 store_def(ctx, &intr->def, result, atype);
3104 }
3105
3106 static void
emit_read_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3107 emit_read_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3108 {
3109 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3110 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3111 nir_alu_type atype, itype;
3112 SpvId src = get_src(ctx, &intr->src[0], &atype);
3113 SpvId type = get_def_type(ctx, &intr->def, atype);
3114 SpvId result = emit_binop(ctx, SpvOpSubgroupReadInvocationKHR, type,
3115 src,
3116 get_src(ctx, &intr->src[1], &itype));
3117 store_def(ctx, &intr->def, result, atype);
3118 }
3119
3120 static void
emit_shader_clock(struct ntv_context * ctx,nir_intrinsic_instr * intr)3121 emit_shader_clock(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3122 {
3123 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityShaderClockKHR);
3124 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_clock");
3125
3126 SpvScope scope = get_scope(nir_intrinsic_memory_scope(intr));
3127 SpvId type = get_def_type(ctx, &intr->def, nir_type_uint);
3128 SpvId result = spirv_builder_emit_unop_const(&ctx->builder, SpvOpReadClockKHR, type, scope);
3129 store_def(ctx, &intr->def, result, nir_type_uint);
3130 }
3131
3132 static void
emit_is_sparse_texels_resident(struct ntv_context * ctx,nir_intrinsic_instr * intr)3133 emit_is_sparse_texels_resident(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3134 {
3135 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySparseResidency);
3136
3137 SpvId type = get_def_type(ctx, &intr->def, nir_type_uint);
3138
3139 /* this will always be stored with the ssa index of the parent instr */
3140 nir_def *ssa = intr->src[0].ssa;
3141 assert(ssa->parent_instr->type == nir_instr_type_alu);
3142 nir_alu_instr *alu = nir_instr_as_alu(ssa->parent_instr);
3143 unsigned index = alu->src[0].src.ssa->index;
3144 assert(index < ctx->num_defs);
3145 assert(ctx->resident_defs[index] != 0);
3146 SpvId resident = ctx->resident_defs[index];
3147
3148 SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageSparseTexelsResident, type, resident);
3149 store_def(ctx, &intr->def, result, nir_type_uint);
3150 }
3151
3152 static void
emit_vote(struct ntv_context * ctx,nir_intrinsic_instr * intr)3153 emit_vote(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3154 {
3155 SpvOp op;
3156
3157 switch (intr->intrinsic) {
3158 case nir_intrinsic_vote_all:
3159 op = SpvOpGroupNonUniformAll;
3160 break;
3161 case nir_intrinsic_vote_any:
3162 op = SpvOpGroupNonUniformAny;
3163 break;
3164 case nir_intrinsic_vote_ieq:
3165 case nir_intrinsic_vote_feq:
3166 op = SpvOpGroupNonUniformAllEqual;
3167 break;
3168 default:
3169 unreachable("unknown vote intrinsic");
3170 }
3171 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityGroupNonUniformVote);
3172 nir_alu_type atype;
3173 SpvId result = spirv_builder_emit_vote(&ctx->builder, op, get_src(ctx, &intr->src[0], &atype));
3174 store_def_raw(ctx, &intr->def, result, nir_type_bool);
3175 }
3176
3177 static void
emit_is_helper_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3178 emit_is_helper_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3179 {
3180 spirv_builder_emit_extension(&ctx->builder,
3181 "SPV_EXT_demote_to_helper_invocation");
3182 SpvId result = spirv_is_helper_invocation(&ctx->builder);
3183 store_def(ctx, &intr->def, result, nir_type_bool);
3184 }
3185
3186 static void
emit_barrier(struct ntv_context * ctx,nir_intrinsic_instr * intr)3187 emit_barrier(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3188 {
3189 SpvScope scope = get_scope(nir_intrinsic_execution_scope(intr));
3190 SpvScope mem_scope = get_scope(nir_intrinsic_memory_scope(intr));
3191 SpvMemorySemanticsMask semantics = 0;
3192
3193 if (nir_intrinsic_memory_scope(intr) != SCOPE_NONE) {
3194 nir_variable_mode modes = nir_intrinsic_memory_modes(intr);
3195
3196 if (modes & nir_var_image)
3197 semantics |= SpvMemorySemanticsImageMemoryMask;
3198
3199 if (modes & nir_var_mem_shared)
3200 semantics |= SpvMemorySemanticsWorkgroupMemoryMask;
3201
3202 if (modes & (nir_var_mem_ssbo | nir_var_mem_global))
3203 semantics |= SpvMemorySemanticsUniformMemoryMask;
3204
3205 if (modes & nir_var_mem_global)
3206 semantics |= SpvMemorySemanticsCrossWorkgroupMemoryMask;
3207
3208 if (modes & (nir_var_shader_out | nir_var_mem_task_payload))
3209 semantics |= SpvMemorySemanticsOutputMemoryMask;
3210
3211 semantics |= SpvMemorySemanticsAcquireReleaseMask;
3212 }
3213
3214 if (nir_intrinsic_execution_scope(intr) != SCOPE_NONE)
3215 spirv_builder_emit_control_barrier(&ctx->builder, scope, mem_scope, semantics);
3216 else
3217 spirv_builder_emit_memory_barrier(&ctx->builder, mem_scope, semantics);
3218 }
3219
3220 static void
emit_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)3221 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3222 {
3223 switch (intr->intrinsic) {
3224 case nir_intrinsic_decl_reg:
3225 /* Nothing to do */
3226 break;
3227
3228 case nir_intrinsic_load_reg:
3229 emit_load_reg(ctx, intr);
3230 break;
3231
3232 case nir_intrinsic_store_reg:
3233 emit_store_reg(ctx, intr);
3234 break;
3235
3236 case nir_intrinsic_discard:
3237 emit_discard(ctx, intr);
3238 break;
3239
3240 case nir_intrinsic_demote:
3241 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDemoteToHelperInvocation);
3242 spirv_builder_emit_demote(&ctx->builder);
3243 break;
3244
3245 case nir_intrinsic_load_deref:
3246 emit_load_deref(ctx, intr);
3247 break;
3248
3249 case nir_intrinsic_store_deref:
3250 emit_store_deref(ctx, intr);
3251 break;
3252
3253 case nir_intrinsic_load_push_constant_zink:
3254 emit_load_push_const(ctx, intr);
3255 break;
3256
3257 case nir_intrinsic_load_global:
3258 case nir_intrinsic_load_global_constant:
3259 emit_load_global(ctx, intr);
3260 break;
3261
3262 case nir_intrinsic_store_global:
3263 emit_store_global(ctx, intr);
3264 break;
3265
3266 case nir_intrinsic_load_front_face:
3267 emit_load_front_face(ctx, intr);
3268 break;
3269
3270 case nir_intrinsic_load_base_instance:
3271 emit_load_uint_input(ctx, intr, &ctx->base_instance_var, "gl_BaseInstance", SpvBuiltInBaseInstance);
3272 break;
3273
3274 case nir_intrinsic_load_instance_id:
3275 emit_load_uint_input(ctx, intr, &ctx->instance_id_var, "gl_InstanceId", SpvBuiltInInstanceIndex);
3276 break;
3277
3278 case nir_intrinsic_load_base_vertex:
3279 emit_load_uint_input(ctx, intr, &ctx->base_vertex_var, "gl_BaseVertex", SpvBuiltInBaseVertex);
3280 break;
3281
3282 case nir_intrinsic_load_draw_id:
3283 emit_load_uint_input(ctx, intr, &ctx->draw_id_var, "gl_DrawID", SpvBuiltInDrawIndex);
3284 break;
3285
3286 case nir_intrinsic_load_vertex_id:
3287 emit_load_uint_input(ctx, intr, &ctx->vertex_id_var, "gl_VertexId", SpvBuiltInVertexIndex);
3288 break;
3289
3290 case nir_intrinsic_load_primitive_id:
3291 emit_load_uint_input(ctx, intr, &ctx->primitive_id_var, "gl_PrimitiveIdIn", SpvBuiltInPrimitiveId);
3292 break;
3293
3294 case nir_intrinsic_load_invocation_id:
3295 emit_load_uint_input(ctx, intr, &ctx->invocation_id_var, "gl_InvocationId", SpvBuiltInInvocationId);
3296 break;
3297
3298 case nir_intrinsic_load_sample_id:
3299 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampleRateShading);
3300 emit_load_uint_input(ctx, intr, &ctx->sample_id_var, "gl_SampleId", SpvBuiltInSampleId);
3301 break;
3302
3303 case nir_intrinsic_load_point_coord_maybe_flipped:
3304 case nir_intrinsic_load_point_coord:
3305 emit_load_vec_input(ctx, intr, &ctx->point_coord_var, "gl_PointCoord", SpvBuiltInPointCoord, nir_type_float);
3306 break;
3307
3308 case nir_intrinsic_load_sample_pos:
3309 emit_load_vec_input(ctx, intr, &ctx->sample_pos_var, "gl_SamplePosition", SpvBuiltInSamplePosition, nir_type_float);
3310 break;
3311
3312 case nir_intrinsic_load_sample_mask_in:
3313 emit_load_uint_input(ctx, intr, &ctx->sample_mask_in_var, "gl_SampleMaskIn", SpvBuiltInSampleMask);
3314 break;
3315
3316 case nir_intrinsic_emit_vertex:
3317 if (ctx->nir->info.gs.vertices_out) //skip vertex emission if !vertices_out
3318 spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr),
3319 ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3320 break;
3321
3322 case nir_intrinsic_end_primitive:
3323 spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr),
3324 ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3325 break;
3326
3327 case nir_intrinsic_load_helper_invocation:
3328 emit_load_vec_input(ctx, intr, &ctx->helper_invocation_var, "gl_HelperInvocation", SpvBuiltInHelperInvocation, nir_type_bool);
3329 break;
3330
3331 case nir_intrinsic_load_patch_vertices_in:
3332 emit_load_vec_input(ctx, intr, &ctx->tess_patch_vertices_in, "gl_PatchVerticesIn",
3333 SpvBuiltInPatchVertices, nir_type_int);
3334 break;
3335
3336 case nir_intrinsic_load_tess_coord:
3337 emit_load_vec_input(ctx, intr, &ctx->tess_coord_var, "gl_TessCoord",
3338 SpvBuiltInTessCoord, nir_type_float);
3339 break;
3340
3341 case nir_intrinsic_barrier:
3342 emit_barrier(ctx, intr);
3343 break;
3344
3345 case nir_intrinsic_interp_deref_at_centroid:
3346 case nir_intrinsic_interp_deref_at_sample:
3347 case nir_intrinsic_interp_deref_at_offset:
3348 emit_interpolate(ctx, intr);
3349 break;
3350
3351 case nir_intrinsic_deref_atomic:
3352 case nir_intrinsic_deref_atomic_swap:
3353 emit_deref_atomic_intrinsic(ctx, intr);
3354 break;
3355
3356 case nir_intrinsic_shared_atomic:
3357 case nir_intrinsic_shared_atomic_swap:
3358 emit_shared_atomic_intrinsic(ctx, intr);
3359 break;
3360
3361 case nir_intrinsic_global_atomic:
3362 case nir_intrinsic_global_atomic_swap:
3363 emit_global_atomic_intrinsic(ctx, intr);
3364 break;
3365
3366 case nir_intrinsic_begin_invocation_interlock:
3367 case nir_intrinsic_end_invocation_interlock:
3368 spirv_builder_emit_interlock(&ctx->builder, intr->intrinsic == nir_intrinsic_end_invocation_interlock);
3369 break;
3370
3371 case nir_intrinsic_get_ssbo_size:
3372 emit_get_ssbo_size(ctx, intr);
3373 break;
3374
3375 case nir_intrinsic_image_deref_store:
3376 emit_image_deref_store(ctx, intr);
3377 break;
3378
3379 case nir_intrinsic_image_deref_sparse_load:
3380 case nir_intrinsic_image_deref_load:
3381 emit_image_deref_load(ctx, intr);
3382 break;
3383
3384 case nir_intrinsic_image_deref_size:
3385 emit_image_deref_size(ctx, intr);
3386 break;
3387
3388 case nir_intrinsic_image_deref_samples:
3389 emit_image_deref_samples(ctx, intr);
3390 break;
3391
3392 case nir_intrinsic_image_deref_atomic:
3393 case nir_intrinsic_image_deref_atomic_swap:
3394 emit_image_intrinsic(ctx, intr);
3395 break;
3396
3397 case nir_intrinsic_load_workgroup_id:
3398 emit_load_vec_input(ctx, intr, &ctx->workgroup_id_var, "gl_WorkGroupID", SpvBuiltInWorkgroupId, nir_type_uint);
3399 break;
3400
3401 case nir_intrinsic_load_num_workgroups:
3402 emit_load_vec_input(ctx, intr, &ctx->num_workgroups_var, "gl_NumWorkGroups", SpvBuiltInNumWorkgroups, nir_type_uint);
3403 break;
3404
3405 case nir_intrinsic_load_local_invocation_id:
3406 emit_load_vec_input(ctx, intr, &ctx->local_invocation_id_var, "gl_LocalInvocationID", SpvBuiltInLocalInvocationId, nir_type_uint);
3407 break;
3408
3409 case nir_intrinsic_load_global_invocation_id:
3410 emit_load_vec_input(ctx, intr, &ctx->global_invocation_id_var, "gl_GlobalInvocationID", SpvBuiltInGlobalInvocationId, nir_type_uint);
3411 break;
3412
3413 case nir_intrinsic_load_local_invocation_index:
3414 emit_load_uint_input(ctx, intr, &ctx->local_invocation_index_var, "gl_LocalInvocationIndex", SpvBuiltInLocalInvocationIndex);
3415 break;
3416
3417 #define LOAD_SHADER_BALLOT(lowercase, camelcase) \
3418 case nir_intrinsic_load_##lowercase: \
3419 emit_load_uint_input(ctx, intr, &ctx->lowercase##_var, "gl_"#camelcase, SpvBuiltIn##camelcase); \
3420 break
3421
3422 LOAD_SHADER_BALLOT(subgroup_id, SubgroupId);
3423 LOAD_SHADER_BALLOT(subgroup_eq_mask, SubgroupEqMask);
3424 LOAD_SHADER_BALLOT(subgroup_ge_mask, SubgroupGeMask);
3425 LOAD_SHADER_BALLOT(subgroup_invocation, SubgroupLocalInvocationId);
3426 LOAD_SHADER_BALLOT(subgroup_le_mask, SubgroupLeMask);
3427 LOAD_SHADER_BALLOT(subgroup_lt_mask, SubgroupLtMask);
3428 LOAD_SHADER_BALLOT(subgroup_size, SubgroupSize);
3429
3430 case nir_intrinsic_ballot:
3431 emit_ballot(ctx, intr);
3432 break;
3433
3434 case nir_intrinsic_read_first_invocation:
3435 emit_read_first_invocation(ctx, intr);
3436 break;
3437
3438 case nir_intrinsic_read_invocation:
3439 emit_read_invocation(ctx, intr);
3440 break;
3441
3442 case nir_intrinsic_load_workgroup_size:
3443 assert(ctx->local_group_size_var);
3444 store_def(ctx, &intr->def, ctx->local_group_size_var, nir_type_uint);
3445 break;
3446
3447 case nir_intrinsic_load_shared:
3448 emit_load_shared(ctx, intr);
3449 break;
3450
3451 case nir_intrinsic_store_shared:
3452 emit_store_shared(ctx, intr);
3453 break;
3454
3455 case nir_intrinsic_load_scratch:
3456 emit_load_scratch(ctx, intr);
3457 break;
3458
3459 case nir_intrinsic_store_scratch:
3460 emit_store_scratch(ctx, intr);
3461 break;
3462
3463 case nir_intrinsic_shader_clock:
3464 emit_shader_clock(ctx, intr);
3465 break;
3466
3467 case nir_intrinsic_vote_all:
3468 case nir_intrinsic_vote_any:
3469 case nir_intrinsic_vote_ieq:
3470 case nir_intrinsic_vote_feq:
3471 emit_vote(ctx, intr);
3472 break;
3473
3474 case nir_intrinsic_is_sparse_texels_resident:
3475 emit_is_sparse_texels_resident(ctx, intr);
3476 break;
3477
3478 case nir_intrinsic_is_helper_invocation:
3479 emit_is_helper_invocation(ctx, intr);
3480 break;
3481
3482 default:
3483 fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
3484 nir_intrinsic_infos[intr->intrinsic].name);
3485 unreachable("unsupported intrinsic");
3486 }
3487 }
3488
3489 static void
emit_undef(struct ntv_context * ctx,nir_undef_instr * undef)3490 emit_undef(struct ntv_context *ctx, nir_undef_instr *undef)
3491 {
3492 SpvId type = undef->def.bit_size == 1 ? get_bvec_type(ctx, undef->def.num_components) :
3493 get_uvec_type(ctx, undef->def.bit_size,
3494 undef->def.num_components);
3495
3496 store_ssa_def(ctx, &undef->def,
3497 spirv_builder_emit_undef(&ctx->builder, type),
3498 undef->def.bit_size == 1 ? nir_type_bool : nir_type_uint);
3499 }
3500
3501 static SpvId
get_src_float(struct ntv_context * ctx,nir_src * src)3502 get_src_float(struct ntv_context *ctx, nir_src *src)
3503 {
3504 nir_alu_type atype;
3505 SpvId def = get_src(ctx, src, &atype);
3506 if (atype == nir_type_float)
3507 return def;
3508 unsigned num_components = nir_src_num_components(*src);
3509 unsigned bit_size = nir_src_bit_size(*src);
3510 return bitcast_to_fvec(ctx, def, bit_size, num_components);
3511 }
3512
3513 static SpvId
get_src_int(struct ntv_context * ctx,nir_src * src)3514 get_src_int(struct ntv_context *ctx, nir_src *src)
3515 {
3516 nir_alu_type atype;
3517 SpvId def = get_src(ctx, src, &atype);
3518 if (atype == nir_type_int)
3519 return def;
3520 unsigned num_components = nir_src_num_components(*src);
3521 unsigned bit_size = nir_src_bit_size(*src);
3522 return bitcast_to_ivec(ctx, def, bit_size, num_components);
3523 }
3524
3525 static inline bool
tex_instr_is_lod_allowed(nir_tex_instr * tex)3526 tex_instr_is_lod_allowed(nir_tex_instr *tex)
3527 {
3528 /* This can only be used with an OpTypeImage that has a Dim operand of 1D, 2D, 3D, or Cube
3529 * - SPIR-V: 3.14. Image Operands
3530 */
3531
3532 return (tex->sampler_dim == GLSL_SAMPLER_DIM_1D ||
3533 tex->sampler_dim == GLSL_SAMPLER_DIM_2D ||
3534 tex->sampler_dim == GLSL_SAMPLER_DIM_3D ||
3535 tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE ||
3536 /* RECT will always become 2D, so this is fine */
3537 tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
3538 }
3539
3540 static void
emit_tex(struct ntv_context * ctx,nir_tex_instr * tex)3541 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
3542 {
3543 assert(tex->op == nir_texop_tex ||
3544 tex->op == nir_texop_txb ||
3545 tex->op == nir_texop_txl ||
3546 tex->op == nir_texop_txd ||
3547 tex->op == nir_texop_txf ||
3548 tex->op == nir_texop_txf_ms ||
3549 tex->op == nir_texop_txs ||
3550 tex->op == nir_texop_lod ||
3551 tex->op == nir_texop_tg4 ||
3552 tex->op == nir_texop_texture_samples ||
3553 tex->op == nir_texop_query_levels);
3554 assert(tex->texture_index == tex->sampler_index || ctx->stage == MESA_SHADER_KERNEL);
3555
3556 SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0,
3557 const_offset = 0, offset = 0, sample = 0, tex_offset = 0, bindless = 0, min_lod = 0;
3558 unsigned coord_components = 0;
3559 nir_variable *bindless_var = NULL;
3560 nir_alu_type atype;
3561 for (unsigned i = 0; i < tex->num_srcs; i++) {
3562 nir_const_value *cv;
3563 switch (tex->src[i].src_type) {
3564 case nir_tex_src_coord:
3565 if (tex->op == nir_texop_txf ||
3566 tex->op == nir_texop_txf_ms)
3567 coord = get_src_int(ctx, &tex->src[i].src);
3568 else
3569 coord = get_src_float(ctx, &tex->src[i].src);
3570 coord_components = nir_src_num_components(tex->src[i].src);
3571 break;
3572
3573 case nir_tex_src_projector:
3574 assert(nir_src_num_components(tex->src[i].src) == 1);
3575 proj = get_src_float(ctx, &tex->src[i].src);
3576 assert(proj != 0);
3577 break;
3578
3579 case nir_tex_src_offset:
3580 cv = nir_src_as_const_value(tex->src[i].src);
3581 if (cv) {
3582 unsigned bit_size = nir_src_bit_size(tex->src[i].src);
3583 unsigned num_components = nir_src_num_components(tex->src[i].src);
3584
3585 SpvId components[NIR_MAX_VEC_COMPONENTS];
3586 for (int j = 0; j < num_components; ++j) {
3587 int64_t tmp = nir_const_value_as_int(cv[j], bit_size);
3588 components[j] = emit_int_const(ctx, bit_size, tmp);
3589 }
3590
3591 if (num_components > 1) {
3592 SpvId type = get_ivec_type(ctx, bit_size, num_components);
3593 const_offset = spirv_builder_const_composite(&ctx->builder,
3594 type,
3595 components,
3596 num_components);
3597 } else
3598 const_offset = components[0];
3599 } else
3600 offset = get_src_int(ctx, &tex->src[i].src);
3601 break;
3602
3603 case nir_tex_src_bias:
3604 assert(tex->op == nir_texop_txb);
3605 bias = get_src_float(ctx, &tex->src[i].src);
3606 assert(bias != 0);
3607 break;
3608
3609 case nir_tex_src_min_lod:
3610 assert(nir_src_num_components(tex->src[i].src) == 1);
3611 min_lod = get_src_float(ctx, &tex->src[i].src);
3612 assert(min_lod != 0);
3613 break;
3614
3615 case nir_tex_src_lod:
3616 assert(nir_src_num_components(tex->src[i].src) == 1);
3617 if (tex->op == nir_texop_txf ||
3618 tex->op == nir_texop_txf_ms ||
3619 tex->op == nir_texop_txs)
3620 lod = get_src_int(ctx, &tex->src[i].src);
3621 else
3622 lod = get_src_float(ctx, &tex->src[i].src);
3623 assert(lod != 0);
3624 break;
3625
3626 case nir_tex_src_ms_index:
3627 assert(nir_src_num_components(tex->src[i].src) == 1);
3628 sample = get_src_int(ctx, &tex->src[i].src);
3629 break;
3630
3631 case nir_tex_src_comparator:
3632 assert(nir_src_num_components(tex->src[i].src) == 1);
3633 dref = get_src_float(ctx, &tex->src[i].src);
3634 assert(dref != 0);
3635 break;
3636
3637 case nir_tex_src_ddx:
3638 dx = get_src_float(ctx, &tex->src[i].src);
3639 assert(dx != 0);
3640 break;
3641
3642 case nir_tex_src_ddy:
3643 dy = get_src_float(ctx, &tex->src[i].src);
3644 assert(dy != 0);
3645 break;
3646
3647 case nir_tex_src_texture_offset:
3648 tex_offset = get_src_int(ctx, &tex->src[i].src);
3649 break;
3650
3651 case nir_tex_src_sampler_offset:
3652 case nir_tex_src_sampler_handle:
3653 /* don't care */
3654 break;
3655
3656 case nir_tex_src_texture_handle:
3657 bindless = get_src(ctx, &tex->src[i].src, &atype);
3658 bindless_var = nir_deref_instr_get_variable(nir_src_as_deref(tex->src[i].src));
3659 break;
3660
3661 default:
3662 fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
3663 unreachable("unknown texture source");
3664 }
3665 }
3666
3667 unsigned texture_index = tex->texture_index;
3668 nir_variable *var = bindless_var ? bindless_var : ctx->sampler_var[tex->texture_index];
3669 nir_variable **sampler_var = bindless ? ctx->bindless_sampler_var : ctx->sampler_var;
3670 if (!bindless_var && (!tex_offset || !var)) {
3671 if (sampler_var[texture_index]) {
3672 if (glsl_type_is_array(sampler_var[texture_index]->type))
3673 tex_offset = emit_uint_const(ctx, 32, 0);
3674 assert(var);
3675 } else {
3676 /* convert constant index back to base + offset */
3677 for (int i = texture_index; i >= 0; i--) {
3678 if (sampler_var[i]) {
3679 assert(glsl_type_is_array(sampler_var[i]->type));
3680 if (!tex_offset)
3681 tex_offset = emit_uint_const(ctx, 32, texture_index - i);
3682 var = sampler_var[i];
3683 texture_index = i;
3684 break;
3685 }
3686 }
3687 }
3688 }
3689 assert(var);
3690 SpvId image_type = find_image_type(ctx, var);
3691 assert(image_type);
3692 SpvId sampled_type;
3693
3694 bool is_buffer = glsl_get_sampler_dim(glsl_without_array(var->type)) ==
3695 GLSL_SAMPLER_DIM_BUF;
3696 if (is_buffer)
3697 sampled_type = image_type;
3698 else
3699 sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
3700 image_type);
3701 assert(sampled_type);
3702
3703 SpvId sampler_id = bindless ? bindless : ctx->samplers[texture_index];
3704 if (tex_offset) {
3705 SpvId ptr = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassUniformConstant, sampled_type);
3706 sampler_id = spirv_builder_emit_access_chain(&ctx->builder, ptr, sampler_id, &tex_offset, 1);
3707 }
3708 SpvId load;
3709 if (ctx->stage == MESA_SHADER_KERNEL) {
3710 SpvId image_load = spirv_builder_emit_load(&ctx->builder, image_type, sampler_id);
3711 if (nir_tex_instr_need_sampler(tex)) {
3712 SpvId sampler_load = spirv_builder_emit_load(&ctx->builder, spirv_builder_type_sampler(&ctx->builder), ctx->cl_samplers[tex->sampler_index]);
3713 load = spirv_builder_emit_sampled_image(&ctx->builder, sampled_type, image_load, sampler_load);
3714 } else {
3715 load = image_load;
3716 }
3717 } else {
3718 load = spirv_builder_emit_load(&ctx->builder, sampled_type, sampler_id);
3719 }
3720
3721 if (tex->is_sparse)
3722 tex->def.num_components--;
3723 SpvId dest_type = get_def_type(ctx, &tex->def, tex->dest_type);
3724
3725 if (nir_tex_instr_is_query(tex))
3726 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3727
3728 if (!tex_instr_is_lod_allowed(tex))
3729 lod = 0;
3730 else if (ctx->stage != MESA_SHADER_FRAGMENT &&
3731 tex->op == nir_texop_tex && ctx->explicit_lod && !lod)
3732 lod = emit_float_const(ctx, 32, 0.0);
3733 if (tex->op == nir_texop_txs) {
3734 SpvId image = is_buffer || ctx->stage == MESA_SHADER_KERNEL ?
3735 load :
3736 spirv_builder_emit_image(&ctx->builder, image_type, load);
3737 /* Its Dim operand must be one of 1D, 2D, 3D, or Cube
3738 * - OpImageQuerySizeLod specification
3739 *
3740 * Additionally, if its Dim is 1D, 2D, 3D, or Cube,
3741 * it must also have either an MS of 1 or a Sampled of 0 or 2.
3742 * - OpImageQuerySize specification
3743 *
3744 * all spirv samplers use these types
3745 */
3746 if (!lod && tex_instr_is_lod_allowed(tex))
3747 lod = emit_uint_const(ctx, 32, 0);
3748 SpvId result = spirv_builder_emit_image_query_size(&ctx->builder,
3749 dest_type, image,
3750 lod);
3751 store_def(ctx, &tex->def, result, tex->dest_type);
3752 return;
3753 }
3754 if (tex->op == nir_texop_query_levels) {
3755 SpvId image = is_buffer || ctx->stage == MESA_SHADER_KERNEL ?
3756 load :
3757 spirv_builder_emit_image(&ctx->builder, image_type, load);
3758 SpvId result = spirv_builder_emit_image_query_levels(&ctx->builder,
3759 dest_type, image);
3760 store_def(ctx, &tex->def, result, tex->dest_type);
3761 return;
3762 }
3763 if (tex->op == nir_texop_texture_samples) {
3764 SpvId image = is_buffer || ctx->stage == MESA_SHADER_KERNEL ?
3765 load :
3766 spirv_builder_emit_image(&ctx->builder, image_type, load);
3767 SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples,
3768 dest_type, image);
3769 store_def(ctx, &tex->def, result, tex->dest_type);
3770 return;
3771 }
3772
3773 if (proj && coord_components > 0) {
3774 SpvId constituents[NIR_MAX_VEC_COMPONENTS + 1];
3775 if (coord_components == 1)
3776 constituents[0] = coord;
3777 else {
3778 assert(coord_components > 1);
3779 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
3780 for (uint32_t i = 0; i < coord_components; ++i)
3781 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
3782 float_type,
3783 coord,
3784 &i, 1);
3785 }
3786
3787 constituents[coord_components++] = proj;
3788
3789 SpvId vec_type = get_fvec_type(ctx, 32, coord_components);
3790 coord = spirv_builder_emit_composite_construct(&ctx->builder,
3791 vec_type,
3792 constituents,
3793 coord_components);
3794 }
3795 if (tex->op == nir_texop_lod) {
3796 SpvId result = spirv_builder_emit_image_query_lod(&ctx->builder,
3797 dest_type, load,
3798 coord);
3799 store_def(ctx, &tex->def, result, tex->dest_type);
3800 return;
3801 }
3802 SpvId actual_dest_type;
3803 unsigned num_components = tex->def.num_components;
3804 switch (nir_alu_type_get_base_type(tex->dest_type)) {
3805 case nir_type_int:
3806 actual_dest_type = get_ivec_type(ctx, 32, num_components);
3807 break;
3808
3809 case nir_type_uint:
3810 actual_dest_type = get_uvec_type(ctx, 32, num_components);
3811 break;
3812
3813 case nir_type_float:
3814 actual_dest_type = get_fvec_type(ctx, 32, num_components);
3815 break;
3816
3817 default:
3818 unreachable("unexpected nir_alu_type");
3819 }
3820
3821 SpvId result;
3822 if (offset)
3823 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3824 if (min_lod)
3825 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityMinLod);
3826 if (tex->op == nir_texop_txf ||
3827 tex->op == nir_texop_txf_ms ||
3828 tex->op == nir_texop_tg4) {
3829 SpvId image = is_buffer || ctx->stage == MESA_SHADER_KERNEL ?
3830 load :
3831 spirv_builder_emit_image(&ctx->builder, image_type, load);
3832
3833 if (tex->op == nir_texop_tg4) {
3834 if (const_offset)
3835 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3836 result = spirv_builder_emit_image_gather(&ctx->builder, actual_dest_type,
3837 load, coord, emit_uint_const(ctx, 32, tex->component),
3838 lod, sample, const_offset, offset, dref, tex->is_sparse);
3839 actual_dest_type = dest_type;
3840 } else {
3841 assert(tex->op == nir_texop_txf_ms || !sample);
3842 bool is_ms;
3843 type_to_dim(glsl_get_sampler_dim(glsl_without_array(var->type)), &is_ms);
3844 assert(is_ms || !sample);
3845 result = spirv_builder_emit_image_fetch(&ctx->builder, actual_dest_type,
3846 image, coord, lod, sample, const_offset, offset, tex->is_sparse);
3847 }
3848 } else {
3849 if (tex->op == nir_texop_txl)
3850 min_lod = 0;
3851 result = spirv_builder_emit_image_sample(&ctx->builder,
3852 actual_dest_type, load,
3853 coord,
3854 proj != 0,
3855 lod, bias, dref, dx, dy,
3856 const_offset, offset, min_lod, tex->is_sparse);
3857 }
3858
3859 if (!bindless_var && (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW)) {
3860 spirv_builder_emit_decoration(&ctx->builder, result,
3861 SpvDecorationRelaxedPrecision);
3862 }
3863
3864 if (tex->is_sparse)
3865 result = extract_sparse_load(ctx, result, actual_dest_type, &tex->def);
3866
3867 if (tex->def.bit_size != 32) {
3868 /* convert FP32 to FP16 */
3869 result = emit_unop(ctx, SpvOpFConvert, dest_type, result);
3870 }
3871
3872 if (tex->is_sparse && tex->is_shadow)
3873 tex->def.num_components++;
3874 store_def(ctx, &tex->def, result, tex->dest_type);
3875 if (tex->is_sparse && !tex->is_shadow)
3876 tex->def.num_components++;
3877 }
3878
3879 static void
start_block(struct ntv_context * ctx,SpvId label)3880 start_block(struct ntv_context *ctx, SpvId label)
3881 {
3882 /* terminate previous block if needed */
3883 if (ctx->block_started)
3884 spirv_builder_emit_branch(&ctx->builder, label);
3885
3886 /* start new block */
3887 spirv_builder_label(&ctx->builder, label);
3888 ctx->block_started = true;
3889 }
3890
3891 static void
branch(struct ntv_context * ctx,SpvId label)3892 branch(struct ntv_context *ctx, SpvId label)
3893 {
3894 assert(ctx->block_started);
3895 spirv_builder_emit_branch(&ctx->builder, label);
3896 ctx->block_started = false;
3897 }
3898
3899 static void
branch_conditional(struct ntv_context * ctx,SpvId condition,SpvId then_id,SpvId else_id)3900 branch_conditional(struct ntv_context *ctx, SpvId condition, SpvId then_id,
3901 SpvId else_id)
3902 {
3903 assert(ctx->block_started);
3904 spirv_builder_emit_branch_conditional(&ctx->builder, condition,
3905 then_id, else_id);
3906 ctx->block_started = false;
3907 }
3908
3909 static void
emit_jump(struct ntv_context * ctx,nir_jump_instr * jump)3910 emit_jump(struct ntv_context *ctx, nir_jump_instr *jump)
3911 {
3912 switch (jump->type) {
3913 case nir_jump_break:
3914 assert(ctx->loop_break);
3915 branch(ctx, ctx->loop_break);
3916 break;
3917
3918 case nir_jump_continue:
3919 assert(ctx->loop_cont);
3920 branch(ctx, ctx->loop_cont);
3921 break;
3922
3923 default:
3924 unreachable("Unsupported jump type\n");
3925 }
3926 }
3927
3928 static void
emit_deref_var(struct ntv_context * ctx,nir_deref_instr * deref)3929 emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref)
3930 {
3931 assert(deref->deref_type == nir_deref_type_var);
3932
3933 struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var);
3934 assert(he);
3935 SpvId result = (SpvId)(intptr_t)he->data;
3936 store_def_raw(ctx, &deref->def, result, get_nir_alu_type(deref->type));
3937 }
3938
3939 static void
emit_deref_array(struct ntv_context * ctx,nir_deref_instr * deref)3940 emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
3941 {
3942 assert(deref->deref_type == nir_deref_type_array);
3943 nir_variable *var = nir_deref_instr_get_variable(deref);
3944
3945 if (!nir_src_is_always_uniform(deref->arr.index)) {
3946 if (deref->modes & nir_var_mem_ubo)
3947 spirv_builder_emit_cap(&ctx->builder,
3948 SpvCapabilityUniformBufferArrayDynamicIndexing);
3949
3950 if (deref->modes & nir_var_mem_ssbo)
3951 spirv_builder_emit_cap(&ctx->builder,
3952 SpvCapabilityStorageBufferArrayDynamicIndexing);
3953
3954 if (deref->modes & (nir_var_uniform | nir_var_image)) {
3955 const struct glsl_type *type = glsl_without_array(var->type);
3956 assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
3957
3958 if (glsl_type_is_sampler(type))
3959 spirv_builder_emit_cap(&ctx->builder,
3960 SpvCapabilitySampledImageArrayDynamicIndexing);
3961 else
3962 spirv_builder_emit_cap(&ctx->builder,
3963 SpvCapabilityStorageImageArrayDynamicIndexing);
3964 }
3965 }
3966
3967 SpvStorageClass storage_class = get_storage_class(var);
3968 SpvId base, type;
3969 nir_alu_type atype = nir_type_uint;
3970 switch (var->data.mode) {
3971
3972 case nir_var_mem_ubo:
3973 case nir_var_mem_ssbo:
3974 base = get_src(ctx, &deref->parent, &atype);
3975 /* this is either the array<buffers> deref or the array<uint> deref */
3976 if (glsl_type_is_struct_or_ifc(deref->type)) {
3977 /* array<buffers> */
3978 type = get_bo_struct_type(ctx, var);
3979 break;
3980 }
3981 /* array<uint> */
3982 FALLTHROUGH;
3983 case nir_var_function_temp:
3984 case nir_var_shader_in:
3985 case nir_var_shader_out:
3986 base = get_src(ctx, &deref->parent, &atype);
3987 type = get_glsl_type(ctx, deref->type);
3988 break;
3989
3990 case nir_var_uniform:
3991 case nir_var_image: {
3992 struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var);
3993 assert(he);
3994 base = (SpvId)(intptr_t)he->data;
3995 const struct glsl_type *gtype = glsl_without_array(var->type);
3996 type = get_image_type(ctx, var,
3997 glsl_type_is_sampler(gtype),
3998 glsl_get_sampler_dim(gtype) == GLSL_SAMPLER_DIM_BUF);
3999 break;
4000 }
4001
4002 default:
4003 unreachable("Unsupported nir_variable_mode\n");
4004 }
4005
4006 nir_alu_type itype;
4007 SpvId index = get_src(ctx, &deref->arr.index, &itype);
4008 if (itype == nir_type_float)
4009 index = emit_bitcast(ctx, get_uvec_type(ctx, 32, 1), index);
4010
4011 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
4012 storage_class,
4013 type);
4014
4015 SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
4016 ptr_type,
4017 base,
4018 &index, 1);
4019 /* uint is a bit of a lie here, it's really just an opaque type */
4020 store_def(ctx, &deref->def, result, get_nir_alu_type(deref->type));
4021 }
4022
4023 static void
emit_deref_struct(struct ntv_context * ctx,nir_deref_instr * deref)4024 emit_deref_struct(struct ntv_context *ctx, nir_deref_instr *deref)
4025 {
4026 assert(deref->deref_type == nir_deref_type_struct);
4027 nir_variable *var = nir_deref_instr_get_variable(deref);
4028
4029 SpvStorageClass storage_class = get_storage_class(var);
4030
4031 SpvId index = emit_uint_const(ctx, 32, deref->strct.index);
4032 SpvId type = (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) ?
4033 get_bo_array_type(ctx, var) :
4034 get_glsl_type(ctx, deref->type);
4035
4036 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
4037 storage_class,
4038 type);
4039
4040 nir_alu_type atype;
4041 SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
4042 ptr_type,
4043 get_src(ctx, &deref->parent, &atype),
4044 &index, 1);
4045 /* uint is a bit of a lie here, it's really just an opaque type */
4046 store_def(ctx, &deref->def, result, get_nir_alu_type(deref->type));
4047 }
4048
4049 static void
emit_deref(struct ntv_context * ctx,nir_deref_instr * deref)4050 emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
4051 {
4052 switch (deref->deref_type) {
4053 case nir_deref_type_var:
4054 emit_deref_var(ctx, deref);
4055 break;
4056
4057 case nir_deref_type_array:
4058 emit_deref_array(ctx, deref);
4059 break;
4060
4061 case nir_deref_type_struct:
4062 emit_deref_struct(ctx, deref);
4063 break;
4064
4065 default:
4066 unreachable("unexpected deref_type");
4067 }
4068 }
4069
4070 static void
emit_block(struct ntv_context * ctx,struct nir_block * block)4071 emit_block(struct ntv_context *ctx, struct nir_block *block)
4072 {
4073 start_block(ctx, block_label(ctx, block));
4074 nir_foreach_instr(instr, block) {
4075 switch (instr->type) {
4076 case nir_instr_type_alu:
4077 emit_alu(ctx, nir_instr_as_alu(instr));
4078 break;
4079 case nir_instr_type_intrinsic:
4080 emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
4081 break;
4082 case nir_instr_type_load_const:
4083 emit_load_const(ctx, nir_instr_as_load_const(instr));
4084 break;
4085 case nir_instr_type_undef:
4086 emit_undef(ctx, nir_instr_as_undef(instr));
4087 break;
4088 case nir_instr_type_tex:
4089 emit_tex(ctx, nir_instr_as_tex(instr));
4090 break;
4091 case nir_instr_type_phi:
4092 unreachable("nir_instr_type_phi not supported");
4093 break;
4094 case nir_instr_type_jump:
4095 emit_jump(ctx, nir_instr_as_jump(instr));
4096 break;
4097 case nir_instr_type_call:
4098 unreachable("nir_instr_type_call not supported");
4099 break;
4100 case nir_instr_type_parallel_copy:
4101 unreachable("nir_instr_type_parallel_copy not supported");
4102 break;
4103 case nir_instr_type_deref:
4104 emit_deref(ctx, nir_instr_as_deref(instr));
4105 break;
4106 }
4107 }
4108 }
4109
4110 static void
4111 emit_cf_list(struct ntv_context *ctx, struct exec_list *list);
4112
4113 static SpvId
get_src_bool(struct ntv_context * ctx,nir_src * src)4114 get_src_bool(struct ntv_context *ctx, nir_src *src)
4115 {
4116 assert(nir_src_bit_size(*src) == 1);
4117 nir_alu_type atype;
4118 return get_src(ctx, src, &atype);
4119 }
4120
4121 static void
emit_if(struct ntv_context * ctx,nir_if * if_stmt)4122 emit_if(struct ntv_context *ctx, nir_if *if_stmt)
4123 {
4124 SpvId condition = get_src_bool(ctx, &if_stmt->condition);
4125
4126 SpvId header_id = spirv_builder_new_id(&ctx->builder);
4127 SpvId then_id = block_label(ctx, nir_if_first_then_block(if_stmt));
4128 SpvId endif_id = spirv_builder_new_id(&ctx->builder);
4129 SpvId else_id = endif_id;
4130
4131 bool has_else = !exec_list_is_empty(&if_stmt->else_list);
4132 if (has_else) {
4133 assert(nir_if_first_else_block(if_stmt)->index < ctx->num_blocks);
4134 else_id = block_label(ctx, nir_if_first_else_block(if_stmt));
4135 }
4136
4137 /* create a header-block */
4138 start_block(ctx, header_id);
4139 spirv_builder_emit_selection_merge(&ctx->builder, endif_id,
4140 SpvSelectionControlMaskNone);
4141 branch_conditional(ctx, condition, then_id, else_id);
4142
4143 emit_cf_list(ctx, &if_stmt->then_list);
4144
4145 if (has_else) {
4146 if (ctx->block_started)
4147 branch(ctx, endif_id);
4148
4149 emit_cf_list(ctx, &if_stmt->else_list);
4150 }
4151
4152 start_block(ctx, endif_id);
4153 }
4154
4155 static void
emit_loop(struct ntv_context * ctx,nir_loop * loop)4156 emit_loop(struct ntv_context *ctx, nir_loop *loop)
4157 {
4158 assert(!nir_loop_has_continue_construct(loop));
4159 SpvId header_id = spirv_builder_new_id(&ctx->builder);
4160 SpvId begin_id = block_label(ctx, nir_loop_first_block(loop));
4161 SpvId break_id = spirv_builder_new_id(&ctx->builder);
4162 SpvId cont_id = spirv_builder_new_id(&ctx->builder);
4163
4164 /* create a header-block */
4165 start_block(ctx, header_id);
4166 spirv_builder_loop_merge(&ctx->builder, break_id, cont_id, SpvLoopControlMaskNone);
4167 branch(ctx, begin_id);
4168
4169 SpvId save_break = ctx->loop_break;
4170 SpvId save_cont = ctx->loop_cont;
4171 ctx->loop_break = break_id;
4172 ctx->loop_cont = cont_id;
4173
4174 emit_cf_list(ctx, &loop->body);
4175
4176 ctx->loop_break = save_break;
4177 ctx->loop_cont = save_cont;
4178
4179 /* loop->body may have already ended our block */
4180 if (ctx->block_started)
4181 branch(ctx, cont_id);
4182 start_block(ctx, cont_id);
4183 branch(ctx, header_id);
4184
4185 start_block(ctx, break_id);
4186 }
4187
4188 static void
emit_cf_list(struct ntv_context * ctx,struct exec_list * list)4189 emit_cf_list(struct ntv_context *ctx, struct exec_list *list)
4190 {
4191 foreach_list_typed(nir_cf_node, node, node, list) {
4192 switch (node->type) {
4193 case nir_cf_node_block:
4194 emit_block(ctx, nir_cf_node_as_block(node));
4195 break;
4196
4197 case nir_cf_node_if:
4198 emit_if(ctx, nir_cf_node_as_if(node));
4199 break;
4200
4201 case nir_cf_node_loop:
4202 emit_loop(ctx, nir_cf_node_as_loop(node));
4203 break;
4204
4205 case nir_cf_node_function:
4206 unreachable("nir_cf_node_function not supported");
4207 break;
4208 }
4209 }
4210 }
4211
4212 static SpvExecutionMode
get_input_prim_type_mode(enum mesa_prim type)4213 get_input_prim_type_mode(enum mesa_prim type)
4214 {
4215 switch (type) {
4216 case MESA_PRIM_POINTS:
4217 return SpvExecutionModeInputPoints;
4218 case MESA_PRIM_LINES:
4219 case MESA_PRIM_LINE_LOOP:
4220 case MESA_PRIM_LINE_STRIP:
4221 return SpvExecutionModeInputLines;
4222 case MESA_PRIM_TRIANGLE_STRIP:
4223 case MESA_PRIM_TRIANGLES:
4224 case MESA_PRIM_TRIANGLE_FAN:
4225 return SpvExecutionModeTriangles;
4226 case MESA_PRIM_QUADS:
4227 case MESA_PRIM_QUAD_STRIP:
4228 return SpvExecutionModeQuads;
4229 break;
4230 case MESA_PRIM_POLYGON:
4231 unreachable("handle polygons in gs");
4232 break;
4233 case MESA_PRIM_LINES_ADJACENCY:
4234 case MESA_PRIM_LINE_STRIP_ADJACENCY:
4235 return SpvExecutionModeInputLinesAdjacency;
4236 case MESA_PRIM_TRIANGLES_ADJACENCY:
4237 case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
4238 return SpvExecutionModeInputTrianglesAdjacency;
4239 break;
4240 default:
4241 debug_printf("unknown geometry shader input mode %u\n", type);
4242 unreachable("error!");
4243 break;
4244 }
4245
4246 return 0;
4247 }
4248 static SpvExecutionMode
get_output_prim_type_mode(enum mesa_prim type)4249 get_output_prim_type_mode(enum mesa_prim type)
4250 {
4251 switch (type) {
4252 case MESA_PRIM_POINTS:
4253 return SpvExecutionModeOutputPoints;
4254 case MESA_PRIM_LINES:
4255 case MESA_PRIM_LINE_LOOP:
4256 unreachable("MESA_PRIM_LINES/LINE_LOOP passed as gs output");
4257 break;
4258 case MESA_PRIM_LINE_STRIP:
4259 return SpvExecutionModeOutputLineStrip;
4260 case MESA_PRIM_TRIANGLE_STRIP:
4261 return SpvExecutionModeOutputTriangleStrip;
4262 case MESA_PRIM_TRIANGLES:
4263 case MESA_PRIM_TRIANGLE_FAN: //FIXME: not sure if right for output
4264 return SpvExecutionModeTriangles;
4265 case MESA_PRIM_QUADS:
4266 case MESA_PRIM_QUAD_STRIP:
4267 return SpvExecutionModeQuads;
4268 case MESA_PRIM_POLYGON:
4269 unreachable("handle polygons in gs");
4270 break;
4271 case MESA_PRIM_LINES_ADJACENCY:
4272 case MESA_PRIM_LINE_STRIP_ADJACENCY:
4273 unreachable("handle line adjacency in gs");
4274 break;
4275 case MESA_PRIM_TRIANGLES_ADJACENCY:
4276 case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
4277 unreachable("handle triangle adjacency in gs");
4278 break;
4279 default:
4280 debug_printf("unknown geometry shader output mode %u\n", type);
4281 unreachable("error!");
4282 break;
4283 }
4284
4285 return 0;
4286 }
4287
4288 static SpvExecutionMode
get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)4289 get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)
4290 {
4291 switch (depth_layout) {
4292 case FRAG_DEPTH_LAYOUT_NONE:
4293 case FRAG_DEPTH_LAYOUT_ANY:
4294 return SpvExecutionModeDepthReplacing;
4295 case FRAG_DEPTH_LAYOUT_GREATER:
4296 return SpvExecutionModeDepthGreater;
4297 case FRAG_DEPTH_LAYOUT_LESS:
4298 return SpvExecutionModeDepthLess;
4299 case FRAG_DEPTH_LAYOUT_UNCHANGED:
4300 return SpvExecutionModeDepthUnchanged;
4301 default:
4302 unreachable("unexpected depth layout");
4303 }
4304 }
4305
4306 static SpvExecutionMode
get_primitive_mode(enum tess_primitive_mode primitive_mode)4307 get_primitive_mode(enum tess_primitive_mode primitive_mode)
4308 {
4309 switch (primitive_mode) {
4310 case TESS_PRIMITIVE_TRIANGLES: return SpvExecutionModeTriangles;
4311 case TESS_PRIMITIVE_QUADS: return SpvExecutionModeQuads;
4312 case TESS_PRIMITIVE_ISOLINES: return SpvExecutionModeIsolines;
4313 default:
4314 unreachable("unknown tess prim type!");
4315 }
4316 }
4317
4318 static SpvExecutionMode
get_spacing(enum gl_tess_spacing spacing)4319 get_spacing(enum gl_tess_spacing spacing)
4320 {
4321 switch (spacing) {
4322 case TESS_SPACING_EQUAL:
4323 return SpvExecutionModeSpacingEqual;
4324 case TESS_SPACING_FRACTIONAL_ODD:
4325 return SpvExecutionModeSpacingFractionalOdd;
4326 case TESS_SPACING_FRACTIONAL_EVEN:
4327 return SpvExecutionModeSpacingFractionalEven;
4328 default:
4329 unreachable("unknown tess spacing!");
4330 }
4331 }
4332
4333 struct spirv_shader *
nir_to_spirv(struct nir_shader * s,const struct zink_shader_info * sinfo,uint32_t spirv_version)4334 nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_t spirv_version)
4335 {
4336 struct spirv_shader *ret = NULL;
4337
4338 struct ntv_context ctx = {0};
4339 ctx.mem_ctx = ralloc_context(NULL);
4340 ctx.nir = s;
4341 ctx.builder.mem_ctx = ctx.mem_ctx;
4342 assert(spirv_version >= SPIRV_VERSION(1, 0));
4343 ctx.spirv_1_4_interfaces = spirv_version >= SPIRV_VERSION(1, 4);
4344
4345 ctx.bindless_set_idx = sinfo->bindless_set_idx;
4346 ctx.glsl_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4347 ctx.bo_array_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4348 ctx.bo_struct_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4349 if (!ctx.glsl_types || !ctx.bo_array_types || !ctx.bo_struct_types ||
4350 !_mesa_hash_table_init(&ctx.image_types, ctx.mem_ctx, _mesa_hash_pointer, _mesa_key_pointer_equal))
4351 goto fail;
4352
4353 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader);
4354
4355 switch (s->info.stage) {
4356 case MESA_SHADER_FRAGMENT:
4357 if (s->info.fs.uses_sample_shading)
4358 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleRateShading);
4359 if (s->info.fs.uses_demote && spirv_version < SPIRV_VERSION(1, 6))
4360 spirv_builder_emit_extension(&ctx.builder,
4361 "SPV_EXT_demote_to_helper_invocation");
4362 break;
4363
4364 case MESA_SHADER_VERTEX:
4365 if (BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID) ||
4366 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_DRAW_ID) ||
4367 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_INSTANCE) ||
4368 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_VERTEX)) {
4369 if (spirv_version < SPIRV_VERSION(1, 3))
4370 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_draw_parameters");
4371 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDrawParameters);
4372 }
4373 break;
4374
4375 case MESA_SHADER_TESS_CTRL:
4376 case MESA_SHADER_TESS_EVAL:
4377 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
4378 /* TODO: check features for this */
4379 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4380 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellationPointSize);
4381 break;
4382
4383 case MESA_SHADER_GEOMETRY:
4384 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4385 if (s->info.gs.active_stream_mask)
4386 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryStreams);
4387 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4388 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryPointSize);
4389 break;
4390
4391 default: ;
4392 }
4393
4394 if (s->info.stage < MESA_SHADER_GEOMETRY) {
4395 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_LAYER) ||
4396 s->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_LAYER)) {
4397 if (spirv_version >= SPIRV_VERSION(1, 5))
4398 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderLayer);
4399 else {
4400 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_viewport_index_layer");
4401 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndexLayerEXT);
4402 }
4403 }
4404 } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
4405 /* incredibly, this is legal and intended.
4406 * https://github.com/KhronosGroup/SPIRV-Registry/issues/95
4407 */
4408 if (s->info.inputs_read & (BITFIELD64_BIT(VARYING_SLOT_LAYER) |
4409 BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID)))
4410 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4411 }
4412
4413 if (s->info.num_ssbos && spirv_version < SPIRV_VERSION(1, 1))
4414 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_storage_buffer_storage_class");
4415
4416 if (s->info.stage < MESA_SHADER_FRAGMENT &&
4417 s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_VIEWPORT)) {
4418 if (s->info.stage < MESA_SHADER_GEOMETRY)
4419 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndex);
4420 else
4421 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityMultiViewport);
4422 }
4423
4424 if (s->info.stage > MESA_SHADER_VERTEX &&
4425 s->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_VIEWPORT)) {
4426 if (s->info.stage < MESA_SHADER_GEOMETRY)
4427 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndex);
4428 else
4429 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityMultiViewport);
4430 }
4431
4432 ctx.stage = s->info.stage;
4433 ctx.sinfo = sinfo;
4434 ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
4435 ctx.explicit_lod = true;
4436 spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageUnknown, 0);
4437
4438 SpvAddressingModel model = SpvAddressingModelLogical;
4439 if (gl_shader_stage_is_compute(s->info.stage)) {
4440 if (s->info.cs.ptr_size == 32)
4441 model = SpvAddressingModelPhysical32;
4442 else if (s->info.cs.ptr_size == 64) {
4443 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityPhysicalStorageBufferAddresses);
4444 model = SpvAddressingModelPhysicalStorageBuffer64;
4445 } else
4446 model = SpvAddressingModelLogical;
4447 }
4448
4449 if (ctx.sinfo->have_vulkan_memory_model) {
4450 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModel);
4451 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModelDeviceScope);
4452 spirv_builder_emit_mem_model(&ctx.builder, model,
4453 SpvMemoryModelVulkan);
4454 } else {
4455 spirv_builder_emit_mem_model(&ctx.builder, model,
4456 SpvMemoryModelGLSL450);
4457 }
4458
4459 if (s->info.stage == MESA_SHADER_FRAGMENT &&
4460 s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
4461 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_stencil_export");
4462 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityStencilExportEXT);
4463 }
4464
4465 SpvExecutionModel exec_model;
4466 switch (s->info.stage) {
4467 case MESA_SHADER_VERTEX:
4468 exec_model = SpvExecutionModelVertex;
4469 break;
4470 case MESA_SHADER_TESS_CTRL:
4471 exec_model = SpvExecutionModelTessellationControl;
4472 break;
4473 case MESA_SHADER_TESS_EVAL:
4474 exec_model = SpvExecutionModelTessellationEvaluation;
4475 break;
4476 case MESA_SHADER_GEOMETRY:
4477 exec_model = SpvExecutionModelGeometry;
4478 break;
4479 case MESA_SHADER_FRAGMENT:
4480 exec_model = SpvExecutionModelFragment;
4481 break;
4482 case MESA_SHADER_COMPUTE:
4483 case MESA_SHADER_KERNEL:
4484 exec_model = SpvExecutionModelGLCompute;
4485 break;
4486 default:
4487 unreachable("invalid stage");
4488 }
4489
4490 SpvId type_void = spirv_builder_type_void(&ctx.builder);
4491 SpvId type_void_func = spirv_builder_type_function(&ctx.builder, type_void,
4492 NULL, 0);
4493 SpvId entry_point = spirv_builder_new_id(&ctx.builder);
4494 spirv_builder_emit_name(&ctx.builder, entry_point, "main");
4495
4496 ctx.vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_pointer,
4497 _mesa_key_pointer_equal);
4498
4499 nir_foreach_variable_with_modes(var, s, nir_var_mem_push_const)
4500 input_var_init(&ctx, var);
4501
4502 nir_foreach_shader_in_variable(var, s)
4503 emit_input(&ctx, var);
4504
4505 int max_output = 0;
4506 nir_foreach_shader_out_variable(var, s) {
4507 /* ignore SPIR-V built-ins, tagged with a sentinel value */
4508 if (var->data.driver_location != UINT_MAX) {
4509 assert(var->data.driver_location < INT_MAX);
4510 unsigned extent = glsl_count_attribute_slots(var->type, false);
4511 max_output = MAX2(max_output, (int)var->data.driver_location + extent);
4512 }
4513 emit_output(&ctx, var);
4514 }
4515
4516 uint32_t tcs_vertices_out_word = 0;
4517
4518 unsigned ubo_counter[2] = {0};
4519 nir_foreach_variable_with_modes(var, s, nir_var_mem_ubo)
4520 ubo_counter[var->data.driver_location != 0]++;
4521 nir_foreach_variable_with_modes(var, s, nir_var_mem_ubo)
4522 emit_bo(&ctx, var, ubo_counter[var->data.driver_location != 0] > 1);
4523
4524 unsigned ssbo_counter = 0;
4525 nir_foreach_variable_with_modes(var, s, nir_var_mem_ssbo)
4526 ssbo_counter++;
4527 nir_foreach_variable_with_modes(var, s, nir_var_mem_ssbo)
4528 emit_bo(&ctx, var, ssbo_counter > 1);
4529
4530 nir_foreach_variable_with_modes(var, s, nir_var_image)
4531 ctx.image_var[var->data.driver_location] = var;
4532 nir_foreach_variable_with_modes(var, s, nir_var_uniform) {
4533 if (glsl_type_is_sampler(glsl_without_array(var->type))) {
4534 if (var->data.descriptor_set == ctx.bindless_set_idx)
4535 ctx.bindless_sampler_var[var->data.driver_location] = var;
4536 else
4537 ctx.sampler_var[var->data.driver_location] = var;
4538 ctx.last_sampler = MAX2(ctx.last_sampler, var->data.driver_location);
4539 }
4540 }
4541 if (sinfo->sampler_mask) {
4542 assert(s->info.stage == MESA_SHADER_KERNEL);
4543 int desc_set = -1;
4544 nir_foreach_variable_with_modes(var, s, nir_var_uniform) {
4545 if (glsl_type_is_sampler(glsl_without_array(var->type))) {
4546 desc_set = var->data.descriptor_set;
4547 break;
4548 }
4549 }
4550 assert(desc_set != -1);
4551 u_foreach_bit(sampler, sinfo->sampler_mask)
4552 emit_sampler(&ctx, sampler, desc_set);
4553 }
4554 nir_foreach_variable_with_modes(var, s, nir_var_image | nir_var_uniform) {
4555 const struct glsl_type *type = glsl_without_array(var->type);
4556 if (glsl_type_is_sampler(type))
4557 emit_image(&ctx, var, get_bare_image_type(&ctx, var, true));
4558 else if (glsl_type_is_image(type))
4559 emit_image(&ctx, var, get_bare_image_type(&ctx, var, false));
4560 }
4561
4562 if (sinfo->float_controls.flush_denorms) {
4563 unsigned execution_mode = s->info.float_controls_execution_mode;
4564 bool flush_16_bit = nir_is_denorm_flush_to_zero(execution_mode, 16);
4565 bool flush_32_bit = nir_is_denorm_flush_to_zero(execution_mode, 32);
4566 bool flush_64_bit = nir_is_denorm_flush_to_zero(execution_mode, 64);
4567 bool preserve_16_bit = nir_is_denorm_preserve(execution_mode, 16);
4568 bool preserve_32_bit = nir_is_denorm_preserve(execution_mode, 32);
4569 bool preserve_64_bit = nir_is_denorm_preserve(execution_mode, 64);
4570 bool emit_cap_flush = false;
4571 bool emit_cap_preserve = false;
4572
4573 if (!sinfo->float_controls.denorms_all_independence) {
4574 bool flush = flush_16_bit && flush_64_bit;
4575 bool preserve = preserve_16_bit && preserve_64_bit;
4576
4577 if (!sinfo->float_controls.denorms_32_bit_independence) {
4578 flush = flush && flush_32_bit;
4579 preserve = preserve && preserve_32_bit;
4580
4581 flush_32_bit = flush;
4582 preserve_32_bit = preserve;
4583 }
4584
4585 flush_16_bit = flush;
4586 flush_64_bit = flush;
4587 preserve_16_bit = preserve;
4588 preserve_64_bit = preserve;
4589 }
4590
4591 if (flush_16_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(0)) {
4592 emit_cap_flush = true;
4593 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4594 SpvExecutionModeDenormFlushToZero, 16);
4595 }
4596 if (flush_32_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(1)) {
4597 emit_cap_flush = true;
4598 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4599 SpvExecutionModeDenormFlushToZero, 32);
4600 }
4601 if (flush_64_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(2)) {
4602 emit_cap_flush = true;
4603 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4604 SpvExecutionModeDenormFlushToZero, 64);
4605 }
4606
4607 if (preserve_16_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(0)) {
4608 emit_cap_preserve = true;
4609 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4610 SpvExecutionModeDenormPreserve, 16);
4611 }
4612 if (preserve_32_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(1)) {
4613 emit_cap_preserve = true;
4614 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4615 SpvExecutionModeDenormPreserve, 32);
4616 }
4617 if (preserve_64_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(2)) {
4618 emit_cap_preserve = true;
4619 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4620 SpvExecutionModeDenormPreserve, 64);
4621 }
4622
4623 if (emit_cap_flush)
4624 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormFlushToZero);
4625 if (emit_cap_preserve)
4626 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormPreserve);
4627 }
4628
4629 switch (s->info.stage) {
4630 case MESA_SHADER_FRAGMENT:
4631 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4632 SpvExecutionModeOriginUpperLeft);
4633 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
4634 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4635 get_depth_layout_mode(s->info.fs.depth_layout));
4636 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
4637 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4638 SpvExecutionModeStencilRefReplacingEXT);
4639 if (s->info.fs.early_fragment_tests)
4640 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4641 SpvExecutionModeEarlyFragmentTests);
4642 if (s->info.fs.post_depth_coverage) {
4643 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_post_depth_coverage");
4644 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleMaskPostDepthCoverage);
4645 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4646 SpvExecutionModePostDepthCoverage);
4647 }
4648
4649 if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered ||
4650 s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4651 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_fragment_shader_interlock");
4652 if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered)
4653 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderPixelInterlockEXT);
4654 if (s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4655 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderSampleInterlockEXT);
4656 if (s->info.fs.pixel_interlock_ordered)
4657 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockOrderedEXT);
4658 if (s->info.fs.pixel_interlock_unordered)
4659 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockUnorderedEXT);
4660 if (s->info.fs.sample_interlock_ordered)
4661 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockOrderedEXT);
4662 if (s->info.fs.sample_interlock_unordered)
4663 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockUnorderedEXT);
4664 break;
4665 case MESA_SHADER_TESS_CTRL:
4666 tcs_vertices_out_word = spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4667 SpvExecutionModeOutputVertices,
4668 s->info.tess.tcs_vertices_out);
4669 break;
4670 case MESA_SHADER_TESS_EVAL:
4671 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4672 get_primitive_mode(s->info.tess._primitive_mode));
4673 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4674 s->info.tess.ccw ? SpvExecutionModeVertexOrderCcw
4675 : SpvExecutionModeVertexOrderCw);
4676 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4677 get_spacing(s->info.tess.spacing));
4678 if (s->info.tess.point_mode)
4679 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePointMode);
4680 break;
4681 case MESA_SHADER_GEOMETRY:
4682 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4683 get_input_prim_type_mode(s->info.gs.input_primitive));
4684 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4685 get_output_prim_type_mode(s->info.gs.output_primitive));
4686 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4687 SpvExecutionModeInvocations,
4688 s->info.gs.invocations);
4689 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4690 SpvExecutionModeOutputVertices,
4691 MAX2(s->info.gs.vertices_out, 1));
4692 break;
4693 case MESA_SHADER_KERNEL:
4694 case MESA_SHADER_COMPUTE:
4695 if (s->info.workgroup_size[0] || s->info.workgroup_size[1] || s->info.workgroup_size[2])
4696 spirv_builder_emit_exec_mode_literal3(&ctx.builder, entry_point, SpvExecutionModeLocalSize,
4697 (uint32_t[3]){(uint32_t)s->info.workgroup_size[0], (uint32_t)s->info.workgroup_size[1],
4698 (uint32_t)s->info.workgroup_size[2]});
4699 else {
4700 SpvId sizes[3];
4701 uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
4702 const char *names[] = {"x", "y", "z"};
4703 for (int i = 0; i < 3; i ++) {
4704 sizes[i] = spirv_builder_spec_const_uint(&ctx.builder, 32);
4705 spirv_builder_emit_specid(&ctx.builder, sizes[i], ids[i]);
4706 spirv_builder_emit_name(&ctx.builder, sizes[i], names[i]);
4707 }
4708 SpvId var_type = get_uvec_type(&ctx, 32, 3);
4709 // Even when using LocalSizeId this need to be initialized for nir_intrinsic_load_workgroup_size
4710 ctx.local_group_size_var = spirv_builder_spec_const_composite(&ctx.builder, var_type, sizes, 3);
4711 spirv_builder_emit_name(&ctx.builder, ctx.local_group_size_var, "gl_LocalGroupSizeARB");
4712
4713 /* WorkgroupSize is deprecated in SPIR-V 1.6 */
4714 if (spirv_version >= SPIRV_VERSION(1, 6)) {
4715 spirv_builder_emit_exec_mode_id3(&ctx.builder, entry_point,
4716 SpvExecutionModeLocalSizeId,
4717 sizes);
4718 } else {
4719 spirv_builder_emit_builtin(&ctx.builder, ctx.local_group_size_var, SpvBuiltInWorkgroupSize);
4720 }
4721 }
4722 if (s->info.cs.has_variable_shared_mem) {
4723 ctx.shared_mem_size = spirv_builder_spec_const_uint(&ctx.builder, 32);
4724 spirv_builder_emit_specid(&ctx.builder, ctx.shared_mem_size, ZINK_VARIABLE_SHARED_MEM);
4725 spirv_builder_emit_name(&ctx.builder, ctx.shared_mem_size, "variable_shared_mem");
4726 }
4727 if (s->info.cs.derivative_group) {
4728 SpvCapability caps[] = { 0, SpvCapabilityComputeDerivativeGroupQuadsNV, SpvCapabilityComputeDerivativeGroupLinearNV };
4729 SpvExecutionMode modes[] = { 0, SpvExecutionModeDerivativeGroupQuadsNV, SpvExecutionModeDerivativeGroupLinearNV };
4730 spirv_builder_emit_extension(&ctx.builder, "SPV_NV_compute_shader_derivatives");
4731 spirv_builder_emit_cap(&ctx.builder, caps[s->info.cs.derivative_group]);
4732 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, modes[s->info.cs.derivative_group]);
4733 ctx.explicit_lod = false;
4734 }
4735 break;
4736 default:
4737 break;
4738 }
4739 if (BITSET_TEST_RANGE(s->info.system_values_read, SYSTEM_VALUE_SUBGROUP_SIZE, SYSTEM_VALUE_SUBGROUP_LT_MASK)) {
4740 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySubgroupBallotKHR);
4741 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_ballot");
4742 }
4743 if (s->info.has_transform_feedback_varyings && s->info.stage != MESA_SHADER_FRAGMENT) {
4744 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTransformFeedback);
4745 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4746 SpvExecutionModeXfb);
4747 }
4748
4749 if (s->info.stage == MESA_SHADER_FRAGMENT && s->info.fs.uses_discard) {
4750 ctx.discard_func = spirv_builder_new_id(&ctx.builder);
4751 spirv_builder_emit_name(&ctx.builder, ctx.discard_func, "discard");
4752 spirv_builder_function(&ctx.builder, ctx.discard_func, type_void,
4753 SpvFunctionControlMaskNone,
4754 type_void_func);
4755 SpvId label = spirv_builder_new_id(&ctx.builder);
4756 spirv_builder_label(&ctx.builder, label);
4757
4758 /* kill is deprecated in SPIR-V 1.6, use terminate instead */
4759 if (spirv_version >= SPIRV_VERSION(1, 6))
4760 spirv_builder_emit_terminate(&ctx.builder);
4761 else
4762 spirv_builder_emit_kill(&ctx.builder);
4763
4764 spirv_builder_function_end(&ctx.builder);
4765 }
4766
4767 spirv_builder_function(&ctx.builder, entry_point, type_void,
4768 SpvFunctionControlMaskNone,
4769 type_void_func);
4770
4771 nir_function_impl *entry = nir_shader_get_entrypoint(s);
4772 nir_metadata_require(entry, nir_metadata_block_index);
4773
4774 ctx.defs = rzalloc_array_size(ctx.mem_ctx,
4775 sizeof(SpvId), entry->ssa_alloc);
4776 ctx.def_types = ralloc_array_size(ctx.mem_ctx,
4777 sizeof(nir_alu_type), entry->ssa_alloc);
4778 if (!ctx.defs || !ctx.def_types)
4779 goto fail;
4780 if (sinfo->have_sparse) {
4781 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySparseResidency);
4782 /* this could be huge, so only alloc if needed since it's extremely unlikely to
4783 * ever be used by anything except cts
4784 */
4785 ctx.resident_defs = rzalloc_array_size(ctx.mem_ctx,
4786 sizeof(SpvId), entry->ssa_alloc);
4787 if (!ctx.resident_defs)
4788 goto fail;
4789 }
4790 ctx.num_defs = entry->ssa_alloc;
4791
4792 SpvId *block_ids = ralloc_array_size(ctx.mem_ctx,
4793 sizeof(SpvId), entry->num_blocks);
4794 if (!block_ids)
4795 goto fail;
4796
4797 for (int i = 0; i < entry->num_blocks; ++i)
4798 block_ids[i] = spirv_builder_new_id(&ctx.builder);
4799
4800 ctx.block_ids = block_ids;
4801 ctx.num_blocks = entry->num_blocks;
4802
4803 /* emit a block only for the variable declarations */
4804 start_block(&ctx, spirv_builder_new_id(&ctx.builder));
4805 spirv_builder_begin_local_vars(&ctx.builder);
4806
4807 nir_foreach_reg_decl(reg, entry) {
4808 if (nir_intrinsic_bit_size(reg) == 1)
4809 init_reg(&ctx, reg, nir_type_bool);
4810 }
4811
4812 nir_foreach_variable_with_modes(var, s, nir_var_shader_temp)
4813 emit_shader_temp(&ctx, var);
4814
4815 nir_foreach_function_temp_variable(var, entry)
4816 emit_temp(&ctx, var);
4817
4818
4819 emit_cf_list(&ctx, &entry->body);
4820
4821 spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
4822 spirv_builder_function_end(&ctx.builder);
4823
4824 spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
4825 "main", ctx.entry_ifaces,
4826 ctx.num_entry_ifaces);
4827
4828 size_t num_words = spirv_builder_get_num_words(&ctx.builder);
4829
4830 ret = ralloc(NULL, struct spirv_shader);
4831 if (!ret)
4832 goto fail;
4833
4834 ret->words = ralloc_size(ret, sizeof(uint32_t) * num_words);
4835 if (!ret->words)
4836 goto fail;
4837
4838 ret->num_words = spirv_builder_get_words(&ctx.builder, ret->words, num_words, spirv_version, &tcs_vertices_out_word);
4839 ret->tcs_vertices_out_word = tcs_vertices_out_word;
4840 assert(ret->num_words == num_words);
4841
4842 ralloc_free(ctx.mem_ctx);
4843
4844 return ret;
4845
4846 fail:
4847 ralloc_free(ctx.mem_ctx);
4848
4849 if (ret)
4850 spirv_shader_delete(ret);
4851
4852 return NULL;
4853 }
4854
4855 void
spirv_shader_delete(struct spirv_shader * s)4856 spirv_shader_delete(struct spirv_shader *s)
4857 {
4858 ralloc_free(s);
4859 }
4860