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