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 atype = infer_nir_alu_type_from_uses_ssa(&load_const->def);
2184 for (int i = 0; i < num_components; i++) {
2185 switch (atype) {
2186 case nir_type_uint: {
2187 uint64_t tmp = nir_const_value_as_uint(load_const->value[i], bit_size);
2188 components[i] = emit_uint_const(ctx, bit_size, tmp);
2189 break;
2190 }
2191 case nir_type_int: {
2192 int64_t tmp = nir_const_value_as_int(load_const->value[i], bit_size);
2193 components[i] = emit_int_const(ctx, bit_size, tmp);
2194 break;
2195 }
2196 case nir_type_float: {
2197 double tmp = nir_const_value_as_float(load_const->value[i], bit_size);
2198 components[i] = emit_float_const(ctx, bit_size, tmp);
2199 break;
2200 }
2201 default:
2202 unreachable("this shouldn't happen!");
2203 }
2204 }
2205 }
2206
2207 if (num_components > 1) {
2208 SpvId type = get_alu_type(ctx, atype, num_components, bit_size);
2209 SpvId value = spirv_builder_const_composite(&ctx->builder,
2210 type, components,
2211 num_components);
2212 store_def(ctx, load_const->def.index, value, atype);
2213 } else {
2214 assert(num_components == 1);
2215 store_def(ctx, load_const->def.index, components[0], atype);
2216 }
2217 }
2218
2219 static void
emit_discard(struct ntv_context * ctx,nir_intrinsic_instr * intr)2220 emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2221 {
2222 assert(ctx->discard_func);
2223 SpvId type_void = spirv_builder_type_void(&ctx->builder);
2224 spirv_builder_function_call(&ctx->builder, type_void,
2225 ctx->discard_func, NULL, 0);
2226 }
2227
2228 static void
emit_load_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2229 emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2230 {
2231 nir_alu_type atype;
2232 SpvId ptr = get_src(ctx, intr->src, &atype);
2233
2234 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2235 SpvId type;
2236 if (glsl_type_is_image(deref->type)) {
2237 nir_variable *var = nir_deref_instr_get_variable(deref);
2238 const struct glsl_type *gtype = glsl_without_array(var->type);
2239 type = get_image_type(ctx, var,
2240 glsl_type_is_sampler(gtype),
2241 glsl_get_sampler_dim(gtype) == GLSL_SAMPLER_DIM_BUF);
2242 atype = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(gtype));
2243 } else {
2244 type = get_glsl_type(ctx, deref->type);
2245 atype = get_nir_alu_type(deref->type);
2246 }
2247 SpvId result;
2248
2249 if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2250 result = emit_atomic(ctx, SpvOpAtomicLoad, type, ptr, 0, 0);
2251 else
2252 result = spirv_builder_emit_load(&ctx->builder, type, ptr);
2253 store_def(ctx, intr->def.index, result, atype);
2254 }
2255
2256 static void
emit_store_deref(struct ntv_context * ctx,nir_intrinsic_instr * intr)2257 emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2258 {
2259 nir_alu_type ptype, stype;
2260 SpvId ptr = get_src(ctx, &intr->src[0], &ptype);
2261 SpvId src = get_src(ctx, &intr->src[1], &stype);
2262
2263 const struct glsl_type *gtype = nir_src_as_deref(intr->src[0])->type;
2264 SpvId type = get_glsl_type(ctx, gtype);
2265 nir_variable *var = nir_intrinsic_get_var(intr, 0);
2266 unsigned wrmask = nir_intrinsic_write_mask(intr);
2267 if (!glsl_type_is_scalar(gtype) &&
2268 wrmask != BITFIELD_MASK(glsl_type_is_array(gtype) ? glsl_get_aoa_size(gtype) : glsl_get_vector_elements(gtype))) {
2269 /* no idea what we do if this fails */
2270 assert(glsl_type_is_array(gtype) || glsl_type_is_vector(gtype));
2271
2272 /* this is a partial write, so we have to loop and do a per-component write */
2273 SpvId result_type;
2274 SpvId member_type;
2275 if (glsl_type_is_vector(gtype)) {
2276 result_type = get_glsl_basetype(ctx, glsl_get_base_type(gtype));
2277 member_type = get_alu_type(ctx, stype, 1, glsl_get_bit_size(gtype));
2278 } else
2279 member_type = result_type = get_glsl_type(ctx, glsl_get_array_element(gtype));
2280 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2281 get_storage_class(var),
2282 result_type);
2283 for (unsigned i = 0; i < 4; i++)
2284 if (wrmask & BITFIELD_BIT(i)) {
2285 SpvId idx = emit_uint_const(ctx, 32, i);
2286 SpvId val = spirv_builder_emit_composite_extract(&ctx->builder, member_type, src, &i, 1);
2287 if (stype != ptype)
2288 val = emit_bitcast(ctx, result_type, val);
2289 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2290 ptr, &idx, 1);
2291 spirv_builder_emit_store(&ctx->builder, member, val);
2292 }
2293 return;
2294
2295 }
2296 SpvId result;
2297 if (ctx->stage == MESA_SHADER_FRAGMENT &&
2298 var->data.mode == nir_var_shader_out &&
2299 var->data.location == FRAG_RESULT_SAMPLE_MASK) {
2300 src = emit_bitcast(ctx, type, src);
2301 /* SampleMask is always an array in spirv, so we need to construct it into one */
2302 result = spirv_builder_emit_composite_construct(&ctx->builder, ctx->sample_mask_type, &src, 1);
2303 } else {
2304 if (ptype == stype)
2305 result = src;
2306 else
2307 result = emit_bitcast(ctx, type, src);
2308 }
2309 if (nir_intrinsic_access(intr) & ACCESS_COHERENT)
2310 spirv_builder_emit_atomic_store(&ctx->builder, ptr, SpvScopeDevice, 0, result);
2311 else
2312 spirv_builder_emit_store(&ctx->builder, ptr, result);
2313 }
2314
2315 static void
emit_load_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2316 emit_load_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2317 {
2318 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2319 unsigned num_components = intr->def.num_components;
2320 unsigned bit_size = intr->def.bit_size;
2321 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2322 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2323 SpvStorageClassWorkgroup,
2324 uint_type);
2325 nir_alu_type atype;
2326 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2327 if (atype == nir_type_float)
2328 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2329 SpvId constituents[NIR_MAX_VEC_COMPONENTS];
2330 SpvId shared_block = get_shared_block(ctx, bit_size);
2331 /* need to convert array -> vec */
2332 for (unsigned i = 0; i < num_components; i++) {
2333 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2334 shared_block, &offset, 1);
2335 constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
2336 offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, 1));
2337 }
2338 SpvId result;
2339 if (num_components > 1)
2340 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
2341 else
2342 result = constituents[0];
2343 store_def(ctx, intr->def.index, result, nir_type_uint);
2344 }
2345
2346 static void
emit_store_shared(struct ntv_context * ctx,nir_intrinsic_instr * intr)2347 emit_store_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2348 {
2349 nir_alu_type atype;
2350 SpvId src = get_src(ctx, &intr->src[0], &atype);
2351
2352 unsigned wrmask = nir_intrinsic_write_mask(intr);
2353 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2354 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2355 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2356 SpvStorageClassWorkgroup,
2357 uint_type);
2358 nir_alu_type otype;
2359 SpvId offset = get_src(ctx, &intr->src[1], &otype);
2360 if (otype == nir_type_float)
2361 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2362 SpvId shared_block = get_shared_block(ctx, bit_size);
2363 /* this is a partial write, so we have to loop and do a per-component write */
2364 u_foreach_bit(i, wrmask) {
2365 SpvId shared_offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, i));
2366 SpvId val = src;
2367 if (nir_src_num_components(intr->src[0]) != 1)
2368 val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &i, 1);
2369 if (atype != nir_type_uint)
2370 val = emit_bitcast(ctx, get_alu_type(ctx, nir_type_uint, 1, bit_size), val);
2371 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2372 shared_block, &shared_offset, 1);
2373 spirv_builder_emit_store(&ctx->builder, member, val);
2374 }
2375 }
2376
2377 static void
emit_load_scratch(struct ntv_context * ctx,nir_intrinsic_instr * intr)2378 emit_load_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2379 {
2380 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2381 unsigned num_components = intr->def.num_components;
2382 unsigned bit_size = intr->def.bit_size;
2383 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2384 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2385 SpvStorageClassPrivate,
2386 uint_type);
2387 nir_alu_type atype;
2388 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2389 if (atype != nir_type_uint)
2390 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[0]), 1);
2391 SpvId constituents[NIR_MAX_VEC_COMPONENTS];
2392 SpvId scratch_block = get_scratch_block(ctx, bit_size);
2393 /* need to convert array -> vec */
2394 for (unsigned i = 0; i < num_components; i++) {
2395 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2396 scratch_block, &offset, 1);
2397 constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
2398 offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, 1));
2399 }
2400 SpvId result;
2401 if (num_components > 1)
2402 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
2403 else
2404 result = constituents[0];
2405 store_def(ctx, intr->def.index, result, nir_type_uint);
2406 }
2407
2408 static void
emit_store_scratch(struct ntv_context * ctx,nir_intrinsic_instr * intr)2409 emit_store_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2410 {
2411 nir_alu_type atype;
2412 SpvId src = get_src(ctx, &intr->src[0], &atype);
2413
2414 unsigned wrmask = nir_intrinsic_write_mask(intr);
2415 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2416 SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
2417 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
2418 SpvStorageClassPrivate,
2419 uint_type);
2420 nir_alu_type otype;
2421 SpvId offset = get_src(ctx, &intr->src[1], &otype);
2422 if (otype != nir_type_uint)
2423 offset = bitcast_to_uvec(ctx, offset, nir_src_bit_size(intr->src[1]), 1);
2424 SpvId scratch_block = get_scratch_block(ctx, bit_size);
2425 /* this is a partial write, so we have to loop and do a per-component write */
2426 u_foreach_bit(i, wrmask) {
2427 SpvId scratch_offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, i));
2428 SpvId val = src;
2429 if (nir_src_num_components(intr->src[0]) != 1)
2430 val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &i, 1);
2431 if (atype != nir_type_uint)
2432 val = emit_bitcast(ctx, get_alu_type(ctx, nir_type_uint, 1, bit_size), val);
2433 SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
2434 scratch_block, &scratch_offset, 1);
2435 spirv_builder_emit_store(&ctx->builder, member, val);
2436 }
2437 }
2438
2439 static void
emit_load_push_const(struct ntv_context * ctx,nir_intrinsic_instr * intr)2440 emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2441 {
2442 SpvId uint_type = get_uvec_type(ctx, 32, 1);
2443 SpvId load_type = get_uvec_type(ctx, 32, 1);
2444
2445 /* number of components being loaded */
2446 unsigned num_components = intr->def.num_components;
2447 SpvId constituents[NIR_MAX_VEC_COMPONENTS * 2];
2448 SpvId result;
2449
2450 /* destination type for the load */
2451 SpvId type = get_def_uvec_type(ctx, &intr->def);
2452 SpvId one = emit_uint_const(ctx, 32, 1);
2453
2454 /* we grab a single array member at a time, so it's a pointer to a uint */
2455 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2456 SpvStorageClassPushConstant,
2457 load_type);
2458
2459 nir_alu_type atype;
2460 SpvId member = get_src(ctx, &intr->src[0], &atype);
2461 if (atype == nir_type_float)
2462 member = bitcast_to_uvec(ctx, member, nir_src_bit_size(intr->src[0]), 1);
2463 /* reuse the offset from ZINK_PUSH_CONST_OFFSET */
2464 SpvId offset = emit_uint_const(ctx, 32, nir_intrinsic_component(intr));
2465 /* OpAccessChain takes an array of indices that drill into a hierarchy based on the type:
2466 * index 0 is accessing 'base'
2467 * index 1 is accessing 'base[index 1]'
2468 *
2469 */
2470 for (unsigned i = 0; i < num_components; i++) {
2471 SpvId indices[2] = { member, offset };
2472 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2473 ctx->push_const_var, indices,
2474 ARRAY_SIZE(indices));
2475 /* load a single value into the constituents array */
2476 constituents[i] = spirv_builder_emit_load(&ctx->builder, load_type, ptr);
2477 /* increment to the next vec4 member index for the next load */
2478 offset = emit_binop(ctx, SpvOpIAdd, uint_type, offset, one);
2479 }
2480
2481 /* if loading more than 1 value, reassemble the results into the desired type,
2482 * otherwise just use the loaded result
2483 */
2484 if (num_components > 1) {
2485 result = spirv_builder_emit_composite_construct(&ctx->builder,
2486 type,
2487 constituents,
2488 num_components);
2489 } else
2490 result = constituents[0];
2491
2492 store_def(ctx, intr->def.index, result, nir_type_uint);
2493 }
2494
2495 static void
emit_load_global(struct ntv_context * ctx,nir_intrinsic_instr * intr)2496 emit_load_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2497 {
2498 bool coherent = ctx->sinfo->have_vulkan_memory_model && nir_intrinsic_access(intr) & ACCESS_COHERENT;
2499 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2500 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2501 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2502 SpvStorageClassPhysicalStorageBuffer,
2503 dest_type);
2504 nir_alu_type atype;
2505 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[0], &atype));
2506 SpvId result = spirv_builder_emit_load_aligned(&ctx->builder, dest_type, ptr, intr->def.bit_size / 8, coherent);
2507 store_def(ctx, intr->def.index, result, nir_type_uint);
2508 }
2509
2510 static void
emit_store_global(struct ntv_context * ctx,nir_intrinsic_instr * intr)2511 emit_store_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2512 {
2513 bool coherent = ctx->sinfo->have_vulkan_memory_model && nir_intrinsic_access(intr) & ACCESS_COHERENT;
2514 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2515 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2516 SpvId dest_type = get_uvec_type(ctx, bit_size, 1);
2517 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2518 SpvStorageClassPhysicalStorageBuffer,
2519 dest_type);
2520 nir_alu_type atype;
2521 SpvId param = get_src(ctx, &intr->src[0], &atype);
2522 if (atype != nir_type_uint)
2523 param = emit_bitcast(ctx, dest_type, param);
2524 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[1], &atype));
2525 spirv_builder_emit_store_aligned(&ctx->builder, ptr, param, bit_size / 8, coherent);
2526 }
2527
2528 static void
emit_load_reg(struct ntv_context * ctx,nir_intrinsic_instr * intr)2529 emit_load_reg(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2530 {
2531 assert(nir_intrinsic_base(intr) == 0 && "no array registers");
2532
2533 nir_intrinsic_instr *decl = nir_reg_get_decl(intr->src[0].ssa);
2534 unsigned num_components = nir_intrinsic_num_components(decl);
2535 unsigned bit_size = nir_intrinsic_bit_size(decl);
2536 unsigned index = decl->def.index;
2537 assert(index < ctx->num_defs);
2538
2539 init_reg(ctx, decl, nir_type_uint);
2540 assert(ctx->defs[index] != 0);
2541
2542 nir_alu_type atype = ctx->def_types[index];
2543 SpvId var = ctx->defs[index];
2544 SpvId type = get_alu_type(ctx, atype, num_components, bit_size);
2545 SpvId result = spirv_builder_emit_load(&ctx->builder, type, var);
2546 store_def(ctx, intr->def.index, result, atype);
2547 }
2548
2549 static void
emit_store_reg(struct ntv_context * ctx,nir_intrinsic_instr * intr)2550 emit_store_reg(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2551 {
2552 nir_alu_type atype;
2553 SpvId param = get_src(ctx, &intr->src[0], &atype);
2554
2555 nir_intrinsic_instr *decl = nir_reg_get_decl(intr->src[1].ssa);
2556 unsigned index = decl->def.index;
2557 unsigned num_components = nir_intrinsic_num_components(decl);
2558 unsigned bit_size = nir_intrinsic_bit_size(decl);
2559
2560 atype = nir_alu_type_get_base_type(atype);
2561 init_reg(ctx, decl, atype);
2562 SpvId var = ctx->defs[index];
2563 nir_alu_type vtype = ctx->def_types[index];
2564 if (atype != vtype) {
2565 assert(vtype != nir_type_bool);
2566 param = emit_bitcast(ctx, get_alu_type(ctx, vtype, num_components, bit_size), param);
2567 }
2568 assert(var);
2569 spirv_builder_emit_store(&ctx->builder, var, param);
2570 }
2571
2572 static SpvId
create_builtin_var(struct ntv_context * ctx,SpvId var_type,SpvStorageClass storage_class,const char * name,SpvBuiltIn builtin)2573 create_builtin_var(struct ntv_context *ctx, SpvId var_type,
2574 SpvStorageClass storage_class,
2575 const char *name, SpvBuiltIn builtin)
2576 {
2577 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2578 storage_class,
2579 var_type);
2580 SpvId var = spirv_builder_emit_var(&ctx->builder, pointer_type,
2581 storage_class);
2582 spirv_builder_emit_name(&ctx->builder, var, name);
2583 spirv_builder_emit_builtin(&ctx->builder, var, builtin);
2584
2585 if (ctx->stage == MESA_SHADER_FRAGMENT) {
2586 switch (builtin) {
2587 case SpvBuiltInSampleId:
2588 case SpvBuiltInSubgroupLocalInvocationId:
2589 spirv_builder_emit_decoration(&ctx->builder, var, SpvDecorationFlat);
2590 break;
2591 default:
2592 break;
2593 }
2594 }
2595
2596 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
2597 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var;
2598 return var;
2599 }
2600
2601 static void
emit_load_front_face(struct ntv_context * ctx,nir_intrinsic_instr * intr)2602 emit_load_front_face(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2603 {
2604 SpvId var_type = spirv_builder_type_bool(&ctx->builder);
2605 if (!ctx->front_face_var)
2606 ctx->front_face_var = create_builtin_var(ctx, var_type,
2607 SpvStorageClassInput,
2608 "gl_FrontFacing",
2609 SpvBuiltInFrontFacing);
2610
2611 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
2612 ctx->front_face_var);
2613 assert(1 == intr->def.num_components);
2614 store_def(ctx, intr->def.index, result, nir_type_bool);
2615 }
2616
2617 static void
emit_load_view_index(struct ntv_context * ctx,nir_intrinsic_instr * intr)2618 emit_load_view_index(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2619 {
2620 SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
2621 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_multiview");
2622 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityMultiView);
2623 if (!ctx->view_index_var)
2624 ctx->view_index_var = create_builtin_var(ctx, var_type,
2625 SpvStorageClassInput,
2626 "gl_ViewIndex",
2627 SpvBuiltInViewIndex);
2628
2629 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type,
2630 ctx->view_index_var);
2631 assert(1 == intr->def.num_components);
2632 store_def(ctx, intr->def.index, result, nir_type_uint);
2633 }
2634
2635 static void
emit_load_uint_input(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId * var_id,const char * var_name,SpvBuiltIn builtin)2636 emit_load_uint_input(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId *var_id, const char *var_name, SpvBuiltIn builtin)
2637 {
2638 SpvId var_type = spirv_builder_type_uint(&ctx->builder, 32);
2639 if (!*var_id) {
2640 if (builtin == SpvBuiltInSampleMask) {
2641 /* gl_SampleMaskIn is an array[1] in spirv... */
2642 var_type = spirv_builder_type_array(&ctx->builder, var_type, emit_uint_const(ctx, 32, 1));
2643 spirv_builder_emit_array_stride(&ctx->builder, var_type, sizeof(uint32_t));
2644 }
2645 *var_id = create_builtin_var(ctx, var_type,
2646 SpvStorageClassInput,
2647 var_name,
2648 builtin);
2649 }
2650
2651 SpvId load_var = *var_id;
2652 if (builtin == SpvBuiltInSampleMask) {
2653 SpvId zero = emit_uint_const(ctx, 32, 0);
2654 var_type = spirv_builder_type_uint(&ctx->builder, 32);
2655 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2656 SpvStorageClassInput,
2657 var_type);
2658 load_var = spirv_builder_emit_access_chain(&ctx->builder, pointer_type, load_var, &zero, 1);
2659 }
2660
2661 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, load_var);
2662 assert(1 == intr->def.num_components);
2663 store_def(ctx, intr->def.index, result, nir_type_uint);
2664 }
2665
2666 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)2667 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)
2668 {
2669 SpvId var_type;
2670
2671 switch (type) {
2672 case nir_type_bool:
2673 var_type = get_bvec_type(ctx, intr->def.num_components);
2674 break;
2675 case nir_type_int:
2676 var_type = get_ivec_type(ctx, intr->def.bit_size,
2677 intr->def.num_components);
2678 break;
2679 case nir_type_uint:
2680 var_type = get_uvec_type(ctx, intr->def.bit_size,
2681 intr->def.num_components);
2682 break;
2683 case nir_type_float:
2684 var_type = get_fvec_type(ctx, intr->def.bit_size,
2685 intr->def.num_components);
2686 break;
2687 default:
2688 unreachable("unknown type passed");
2689 }
2690 if (!*var_id)
2691 *var_id = create_builtin_var(ctx, var_type,
2692 SpvStorageClassInput,
2693 var_name,
2694 builtin);
2695
2696 SpvId result = spirv_builder_emit_load(&ctx->builder, var_type, *var_id);
2697 store_def(ctx, intr->def.index, result, type);
2698 }
2699
2700 static void
emit_interpolate(struct ntv_context * ctx,nir_intrinsic_instr * intr)2701 emit_interpolate(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2702 {
2703 SpvId op;
2704 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInterpolationFunction);
2705 SpvId src1 = 0;
2706 nir_alu_type atype;
2707 switch (intr->intrinsic) {
2708 case nir_intrinsic_interp_deref_at_centroid:
2709 op = GLSLstd450InterpolateAtCentroid;
2710 break;
2711 case nir_intrinsic_interp_deref_at_sample:
2712 op = GLSLstd450InterpolateAtSample;
2713 src1 = get_src(ctx, &intr->src[1], &atype);
2714 if (atype != nir_type_int)
2715 src1 = emit_bitcast(ctx, get_ivec_type(ctx, 32, 1), src1);
2716 break;
2717 case nir_intrinsic_interp_deref_at_offset:
2718 op = GLSLstd450InterpolateAtOffset;
2719 src1 = get_src(ctx, &intr->src[1], &atype);
2720 /*
2721 The offset operand must be a vector of 2 components of 32-bit floating-point type.
2722 - InterpolateAtOffset spec
2723 */
2724 if (atype != nir_type_float)
2725 src1 = emit_bitcast(ctx, get_fvec_type(ctx, 32, 2), src1);
2726 break;
2727 default:
2728 unreachable("unknown interp op");
2729 }
2730 nir_alu_type ptype;
2731 SpvId ptr = get_src(ctx, &intr->src[0], &ptype);
2732 SpvId result;
2733 const struct glsl_type *gtype = nir_src_as_deref(intr->src[0])->type;
2734 assert(glsl_get_vector_elements(gtype) == intr->num_components);
2735 assert(ptype == get_nir_alu_type(gtype));
2736 if (intr->intrinsic == nir_intrinsic_interp_deref_at_centroid)
2737 result = emit_builtin_unop(ctx, op, get_glsl_type(ctx, gtype), ptr);
2738 else
2739 result = emit_builtin_binop(ctx, op, get_glsl_type(ctx, gtype), ptr, src1);
2740 store_def(ctx, intr->def.index, result, ptype);
2741 }
2742
2743 static void
handle_atomic_op(struct ntv_context * ctx,nir_intrinsic_instr * intr,SpvId ptr,SpvId param,SpvId param2,nir_alu_type type)2744 handle_atomic_op(struct ntv_context *ctx, nir_intrinsic_instr *intr, SpvId ptr, SpvId param, SpvId param2, nir_alu_type type)
2745 {
2746 SpvId dest_type = get_def_type(ctx, &intr->def, type);
2747 SpvId result = emit_atomic(ctx,
2748 get_atomic_op(ctx, intr->def.bit_size, nir_intrinsic_atomic_op(intr)),
2749 dest_type, ptr, param, param2);
2750 assert(result);
2751 store_def(ctx, intr->def.index, result, type);
2752 }
2753
2754 static void
emit_deref_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2755 emit_deref_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2756 {
2757 nir_alu_type atype;
2758 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2759 SpvId ptr = get_src(ctx, &intr->src[0], &atype);
2760 if (atype != ret_type && ret_type == nir_type_float) {
2761 unsigned bit_size = nir_src_bit_size(intr->src[0]);
2762 SpvId *float_array_type = &ctx->float_array_type[bit_size == 32 ? 0 : 1];
2763 if (!*float_array_type) {
2764 *float_array_type = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassStorageBuffer,
2765 spirv_builder_type_float(&ctx->builder, bit_size));
2766 }
2767 ptr = emit_unop(ctx, SpvOpBitcast, *float_array_type, ptr);
2768 }
2769
2770 SpvId param = get_src(ctx, &intr->src[1], &atype);
2771 if (atype != ret_type)
2772 param = cast_src_to_type(ctx, param, intr->src[1], ret_type);
2773
2774 SpvId param2 = 0;
2775
2776 if (nir_src_bit_size(intr->src[1]) == 64)
2777 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2778
2779 if (intr->intrinsic == nir_intrinsic_deref_atomic_swap) {
2780 param2 = get_src(ctx, &intr->src[2], &atype);
2781 if (atype != ret_type)
2782 param2 = cast_src_to_type(ctx, param2, intr->src[2], ret_type);
2783 }
2784
2785 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2786 }
2787
2788 static void
emit_shared_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2789 emit_shared_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2790 {
2791 unsigned bit_size = nir_src_bit_size(intr->src[1]);
2792 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2793 nir_alu_type atype;
2794 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2795 SpvId param = get_src(ctx, &intr->src[1], &atype);
2796 if (atype != ret_type)
2797 param = cast_src_to_type(ctx, param, intr->src[1], ret_type);
2798
2799 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2800 SpvStorageClassWorkgroup,
2801 dest_type);
2802 SpvId offset = get_src(ctx, &intr->src[0], &atype);
2803 if (atype != nir_type_uint)
2804 offset = cast_src_to_type(ctx, offset, intr->src[0], nir_type_uint);
2805 offset = emit_binop(ctx, SpvOpUDiv, get_uvec_type(ctx, 32, 1), offset, emit_uint_const(ctx, 32, bit_size / 8));
2806 SpvId shared_block = get_shared_block(ctx, bit_size);
2807 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2808 shared_block, &offset, 1);
2809 if (nir_src_bit_size(intr->src[1]) == 64)
2810 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2811 SpvId param2 = 0;
2812
2813 if (intr->intrinsic == nir_intrinsic_shared_atomic_swap) {
2814 param2 = get_src(ctx, &intr->src[2], &atype);
2815 if (atype != ret_type)
2816 param2 = cast_src_to_type(ctx, param2, intr->src[2], ret_type);
2817 }
2818
2819 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2820 }
2821
2822 static void
emit_global_atomic_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)2823 emit_global_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2824 {
2825 unsigned bit_size = nir_src_bit_size(intr->src[1]);
2826 SpvId dest_type = get_def_type(ctx, &intr->def, nir_type_uint);
2827 nir_alu_type atype;
2828 nir_alu_type ret_type = nir_atomic_op_type(nir_intrinsic_atomic_op(intr)) == nir_type_float ? nir_type_float : nir_type_uint;
2829 SpvId param = get_src(ctx, &intr->src[1], &atype);
2830
2831 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
2832 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2833 SpvStorageClassPhysicalStorageBuffer,
2834 dest_type);
2835 SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[0], &atype));
2836
2837 if (bit_size == 64)
2838 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityInt64Atomics);
2839 SpvId param2 = 0;
2840
2841 if (intr->intrinsic == nir_intrinsic_global_atomic_swap)
2842 param2 = get_src(ctx, &intr->src[2], &atype);
2843
2844 handle_atomic_op(ctx, intr, ptr, param, param2, ret_type);
2845 }
2846
2847 static void
emit_get_ssbo_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)2848 emit_get_ssbo_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2849 {
2850 SpvId uint_type = get_uvec_type(ctx, 32, 1);
2851 nir_variable *var = ctx->ssbo_vars;
2852 const struct glsl_type *bare_type = glsl_without_array(var->type);
2853 unsigned last_member_idx = glsl_get_length(bare_type) - 1;
2854 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
2855 SpvStorageClassStorageBuffer,
2856 get_bo_struct_type(ctx, var));
2857 nir_alu_type atype;
2858 SpvId bo = get_src(ctx, &intr->src[0], &atype);
2859 if (atype == nir_type_float)
2860 bo = bitcast_to_uvec(ctx, bo, nir_src_bit_size(intr->src[0]), 1);
2861 SpvId indices[] = { bo };
2862 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
2863 ctx->ssbos[2], indices,
2864 ARRAY_SIZE(indices));
2865 SpvId result = spirv_builder_emit_binop(&ctx->builder, SpvOpArrayLength, uint_type,
2866 ptr, last_member_idx);
2867 /* this is going to be converted by nir to:
2868
2869 length = (buffer_size - offset) / stride
2870
2871 * so we need to un-convert it to avoid having the calculation performed twice
2872 */
2873 const struct glsl_type *last_member = glsl_get_struct_field(bare_type, last_member_idx);
2874 /* multiply by stride */
2875 result = emit_binop(ctx, SpvOpIMul, uint_type, result, emit_uint_const(ctx, 32, glsl_get_explicit_stride(last_member)));
2876 /* get total ssbo size by adding offset */
2877 result = emit_binop(ctx, SpvOpIAdd, uint_type, result,
2878 emit_uint_const(ctx, 32,
2879 glsl_get_struct_field_offset(bare_type, last_member_idx)));
2880 store_def(ctx, intr->def.index, result, nir_type_uint);
2881 }
2882
2883 static SpvId
get_image_coords(struct ntv_context * ctx,const struct glsl_type * type,nir_src * src)2884 get_image_coords(struct ntv_context *ctx, const struct glsl_type *type, nir_src *src)
2885 {
2886 uint32_t num_coords = glsl_get_sampler_coordinate_components(type);
2887 uint32_t src_components = nir_src_num_components(*src);
2888
2889 nir_alu_type atype;
2890 SpvId spv = get_src(ctx, src, &atype);
2891 if (num_coords == src_components)
2892 return spv;
2893
2894 /* need to extract the coord dimensions that the image can use */
2895 SpvId vec_type = get_alu_type(ctx, atype, num_coords, 32);
2896 if (num_coords == 1)
2897 return spirv_builder_emit_vector_extract(&ctx->builder, vec_type, spv, 0);
2898 uint32_t constituents[4];
2899 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);
2900 assert(num_coords < ARRAY_SIZE(constituents));
2901 for (unsigned i = 0; i < num_coords; i++)
2902 constituents[i] = i < src_components ? i : zero;
2903 return spirv_builder_emit_vector_shuffle(&ctx->builder, vec_type, spv, spv, constituents, num_coords);
2904 }
2905
2906 static void
emit_image_deref_store(struct ntv_context * ctx,nir_intrinsic_instr * intr)2907 emit_image_deref_store(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2908 {
2909 nir_alu_type atype;
2910 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
2911 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2912 nir_variable *var = nir_deref_instr_get_variable(deref);
2913 SpvId img_type = find_image_type(ctx, var);
2914 const struct glsl_type *type = glsl_without_array(var->type);
2915 SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2916 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2917 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2918 SpvId texel = get_src(ctx, &intr->src[3], &atype);
2919 /* texel type must match image type */
2920 if (atype != nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(type)))
2921 texel = emit_bitcast(ctx,
2922 spirv_builder_type_vector(&ctx->builder, base_type, 4),
2923 texel);
2924 bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2925 glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2926 SpvId sample = use_sample ? get_src(ctx, &intr->src[2], &atype) : 0;
2927 assert(nir_src_bit_size(intr->src[3]) == glsl_base_type_bit_size(glsl_get_sampler_result_type(type)));
2928 spirv_builder_emit_image_write(&ctx->builder, img, coord, texel, 0, sample, 0);
2929 }
2930
2931 static SpvId
extract_sparse_load(struct ntv_context * ctx,SpvId result,SpvId dest_type,nir_def * def)2932 extract_sparse_load(struct ntv_context *ctx, SpvId result, SpvId dest_type, nir_def *def)
2933 {
2934 /* Result Type must be an OpTypeStruct with two members.
2935 * The first member’s type must be an integer type scalar.
2936 * It holds a Residency Code that can be passed to OpImageSparseTexelsResident
2937 * - OpImageSparseRead spec
2938 */
2939 uint32_t idx = 0;
2940 SpvId resident = spirv_builder_emit_composite_extract(&ctx->builder, spirv_builder_type_uint(&ctx->builder, 32), result, &idx, 1);
2941 idx = 1;
2942 /* normal vec4 return */
2943 if (def->num_components == 4)
2944 result = spirv_builder_emit_composite_extract(&ctx->builder, dest_type, result, &idx, 1);
2945 else {
2946 /* shadow */
2947 assert(def->num_components == 1);
2948 SpvId type = spirv_builder_type_float(&ctx->builder, def->bit_size);
2949 SpvId val[2];
2950 /* pad to 2 components: the upcoming is_sparse_texels_resident instr will always use the
2951 * separate residency value, but the shader still expects this return to be a vec2,
2952 * so give it a vec2
2953 */
2954 val[0] = spirv_builder_emit_composite_extract(&ctx->builder, type, result, &idx, 1);
2955 val[1] = emit_float_const(ctx, def->bit_size, 0);
2956 result = spirv_builder_emit_composite_construct(&ctx->builder, get_fvec_type(ctx, def->bit_size, 2), val, 2);
2957 }
2958 assert(resident != 0);
2959 assert(def->index < ctx->num_defs);
2960 ctx->resident_defs[def->index] = resident;
2961 return result;
2962 }
2963
2964 static void
emit_image_deref_load(struct ntv_context * ctx,nir_intrinsic_instr * intr)2965 emit_image_deref_load(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2966 {
2967 bool sparse = intr->intrinsic == nir_intrinsic_image_deref_sparse_load;
2968 nir_alu_type atype;
2969 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
2970 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2971 nir_variable *var = nir_deref_instr_get_variable(deref);
2972 bool mediump = (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW);
2973 SpvId img_type = find_image_type(ctx, var);
2974 const struct glsl_type *type = glsl_without_array(var->type);
2975 SpvId base_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
2976 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
2977 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
2978 bool use_sample = glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS ||
2979 glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
2980 SpvId sample = use_sample ? get_src(ctx, &intr->src[2], &atype) : 0;
2981 SpvId dest_type = spirv_builder_type_vector(&ctx->builder, base_type,
2982 intr->def.num_components);
2983 SpvId result = spirv_builder_emit_image_read(&ctx->builder,
2984 dest_type,
2985 img, coord, 0, sample, 0, sparse);
2986 if (sparse)
2987 result = extract_sparse_load(ctx, result, dest_type, &intr->def);
2988
2989 if (!sparse && mediump) {
2990 spirv_builder_emit_decoration(&ctx->builder, result,
2991 SpvDecorationRelaxedPrecision);
2992 }
2993
2994 store_def(ctx, intr->def.index, result, nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(type)));
2995 }
2996
2997 static void
emit_image_deref_size(struct ntv_context * ctx,nir_intrinsic_instr * intr)2998 emit_image_deref_size(struct ntv_context *ctx, nir_intrinsic_instr *intr)
2999 {
3000 nir_alu_type atype;
3001 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3002 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3003 nir_variable *var = nir_deref_instr_get_variable(deref);
3004 SpvId img_type = find_image_type(ctx, var);
3005 const struct glsl_type *type = glsl_without_array(var->type);
3006 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
3007 unsigned num_components = glsl_get_sampler_coordinate_components(type);
3008 /* SPIRV requires 2 components for non-array cube size */
3009 if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE && !glsl_sampler_type_is_array(type))
3010 num_components = 2;
3011
3012 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3013 SpvId result = spirv_builder_emit_image_query_size(&ctx->builder, get_uvec_type(ctx, 32, num_components), img, 0);
3014 store_def(ctx, intr->def.index, result, nir_type_uint);
3015 }
3016
3017 static void
emit_image_deref_samples(struct ntv_context * ctx,nir_intrinsic_instr * intr)3018 emit_image_deref_samples(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3019 {
3020 nir_alu_type atype;
3021 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3022 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3023 nir_variable *var = nir_deref_instr_get_variable(deref);
3024 SpvId img_type = find_image_type(ctx, var);
3025 SpvId img = spirv_builder_emit_load(&ctx->builder, img_type, img_var);
3026
3027 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3028 SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples, get_def_type(ctx, &intr->def, nir_type_uint), img);
3029 store_def(ctx, intr->def.index, result, nir_type_uint);
3030 }
3031
3032 static void
emit_image_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)3033 emit_image_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3034 {
3035 nir_alu_type atype, ptype;
3036 SpvId param = get_src(ctx, &intr->src[3], &ptype);
3037 SpvId img_var = get_src(ctx, &intr->src[0], &atype);
3038 nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
3039 nir_variable *var = nir_deref_instr_get_variable(deref);
3040 const struct glsl_type *type = glsl_without_array(var->type);
3041 bool is_ms;
3042 type_to_dim(glsl_get_sampler_dim(type), &is_ms);
3043 SpvId sample = is_ms ? get_src(ctx, &intr->src[2], &atype) : emit_uint_const(ctx, 32, 0);
3044 SpvId coord = get_image_coords(ctx, type, &intr->src[1]);
3045 enum glsl_base_type glsl_result_type = glsl_get_sampler_result_type(type);
3046 SpvId base_type = get_glsl_basetype(ctx, glsl_result_type);
3047 SpvId texel = spirv_builder_emit_image_texel_pointer(&ctx->builder, base_type, img_var, coord, sample);
3048 SpvId param2 = 0;
3049
3050 /* The type of Value must be the same as Result Type.
3051 * The type of the value pointed to by Pointer must be the same as Result Type.
3052 */
3053 nir_alu_type ntype = nir_get_nir_type_for_glsl_base_type(glsl_result_type);
3054 if (ptype != ntype) {
3055 SpvId cast_type = get_def_type(ctx, &intr->def, ntype);
3056 param = emit_bitcast(ctx, cast_type, param);
3057 }
3058
3059 if (intr->intrinsic == nir_intrinsic_image_deref_atomic_swap) {
3060 param2 = get_src(ctx, &intr->src[4], &ptype);
3061 if (ptype != ntype) {
3062 SpvId cast_type = get_def_type(ctx, &intr->def, ntype);
3063 param2 = emit_bitcast(ctx, cast_type, param2);
3064 }
3065 }
3066
3067 handle_atomic_op(ctx, intr, texel, param, param2, ntype);
3068 }
3069
3070 static void
emit_ballot(struct ntv_context * ctx,nir_intrinsic_instr * intr)3071 emit_ballot(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3072 {
3073 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3074 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3075 SpvId type = get_def_uvec_type(ctx, &intr->def);
3076 nir_alu_type atype;
3077 SpvId result = emit_unop(ctx, SpvOpSubgroupBallotKHR, type, get_src(ctx, &intr->src[0], &atype));
3078 store_def(ctx, intr->def.index, result, nir_type_uint);
3079 }
3080
3081 static void
emit_read_first_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3082 emit_read_first_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3083 {
3084 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3085 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3086 nir_alu_type atype;
3087 SpvId src = get_src(ctx, &intr->src[0], &atype);
3088 SpvId type = get_def_type(ctx, &intr->def, atype);
3089 SpvId result = emit_unop(ctx, SpvOpSubgroupFirstInvocationKHR, type, src);
3090 store_def(ctx, intr->def.index, result, atype);
3091 }
3092
3093 static void
emit_read_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3094 emit_read_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3095 {
3096 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySubgroupBallotKHR);
3097 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_ballot");
3098 nir_alu_type atype, itype;
3099 SpvId src = get_src(ctx, &intr->src[0], &atype);
3100 SpvId type = get_def_type(ctx, &intr->def, atype);
3101 SpvId result = emit_binop(ctx, SpvOpSubgroupReadInvocationKHR, type,
3102 src,
3103 get_src(ctx, &intr->src[1], &itype));
3104 store_def(ctx, intr->def.index, result, atype);
3105 }
3106
3107 static void
emit_shader_clock(struct ntv_context * ctx,nir_intrinsic_instr * intr)3108 emit_shader_clock(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3109 {
3110 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityShaderClockKHR);
3111 spirv_builder_emit_extension(&ctx->builder, "SPV_KHR_shader_clock");
3112
3113 SpvScope scope = get_scope(nir_intrinsic_memory_scope(intr));
3114 SpvId type = get_def_type(ctx, &intr->def, nir_type_uint);
3115 SpvId result = spirv_builder_emit_unop_const(&ctx->builder, SpvOpReadClockKHR, type, scope);
3116 store_def(ctx, intr->def.index, result, nir_type_uint);
3117 }
3118
3119 static void
emit_is_sparse_texels_resident(struct ntv_context * ctx,nir_intrinsic_instr * intr)3120 emit_is_sparse_texels_resident(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3121 {
3122 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySparseResidency);
3123
3124 SpvId type = get_def_type(ctx, &intr->def, nir_type_uint);
3125
3126 unsigned index = intr->src[0].ssa->index;
3127 assert(index < ctx->num_defs);
3128 assert(ctx->resident_defs[index] != 0);
3129 SpvId resident = ctx->resident_defs[index];
3130
3131 SpvId result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageSparseTexelsResident, type, resident);
3132 store_def(ctx, intr->def.index, result, nir_type_uint);
3133 }
3134
3135 static void
emit_vote(struct ntv_context * ctx,nir_intrinsic_instr * intr)3136 emit_vote(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3137 {
3138 SpvOp op;
3139
3140 switch (intr->intrinsic) {
3141 case nir_intrinsic_vote_all:
3142 op = SpvOpGroupNonUniformAll;
3143 break;
3144 case nir_intrinsic_vote_any:
3145 op = SpvOpGroupNonUniformAny;
3146 break;
3147 case nir_intrinsic_vote_ieq:
3148 case nir_intrinsic_vote_feq:
3149 op = SpvOpGroupNonUniformAllEqual;
3150 break;
3151 default:
3152 unreachable("unknown vote intrinsic");
3153 }
3154 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityGroupNonUniformVote);
3155 nir_alu_type atype;
3156 SpvId result = spirv_builder_emit_vote(&ctx->builder, op, get_src(ctx, &intr->src[0], &atype));
3157 store_def(ctx, intr->def.index, result, nir_type_bool);
3158 }
3159
3160 static void
emit_is_helper_invocation(struct ntv_context * ctx,nir_intrinsic_instr * intr)3161 emit_is_helper_invocation(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3162 {
3163 spirv_builder_emit_extension(&ctx->builder,
3164 "SPV_EXT_demote_to_helper_invocation");
3165 SpvId result = spirv_is_helper_invocation(&ctx->builder);
3166 store_def(ctx, intr->def.index, result, nir_type_bool);
3167 }
3168
3169 static void
emit_barrier(struct ntv_context * ctx,nir_intrinsic_instr * intr)3170 emit_barrier(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3171 {
3172 SpvScope scope = get_scope(nir_intrinsic_execution_scope(intr));
3173 SpvScope mem_scope = get_scope(nir_intrinsic_memory_scope(intr));
3174 SpvMemorySemanticsMask semantics = 0;
3175
3176 if (nir_intrinsic_memory_scope(intr) != SCOPE_NONE) {
3177 nir_variable_mode modes = nir_intrinsic_memory_modes(intr);
3178
3179 if (modes & nir_var_image)
3180 semantics |= SpvMemorySemanticsImageMemoryMask;
3181
3182 if (modes & nir_var_mem_shared)
3183 semantics |= SpvMemorySemanticsWorkgroupMemoryMask;
3184
3185 if (modes & (nir_var_mem_ssbo | nir_var_mem_global))
3186 semantics |= SpvMemorySemanticsUniformMemoryMask;
3187
3188 if (modes & nir_var_mem_global)
3189 semantics |= SpvMemorySemanticsCrossWorkgroupMemoryMask;
3190
3191 if (modes & (nir_var_shader_out | nir_var_mem_task_payload))
3192 semantics |= SpvMemorySemanticsOutputMemoryMask;
3193
3194 if (!modes)
3195 semantics = SpvMemorySemanticsWorkgroupMemoryMask |
3196 SpvMemorySemanticsUniformMemoryMask |
3197 SpvMemorySemanticsImageMemoryMask |
3198 SpvMemorySemanticsCrossWorkgroupMemoryMask;
3199 semantics |= SpvMemorySemanticsAcquireReleaseMask;
3200 }
3201
3202 if (nir_intrinsic_execution_scope(intr) != SCOPE_NONE)
3203 spirv_builder_emit_control_barrier(&ctx->builder, scope, mem_scope, semantics);
3204 else
3205 spirv_builder_emit_memory_barrier(&ctx->builder, mem_scope, semantics);
3206 }
3207
3208 static void
emit_derivative(struct ntv_context * ctx,nir_intrinsic_instr * intr)3209 emit_derivative(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3210 {
3211 SpvOp op;
3212 switch (intr->intrinsic) {
3213 case nir_intrinsic_ddx:
3214 op = SpvOpDPdx;
3215 break;
3216 case nir_intrinsic_ddy:
3217 op = SpvOpDPdy;
3218 break;
3219 case nir_intrinsic_ddx_fine:
3220 op = SpvOpDPdxFine;
3221 break;
3222 case nir_intrinsic_ddy_fine:
3223 op = SpvOpDPdyFine;
3224 break;
3225 case nir_intrinsic_ddx_coarse:
3226 op = SpvOpDPdxCoarse;
3227 break;
3228 case nir_intrinsic_ddy_coarse:
3229 op = SpvOpDPdyCoarse;
3230 break;
3231 default:
3232 unreachable("invalid ddx/ddy");
3233 }
3234
3235 if (op != SpvOpDPdx && op != SpvOpDPdy)
3236 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDerivativeControl);
3237
3238 SpvId type = get_fvec_type(ctx, intr->def.bit_size, intr->def.num_components);
3239
3240 nir_alu_type atype;
3241 SpvId value = get_src(ctx, &intr->src[0], &atype);
3242 if (atype != nir_type_float)
3243 value = emit_bitcast(ctx, type, value);
3244
3245 SpvId result = emit_unop(ctx, op, type, value);
3246 store_def(ctx, intr->def.index, result, nir_type_float);
3247 }
3248
3249 static void
emit_intrinsic(struct ntv_context * ctx,nir_intrinsic_instr * intr)3250 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
3251 {
3252 switch (intr->intrinsic) {
3253 case nir_intrinsic_decl_reg:
3254 /* Nothing to do */
3255 break;
3256
3257 case nir_intrinsic_load_reg:
3258 emit_load_reg(ctx, intr);
3259 break;
3260
3261 case nir_intrinsic_store_reg:
3262 emit_store_reg(ctx, intr);
3263 break;
3264
3265 case nir_intrinsic_terminate:
3266 emit_discard(ctx, intr);
3267 break;
3268
3269 case nir_intrinsic_demote:
3270 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityDemoteToHelperInvocation);
3271 spirv_builder_emit_demote(&ctx->builder);
3272 break;
3273
3274 case nir_intrinsic_load_deref:
3275 emit_load_deref(ctx, intr);
3276 break;
3277
3278 case nir_intrinsic_store_deref:
3279 emit_store_deref(ctx, intr);
3280 break;
3281
3282 case nir_intrinsic_load_push_constant_zink:
3283 emit_load_push_const(ctx, intr);
3284 break;
3285
3286 case nir_intrinsic_load_global:
3287 case nir_intrinsic_load_global_constant:
3288 emit_load_global(ctx, intr);
3289 break;
3290
3291 case nir_intrinsic_store_global:
3292 emit_store_global(ctx, intr);
3293 break;
3294
3295 case nir_intrinsic_load_front_face:
3296 emit_load_front_face(ctx, intr);
3297 break;
3298
3299 case nir_intrinsic_load_view_index:
3300 emit_load_view_index(ctx, intr);
3301 break;
3302
3303 case nir_intrinsic_load_base_instance:
3304 emit_load_uint_input(ctx, intr, &ctx->base_instance_var, "gl_BaseInstance", SpvBuiltInBaseInstance);
3305 break;
3306
3307 case nir_intrinsic_load_instance_id:
3308 emit_load_uint_input(ctx, intr, &ctx->instance_id_var, "gl_InstanceId", SpvBuiltInInstanceIndex);
3309 break;
3310
3311 case nir_intrinsic_load_base_vertex:
3312 emit_load_uint_input(ctx, intr, &ctx->base_vertex_var, "gl_BaseVertex", SpvBuiltInBaseVertex);
3313 break;
3314
3315 case nir_intrinsic_load_draw_id:
3316 emit_load_uint_input(ctx, intr, &ctx->draw_id_var, "gl_DrawID", SpvBuiltInDrawIndex);
3317 break;
3318
3319 case nir_intrinsic_load_vertex_id:
3320 emit_load_uint_input(ctx, intr, &ctx->vertex_id_var, "gl_VertexId", SpvBuiltInVertexIndex);
3321 break;
3322
3323 case nir_intrinsic_load_primitive_id:
3324 emit_load_uint_input(ctx, intr, &ctx->primitive_id_var, "gl_PrimitiveIdIn", SpvBuiltInPrimitiveId);
3325 break;
3326
3327 case nir_intrinsic_load_invocation_id:
3328 emit_load_uint_input(ctx, intr, &ctx->invocation_id_var, "gl_InvocationId", SpvBuiltInInvocationId);
3329 break;
3330
3331 case nir_intrinsic_load_sample_id:
3332 spirv_builder_emit_cap(&ctx->builder, SpvCapabilitySampleRateShading);
3333 emit_load_uint_input(ctx, intr, &ctx->sample_id_var, "gl_SampleId", SpvBuiltInSampleId);
3334 break;
3335
3336 case nir_intrinsic_load_point_coord_maybe_flipped:
3337 case nir_intrinsic_load_point_coord:
3338 emit_load_vec_input(ctx, intr, &ctx->point_coord_var, "gl_PointCoord", SpvBuiltInPointCoord, nir_type_float);
3339 break;
3340
3341 case nir_intrinsic_load_sample_pos:
3342 emit_load_vec_input(ctx, intr, &ctx->sample_pos_var, "gl_SamplePosition", SpvBuiltInSamplePosition, nir_type_float);
3343 break;
3344
3345 case nir_intrinsic_load_sample_mask_in:
3346 emit_load_uint_input(ctx, intr, &ctx->sample_mask_in_var, "gl_SampleMaskIn", SpvBuiltInSampleMask);
3347 break;
3348
3349 case nir_intrinsic_emit_vertex:
3350 if (ctx->nir->info.gs.vertices_out) //skip vertex emission if !vertices_out
3351 spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr),
3352 ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3353 break;
3354
3355 case nir_intrinsic_end_primitive:
3356 spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr),
3357 ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
3358 break;
3359
3360 case nir_intrinsic_load_helper_invocation:
3361 emit_load_vec_input(ctx, intr, &ctx->helper_invocation_var, "gl_HelperInvocation", SpvBuiltInHelperInvocation, nir_type_bool);
3362 break;
3363
3364 case nir_intrinsic_load_patch_vertices_in:
3365 emit_load_vec_input(ctx, intr, &ctx->tess_patch_vertices_in, "gl_PatchVerticesIn",
3366 SpvBuiltInPatchVertices, nir_type_int);
3367 break;
3368
3369 case nir_intrinsic_load_tess_coord:
3370 emit_load_vec_input(ctx, intr, &ctx->tess_coord_var, "gl_TessCoord",
3371 SpvBuiltInTessCoord, nir_type_float);
3372 break;
3373
3374 case nir_intrinsic_barrier:
3375 emit_barrier(ctx, intr);
3376 break;
3377
3378 case nir_intrinsic_interp_deref_at_centroid:
3379 case nir_intrinsic_interp_deref_at_sample:
3380 case nir_intrinsic_interp_deref_at_offset:
3381 emit_interpolate(ctx, intr);
3382 break;
3383
3384 case nir_intrinsic_deref_atomic:
3385 case nir_intrinsic_deref_atomic_swap:
3386 emit_deref_atomic_intrinsic(ctx, intr);
3387 break;
3388
3389 case nir_intrinsic_shared_atomic:
3390 case nir_intrinsic_shared_atomic_swap:
3391 emit_shared_atomic_intrinsic(ctx, intr);
3392 break;
3393
3394 case nir_intrinsic_global_atomic:
3395 case nir_intrinsic_global_atomic_swap:
3396 emit_global_atomic_intrinsic(ctx, intr);
3397 break;
3398
3399 case nir_intrinsic_begin_invocation_interlock:
3400 case nir_intrinsic_end_invocation_interlock:
3401 spirv_builder_emit_interlock(&ctx->builder, intr->intrinsic == nir_intrinsic_end_invocation_interlock);
3402 break;
3403
3404 case nir_intrinsic_get_ssbo_size:
3405 emit_get_ssbo_size(ctx, intr);
3406 break;
3407
3408 case nir_intrinsic_image_deref_store:
3409 emit_image_deref_store(ctx, intr);
3410 break;
3411
3412 case nir_intrinsic_image_deref_sparse_load:
3413 case nir_intrinsic_image_deref_load:
3414 emit_image_deref_load(ctx, intr);
3415 break;
3416
3417 case nir_intrinsic_image_deref_size:
3418 emit_image_deref_size(ctx, intr);
3419 break;
3420
3421 case nir_intrinsic_image_deref_samples:
3422 emit_image_deref_samples(ctx, intr);
3423 break;
3424
3425 case nir_intrinsic_image_deref_atomic:
3426 case nir_intrinsic_image_deref_atomic_swap:
3427 emit_image_intrinsic(ctx, intr);
3428 break;
3429
3430 case nir_intrinsic_load_workgroup_id:
3431 emit_load_vec_input(ctx, intr, &ctx->workgroup_id_var, "gl_WorkGroupID", SpvBuiltInWorkgroupId, nir_type_uint);
3432 break;
3433
3434 case nir_intrinsic_load_num_workgroups:
3435 emit_load_vec_input(ctx, intr, &ctx->num_workgroups_var, "gl_NumWorkGroups", SpvBuiltInNumWorkgroups, nir_type_uint);
3436 break;
3437
3438 case nir_intrinsic_load_local_invocation_id:
3439 emit_load_vec_input(ctx, intr, &ctx->local_invocation_id_var, "gl_LocalInvocationID", SpvBuiltInLocalInvocationId, nir_type_uint);
3440 break;
3441
3442 case nir_intrinsic_load_global_invocation_id:
3443 emit_load_vec_input(ctx, intr, &ctx->global_invocation_id_var, "gl_GlobalInvocationID", SpvBuiltInGlobalInvocationId, nir_type_uint);
3444 break;
3445
3446 case nir_intrinsic_load_local_invocation_index:
3447 emit_load_uint_input(ctx, intr, &ctx->local_invocation_index_var, "gl_LocalInvocationIndex", SpvBuiltInLocalInvocationIndex);
3448 break;
3449
3450 #define LOAD_SHADER_BALLOT(lowercase, camelcase) \
3451 case nir_intrinsic_load_##lowercase: \
3452 emit_load_uint_input(ctx, intr, &ctx->lowercase##_var, "gl_"#camelcase, SpvBuiltIn##camelcase); \
3453 break
3454
3455 LOAD_SHADER_BALLOT(subgroup_id, SubgroupId);
3456 LOAD_SHADER_BALLOT(subgroup_eq_mask, SubgroupEqMask);
3457 LOAD_SHADER_BALLOT(subgroup_ge_mask, SubgroupGeMask);
3458 LOAD_SHADER_BALLOT(subgroup_invocation, SubgroupLocalInvocationId);
3459 LOAD_SHADER_BALLOT(subgroup_le_mask, SubgroupLeMask);
3460 LOAD_SHADER_BALLOT(subgroup_lt_mask, SubgroupLtMask);
3461 LOAD_SHADER_BALLOT(subgroup_size, SubgroupSize);
3462
3463 case nir_intrinsic_ballot:
3464 emit_ballot(ctx, intr);
3465 break;
3466
3467 case nir_intrinsic_read_first_invocation:
3468 emit_read_first_invocation(ctx, intr);
3469 break;
3470
3471 case nir_intrinsic_read_invocation:
3472 emit_read_invocation(ctx, intr);
3473 break;
3474
3475 case nir_intrinsic_load_workgroup_size:
3476 assert(ctx->local_group_size_var);
3477 store_def(ctx, intr->def.index, ctx->local_group_size_var, nir_type_uint);
3478 break;
3479
3480 case nir_intrinsic_load_shared:
3481 emit_load_shared(ctx, intr);
3482 break;
3483
3484 case nir_intrinsic_store_shared:
3485 emit_store_shared(ctx, intr);
3486 break;
3487
3488 case nir_intrinsic_load_scratch:
3489 emit_load_scratch(ctx, intr);
3490 break;
3491
3492 case nir_intrinsic_store_scratch:
3493 emit_store_scratch(ctx, intr);
3494 break;
3495
3496 case nir_intrinsic_shader_clock:
3497 emit_shader_clock(ctx, intr);
3498 break;
3499
3500 case nir_intrinsic_vote_all:
3501 case nir_intrinsic_vote_any:
3502 case nir_intrinsic_vote_ieq:
3503 case nir_intrinsic_vote_feq:
3504 emit_vote(ctx, intr);
3505 break;
3506
3507 case nir_intrinsic_is_sparse_resident_zink:
3508 emit_is_sparse_texels_resident(ctx, intr);
3509 break;
3510
3511 case nir_intrinsic_is_helper_invocation:
3512 emit_is_helper_invocation(ctx, intr);
3513 break;
3514
3515 case nir_intrinsic_ddx:
3516 case nir_intrinsic_ddy:
3517 case nir_intrinsic_ddx_fine:
3518 case nir_intrinsic_ddy_fine:
3519 case nir_intrinsic_ddx_coarse:
3520 case nir_intrinsic_ddy_coarse:
3521 emit_derivative(ctx, intr);
3522 break;
3523
3524 default:
3525 fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
3526 nir_intrinsic_infos[intr->intrinsic].name);
3527 unreachable("unsupported intrinsic");
3528 }
3529 }
3530
3531 static void
emit_undef(struct ntv_context * ctx,nir_undef_instr * undef)3532 emit_undef(struct ntv_context *ctx, nir_undef_instr *undef)
3533 {
3534 SpvId type = undef->def.bit_size == 1 ? get_bvec_type(ctx, undef->def.num_components) :
3535 get_uvec_type(ctx, undef->def.bit_size,
3536 undef->def.num_components);
3537
3538 store_def(ctx, undef->def.index,
3539 spirv_builder_emit_undef(&ctx->builder, type),
3540 undef->def.bit_size == 1 ? nir_type_bool : nir_type_uint);
3541 }
3542
3543 static SpvId
get_src_float(struct ntv_context * ctx,nir_src * src)3544 get_src_float(struct ntv_context *ctx, nir_src *src)
3545 {
3546 nir_alu_type atype;
3547 SpvId def = get_src(ctx, src, &atype);
3548 if (atype == nir_type_float)
3549 return def;
3550 unsigned num_components = nir_src_num_components(*src);
3551 unsigned bit_size = nir_src_bit_size(*src);
3552 return bitcast_to_fvec(ctx, def, bit_size, num_components);
3553 }
3554
3555 static SpvId
get_src_int(struct ntv_context * ctx,nir_src * src)3556 get_src_int(struct ntv_context *ctx, nir_src *src)
3557 {
3558 nir_alu_type atype;
3559 SpvId def = get_src(ctx, src, &atype);
3560 if (atype == nir_type_int)
3561 return def;
3562 unsigned num_components = nir_src_num_components(*src);
3563 unsigned bit_size = nir_src_bit_size(*src);
3564 return bitcast_to_ivec(ctx, def, bit_size, num_components);
3565 }
3566
3567 static inline bool
tex_instr_is_lod_allowed(nir_tex_instr * tex)3568 tex_instr_is_lod_allowed(nir_tex_instr *tex)
3569 {
3570 /* This can only be used with an OpTypeImage that has a Dim operand of 1D, 2D, 3D, or Cube
3571 * - SPIR-V: 3.14. Image Operands
3572 */
3573
3574 return (tex->sampler_dim == GLSL_SAMPLER_DIM_1D ||
3575 tex->sampler_dim == GLSL_SAMPLER_DIM_2D ||
3576 tex->sampler_dim == GLSL_SAMPLER_DIM_3D ||
3577 tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE ||
3578 /* External images are interpreted as 2D in type_to_dim,
3579 * so LOD is allowed */
3580 tex->sampler_dim == GLSL_SAMPLER_DIM_EXTERNAL ||
3581 /* RECT will always become 2D, so this is fine */
3582 tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
3583 }
3584
3585 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)3586 get_tex_srcs(struct ntv_context *ctx, nir_tex_instr *tex,
3587 nir_variable **bindless_var, unsigned *coord_components,
3588 struct spriv_tex_src *tex_src)
3589 {
3590 nir_variable *var = NULL;
3591 nir_alu_type atype;
3592 tex_src->sparse = tex->is_sparse;
3593 for (unsigned i = 0; i < tex->num_srcs; i++) {
3594 nir_const_value *cv;
3595 switch (tex->src[i].src_type) {
3596 case nir_tex_src_texture_deref:
3597 var = nir_deref_instr_get_variable(nir_instr_as_deref(tex->src[i].src.ssa->parent_instr));
3598 tex_src->src = get_src(ctx, &tex->src[i].src, &atype);
3599 break;
3600 case nir_tex_src_sampler_deref:
3601 tex_src->cl_sampler = get_src(ctx, &tex->src[i].src, &atype);
3602 break;
3603
3604 case nir_tex_src_coord:
3605 if (tex->op == nir_texop_txf ||
3606 tex->op == nir_texop_txf_ms)
3607 tex_src->coord = get_src_int(ctx, &tex->src[i].src);
3608 else
3609 tex_src->coord = get_src_float(ctx, &tex->src[i].src);
3610 *coord_components = nir_src_num_components(tex->src[i].src);
3611 break;
3612
3613 case nir_tex_src_projector:
3614 assert(nir_src_num_components(tex->src[i].src) == 1);
3615 tex_src->proj = get_src_float(ctx, &tex->src[i].src);
3616 assert(tex_src->proj != 0);
3617 break;
3618
3619 case nir_tex_src_offset:
3620 cv = nir_src_as_const_value(tex->src[i].src);
3621 if (cv) {
3622 unsigned bit_size = nir_src_bit_size(tex->src[i].src);
3623 unsigned num_components = nir_src_num_components(tex->src[i].src);
3624
3625 SpvId components[NIR_MAX_VEC_COMPONENTS];
3626 for (int j = 0; j < num_components; ++j) {
3627 int64_t tmp = nir_const_value_as_int(cv[j], bit_size);
3628 components[j] = emit_int_const(ctx, bit_size, tmp);
3629 }
3630
3631 if (num_components > 1) {
3632 SpvId type = get_ivec_type(ctx, bit_size, num_components);
3633 tex_src->const_offset = spirv_builder_const_composite(&ctx->builder,
3634 type,
3635 components,
3636 num_components);
3637 } else
3638 tex_src->const_offset = components[0];
3639 } else
3640 tex_src->offset = get_src_int(ctx, &tex->src[i].src);
3641 break;
3642
3643 case nir_tex_src_bias:
3644 assert(tex->op == nir_texop_txb);
3645 tex_src->bias = get_src_float(ctx, &tex->src[i].src);
3646 assert(tex_src->bias != 0);
3647 break;
3648
3649 case nir_tex_src_min_lod:
3650 assert(nir_src_num_components(tex->src[i].src) == 1);
3651 tex_src->min_lod = get_src_float(ctx, &tex->src[i].src);
3652 assert(tex_src->min_lod != 0);
3653 break;
3654
3655 case nir_tex_src_lod:
3656 assert(nir_src_num_components(tex->src[i].src) == 1);
3657 if (tex->op == nir_texop_txf ||
3658 tex->op == nir_texop_txf_ms ||
3659 tex->op == nir_texop_txs)
3660 tex_src->lod = get_src_int(ctx, &tex->src[i].src);
3661 else
3662 tex_src->lod = get_src_float(ctx, &tex->src[i].src);
3663 assert(tex_src->lod != 0);
3664 break;
3665
3666 case nir_tex_src_ms_index:
3667 assert(nir_src_num_components(tex->src[i].src) == 1);
3668 tex_src->sample = get_src_int(ctx, &tex->src[i].src);
3669 break;
3670
3671 case nir_tex_src_comparator:
3672 assert(nir_src_num_components(tex->src[i].src) == 1);
3673 tex_src->dref = get_src_float(ctx, &tex->src[i].src);
3674 assert(tex_src->dref != 0);
3675 break;
3676
3677 case nir_tex_src_ddx:
3678 tex_src->dx = get_src_float(ctx, &tex->src[i].src);
3679 assert(tex_src->dx != 0);
3680 break;
3681
3682 case nir_tex_src_ddy:
3683 tex_src->dy = get_src_float(ctx, &tex->src[i].src);
3684 assert(tex_src->dy != 0);
3685 break;
3686
3687 case nir_tex_src_texture_offset:
3688 tex_src->tex_offset = get_src_int(ctx, &tex->src[i].src);
3689 break;
3690
3691 case nir_tex_src_sampler_offset:
3692 case nir_tex_src_sampler_handle:
3693 /* don't care */
3694 break;
3695
3696 case nir_tex_src_texture_handle:
3697 tex_src->src = get_src(ctx, &tex->src[i].src, &atype);
3698 var = *bindless_var = nir_deref_instr_get_variable(nir_src_as_deref(tex->src[i].src));
3699 break;
3700
3701 default:
3702 fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
3703 unreachable("unknown texture source");
3704 }
3705 }
3706 return var;
3707 }
3708
3709 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)3710 get_texture_load(struct ntv_context *ctx, SpvId sampler_id, nir_tex_instr *tex,
3711 SpvId cl_sampler, SpvId image_type, SpvId sampled_type)
3712 {
3713 if (ctx->stage == MESA_SHADER_KERNEL) {
3714 SpvId image_load = spirv_builder_emit_load(&ctx->builder, image_type, sampler_id);
3715 if (nir_tex_instr_need_sampler(tex)) {
3716 SpvId sampler_load = spirv_builder_emit_load(&ctx->builder, spirv_builder_type_sampler(&ctx->builder),
3717 cl_sampler);
3718 return spirv_builder_emit_sampled_image(&ctx->builder, sampled_type, image_load, sampler_load);
3719 } else {
3720 return image_load;
3721 }
3722 } else {
3723 return spirv_builder_emit_load(&ctx->builder, sampled_type, sampler_id);
3724 }
3725 }
3726
3727 static SpvId
get_texop_dest_type(struct ntv_context * ctx,const nir_tex_instr * tex)3728 get_texop_dest_type(struct ntv_context *ctx, const nir_tex_instr *tex)
3729 {
3730 SpvId actual_dest_type;
3731 unsigned num_components = tex->def.num_components;
3732 switch (nir_alu_type_get_base_type(tex->dest_type)) {
3733 case nir_type_int:
3734 actual_dest_type = get_ivec_type(ctx, 32, num_components);
3735 break;
3736
3737 case nir_type_uint:
3738 actual_dest_type = get_uvec_type(ctx, 32, num_components);
3739 break;
3740
3741 case nir_type_float:
3742 actual_dest_type = get_fvec_type(ctx, 32, num_components);
3743 break;
3744
3745 default:
3746 unreachable("unexpected nir_alu_type");
3747 }
3748
3749 return actual_dest_type;
3750 }
3751
3752 static void
move_tex_proj_to_coord(struct ntv_context * ctx,unsigned coord_components,struct spriv_tex_src * tex_src)3753 move_tex_proj_to_coord(struct ntv_context *ctx, unsigned coord_components, struct spriv_tex_src *tex_src)
3754 {
3755 SpvId constituents[NIR_MAX_VEC_COMPONENTS + 1];
3756 if (coord_components == 1)
3757 constituents[0] = tex_src->coord;
3758 else {
3759 assert(coord_components > 1);
3760 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
3761 for (uint32_t i = 0; i < coord_components; ++i)
3762 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
3763 float_type,
3764 tex_src->coord,
3765 &i, 1);
3766 }
3767
3768 constituents[coord_components++] = tex_src->proj;
3769
3770 SpvId vec_type = get_fvec_type(ctx, 32, coord_components);
3771 tex_src->coord = spirv_builder_emit_composite_construct(&ctx->builder,
3772 vec_type,
3773 constituents,
3774 coord_components);
3775 }
3776
3777 static SpvId
get_tex_image_to_load(struct ntv_context * ctx,SpvId image_type,bool is_buffer,SpvId load)3778 get_tex_image_to_load( struct ntv_context *ctx, SpvId image_type, bool is_buffer, SpvId load)
3779 {
3780 return is_buffer || ctx->stage == MESA_SHADER_KERNEL ?
3781 load :
3782 spirv_builder_emit_image(&ctx->builder, image_type, load);
3783 }
3784
3785 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)3786 emit_tex_readop(struct ntv_context *ctx, nir_variable *bindless_var, SpvId load,
3787 struct spriv_tex_src *tex_src, SpvId dest_type, bool is_buffer,
3788 nir_variable *var, SpvId image_type, nir_tex_instr *tex)
3789 {
3790 SpvId actual_dest_type = get_texop_dest_type(ctx, tex);
3791
3792 SpvId result;
3793 if (tex_src->offset)
3794 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3795 if (tex_src->min_lod)
3796 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityMinLod);
3797 if (tex->op == nir_texop_txf ||
3798 tex->op == nir_texop_txf_ms ||
3799 tex->op == nir_texop_tg4) {
3800 SpvId image = get_tex_image_to_load(ctx, image_type, is_buffer, load);
3801
3802 if (tex->op == nir_texop_tg4) {
3803 if (tex_src->const_offset)
3804 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
3805 result = spirv_builder_emit_image_gather(&ctx->builder, actual_dest_type,
3806 load, tex_src, emit_uint_const(ctx, 32, tex->component));
3807 actual_dest_type = dest_type;
3808 } else {
3809 assert(tex->op == nir_texop_txf_ms || !tex_src->sample);
3810 bool is_ms;
3811 type_to_dim(glsl_get_sampler_dim(glsl_without_array(var->type)), &is_ms);
3812 assert(is_ms || !tex_src->sample);
3813 result = spirv_builder_emit_image_fetch(&ctx->builder, actual_dest_type,
3814 image, tex_src);
3815 }
3816 } else {
3817 if (tex->op == nir_texop_txl)
3818 tex_src->min_lod = 0;
3819 result = spirv_builder_emit_image_sample(&ctx->builder,
3820 actual_dest_type, load,
3821 tex_src);
3822 }
3823
3824 if (!bindless_var && (var->data.precision == GLSL_PRECISION_MEDIUM || var->data.precision == GLSL_PRECISION_LOW)) {
3825 spirv_builder_emit_decoration(&ctx->builder, result,
3826 SpvDecorationRelaxedPrecision);
3827 }
3828
3829 if (tex->is_sparse)
3830 result = extract_sparse_load(ctx, result, actual_dest_type, &tex->def);
3831
3832 if (tex->def.bit_size != 32) {
3833 /* convert FP32 to FP16 */
3834 result = emit_unop(ctx, SpvOpFConvert, dest_type, result);
3835 }
3836
3837 return result;
3838 }
3839
3840 static void
emit_tex(struct ntv_context * ctx,nir_tex_instr * tex)3841 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
3842 {
3843 assert(tex->op == nir_texop_tex ||
3844 tex->op == nir_texop_txb ||
3845 tex->op == nir_texop_txl ||
3846 tex->op == nir_texop_txd ||
3847 tex->op == nir_texop_txf ||
3848 tex->op == nir_texop_txf_ms ||
3849 tex->op == nir_texop_txs ||
3850 tex->op == nir_texop_lod ||
3851 tex->op == nir_texop_tg4 ||
3852 tex->op == nir_texop_texture_samples ||
3853 tex->op == nir_texop_query_levels);
3854
3855 struct spriv_tex_src tex_src = {0};
3856 unsigned coord_components = 0;
3857 nir_variable *bindless_var = NULL;
3858 nir_variable *var = get_tex_srcs(ctx, tex, &bindless_var, &coord_components, &tex_src);
3859
3860 assert(var);
3861 SpvId image_type = find_image_type(ctx, var);
3862 assert(image_type);
3863
3864 bool is_buffer = glsl_get_sampler_dim(glsl_without_array(var->type)) ==
3865 GLSL_SAMPLER_DIM_BUF;
3866 SpvId sampled_type = is_buffer ? image_type :
3867 spirv_builder_type_sampled_image(&ctx->builder, image_type);
3868 assert(sampled_type);
3869
3870 SpvId sampler_id = tex_src.src;
3871 if (tex_src.tex_offset) {
3872 SpvId ptr = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassUniformConstant, sampled_type);
3873 sampler_id = spirv_builder_emit_access_chain(&ctx->builder, ptr, sampler_id, &tex_src.tex_offset, 1);
3874 }
3875
3876 SpvId load = get_texture_load(ctx, sampler_id, tex, tex_src.cl_sampler, image_type, sampled_type);
3877
3878 if (tex->is_sparse)
3879 tex->def.num_components--;
3880 SpvId dest_type = get_def_type(ctx, &tex->def, tex->dest_type);
3881
3882 if (nir_tex_instr_is_query(tex))
3883 spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageQuery);
3884
3885 if (!tex_instr_is_lod_allowed(tex))
3886 tex_src.lod = 0;
3887 else if (ctx->stage != MESA_SHADER_FRAGMENT &&
3888 tex->op == nir_texop_tex && ctx->explicit_lod && !tex_src.lod)
3889 tex_src.lod = emit_float_const(ctx, 32, 0.0);
3890
3891 if (tex_src.proj && coord_components > 0)
3892 move_tex_proj_to_coord(ctx, coord_components, &tex_src);
3893
3894 SpvId result = 0;
3895
3896 switch (tex->op) {
3897 case nir_texop_txs: {
3898 SpvId image = get_tex_image_to_load(ctx, image_type, is_buffer, load);
3899 /* Its Dim operand must be one of 1D, 2D, 3D, or Cube
3900 * - OpImageQuerySizeLod specification
3901 *
3902 * Additionally, if its Dim is 1D, 2D, 3D, or Cube,
3903 * it must also have either an MS of 1 or a Sampled of 0 or 2.
3904 * - OpImageQuerySize specification
3905 *
3906 * all spirv samplers use these types
3907 */
3908 if (!tex_src.lod && tex_instr_is_lod_allowed(tex))
3909 tex_src.lod = emit_uint_const(ctx, 32, 0);
3910 result = spirv_builder_emit_image_query_size(&ctx->builder,
3911 dest_type, image,
3912 tex_src.lod);
3913 break;
3914 }
3915 case nir_texop_query_levels: {
3916 SpvId image = get_tex_image_to_load(ctx, image_type, is_buffer, load);
3917 result = spirv_builder_emit_image_query_levels(&ctx->builder,
3918 dest_type, image);
3919 break;
3920 }
3921 case nir_texop_texture_samples: {
3922 SpvId image = get_tex_image_to_load(ctx, image_type, is_buffer, load);
3923 result = spirv_builder_emit_unop(&ctx->builder, SpvOpImageQuerySamples,
3924 dest_type, image);
3925 break;
3926 }
3927 case nir_texop_lod: {
3928 result = spirv_builder_emit_image_query_lod(&ctx->builder,
3929 dest_type, load,
3930 tex_src.coord);
3931 break;
3932 }
3933 default:
3934 result = emit_tex_readop(ctx, bindless_var, load, &tex_src,
3935 dest_type, is_buffer, var, image_type, tex);
3936 break;
3937 }
3938
3939 store_def(ctx, tex->def.index, result, tex->dest_type);
3940
3941 if (tex->is_sparse)
3942 tex->def.num_components++;
3943 }
3944
3945 static void
start_block(struct ntv_context * ctx,SpvId label)3946 start_block(struct ntv_context *ctx, SpvId label)
3947 {
3948 /* terminate previous block if needed */
3949 if (ctx->block_started)
3950 spirv_builder_emit_branch(&ctx->builder, label);
3951
3952 /* start new block */
3953 spirv_builder_label(&ctx->builder, label);
3954 ctx->block_started = true;
3955 }
3956
3957 static void
branch(struct ntv_context * ctx,SpvId label)3958 branch(struct ntv_context *ctx, SpvId label)
3959 {
3960 assert(ctx->block_started);
3961 spirv_builder_emit_branch(&ctx->builder, label);
3962 ctx->block_started = false;
3963 }
3964
3965 static void
branch_conditional(struct ntv_context * ctx,SpvId condition,SpvId then_id,SpvId else_id)3966 branch_conditional(struct ntv_context *ctx, SpvId condition, SpvId then_id,
3967 SpvId else_id)
3968 {
3969 assert(ctx->block_started);
3970 spirv_builder_emit_branch_conditional(&ctx->builder, condition,
3971 then_id, else_id);
3972 ctx->block_started = false;
3973 }
3974
3975 static void
emit_jump(struct ntv_context * ctx,nir_jump_instr * jump)3976 emit_jump(struct ntv_context *ctx, nir_jump_instr *jump)
3977 {
3978 switch (jump->type) {
3979 case nir_jump_break:
3980 assert(ctx->loop_break);
3981 branch(ctx, ctx->loop_break);
3982 break;
3983
3984 case nir_jump_continue:
3985 assert(ctx->loop_cont);
3986 branch(ctx, ctx->loop_cont);
3987 break;
3988
3989 default:
3990 unreachable("Unsupported jump type\n");
3991 }
3992 }
3993
3994 static void
emit_deref_var(struct ntv_context * ctx,nir_deref_instr * deref)3995 emit_deref_var(struct ntv_context *ctx, nir_deref_instr *deref)
3996 {
3997 assert(deref->deref_type == nir_deref_type_var);
3998
3999 struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var);
4000 assert(he);
4001 SpvId result = (SpvId)(intptr_t)he->data;
4002 store_def(ctx, deref->def.index, result, get_nir_alu_type(deref->type));
4003 }
4004
4005 static void
emit_deref_array(struct ntv_context * ctx,nir_deref_instr * deref)4006 emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
4007 {
4008 assert(deref->deref_type == nir_deref_type_array);
4009 nir_variable *var = nir_deref_instr_get_variable(deref);
4010
4011 if (!nir_src_is_always_uniform(deref->arr.index)) {
4012 if (deref->modes & nir_var_mem_ubo)
4013 spirv_builder_emit_cap(&ctx->builder,
4014 SpvCapabilityUniformBufferArrayDynamicIndexing);
4015
4016 if (deref->modes & nir_var_mem_ssbo)
4017 spirv_builder_emit_cap(&ctx->builder,
4018 SpvCapabilityStorageBufferArrayDynamicIndexing);
4019
4020 if (deref->modes & (nir_var_uniform | nir_var_image)) {
4021 const struct glsl_type *type = glsl_without_array(var->type);
4022 assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
4023
4024 if (glsl_type_is_sampler(type))
4025 spirv_builder_emit_cap(&ctx->builder,
4026 SpvCapabilitySampledImageArrayDynamicIndexing);
4027 else
4028 spirv_builder_emit_cap(&ctx->builder,
4029 SpvCapabilityStorageImageArrayDynamicIndexing);
4030 }
4031 }
4032
4033 SpvStorageClass storage_class = get_storage_class(var);
4034 SpvId type;
4035 nir_alu_type atype = nir_type_uint;
4036
4037 SpvId base = get_src(ctx, &deref->parent, &atype);
4038
4039 switch (var->data.mode) {
4040
4041 case nir_var_mem_ubo:
4042 case nir_var_mem_ssbo:
4043 base = get_src(ctx, &deref->parent, &atype);
4044 /* this is either the array<buffers> deref or the array<uint> deref */
4045 if (glsl_type_is_struct_or_ifc(deref->type)) {
4046 /* array<buffers> */
4047 type = get_bo_struct_type(ctx, var);
4048 break;
4049 }
4050 /* array<uint> */
4051 FALLTHROUGH;
4052 case nir_var_function_temp:
4053 case nir_var_shader_in:
4054 case nir_var_shader_out:
4055 base = get_src(ctx, &deref->parent, &atype);
4056 type = get_glsl_type(ctx, deref->type);
4057 break;
4058
4059 case nir_var_uniform:
4060 case nir_var_image: {
4061 base = get_src(ctx, &deref->parent, &atype);
4062 const struct glsl_type *gtype = glsl_without_array(deref->type);
4063 type = get_image_type(ctx, var,
4064 glsl_type_is_sampler(gtype),
4065 glsl_get_sampler_dim(gtype) == GLSL_SAMPLER_DIM_BUF);
4066 break;
4067 }
4068
4069 default:
4070 unreachable("Unsupported nir_variable_mode\n");
4071 }
4072
4073 nir_alu_type itype;
4074 SpvId index = get_src(ctx, &deref->arr.index, &itype);
4075 if (itype == nir_type_float)
4076 index = emit_bitcast(ctx, get_uvec_type(ctx, 32, 1), index);
4077
4078 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
4079 storage_class,
4080 type);
4081
4082 SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
4083 ptr_type,
4084 base,
4085 &index, 1);
4086 /* uint is a bit of a lie here, it's really just an opaque type */
4087 store_def(ctx, deref->def.index, result, get_nir_alu_type(deref->type));
4088 }
4089
4090 static void
emit_deref_struct(struct ntv_context * ctx,nir_deref_instr * deref)4091 emit_deref_struct(struct ntv_context *ctx, nir_deref_instr *deref)
4092 {
4093 assert(deref->deref_type == nir_deref_type_struct);
4094 nir_variable *var = nir_deref_instr_get_variable(deref);
4095
4096 SpvStorageClass storage_class = get_storage_class(var);
4097
4098 SpvId index = emit_uint_const(ctx, 32, deref->strct.index);
4099 SpvId type = (var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo)) ?
4100 get_bo_array_type(ctx, var) :
4101 get_glsl_type(ctx, deref->type);
4102
4103 SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
4104 storage_class,
4105 type);
4106
4107 nir_alu_type atype;
4108 SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
4109 ptr_type,
4110 get_src(ctx, &deref->parent, &atype),
4111 &index, 1);
4112 /* uint is a bit of a lie here, it's really just an opaque type */
4113 store_def(ctx, deref->def.index, result, get_nir_alu_type(deref->type));
4114 }
4115
4116 static void
emit_deref(struct ntv_context * ctx,nir_deref_instr * deref)4117 emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
4118 {
4119 switch (deref->deref_type) {
4120 case nir_deref_type_var:
4121 emit_deref_var(ctx, deref);
4122 break;
4123
4124 case nir_deref_type_array:
4125 emit_deref_array(ctx, deref);
4126 break;
4127
4128 case nir_deref_type_struct:
4129 emit_deref_struct(ctx, deref);
4130 break;
4131
4132 default:
4133 unreachable("unexpected deref_type");
4134 }
4135 }
4136
4137 static void
emit_block(struct ntv_context * ctx,struct nir_block * block)4138 emit_block(struct ntv_context *ctx, struct nir_block *block)
4139 {
4140 start_block(ctx, block_label(ctx, block));
4141 nir_foreach_instr(instr, block) {
4142 switch (instr->type) {
4143 case nir_instr_type_alu:
4144 emit_alu(ctx, nir_instr_as_alu(instr));
4145 break;
4146 case nir_instr_type_intrinsic:
4147 emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
4148 break;
4149 case nir_instr_type_load_const:
4150 emit_load_const(ctx, nir_instr_as_load_const(instr));
4151 break;
4152 case nir_instr_type_undef:
4153 emit_undef(ctx, nir_instr_as_undef(instr));
4154 break;
4155 case nir_instr_type_tex:
4156 emit_tex(ctx, nir_instr_as_tex(instr));
4157 break;
4158 case nir_instr_type_phi:
4159 unreachable("nir_instr_type_phi not supported");
4160 break;
4161 case nir_instr_type_jump:
4162 emit_jump(ctx, nir_instr_as_jump(instr));
4163 break;
4164 case nir_instr_type_call:
4165 unreachable("nir_instr_type_call not supported");
4166 break;
4167 case nir_instr_type_parallel_copy:
4168 unreachable("nir_instr_type_parallel_copy not supported");
4169 break;
4170 case nir_instr_type_deref:
4171 emit_deref(ctx, nir_instr_as_deref(instr));
4172 break;
4173 case nir_instr_type_debug_info:
4174 unreachable("nir_instr_type_debug_info not supported");
4175 break;
4176 }
4177 }
4178 }
4179
4180 static void
4181 emit_cf_list(struct ntv_context *ctx, struct exec_list *list);
4182
4183 static SpvId
get_src_bool(struct ntv_context * ctx,nir_src * src)4184 get_src_bool(struct ntv_context *ctx, nir_src *src)
4185 {
4186 assert(nir_src_bit_size(*src) == 1);
4187 nir_alu_type atype;
4188 return get_src(ctx, src, &atype);
4189 }
4190
4191 static void
emit_if(struct ntv_context * ctx,nir_if * if_stmt)4192 emit_if(struct ntv_context *ctx, nir_if *if_stmt)
4193 {
4194 SpvId condition = get_src_bool(ctx, &if_stmt->condition);
4195
4196 SpvId header_id = spirv_builder_new_id(&ctx->builder);
4197 SpvId then_id = block_label(ctx, nir_if_first_then_block(if_stmt));
4198 SpvId endif_id = spirv_builder_new_id(&ctx->builder);
4199 SpvId else_id = endif_id;
4200
4201 bool has_else = !exec_list_is_empty(&if_stmt->else_list);
4202 if (has_else) {
4203 assert(nir_if_first_else_block(if_stmt)->index < ctx->num_blocks);
4204 else_id = block_label(ctx, nir_if_first_else_block(if_stmt));
4205 }
4206
4207 /* create a header-block */
4208 start_block(ctx, header_id);
4209 spirv_builder_emit_selection_merge(&ctx->builder, endif_id,
4210 SpvSelectionControlMaskNone);
4211 branch_conditional(ctx, condition, then_id, else_id);
4212
4213 emit_cf_list(ctx, &if_stmt->then_list);
4214
4215 if (has_else) {
4216 if (ctx->block_started)
4217 branch(ctx, endif_id);
4218
4219 emit_cf_list(ctx, &if_stmt->else_list);
4220 }
4221
4222 start_block(ctx, endif_id);
4223 }
4224
4225 static void
emit_loop(struct ntv_context * ctx,nir_loop * loop)4226 emit_loop(struct ntv_context *ctx, nir_loop *loop)
4227 {
4228 assert(!nir_loop_has_continue_construct(loop));
4229 SpvId header_id = spirv_builder_new_id(&ctx->builder);
4230 SpvId begin_id = block_label(ctx, nir_loop_first_block(loop));
4231 SpvId break_id = spirv_builder_new_id(&ctx->builder);
4232 SpvId cont_id = spirv_builder_new_id(&ctx->builder);
4233
4234 /* create a header-block */
4235 start_block(ctx, header_id);
4236 spirv_builder_loop_merge(&ctx->builder, break_id, cont_id, SpvLoopControlMaskNone);
4237 branch(ctx, begin_id);
4238
4239 SpvId save_break = ctx->loop_break;
4240 SpvId save_cont = ctx->loop_cont;
4241 ctx->loop_break = break_id;
4242 ctx->loop_cont = cont_id;
4243
4244 emit_cf_list(ctx, &loop->body);
4245
4246 ctx->loop_break = save_break;
4247 ctx->loop_cont = save_cont;
4248
4249 /* loop->body may have already ended our block */
4250 if (ctx->block_started)
4251 branch(ctx, cont_id);
4252 start_block(ctx, cont_id);
4253 branch(ctx, header_id);
4254
4255 start_block(ctx, break_id);
4256 }
4257
4258 static void
emit_cf_list(struct ntv_context * ctx,struct exec_list * list)4259 emit_cf_list(struct ntv_context *ctx, struct exec_list *list)
4260 {
4261 foreach_list_typed(nir_cf_node, node, node, list) {
4262 switch (node->type) {
4263 case nir_cf_node_block:
4264 emit_block(ctx, nir_cf_node_as_block(node));
4265 break;
4266
4267 case nir_cf_node_if:
4268 emit_if(ctx, nir_cf_node_as_if(node));
4269 break;
4270
4271 case nir_cf_node_loop:
4272 emit_loop(ctx, nir_cf_node_as_loop(node));
4273 break;
4274
4275 case nir_cf_node_function:
4276 unreachable("nir_cf_node_function not supported");
4277 break;
4278 }
4279 }
4280 }
4281
4282 static SpvExecutionMode
get_input_prim_type_mode(enum mesa_prim type)4283 get_input_prim_type_mode(enum mesa_prim type)
4284 {
4285 switch (type) {
4286 case MESA_PRIM_POINTS:
4287 return SpvExecutionModeInputPoints;
4288 case MESA_PRIM_LINES:
4289 case MESA_PRIM_LINE_LOOP:
4290 case MESA_PRIM_LINE_STRIP:
4291 return SpvExecutionModeInputLines;
4292 case MESA_PRIM_TRIANGLE_STRIP:
4293 case MESA_PRIM_TRIANGLES:
4294 case MESA_PRIM_TRIANGLE_FAN:
4295 return SpvExecutionModeTriangles;
4296 case MESA_PRIM_QUADS:
4297 case MESA_PRIM_QUAD_STRIP:
4298 return SpvExecutionModeQuads;
4299 break;
4300 case MESA_PRIM_POLYGON:
4301 unreachable("handle polygons in gs");
4302 break;
4303 case MESA_PRIM_LINES_ADJACENCY:
4304 case MESA_PRIM_LINE_STRIP_ADJACENCY:
4305 return SpvExecutionModeInputLinesAdjacency;
4306 case MESA_PRIM_TRIANGLES_ADJACENCY:
4307 case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
4308 return SpvExecutionModeInputTrianglesAdjacency;
4309 break;
4310 default:
4311 debug_printf("unknown geometry shader input mode %u\n", type);
4312 unreachable("error!");
4313 break;
4314 }
4315
4316 return 0;
4317 }
4318 static SpvExecutionMode
get_output_prim_type_mode(enum mesa_prim type)4319 get_output_prim_type_mode(enum mesa_prim type)
4320 {
4321 switch (type) {
4322 case MESA_PRIM_POINTS:
4323 return SpvExecutionModeOutputPoints;
4324 case MESA_PRIM_LINES:
4325 case MESA_PRIM_LINE_LOOP:
4326 unreachable("MESA_PRIM_LINES/LINE_LOOP passed as gs output");
4327 break;
4328 case MESA_PRIM_LINE_STRIP:
4329 return SpvExecutionModeOutputLineStrip;
4330 case MESA_PRIM_TRIANGLE_STRIP:
4331 return SpvExecutionModeOutputTriangleStrip;
4332 case MESA_PRIM_TRIANGLES:
4333 case MESA_PRIM_TRIANGLE_FAN: //FIXME: not sure if right for output
4334 return SpvExecutionModeTriangles;
4335 case MESA_PRIM_QUADS:
4336 case MESA_PRIM_QUAD_STRIP:
4337 return SpvExecutionModeQuads;
4338 case MESA_PRIM_POLYGON:
4339 unreachable("handle polygons in gs");
4340 break;
4341 case MESA_PRIM_LINES_ADJACENCY:
4342 case MESA_PRIM_LINE_STRIP_ADJACENCY:
4343 unreachable("handle line adjacency in gs");
4344 break;
4345 case MESA_PRIM_TRIANGLES_ADJACENCY:
4346 case MESA_PRIM_TRIANGLE_STRIP_ADJACENCY:
4347 unreachable("handle triangle adjacency in gs");
4348 break;
4349 default:
4350 debug_printf("unknown geometry shader output mode %u\n", type);
4351 unreachable("error!");
4352 break;
4353 }
4354
4355 return 0;
4356 }
4357
4358 static SpvExecutionMode
get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)4359 get_depth_layout_mode(enum gl_frag_depth_layout depth_layout)
4360 {
4361 switch (depth_layout) {
4362 case FRAG_DEPTH_LAYOUT_NONE:
4363 case FRAG_DEPTH_LAYOUT_ANY:
4364 return SpvExecutionModeDepthReplacing;
4365 case FRAG_DEPTH_LAYOUT_GREATER:
4366 return SpvExecutionModeDepthGreater;
4367 case FRAG_DEPTH_LAYOUT_LESS:
4368 return SpvExecutionModeDepthLess;
4369 case FRAG_DEPTH_LAYOUT_UNCHANGED:
4370 return SpvExecutionModeDepthUnchanged;
4371 default:
4372 unreachable("unexpected depth layout");
4373 }
4374 }
4375
4376 static SpvExecutionMode
get_primitive_mode(enum tess_primitive_mode primitive_mode)4377 get_primitive_mode(enum tess_primitive_mode primitive_mode)
4378 {
4379 switch (primitive_mode) {
4380 case TESS_PRIMITIVE_TRIANGLES: return SpvExecutionModeTriangles;
4381 case TESS_PRIMITIVE_QUADS: return SpvExecutionModeQuads;
4382 case TESS_PRIMITIVE_ISOLINES: return SpvExecutionModeIsolines;
4383 default:
4384 unreachable("unknown tess prim type!");
4385 }
4386 }
4387
4388 static SpvExecutionMode
get_spacing(enum gl_tess_spacing spacing)4389 get_spacing(enum gl_tess_spacing spacing)
4390 {
4391 switch (spacing) {
4392 case TESS_SPACING_EQUAL:
4393 return SpvExecutionModeSpacingEqual;
4394 case TESS_SPACING_FRACTIONAL_ODD:
4395 return SpvExecutionModeSpacingFractionalOdd;
4396 case TESS_SPACING_FRACTIONAL_EVEN:
4397 return SpvExecutionModeSpacingFractionalEven;
4398 default:
4399 unreachable("unknown tess spacing!");
4400 }
4401 }
4402
4403 struct spirv_shader *
nir_to_spirv(struct nir_shader * s,const struct zink_shader_info * sinfo,const struct zink_screen * screen)4404 nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, const struct zink_screen *screen)
4405 {
4406 const uint32_t spirv_version = screen->spirv_version;
4407 struct spirv_shader *ret = NULL;
4408
4409 struct ntv_context ctx = {0};
4410 ctx.mem_ctx = ralloc_context(NULL);
4411 ctx.nir = s;
4412 ctx.builder.mem_ctx = ctx.mem_ctx;
4413 assert(spirv_version >= SPIRV_VERSION(1, 0));
4414 ctx.spirv_1_4_interfaces = spirv_version >= SPIRV_VERSION(1, 4);
4415
4416 ctx.bindless_set_idx = sinfo->bindless_set_idx;
4417 ctx.glsl_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4418 ctx.bo_array_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4419 ctx.bo_struct_types = _mesa_pointer_hash_table_create(ctx.mem_ctx);
4420 if (!ctx.glsl_types || !ctx.bo_array_types || !ctx.bo_struct_types ||
4421 !_mesa_hash_table_init(&ctx.image_types, ctx.mem_ctx, _mesa_hash_pointer, _mesa_key_pointer_equal))
4422 goto fail;
4423
4424 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader);
4425
4426 switch (s->info.stage) {
4427 case MESA_SHADER_FRAGMENT:
4428 if (s->info.fs.uses_sample_shading)
4429 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleRateShading);
4430 if (s->info.fs.uses_discard && spirv_version < SPIRV_VERSION(1, 6) &&
4431 screen->info.have_EXT_shader_demote_to_helper_invocation)
4432 spirv_builder_emit_extension(&ctx.builder,
4433 "SPV_EXT_demote_to_helper_invocation");
4434 break;
4435
4436 case MESA_SHADER_VERTEX:
4437 if (BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID) ||
4438 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_DRAW_ID) ||
4439 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_INSTANCE) ||
4440 BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_BASE_VERTEX)) {
4441 if (spirv_version < SPIRV_VERSION(1, 3))
4442 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_draw_parameters");
4443 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDrawParameters);
4444 }
4445 break;
4446
4447 case MESA_SHADER_TESS_CTRL:
4448 case MESA_SHADER_TESS_EVAL:
4449 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
4450 /* TODO: check features for this */
4451 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4452 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellationPointSize);
4453 break;
4454
4455 case MESA_SHADER_GEOMETRY:
4456 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4457 if (s->info.gs.active_stream_mask)
4458 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryStreams);
4459 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
4460 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometryPointSize);
4461 break;
4462
4463 default: ;
4464 }
4465
4466 if (s->info.stage < MESA_SHADER_GEOMETRY) {
4467 if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_LAYER) ||
4468 s->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_LAYER)) {
4469 if (spirv_version >= SPIRV_VERSION(1, 5))
4470 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderLayer);
4471 else {
4472 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_viewport_index_layer");
4473 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndexLayerEXT);
4474 }
4475 }
4476 } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
4477 /* incredibly, this is legal and intended.
4478 * https://github.com/KhronosGroup/SPIRV-Registry/issues/95
4479 */
4480 if (s->info.inputs_read & (BITFIELD64_BIT(VARYING_SLOT_LAYER) |
4481 BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID)))
4482 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
4483 }
4484
4485 if (s->info.num_ssbos && spirv_version < SPIRV_VERSION(1, 1))
4486 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_storage_buffer_storage_class");
4487
4488 if (s->info.stage < MESA_SHADER_FRAGMENT &&
4489 s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_VIEWPORT)) {
4490 if (s->info.stage < MESA_SHADER_GEOMETRY)
4491 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndex);
4492 else
4493 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityMultiViewport);
4494 }
4495
4496 if (s->info.stage > MESA_SHADER_VERTEX &&
4497 s->info.inputs_read & BITFIELD64_BIT(VARYING_SLOT_VIEWPORT)) {
4498 if (s->info.stage < MESA_SHADER_GEOMETRY)
4499 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShaderViewportIndex);
4500 else
4501 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityMultiViewport);
4502 }
4503
4504 ctx.stage = s->info.stage;
4505 ctx.sinfo = sinfo;
4506 ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
4507 ctx.explicit_lod = true;
4508 spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageUnknown, 0);
4509
4510 SpvAddressingModel model = SpvAddressingModelLogical;
4511 if (gl_shader_stage_is_compute(s->info.stage)) {
4512 if (s->info.cs.ptr_size == 32)
4513 model = SpvAddressingModelPhysical32;
4514 else if (s->info.cs.ptr_size == 64) {
4515 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityPhysicalStorageBufferAddresses);
4516 model = SpvAddressingModelPhysicalStorageBuffer64;
4517 } else
4518 model = SpvAddressingModelLogical;
4519 }
4520
4521 if (ctx.sinfo->have_vulkan_memory_model) {
4522 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModel);
4523 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModelDeviceScope);
4524 spirv_builder_emit_mem_model(&ctx.builder, model,
4525 SpvMemoryModelVulkan);
4526 } else {
4527 spirv_builder_emit_mem_model(&ctx.builder, model,
4528 SpvMemoryModelGLSL450);
4529 }
4530
4531 if (s->info.stage == MESA_SHADER_FRAGMENT &&
4532 s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
4533 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_shader_stencil_export");
4534 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityStencilExportEXT);
4535 }
4536
4537 SpvExecutionModel exec_model;
4538 switch (s->info.stage) {
4539 case MESA_SHADER_VERTEX:
4540 exec_model = SpvExecutionModelVertex;
4541 break;
4542 case MESA_SHADER_TESS_CTRL:
4543 exec_model = SpvExecutionModelTessellationControl;
4544 break;
4545 case MESA_SHADER_TESS_EVAL:
4546 exec_model = SpvExecutionModelTessellationEvaluation;
4547 break;
4548 case MESA_SHADER_GEOMETRY:
4549 exec_model = SpvExecutionModelGeometry;
4550 break;
4551 case MESA_SHADER_FRAGMENT:
4552 exec_model = SpvExecutionModelFragment;
4553 break;
4554 case MESA_SHADER_COMPUTE:
4555 case MESA_SHADER_KERNEL:
4556 exec_model = SpvExecutionModelGLCompute;
4557 break;
4558 default:
4559 unreachable("invalid stage");
4560 }
4561
4562 SpvId type_void = spirv_builder_type_void(&ctx.builder);
4563 SpvId type_void_func = spirv_builder_type_function(&ctx.builder, type_void,
4564 NULL, 0);
4565 SpvId entry_point = spirv_builder_new_id(&ctx.builder);
4566 spirv_builder_emit_name(&ctx.builder, entry_point, "main");
4567
4568 ctx.vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_pointer,
4569 _mesa_key_pointer_equal);
4570
4571 nir_foreach_variable_with_modes(var, s, nir_var_mem_push_const)
4572 input_var_init(&ctx, var);
4573
4574 nir_foreach_shader_in_variable(var, s)
4575 emit_input(&ctx, var);
4576
4577 int max_output = 0;
4578 nir_foreach_shader_out_variable(var, s) {
4579 /* ignore SPIR-V built-ins, tagged with a sentinel value */
4580 if (var->data.driver_location != UINT_MAX) {
4581 assert(var->data.driver_location < INT_MAX);
4582 unsigned extent = glsl_count_attribute_slots(var->type, false);
4583 max_output = MAX2(max_output, (int)var->data.driver_location + extent);
4584 }
4585 emit_output(&ctx, var);
4586 }
4587
4588 uint32_t tcs_vertices_out_word = 0;
4589
4590 unsigned ubo_counter[2] = {0};
4591 nir_foreach_variable_with_modes(var, s, nir_var_mem_ubo)
4592 ubo_counter[var->data.driver_location != 0]++;
4593 nir_foreach_variable_with_modes(var, s, nir_var_mem_ubo)
4594 emit_bo(&ctx, var, ubo_counter[var->data.driver_location != 0] > 1);
4595
4596 unsigned ssbo_counter = 0;
4597 nir_foreach_variable_with_modes(var, s, nir_var_mem_ssbo)
4598 ssbo_counter++;
4599 nir_foreach_variable_with_modes(var, s, nir_var_mem_ssbo)
4600 emit_bo(&ctx, var, ssbo_counter > 1);
4601
4602 nir_foreach_variable_with_modes(var, s, nir_var_image)
4603 ctx.image_var[var->data.driver_location] = var;
4604 nir_foreach_variable_with_modes(var, s, nir_var_uniform) {
4605 if (glsl_type_is_sampler(glsl_without_array(var->type))) {
4606 if (var->data.descriptor_set == ctx.bindless_set_idx)
4607 ctx.bindless_sampler_var[var->data.driver_location] = var;
4608 else
4609 ctx.sampler_var[var->data.driver_location] = var;
4610 ctx.last_sampler = MAX2(ctx.last_sampler, var->data.driver_location);
4611 }
4612 }
4613 nir_foreach_variable_with_modes(var, s, nir_var_image | nir_var_uniform) {
4614 const struct glsl_type *type = glsl_without_array(var->type);
4615 if (glsl_type_is_bare_sampler(type))
4616 emit_sampler(&ctx, var);
4617 else if (glsl_type_is_sampler(type))
4618 emit_image(&ctx, var, get_bare_image_type(&ctx, var, true));
4619 else if (glsl_type_is_image(type))
4620 emit_image(&ctx, var, get_bare_image_type(&ctx, var, false));
4621 }
4622
4623 if (sinfo->float_controls.flush_denorms) {
4624 unsigned execution_mode = s->info.float_controls_execution_mode;
4625 bool flush_16_bit = nir_is_denorm_flush_to_zero(execution_mode, 16);
4626 bool flush_32_bit = nir_is_denorm_flush_to_zero(execution_mode, 32);
4627 bool flush_64_bit = nir_is_denorm_flush_to_zero(execution_mode, 64);
4628 bool preserve_16_bit = nir_is_denorm_preserve(execution_mode, 16);
4629 bool preserve_32_bit = nir_is_denorm_preserve(execution_mode, 32);
4630 bool preserve_64_bit = nir_is_denorm_preserve(execution_mode, 64);
4631 bool emit_cap_flush = false;
4632 bool emit_cap_preserve = false;
4633
4634 if (!sinfo->float_controls.denorms_all_independence) {
4635 bool flush = flush_16_bit && flush_64_bit;
4636 bool preserve = preserve_16_bit && preserve_64_bit;
4637
4638 if (!sinfo->float_controls.denorms_32_bit_independence) {
4639 flush = flush && flush_32_bit;
4640 preserve = preserve && preserve_32_bit;
4641
4642 flush_32_bit = flush;
4643 preserve_32_bit = preserve;
4644 }
4645
4646 flush_16_bit = flush;
4647 flush_64_bit = flush;
4648 preserve_16_bit = preserve;
4649 preserve_64_bit = preserve;
4650 }
4651
4652 if (flush_16_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(0)) {
4653 emit_cap_flush = true;
4654 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4655 SpvExecutionModeDenormFlushToZero, 16);
4656 }
4657 if (flush_32_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(1)) {
4658 emit_cap_flush = true;
4659 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4660 SpvExecutionModeDenormFlushToZero, 32);
4661 }
4662 if (flush_64_bit && sinfo->float_controls.flush_denorms & BITFIELD_BIT(2)) {
4663 emit_cap_flush = true;
4664 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4665 SpvExecutionModeDenormFlushToZero, 64);
4666 }
4667
4668 if (preserve_16_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(0)) {
4669 emit_cap_preserve = true;
4670 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4671 SpvExecutionModeDenormPreserve, 16);
4672 }
4673 if (preserve_32_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(1)) {
4674 emit_cap_preserve = true;
4675 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4676 SpvExecutionModeDenormPreserve, 32);
4677 }
4678 if (preserve_64_bit && sinfo->float_controls.preserve_denorms & BITFIELD_BIT(2)) {
4679 emit_cap_preserve = true;
4680 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4681 SpvExecutionModeDenormPreserve, 64);
4682 }
4683
4684 if (emit_cap_flush)
4685 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormFlushToZero);
4686 if (emit_cap_preserve)
4687 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityDenormPreserve);
4688 }
4689
4690 switch (s->info.stage) {
4691 case MESA_SHADER_FRAGMENT:
4692 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4693 SpvExecutionModeOriginUpperLeft);
4694 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
4695 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4696 get_depth_layout_mode(s->info.fs.depth_layout));
4697 if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL))
4698 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4699 SpvExecutionModeStencilRefReplacingEXT);
4700 if (s->info.fs.early_fragment_tests)
4701 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4702 SpvExecutionModeEarlyFragmentTests);
4703 if (s->info.fs.post_depth_coverage) {
4704 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_post_depth_coverage");
4705 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampleMaskPostDepthCoverage);
4706 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4707 SpvExecutionModePostDepthCoverage);
4708 }
4709
4710 if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered ||
4711 s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4712 spirv_builder_emit_extension(&ctx.builder, "SPV_EXT_fragment_shader_interlock");
4713 if (s->info.fs.pixel_interlock_ordered || s->info.fs.pixel_interlock_unordered)
4714 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderPixelInterlockEXT);
4715 if (s->info.fs.sample_interlock_ordered || s->info.fs.sample_interlock_unordered)
4716 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityFragmentShaderSampleInterlockEXT);
4717 if (s->info.fs.pixel_interlock_ordered)
4718 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockOrderedEXT);
4719 if (s->info.fs.pixel_interlock_unordered)
4720 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePixelInterlockUnorderedEXT);
4721 if (s->info.fs.sample_interlock_ordered)
4722 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockOrderedEXT);
4723 if (s->info.fs.sample_interlock_unordered)
4724 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSampleInterlockUnorderedEXT);
4725 break;
4726 case MESA_SHADER_TESS_CTRL:
4727 tcs_vertices_out_word = spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4728 SpvExecutionModeOutputVertices,
4729 s->info.tess.tcs_vertices_out);
4730 break;
4731 case MESA_SHADER_TESS_EVAL:
4732 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4733 get_primitive_mode(s->info.tess._primitive_mode));
4734 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4735 s->info.tess.ccw ? SpvExecutionModeVertexOrderCcw
4736 : SpvExecutionModeVertexOrderCw);
4737 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4738 get_spacing(s->info.tess.spacing));
4739 if (s->info.tess.point_mode)
4740 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePointMode);
4741 break;
4742 case MESA_SHADER_GEOMETRY:
4743 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4744 get_input_prim_type_mode(s->info.gs.input_primitive));
4745 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4746 get_output_prim_type_mode(s->info.gs.output_primitive));
4747 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4748 SpvExecutionModeInvocations,
4749 s->info.gs.invocations);
4750 spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point,
4751 SpvExecutionModeOutputVertices,
4752 MAX2(s->info.gs.vertices_out, 1));
4753 break;
4754 case MESA_SHADER_KERNEL:
4755 case MESA_SHADER_COMPUTE:
4756 if (s->info.workgroup_size[0] || s->info.workgroup_size[1] || s->info.workgroup_size[2])
4757 spirv_builder_emit_exec_mode_literal3(&ctx.builder, entry_point, SpvExecutionModeLocalSize,
4758 (uint32_t[3]){(uint32_t)s->info.workgroup_size[0], (uint32_t)s->info.workgroup_size[1],
4759 (uint32_t)s->info.workgroup_size[2]});
4760 else {
4761 SpvId sizes[3];
4762 uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
4763 const char *names[] = {"x", "y", "z"};
4764 for (int i = 0; i < 3; i ++) {
4765 sizes[i] = spirv_builder_spec_const_uint(&ctx.builder, 32);
4766 spirv_builder_emit_specid(&ctx.builder, sizes[i], ids[i]);
4767 spirv_builder_emit_name(&ctx.builder, sizes[i], names[i]);
4768 }
4769 SpvId var_type = get_uvec_type(&ctx, 32, 3);
4770 // Even when using LocalSizeId this need to be initialized for nir_intrinsic_load_workgroup_size
4771 ctx.local_group_size_var = spirv_builder_spec_const_composite(&ctx.builder, var_type, sizes, 3);
4772 spirv_builder_emit_name(&ctx.builder, ctx.local_group_size_var, "gl_LocalGroupSizeARB");
4773
4774 /* WorkgroupSize is deprecated in SPIR-V 1.6 */
4775 if (spirv_version >= SPIRV_VERSION(1, 6)) {
4776 spirv_builder_emit_exec_mode_id3(&ctx.builder, entry_point,
4777 SpvExecutionModeLocalSizeId,
4778 sizes);
4779 } else {
4780 spirv_builder_emit_builtin(&ctx.builder, ctx.local_group_size_var, SpvBuiltInWorkgroupSize);
4781 }
4782 }
4783 if (s->info.cs.has_variable_shared_mem) {
4784 ctx.shared_mem_size = spirv_builder_spec_const_uint(&ctx.builder, 32);
4785 spirv_builder_emit_specid(&ctx.builder, ctx.shared_mem_size, ZINK_VARIABLE_SHARED_MEM);
4786 spirv_builder_emit_name(&ctx.builder, ctx.shared_mem_size, "variable_shared_mem");
4787 }
4788 if (s->info.derivative_group) {
4789 SpvCapability caps[] = { 0, SpvCapabilityComputeDerivativeGroupQuadsNV, SpvCapabilityComputeDerivativeGroupLinearNV };
4790 SpvExecutionMode modes[] = { 0, SpvExecutionModeDerivativeGroupQuadsNV, SpvExecutionModeDerivativeGroupLinearNV };
4791 spirv_builder_emit_extension(&ctx.builder, "SPV_NV_compute_shader_derivatives");
4792 spirv_builder_emit_cap(&ctx.builder, caps[s->info.derivative_group]);
4793 spirv_builder_emit_exec_mode(&ctx.builder, entry_point, modes[s->info.derivative_group]);
4794 ctx.explicit_lod = false;
4795 }
4796 break;
4797 default:
4798 break;
4799 }
4800 if (BITSET_TEST_RANGE(s->info.system_values_read, SYSTEM_VALUE_SUBGROUP_SIZE, SYSTEM_VALUE_SUBGROUP_LT_MASK)) {
4801 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySubgroupBallotKHR);
4802 spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_shader_ballot");
4803 }
4804 if (s->info.has_transform_feedback_varyings && s->info.stage != MESA_SHADER_FRAGMENT) {
4805 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTransformFeedback);
4806 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
4807 SpvExecutionModeXfb);
4808 }
4809
4810 if (s->info.stage == MESA_SHADER_FRAGMENT && s->info.fs.uses_discard) {
4811 ctx.discard_func = spirv_builder_new_id(&ctx.builder);
4812 spirv_builder_emit_name(&ctx.builder, ctx.discard_func, "discard");
4813 spirv_builder_function(&ctx.builder, ctx.discard_func, type_void,
4814 SpvFunctionControlMaskNone,
4815 type_void_func);
4816 SpvId label = spirv_builder_new_id(&ctx.builder);
4817 spirv_builder_label(&ctx.builder, label);
4818
4819 /* kill is deprecated in SPIR-V 1.6, use terminate instead */
4820 if (spirv_version >= SPIRV_VERSION(1, 6))
4821 spirv_builder_emit_terminate(&ctx.builder);
4822 else
4823 spirv_builder_emit_kill(&ctx.builder);
4824
4825 spirv_builder_function_end(&ctx.builder);
4826 }
4827
4828 spirv_builder_function(&ctx.builder, entry_point, type_void,
4829 SpvFunctionControlMaskNone,
4830 type_void_func);
4831
4832 nir_function_impl *entry = nir_shader_get_entrypoint(s);
4833 nir_metadata_require(entry, nir_metadata_block_index);
4834
4835 ctx.defs = rzalloc_array_size(ctx.mem_ctx,
4836 sizeof(SpvId), entry->ssa_alloc);
4837 ctx.def_types = ralloc_array_size(ctx.mem_ctx,
4838 sizeof(nir_alu_type), entry->ssa_alloc);
4839 if (!ctx.defs || !ctx.def_types)
4840 goto fail;
4841 if (sinfo->have_sparse) {
4842 spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySparseResidency);
4843 /* this could be huge, so only alloc if needed since it's extremely unlikely to
4844 * ever be used by anything except cts
4845 */
4846 ctx.resident_defs = rzalloc_array_size(ctx.mem_ctx,
4847 sizeof(SpvId), entry->ssa_alloc);
4848 if (!ctx.resident_defs)
4849 goto fail;
4850 }
4851 ctx.num_defs = entry->ssa_alloc;
4852
4853 SpvId *block_ids = ralloc_array_size(ctx.mem_ctx,
4854 sizeof(SpvId), entry->num_blocks);
4855 if (!block_ids)
4856 goto fail;
4857
4858 for (int i = 0; i < entry->num_blocks; ++i)
4859 block_ids[i] = spirv_builder_new_id(&ctx.builder);
4860
4861 ctx.block_ids = block_ids;
4862 ctx.num_blocks = entry->num_blocks;
4863
4864 /* emit a block only for the variable declarations */
4865 start_block(&ctx, spirv_builder_new_id(&ctx.builder));
4866 spirv_builder_begin_local_vars(&ctx.builder);
4867
4868 nir_foreach_reg_decl(reg, entry) {
4869 if (nir_intrinsic_bit_size(reg) == 1)
4870 init_reg(&ctx, reg, nir_type_bool);
4871 }
4872
4873 nir_foreach_variable_with_modes(var, s, nir_var_shader_temp)
4874 emit_shader_temp(&ctx, var);
4875
4876 nir_foreach_function_temp_variable(var, entry)
4877 emit_temp(&ctx, var);
4878
4879
4880 emit_cf_list(&ctx, &entry->body);
4881
4882 spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
4883 spirv_builder_function_end(&ctx.builder);
4884
4885 spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
4886 "main", ctx.entry_ifaces,
4887 ctx.num_entry_ifaces);
4888
4889 size_t num_words = spirv_builder_get_num_words(&ctx.builder);
4890
4891 ret = ralloc(NULL, struct spirv_shader);
4892 if (!ret)
4893 goto fail;
4894
4895 ret->words = ralloc_size(ret, sizeof(uint32_t) * num_words);
4896 if (!ret->words)
4897 goto fail;
4898
4899 ret->num_words = spirv_builder_get_words(&ctx.builder, ret->words, num_words, spirv_version, &tcs_vertices_out_word);
4900 ret->tcs_vertices_out_word = tcs_vertices_out_word;
4901 assert(ret->num_words == num_words);
4902
4903 ralloc_free(ctx.mem_ctx);
4904
4905 return ret;
4906
4907 fail:
4908 ralloc_free(ctx.mem_ctx);
4909
4910 if (ret)
4911 spirv_shader_delete(ret);
4912
4913 return NULL;
4914 }
4915
4916 void
spirv_shader_delete(struct spirv_shader * s)4917 spirv_shader_delete(struct spirv_shader *s)
4918 {
4919 ralloc_free(s);
4920 }
4921