zink: introduce opengl over vulkan
[mesa.git] / src / gallium / drivers / zink / nir_to_spirv / nir_to_spirv.c
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_memory.h"
30
31 struct ntv_context {
32 struct spirv_builder builder;
33
34 SpvId GLSL_std_450;
35
36 gl_shader_stage stage;
37 SpvId inputs[PIPE_MAX_SHADER_INPUTS][4];
38 SpvId outputs[PIPE_MAX_SHADER_OUTPUTS][4];
39
40 SpvId ubos[128];
41 size_t num_ubos;
42 SpvId samplers[PIPE_MAX_SAMPLERS];
43 size_t num_samplers;
44 SpvId entry_ifaces[PIPE_MAX_SHADER_INPUTS * 4 + PIPE_MAX_SHADER_OUTPUTS * 4];
45 size_t num_entry_ifaces;
46
47 SpvId *defs;
48 size_t num_defs;
49 };
50
51 static SpvId
52 get_bvec_type(struct ntv_context *ctx, int num_components)
53 {
54 SpvId bool_type = spirv_builder_type_bool(&ctx->builder);
55 if (num_components > 1)
56 return spirv_builder_type_vector(&ctx->builder, bool_type,
57 num_components);
58
59 assert(num_components == 1);
60 return bool_type;
61 }
62
63 static SpvId
64 get_fvec_type(struct ntv_context *ctx, unsigned bit_size, unsigned num_components)
65 {
66 assert(bit_size == 32); // only 32-bit floats supported so far
67
68 SpvId float_type = spirv_builder_type_float(&ctx->builder, bit_size);
69 if (num_components > 1)
70 return spirv_builder_type_vector(&ctx->builder, float_type,
71 num_components);
72
73 assert(num_components == 1);
74 return float_type;
75 }
76
77 static SpvId
78 get_dest_type(struct ntv_context *ctx, nir_dest *dest)
79 {
80 return get_fvec_type(ctx, nir_dest_bit_size(*dest),
81 nir_dest_num_components(*dest));
82 }
83
84 static SpvId
85 get_glsl_basetype(struct ntv_context *ctx, enum glsl_base_type type)
86 {
87 switch (type) {
88 case GLSL_TYPE_FLOAT:
89 return spirv_builder_type_float(&ctx->builder, 32);
90
91 case GLSL_TYPE_INT:
92 return spirv_builder_type_int(&ctx->builder, 32);
93
94 case GLSL_TYPE_UINT:
95 return spirv_builder_type_uint(&ctx->builder, 32);
96 /* TODO: handle more types */
97
98 default:
99 unreachable("unknown GLSL type");
100 }
101 }
102
103 static SpvId
104 get_glsl_type(struct ntv_context *ctx, const struct glsl_type *type)
105 {
106 assert(type);
107 if (glsl_type_is_scalar(type))
108 return get_glsl_basetype(ctx, glsl_get_base_type(type));
109
110 if (glsl_type_is_vector(type))
111 return spirv_builder_type_vector(&ctx->builder,
112 get_glsl_basetype(ctx, glsl_get_base_type(type)),
113 glsl_get_vector_elements(type));
114
115 unreachable("we shouldn't get here, I think...");
116 }
117
118 static void
119 emit_input(struct ntv_context *ctx, struct nir_variable *var)
120 {
121 SpvId vec_type = get_glsl_type(ctx, var->type);
122 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
123 SpvStorageClassInput,
124 vec_type);
125 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
126 SpvStorageClassInput);
127
128 if (var->name)
129 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
130
131 if (ctx->stage == MESA_SHADER_FRAGMENT) {
132 switch (var->data.location) {
133 case VARYING_SLOT_POS:
134 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragCoord);
135 break;
136
137 default:
138 spirv_builder_emit_location(&ctx->builder, var_id,
139 var->data.driver_location);
140 break;
141 }
142 } else {
143 spirv_builder_emit_location(&ctx->builder, var_id,
144 var->data.driver_location);
145 }
146
147 if (var->data.location_frac)
148 spirv_builder_emit_component(&ctx->builder, var_id,
149 var->data.location_frac);
150
151 if (var->data.interpolation == INTERP_MODE_FLAT)
152 spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationFlat);
153
154 assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS);
155 assert(var->data.location_frac < 4);
156 assert(ctx->inputs[var->data.driver_location][var->data.location_frac] == 0);
157 ctx->inputs[var->data.driver_location][var->data.location_frac] = var_id;
158
159 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
160 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
161 }
162
163 static void
164 emit_output(struct ntv_context *ctx, struct nir_variable *var)
165 {
166 SpvId vec_type = get_glsl_type(ctx, var->type);
167 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
168 SpvStorageClassOutput,
169 vec_type);
170 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
171 SpvStorageClassOutput);
172 if (var->name)
173 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
174
175
176 if (ctx->stage == MESA_SHADER_VERTEX) {
177 switch (var->data.location) {
178 case VARYING_SLOT_POS:
179 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInPosition);
180 break;
181
182 case VARYING_SLOT_PSIZ:
183 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInPointSize);
184 break;
185
186 default:
187 spirv_builder_emit_location(&ctx->builder, var_id,
188 var->data.driver_location - 1);
189 }
190 } else if (ctx->stage == MESA_SHADER_FRAGMENT) {
191 switch (var->data.location) {
192 case FRAG_RESULT_DEPTH:
193 spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInFragDepth);
194 break;
195
196 default:
197 spirv_builder_emit_location(&ctx->builder, var_id,
198 var->data.driver_location);
199 }
200 }
201
202 if (var->data.location_frac)
203 spirv_builder_emit_component(&ctx->builder, var_id,
204 var->data.location_frac);
205
206 assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS);
207 assert(var->data.location_frac < 4);
208 assert(ctx->outputs[var->data.driver_location][var->data.location_frac] == 0);
209 ctx->outputs[var->data.driver_location][var->data.location_frac] = var_id;
210
211 assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
212 ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
213 }
214
215 static SpvDim
216 type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
217 {
218 *is_ms = false;
219 switch (gdim) {
220 case GLSL_SAMPLER_DIM_1D:
221 return SpvDim1D;
222 case GLSL_SAMPLER_DIM_2D:
223 return SpvDim2D;
224 case GLSL_SAMPLER_DIM_RECT:
225 return SpvDimRect;
226 case GLSL_SAMPLER_DIM_CUBE:
227 return SpvDimCube;
228 case GLSL_SAMPLER_DIM_3D:
229 return SpvDim3D;
230 case GLSL_SAMPLER_DIM_MS:
231 *is_ms = true;
232 return SpvDim2D;
233 default:
234 fprintf(stderr, "unknown sampler type %d\n", gdim);
235 break;
236 }
237 return SpvDim2D;
238 }
239
240 static void
241 emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
242 {
243 bool is_ms;
244 SpvDim dimension = type_to_dim(glsl_get_sampler_dim(var->type), &is_ms);
245 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
246 SpvId image_type = spirv_builder_type_image(&ctx->builder, float_type,
247 dimension, false, glsl_sampler_type_is_array(var->type), is_ms, 1,
248 SpvImageFormatUnknown);
249
250 SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
251 image_type);
252 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
253 SpvStorageClassUniformConstant,
254 sampled_type);
255 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
256 SpvStorageClassUniformConstant);
257
258 if (var->name)
259 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
260
261 assert(ctx->num_samplers < ARRAY_SIZE(ctx->samplers));
262 ctx->samplers[ctx->num_samplers++] = var_id;
263
264 spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
265 var->data.descriptor_set);
266 spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
267 }
268
269 static void
270 emit_ubo(struct ntv_context *ctx, struct nir_variable *var)
271 {
272 uint32_t size = glsl_count_attribute_slots(var->type, false);
273 SpvId vec4_type = get_fvec_type(ctx, 32, 4);
274 SpvId array_length = spirv_builder_const_uint(&ctx->builder, 32, size);
275 SpvId array_type = spirv_builder_type_array(&ctx->builder, vec4_type,
276 array_length);
277 spirv_builder_emit_array_stride(&ctx->builder, array_type, 16);
278
279 // wrap UBO-array in a struct
280 SpvId struct_type = spirv_builder_type_struct(&ctx->builder, &array_type, 1);
281 if (var->name) {
282 char struct_name[100];
283 snprintf(struct_name, sizeof(struct_name), "struct_%s", var->name);
284 spirv_builder_emit_name(&ctx->builder, struct_type, struct_name);
285 }
286
287 spirv_builder_emit_decoration(&ctx->builder, struct_type,
288 SpvDecorationBlock);
289 spirv_builder_emit_member_offset(&ctx->builder, struct_type, 0, 0);
290
291
292 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
293 SpvStorageClassUniform,
294 struct_type);
295
296 SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
297 SpvStorageClassUniform);
298 if (var->name)
299 spirv_builder_emit_name(&ctx->builder, var_id, var->name);
300
301 assert(ctx->num_ubos < ARRAY_SIZE(ctx->ubos));
302 ctx->ubos[ctx->num_ubos++] = var_id;
303
304 spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
305 var->data.descriptor_set);
306 spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
307 }
308
309 static void
310 emit_uniform(struct ntv_context *ctx, struct nir_variable *var)
311 {
312 if (glsl_type_is_sampler(var->type))
313 emit_sampler(ctx, var);
314 else if (var->interface_type)
315 emit_ubo(ctx, var);
316 }
317
318 static SpvId
319 get_src(struct ntv_context *ctx, nir_src *src)
320 {
321 assert(src->is_ssa);
322 assert(src->ssa->index < ctx->num_defs);
323 assert(ctx->defs[src->ssa->index] != 0);
324 return ctx->defs[src->ssa->index];
325 }
326
327 static SpvId
328 get_alu_src(struct ntv_context *ctx, nir_alu_instr *alu, unsigned src)
329 {
330 assert(!alu->src[src].negate);
331 assert(!alu->src[src].abs);
332
333 SpvId def = get_src(ctx, &alu->src[src].src);
334
335 unsigned used_channels = 0;
336 bool need_swizzle = false;
337 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
338 if (!nir_alu_instr_channel_used(alu, src, i))
339 continue;
340
341 used_channels++;
342
343 if (alu->src[src].swizzle[i] != i)
344 need_swizzle = true;
345 }
346 assert(used_channels != 0);
347
348 unsigned live_channels = nir_src_num_components(alu->src[src].src);
349 if (used_channels != live_channels)
350 need_swizzle = true;
351
352 if (!need_swizzle)
353 return def;
354
355 int bit_size = nir_src_bit_size(alu->src[src].src);
356
357 if (used_channels == 1) {
358 SpvId result_type = spirv_builder_type_float(&ctx->builder, bit_size);
359 uint32_t indices[] = { alu->src[src].swizzle[0] };
360 return spirv_builder_emit_composite_extract(&ctx->builder, result_type,
361 def, indices,
362 ARRAY_SIZE(indices));
363 } else if (live_channels == 1) {
364 SpvId type = get_fvec_type(ctx, bit_size, used_channels);
365
366 SpvId constituents[NIR_MAX_VEC_COMPONENTS];
367 for (unsigned i = 0; i < used_channels; ++i)
368 constituents[i] = def;
369
370 return spirv_builder_emit_composite_construct(&ctx->builder, type,
371 constituents,
372 used_channels);
373 } else {
374 uint32_t components[NIR_MAX_VEC_COMPONENTS];
375 size_t num_components = 0;
376 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
377 if (!nir_alu_instr_channel_used(alu, src, i))
378 continue;
379
380 components[num_components++] = alu->src[src].swizzle[i];
381 }
382
383 SpvId vecType = get_fvec_type(ctx, bit_size, used_channels);
384 return spirv_builder_emit_vector_shuffle(&ctx->builder, vecType,
385 def, def, components, num_components);
386 }
387 }
388
389 static void
390 store_ssa_def(struct ntv_context *ctx, nir_ssa_def *ssa, SpvId result)
391 {
392 assert(result != 0);
393 assert(ssa->index < ctx->num_defs);
394 ctx->defs[ssa->index] = result;
395 }
396
397 static void
398 store_dest(struct ntv_context *ctx, nir_dest *dest, SpvId result)
399 {
400 assert(dest->is_ssa);
401 store_ssa_def(ctx, &dest->ssa, result);
402 }
403
404 static void
405 store_alu_result(struct ntv_context *ctx, nir_alu_dest *dest, SpvId result)
406 {
407 assert(!dest->saturate);
408 return store_dest(ctx, &dest->dest, result);
409 }
410
411 static SpvId
412 emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src)
413 {
414 return spirv_builder_emit_unop(&ctx->builder, op, type, src);
415 }
416
417 static SpvId
418 emit_binop(struct ntv_context *ctx, SpvOp op, SpvId type,
419 SpvId src0, SpvId src1)
420 {
421 return spirv_builder_emit_binop(&ctx->builder, op, type, src0, src1);
422 }
423
424 static SpvId
425 emit_triop(struct ntv_context *ctx, SpvOp op, SpvId type,
426 SpvId src0, SpvId src1, SpvId src2)
427 {
428 return spirv_builder_emit_triop(&ctx->builder, op, type, src0, src1, src2);
429 }
430
431 static SpvId
432 emit_builtin_unop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
433 SpvId src)
434 {
435 SpvId args[] = { src };
436 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
437 op, args, ARRAY_SIZE(args));
438 }
439
440 static SpvId
441 emit_builtin_binop(struct ntv_context *ctx, enum GLSLstd450 op, SpvId type,
442 SpvId src0, SpvId src1)
443 {
444 SpvId args[] = { src0, src1 };
445 return spirv_builder_emit_ext_inst(&ctx->builder, type, ctx->GLSL_std_450,
446 op, args, ARRAY_SIZE(args));
447 }
448
449 static SpvId
450 get_fvec_constant(struct ntv_context *ctx, int bit_size, int num_components,
451 float values[])
452 {
453 assert(bit_size == 32);
454
455 if (num_components > 1) {
456 SpvId components[num_components];
457 for (int i = 0; i < num_components; i++)
458 components[i] = spirv_builder_const_float(&ctx->builder, bit_size,
459 values[i]);
460
461 SpvId type = get_fvec_type(ctx, bit_size, num_components);
462 return spirv_builder_const_composite(&ctx->builder, type, components,
463 num_components);
464 }
465
466 assert(num_components == 1);
467 return spirv_builder_const_float(&ctx->builder, bit_size, values[0]);
468 }
469
470 static void
471 emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
472 {
473 SpvId src[nir_op_infos[alu->op].num_inputs];
474 for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
475 src[i] = get_alu_src(ctx, alu, i);
476
477 SpvId dest_type = get_dest_type(ctx, &alu->dest.dest);
478
479 SpvId result = 0;
480 switch (alu->op) {
481 case nir_op_mov:
482 assert(nir_op_infos[alu->op].num_inputs == 1);
483 result = src[0];
484 break;
485
486 #define UNOP(nir_op, spirv_op) \
487 case nir_op: \
488 assert(nir_op_infos[alu->op].num_inputs == 1); \
489 result = emit_unop(ctx, spirv_op, dest_type, src[0]); \
490 break;
491
492 #define BUILTIN_UNOP(nir_op, spirv_op) \
493 case nir_op: \
494 assert(nir_op_infos[alu->op].num_inputs == 1); \
495 result = emit_builtin_unop(ctx, spirv_op, dest_type, src[0]); \
496 break;
497
498 UNOP(nir_op_fneg, SpvOpFNegate)
499 UNOP(nir_op_fddx, SpvOpDPdx)
500 UNOP(nir_op_fddy, SpvOpDPdy)
501
502 BUILTIN_UNOP(nir_op_fabs, GLSLstd450FAbs)
503 BUILTIN_UNOP(nir_op_fsqrt, GLSLstd450Sqrt)
504 BUILTIN_UNOP(nir_op_frsq, GLSLstd450InverseSqrt)
505 BUILTIN_UNOP(nir_op_flog2, GLSLstd450Log2)
506 BUILTIN_UNOP(nir_op_fexp2, GLSLstd450Exp2)
507 BUILTIN_UNOP(nir_op_ffract, GLSLstd450Fract)
508 BUILTIN_UNOP(nir_op_ffloor, GLSLstd450Floor)
509 BUILTIN_UNOP(nir_op_fceil, GLSLstd450Ceil)
510 BUILTIN_UNOP(nir_op_ftrunc, GLSLstd450Trunc)
511 BUILTIN_UNOP(nir_op_fround_even, GLSLstd450RoundEven)
512 BUILTIN_UNOP(nir_op_fsign, GLSLstd450FSign)
513 BUILTIN_UNOP(nir_op_fsin, GLSLstd450Sin)
514 BUILTIN_UNOP(nir_op_fcos, GLSLstd450Cos)
515
516 case nir_op_frcp: {
517 assert(nir_op_infos[alu->op].num_inputs == 1);
518 float one[4] = { 1, 1, 1, 1 };
519 src[1] = src[0];
520 src[0] = get_fvec_constant(ctx, nir_dest_bit_size(alu->dest.dest),
521 nir_dest_num_components(alu->dest.dest),
522 one);
523 result = emit_binop(ctx, SpvOpFDiv, dest_type, src[0], src[1]);
524 }
525 break;
526
527 #undef UNOP
528 #undef BUILTIN_UNOP
529
530 #define BINOP(nir_op, spirv_op) \
531 case nir_op: \
532 assert(nir_op_infos[alu->op].num_inputs == 2); \
533 result = emit_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
534 break;
535
536 #define BUILTIN_BINOP(nir_op, spirv_op) \
537 case nir_op: \
538 assert(nir_op_infos[alu->op].num_inputs == 2); \
539 result = emit_builtin_binop(ctx, spirv_op, dest_type, src[0], src[1]); \
540 break;
541
542 BINOP(nir_op_fadd, SpvOpFAdd)
543 BINOP(nir_op_fsub, SpvOpFSub)
544 BINOP(nir_op_fmul, SpvOpFMul)
545 BINOP(nir_op_flt, SpvOpFUnordLessThan)
546 BINOP(nir_op_fge, SpvOpFUnordGreaterThanEqual)
547
548 BUILTIN_BINOP(nir_op_fmin, GLSLstd450FMin)
549 BUILTIN_BINOP(nir_op_fmax, GLSLstd450FMax)
550
551 #undef BINOP
552 #undef BUILTIN_BINOP
553
554 case nir_op_fdot2:
555 case nir_op_fdot3:
556 case nir_op_fdot4:
557 assert(nir_op_infos[alu->op].num_inputs == 2);
558 result = emit_binop(ctx, SpvOpDot, dest_type, src[0], src[1]);
559 break;
560
561 case nir_op_seq:
562 case nir_op_sne:
563 case nir_op_slt:
564 case nir_op_sge: {
565 assert(nir_op_infos[alu->op].num_inputs == 2);
566 int num_components = nir_dest_num_components(alu->dest.dest);
567 SpvId bool_type = get_bvec_type(ctx, num_components);
568
569 SpvId zero = spirv_builder_const_float(&ctx->builder, 32, 0.0f);
570 SpvId one = spirv_builder_const_float(&ctx->builder, 32, 1.0f);
571 if (num_components > 1) {
572 SpvId zero_comps[num_components], one_comps[num_components];
573 for (int i = 0; i < num_components; i++) {
574 zero_comps[i] = zero;
575 one_comps[i] = one;
576 }
577
578 zero = spirv_builder_const_composite(&ctx->builder, dest_type,
579 zero_comps, num_components);
580 one = spirv_builder_const_composite(&ctx->builder, dest_type,
581 one_comps, num_components);
582 }
583
584 SpvOp op;
585 switch (alu->op) {
586 case nir_op_seq: op = SpvOpFOrdEqual; break;
587 case nir_op_sne: op = SpvOpFOrdNotEqual; break;
588 case nir_op_slt: op = SpvOpFOrdLessThan; break;
589 case nir_op_sge: op = SpvOpFOrdGreaterThanEqual; break;
590 default: unreachable("unexpected op");
591 }
592
593 result = emit_binop(ctx, op, bool_type, src[0], src[1]);
594 result = emit_triop(ctx, SpvOpSelect, dest_type, result, one, zero);
595 }
596 break;
597
598 case nir_op_fcsel: {
599 assert(nir_op_infos[alu->op].num_inputs == 3);
600 int num_components = nir_dest_num_components(alu->dest.dest);
601 SpvId bool_type = get_bvec_type(ctx, num_components);
602
603 float zero[4] = { 0, 0, 0, 0 };
604 SpvId cmp = get_fvec_constant(ctx, nir_src_bit_size(alu->src[0].src),
605 num_components, zero);
606
607 result = emit_binop(ctx, SpvOpFOrdGreaterThan, bool_type, src[0], cmp);
608 result = emit_triop(ctx, SpvOpSelect, dest_type, result, src[1], src[2]);
609 }
610 break;
611
612 case nir_op_vec2:
613 case nir_op_vec3:
614 case nir_op_vec4: {
615 int num_inputs = nir_op_infos[alu->op].num_inputs;
616 assert(2 <= num_inputs && num_inputs <= 4);
617 result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type,
618 src, num_inputs);
619 }
620 break;
621
622 default:
623 fprintf(stderr, "emit_alu: not implemented (%s)\n",
624 nir_op_infos[alu->op].name);
625
626 unreachable("unsupported opcode");
627 return;
628 }
629
630 store_alu_result(ctx, &alu->dest, result);
631 }
632
633 static void
634 emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const)
635 {
636 float values[NIR_MAX_VEC_COMPONENTS];
637 for (int i = 0; i < load_const->def.num_components; ++i)
638 values[i] = load_const->value[i].f32;
639
640 SpvId constant = get_fvec_constant(ctx, load_const->def.bit_size,
641 load_const->def.num_components,
642 values);
643 store_ssa_def(ctx, &load_const->def, constant);
644 }
645
646 static void
647 emit_load_input(struct ntv_context *ctx, nir_intrinsic_instr *intr)
648 {
649 nir_const_value *const_offset = nir_src_as_const_value(intr->src[0]);
650 if (const_offset) {
651 SpvId type = get_dest_type(ctx, &intr->dest);
652
653 int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32;
654 assert(driver_location < PIPE_MAX_SHADER_INPUTS);
655 int location_frac = nir_intrinsic_component(intr);
656 assert(location_frac < 4);
657
658 SpvId ptr = ctx->inputs[driver_location][location_frac];
659 assert(ptr > 0);
660
661 store_dest(ctx, &intr->dest, spirv_builder_emit_load(&ctx->builder, type, ptr));
662 } else
663 unreachable("input-addressing not yet supported");
664 }
665
666 static void
667 emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
668 {
669 nir_const_value *const_block_index = nir_src_as_const_value(intr->src[0]);
670 assert(const_block_index); // no dynamic indexing for now
671 assert(const_block_index->u32 == 0); // we only support the default UBO for now
672
673 nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]);
674 if (const_offset) {
675 SpvId vec4_type = get_fvec_type(ctx, 32, 4);
676 SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
677 SpvStorageClassUniform,
678 vec4_type);
679
680 unsigned idx = const_offset->u32;
681 SpvId member = spirv_builder_const_uint(&ctx->builder, 32, 0);
682 SpvId offset = spirv_builder_const_uint(&ctx->builder, 32, idx);
683 SpvId offsets[] = { member, offset };
684 SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
685 ctx->ubos[0], offsets,
686 ARRAY_SIZE(offsets));
687 SpvId result = spirv_builder_emit_load(&ctx->builder, vec4_type, ptr);
688
689 SpvId type = get_dest_type(ctx, &intr->dest);
690 unsigned num_components = nir_dest_num_components(intr->dest);
691 if (num_components == 1) {
692 uint32_t components[] = { 0 };
693 result = spirv_builder_emit_composite_extract(&ctx->builder,
694 type,
695 result, components,
696 1);
697 } else if (num_components < 4) {
698 SpvId constituents[num_components];
699 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
700 for (uint32_t i = 0; i < num_components; ++i)
701 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
702 float_type,
703 result, &i,
704 1);
705
706 result = spirv_builder_emit_composite_construct(&ctx->builder,
707 type,
708 constituents,
709 num_components);
710 }
711
712 store_dest(ctx, &intr->dest, result);
713 } else
714 unreachable("uniform-addressing not yet supported");
715 }
716
717 static void
718 emit_store_output(struct ntv_context *ctx, nir_intrinsic_instr *intr)
719 {
720 nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]);
721 if (const_offset) {
722 int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32;
723 assert(driver_location < PIPE_MAX_SHADER_OUTPUTS);
724 int location_frac = nir_intrinsic_component(intr);
725 assert(location_frac < 4);
726
727 SpvId ptr = ctx->outputs[driver_location][location_frac];
728 assert(ptr > 0);
729
730 SpvId src = get_src(ctx, &intr->src[0]);
731 spirv_builder_emit_store(&ctx->builder, ptr, src);
732 } else
733 unreachable("output-addressing not yet supported");
734 }
735
736 static void
737 emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
738 {
739 switch (intr->intrinsic) {
740 case nir_intrinsic_load_input:
741 emit_load_input(ctx, intr);
742 break;
743
744 case nir_intrinsic_load_ubo:
745 emit_load_ubo(ctx, intr);
746 break;
747
748 case nir_intrinsic_store_output:
749 emit_store_output(ctx, intr);
750 break;
751
752 default:
753 fprintf(stderr, "emit_intrinsic: not implemented (%s)\n",
754 nir_intrinsic_infos[intr->intrinsic].name);
755 unreachable("unsupported intrinsic");
756 }
757 }
758
759 static void
760 emit_undef(struct ntv_context *ctx, nir_ssa_undef_instr *undef)
761 {
762 SpvId type = get_fvec_type(ctx, undef->def.bit_size,
763 undef->def.num_components);
764
765 store_ssa_def(ctx, &undef->def,
766 spirv_builder_emit_undef(&ctx->builder, type));
767 }
768
769 static void
770 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
771 {
772 assert(tex->op == nir_texop_tex);
773 assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
774 assert(tex->texture_index == tex->sampler_index);
775
776 bool has_proj = false;
777 SpvId coord = 0, proj;
778 unsigned coord_size;
779 for (unsigned i = 0; i < tex->num_srcs; i++) {
780 switch (tex->src[i].src_type) {
781 case nir_tex_src_coord:
782 coord = get_src(ctx, &tex->src[i].src);
783 coord_size = nir_src_num_components(tex->src[i].src);
784 break;
785
786 case nir_tex_src_projector:
787 has_proj = true;
788 proj = get_src(ctx, &tex->src[i].src);
789 break;
790
791 default:
792 fprintf(stderr, "texture source: %d\n", tex->src[i].src_type);
793 unreachable("unknown texture source");
794 }
795 }
796
797 bool is_ms;
798 SpvDim dimension = type_to_dim(tex->sampler_dim, &is_ms);
799 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
800 SpvId image_type = spirv_builder_type_image(&ctx->builder, float_type,
801 dimension, false, tex->is_array, is_ms, 1,
802 SpvImageFormatUnknown);
803 SpvId sampled_type = spirv_builder_type_sampled_image(&ctx->builder,
804 image_type);
805
806 assert(tex->texture_index < ctx->num_samplers);
807 SpvId load = spirv_builder_emit_load(&ctx->builder, sampled_type,
808 ctx->samplers[tex->texture_index]);
809
810 SpvId dest_type = get_dest_type(ctx, &tex->dest);
811
812 SpvId result;
813 if (has_proj) {
814 SpvId constituents[coord_size + 1];
815 SpvId float_type = spirv_builder_type_float(&ctx->builder, 32);
816 for (uint32_t i = 0; i < coord_size; ++i)
817 constituents[i] = spirv_builder_emit_composite_extract(&ctx->builder,
818 float_type,
819 coord,
820 &i, 1);
821
822 constituents[coord_size++] = proj;
823
824 SpvId vec_type = get_fvec_type(ctx, 32, coord_size);
825 SpvId merged = spirv_builder_emit_composite_construct(&ctx->builder,
826 vec_type,
827 constituents,
828 coord_size);
829
830 result = spirv_builder_emit_image_sample_proj_implicit_lod(&ctx->builder,
831 dest_type,
832 load,
833 merged);
834 } else
835 result = spirv_builder_emit_image_sample_implicit_lod(&ctx->builder,
836 dest_type, load,
837 coord);
838 spirv_builder_emit_decoration(&ctx->builder, result,
839 SpvDecorationRelaxedPrecision);
840
841 store_dest(ctx, &tex->dest, result);
842 }
843
844 static void
845 emit_block(struct ntv_context *ctx, struct nir_block *block)
846 {
847 nir_foreach_instr(instr, block) {
848 switch (instr->type) {
849 case nir_instr_type_alu:
850 emit_alu(ctx, nir_instr_as_alu(instr));
851 break;
852 case nir_instr_type_intrinsic:
853 emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
854 break;
855 case nir_instr_type_load_const:
856 emit_load_const(ctx, nir_instr_as_load_const(instr));
857 break;
858 case nir_instr_type_ssa_undef:
859 emit_undef(ctx, nir_instr_as_ssa_undef(instr));
860 break;
861 case nir_instr_type_tex:
862 emit_tex(ctx, nir_instr_as_tex(instr));
863 break;
864 case nir_instr_type_phi:
865 unreachable("nir_instr_type_phi not supported");
866 break;
867 case nir_instr_type_jump:
868 unreachable("nir_instr_type_jump not supported");
869 break;
870 case nir_instr_type_call:
871 unreachable("nir_instr_type_call not supported");
872 break;
873 case nir_instr_type_parallel_copy:
874 unreachable("nir_instr_type_parallel_copy not supported");
875 break;
876 case nir_instr_type_deref:
877 unreachable("nir_instr_type_deref not supported");
878 break;
879 }
880 }
881 }
882
883 static void
884 emit_cf_list(struct ntv_context *ctx, struct exec_list *list)
885 {
886 foreach_list_typed(nir_cf_node, node, node, list) {
887 switch (node->type) {
888 case nir_cf_node_block:
889 emit_block(ctx, nir_cf_node_as_block(node));
890 break;
891
892 case nir_cf_node_if:
893 unreachable("nir_cf_node_if not supported");
894 break;
895
896 case nir_cf_node_loop:
897 unreachable("nir_cf_node_loop not supported");
898 break;
899
900 case nir_cf_node_function:
901 unreachable("nir_cf_node_function not supported");
902 break;
903 }
904 }
905 }
906
907 struct spirv_shader *
908 nir_to_spirv(struct nir_shader *s)
909 {
910 struct spirv_shader *ret = NULL;
911
912 struct ntv_context ctx = {};
913
914 switch (s->info.stage) {
915 case MESA_SHADER_VERTEX:
916 case MESA_SHADER_FRAGMENT:
917 case MESA_SHADER_COMPUTE:
918 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader);
919 break;
920
921 case MESA_SHADER_TESS_CTRL:
922 case MESA_SHADER_TESS_EVAL:
923 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
924 break;
925
926 case MESA_SHADER_GEOMETRY:
927 spirv_builder_emit_cap(&ctx.builder, SpvCapabilityGeometry);
928 break;
929
930 default:
931 unreachable("invalid stage");
932 }
933
934 ctx.stage = s->info.stage;
935 ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
936 spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageGLSL, 450);
937
938 spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
939 SpvMemoryModelGLSL450);
940
941 SpvExecutionModel exec_model;
942 switch (s->info.stage) {
943 case MESA_SHADER_VERTEX:
944 exec_model = SpvExecutionModelVertex;
945 break;
946 case MESA_SHADER_TESS_CTRL:
947 exec_model = SpvExecutionModelTessellationControl;
948 break;
949 case MESA_SHADER_TESS_EVAL:
950 exec_model = SpvExecutionModelTessellationEvaluation;
951 break;
952 case MESA_SHADER_GEOMETRY:
953 exec_model = SpvExecutionModelGeometry;
954 break;
955 case MESA_SHADER_FRAGMENT:
956 exec_model = SpvExecutionModelFragment;
957 break;
958 case MESA_SHADER_COMPUTE:
959 exec_model = SpvExecutionModelGLCompute;
960 break;
961 default:
962 unreachable("invalid stage");
963 }
964
965 SpvId type_void = spirv_builder_type_void(&ctx.builder);
966 SpvId type_main = spirv_builder_type_function(&ctx.builder, type_void,
967 NULL, 0);
968 SpvId entry_point = spirv_builder_new_id(&ctx.builder);
969 SpvId label = spirv_builder_new_id(&ctx.builder);
970 spirv_builder_emit_name(&ctx.builder, entry_point, "main");
971
972 nir_foreach_variable(var, &s->inputs)
973 emit_input(&ctx, var);
974
975 nir_foreach_variable(var, &s->outputs)
976 emit_output(&ctx, var);
977
978 nir_foreach_variable(var, &s->uniforms)
979 emit_uniform(&ctx, var);
980
981 spirv_builder_emit_entry_point(&ctx.builder, exec_model, entry_point,
982 "main", ctx.entry_ifaces,
983 ctx.num_entry_ifaces);
984 if (s->info.stage == MESA_SHADER_FRAGMENT)
985 spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
986 SpvExecutionModeOriginUpperLeft);
987
988
989 spirv_builder_function(&ctx.builder, entry_point, type_void,
990 SpvFunctionControlMaskNone,
991 type_main);
992 spirv_builder_label(&ctx.builder, label);
993
994 nir_function_impl *entry = nir_shader_get_entrypoint(s);
995
996 ctx.defs = (SpvId *)malloc(sizeof(SpvId) * entry->ssa_alloc);
997 if (!ctx.defs)
998 goto fail;
999 ctx.num_defs = entry->ssa_alloc;
1000
1001 emit_cf_list(&ctx, &entry->body);
1002 free(ctx.defs);
1003
1004 spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
1005 spirv_builder_function_end(&ctx.builder);
1006
1007 size_t num_words = spirv_builder_get_num_words(&ctx.builder);
1008
1009 ret = CALLOC_STRUCT(spirv_shader);
1010 if (!ret)
1011 goto fail;
1012
1013 ret->words = MALLOC(sizeof(uint32_t) * num_words);
1014 if (!ret->words)
1015 goto fail;
1016
1017 ret->num_words = spirv_builder_get_words(&ctx.builder, ret->words, num_words);
1018 assert(ret->num_words == num_words);
1019
1020 return ret;
1021
1022 fail:
1023
1024 if (ret)
1025 spirv_shader_delete(ret);
1026
1027 return NULL;
1028 }
1029
1030 void
1031 spirv_shader_delete(struct spirv_shader *s)
1032 {
1033 FREE(s->words);
1034 FREE(s);
1035 }