Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/microsoft/compiler/nir_to_dxil.c
4564 views
1
/*
2
* Copyright © Microsoft Corporation
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
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* 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 NONINFRINGEMENT.  IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "nir_to_dxil.h"
25
26
#include "dxil_module.h"
27
#include "dxil_container.h"
28
#include "dxil_function.h"
29
#include "dxil_signature.h"
30
#include "dxil_enums.h"
31
#include "dxil_dump.h"
32
#include "dxil_nir.h"
33
34
#include "util/u_debug.h"
35
#include "util/u_math.h"
36
#include "util/u_dynarray.h"
37
#include "nir/nir_builder.h"
38
39
#include "git_sha1.h"
40
41
#include "vulkan/vulkan_core.h"
42
43
#include <stdint.h>
44
45
int debug_dxil = 0;
46
47
static const struct debug_named_value
48
dxil_debug_options[] = {
49
{ "verbose", DXIL_DEBUG_VERBOSE, NULL },
50
{ "dump_blob", DXIL_DEBUG_DUMP_BLOB , "Write shader blobs" },
51
{ "trace", DXIL_DEBUG_TRACE , "Trace instruction conversion" },
52
{ "dump_module", DXIL_DEBUG_DUMP_MODULE, "dump module tree to stderr"},
53
DEBUG_NAMED_VALUE_END
54
};
55
56
DEBUG_GET_ONCE_FLAGS_OPTION(debug_dxil, "DXIL_DEBUG", dxil_debug_options, 0)
57
58
#define NIR_INSTR_UNSUPPORTED(instr) \
59
if (debug_dxil & DXIL_DEBUG_VERBOSE) \
60
do { \
61
fprintf(stderr, "Unsupported instruction:"); \
62
nir_print_instr(instr, stderr); \
63
fprintf(stderr, "\n"); \
64
} while (0)
65
66
#define TRACE_CONVERSION(instr) \
67
if (debug_dxil & DXIL_DEBUG_TRACE) \
68
do { \
69
fprintf(stderr, "Convert '"); \
70
nir_print_instr(instr, stderr); \
71
fprintf(stderr, "'\n"); \
72
} while (0)
73
74
static const nir_shader_compiler_options
75
nir_options = {
76
.lower_ineg = true,
77
.lower_fneg = true,
78
.lower_ffma16 = true,
79
.lower_ffma32 = true,
80
.lower_isign = true,
81
.lower_fsign = true,
82
.lower_iabs = true,
83
.lower_fmod = true,
84
.lower_fpow = true,
85
.lower_scmp = true,
86
.lower_ldexp = true,
87
.lower_flrp16 = true,
88
.lower_flrp32 = true,
89
.lower_flrp64 = true,
90
.lower_bitfield_extract_to_shifts = true,
91
.lower_extract_word = true,
92
.lower_extract_byte = true,
93
.lower_insert_word = true,
94
.lower_insert_byte = true,
95
.lower_all_io_to_elements = true,
96
.lower_all_io_to_temps = true,
97
.lower_hadd = true,
98
.lower_add_sat = true,
99
.lower_uadd_carry = true,
100
.lower_mul_high = true,
101
.lower_rotate = true,
102
.lower_pack_64_2x32_split = true,
103
.lower_pack_32_2x16_split = true,
104
.lower_unpack_64_2x32_split = true,
105
.lower_unpack_32_2x16_split = true,
106
.has_fsub = true,
107
.has_isub = true,
108
.use_scoped_barrier = true,
109
.vertex_id_zero_based = true,
110
.lower_base_vertex = true,
111
.has_cs_global_id = true,
112
.has_txs = true,
113
};
114
115
const nir_shader_compiler_options*
116
dxil_get_nir_compiler_options(void)
117
{
118
return &nir_options;
119
}
120
121
static bool
122
emit_llvm_ident(struct dxil_module *m)
123
{
124
const struct dxil_mdnode *compiler = dxil_get_metadata_string(m, "Mesa version " PACKAGE_VERSION MESA_GIT_SHA1);
125
if (!compiler)
126
return false;
127
128
const struct dxil_mdnode *llvm_ident = dxil_get_metadata_node(m, &compiler, 1);
129
return llvm_ident &&
130
dxil_add_metadata_named_node(m, "llvm.ident", &llvm_ident, 1);
131
}
132
133
static bool
134
emit_named_version(struct dxil_module *m, const char *name,
135
int major, int minor)
136
{
137
const struct dxil_mdnode *major_node = dxil_get_metadata_int32(m, major);
138
const struct dxil_mdnode *minor_node = dxil_get_metadata_int32(m, minor);
139
const struct dxil_mdnode *version_nodes[] = { major_node, minor_node };
140
const struct dxil_mdnode *version = dxil_get_metadata_node(m, version_nodes,
141
ARRAY_SIZE(version_nodes));
142
return dxil_add_metadata_named_node(m, name, &version, 1);
143
}
144
145
static const char *
146
get_shader_kind_str(enum dxil_shader_kind kind)
147
{
148
switch (kind) {
149
case DXIL_PIXEL_SHADER:
150
return "ps";
151
case DXIL_VERTEX_SHADER:
152
return "vs";
153
case DXIL_GEOMETRY_SHADER:
154
return "gs";
155
case DXIL_HULL_SHADER:
156
return "hs";
157
case DXIL_DOMAIN_SHADER:
158
return "ds";
159
case DXIL_COMPUTE_SHADER:
160
return "cs";
161
default:
162
unreachable("invalid shader kind");
163
}
164
}
165
166
static bool
167
emit_dx_shader_model(struct dxil_module *m)
168
{
169
const struct dxil_mdnode *type_node = dxil_get_metadata_string(m, get_shader_kind_str(m->shader_kind));
170
const struct dxil_mdnode *major_node = dxil_get_metadata_int32(m, m->major_version);
171
const struct dxil_mdnode *minor_node = dxil_get_metadata_int32(m, m->minor_version);
172
const struct dxil_mdnode *shader_model[] = { type_node, major_node,
173
minor_node };
174
const struct dxil_mdnode *dx_shader_model = dxil_get_metadata_node(m, shader_model, ARRAY_SIZE(shader_model));
175
176
return dxil_add_metadata_named_node(m, "dx.shaderModel",
177
&dx_shader_model, 1);
178
}
179
180
enum {
181
DXIL_TYPED_BUFFER_ELEMENT_TYPE_TAG = 0,
182
DXIL_STRUCTURED_BUFFER_ELEMENT_STRIDE_TAG = 1
183
};
184
185
enum dxil_intr {
186
DXIL_INTR_LOAD_INPUT = 4,
187
DXIL_INTR_STORE_OUTPUT = 5,
188
DXIL_INTR_FABS = 6,
189
DXIL_INTR_SATURATE = 7,
190
191
DXIL_INTR_ISFINITE = 10,
192
DXIL_INTR_ISNORMAL = 11,
193
194
DXIL_INTR_FCOS = 12,
195
DXIL_INTR_FSIN = 13,
196
197
DXIL_INTR_FEXP2 = 21,
198
DXIL_INTR_FRC = 22,
199
DXIL_INTR_FLOG2 = 23,
200
201
DXIL_INTR_SQRT = 24,
202
DXIL_INTR_RSQRT = 25,
203
DXIL_INTR_ROUND_NE = 26,
204
DXIL_INTR_ROUND_NI = 27,
205
DXIL_INTR_ROUND_PI = 28,
206
DXIL_INTR_ROUND_Z = 29,
207
208
DXIL_INTR_COUNTBITS = 31,
209
DXIL_INTR_FIRSTBIT_HI = 33,
210
211
DXIL_INTR_FMAX = 35,
212
DXIL_INTR_FMIN = 36,
213
DXIL_INTR_IMAX = 37,
214
DXIL_INTR_IMIN = 38,
215
DXIL_INTR_UMAX = 39,
216
DXIL_INTR_UMIN = 40,
217
218
DXIL_INTR_FMA = 47,
219
220
DXIL_INTR_CREATE_HANDLE = 57,
221
DXIL_INTR_CBUFFER_LOAD_LEGACY = 59,
222
223
DXIL_INTR_SAMPLE = 60,
224
DXIL_INTR_SAMPLE_BIAS = 61,
225
DXIL_INTR_SAMPLE_LEVEL = 62,
226
DXIL_INTR_SAMPLE_GRAD = 63,
227
DXIL_INTR_SAMPLE_CMP = 64,
228
DXIL_INTR_SAMPLE_CMP_LVL_ZERO = 65,
229
230
DXIL_INTR_TEXTURE_LOAD = 66,
231
DXIL_INTR_TEXTURE_STORE = 67,
232
233
DXIL_INTR_BUFFER_LOAD = 68,
234
DXIL_INTR_BUFFER_STORE = 69,
235
236
DXIL_INTR_TEXTURE_SIZE = 72,
237
238
DXIL_INTR_ATOMIC_BINOP = 78,
239
DXIL_INTR_ATOMIC_CMPXCHG = 79,
240
DXIL_INTR_BARRIER = 80,
241
DXIL_INTR_TEXTURE_LOD = 81,
242
243
DXIL_INTR_DISCARD = 82,
244
DXIL_INTR_DDX_COARSE = 83,
245
DXIL_INTR_DDY_COARSE = 84,
246
DXIL_INTR_DDX_FINE = 85,
247
DXIL_INTR_DDY_FINE = 86,
248
249
DXIL_INTR_THREAD_ID = 93,
250
DXIL_INTR_GROUP_ID = 94,
251
DXIL_INTR_THREAD_ID_IN_GROUP = 95,
252
253
DXIL_INTR_EMIT_STREAM = 97,
254
DXIL_INTR_CUT_STREAM = 98,
255
256
DXIL_INTR_MAKE_DOUBLE = 101,
257
DXIL_INTR_SPLIT_DOUBLE = 102,
258
259
DXIL_INTR_PRIMITIVE_ID = 108,
260
261
DXIL_INTR_LEGACY_F32TOF16 = 130,
262
DXIL_INTR_LEGACY_F16TOF32 = 131,
263
264
DXIL_INTR_ATTRIBUTE_AT_VERTEX = 137,
265
};
266
267
enum dxil_atomic_op {
268
DXIL_ATOMIC_ADD = 0,
269
DXIL_ATOMIC_AND = 1,
270
DXIL_ATOMIC_OR = 2,
271
DXIL_ATOMIC_XOR = 3,
272
DXIL_ATOMIC_IMIN = 4,
273
DXIL_ATOMIC_IMAX = 5,
274
DXIL_ATOMIC_UMIN = 6,
275
DXIL_ATOMIC_UMAX = 7,
276
DXIL_ATOMIC_EXCHANGE = 8,
277
};
278
279
typedef struct {
280
unsigned id;
281
unsigned binding;
282
unsigned size;
283
unsigned space;
284
} resource_array_layout;
285
286
static void
287
fill_resource_metadata(struct dxil_module *m, const struct dxil_mdnode **fields,
288
const struct dxil_type *struct_type,
289
const char *name, const resource_array_layout *layout)
290
{
291
const struct dxil_type *pointer_type = dxil_module_get_pointer_type(m, struct_type);
292
const struct dxil_value *pointer_undef = dxil_module_get_undef(m, pointer_type);
293
294
fields[0] = dxil_get_metadata_int32(m, layout->id); // resource ID
295
fields[1] = dxil_get_metadata_value(m, pointer_type, pointer_undef); // global constant symbol
296
fields[2] = dxil_get_metadata_string(m, name ? name : ""); // name
297
fields[3] = dxil_get_metadata_int32(m, layout->space); // space ID
298
fields[4] = dxil_get_metadata_int32(m, layout->binding); // lower bound
299
fields[5] = dxil_get_metadata_int32(m, layout->size); // range size
300
}
301
302
static const struct dxil_mdnode *
303
emit_srv_metadata(struct dxil_module *m, const struct dxil_type *elem_type,
304
const char *name, const resource_array_layout *layout,
305
enum dxil_component_type comp_type,
306
enum dxil_resource_kind res_kind)
307
{
308
const struct dxil_mdnode *fields[9];
309
310
const struct dxil_mdnode *metadata_tag_nodes[2];
311
312
fill_resource_metadata(m, fields, elem_type, name, layout);
313
fields[6] = dxil_get_metadata_int32(m, res_kind); // resource shape
314
fields[7] = dxil_get_metadata_int1(m, 0); // sample count
315
if (res_kind != DXIL_RESOURCE_KIND_RAW_BUFFER &&
316
res_kind != DXIL_RESOURCE_KIND_STRUCTURED_BUFFER) {
317
metadata_tag_nodes[0] = dxil_get_metadata_int32(m, DXIL_TYPED_BUFFER_ELEMENT_TYPE_TAG);
318
metadata_tag_nodes[1] = dxil_get_metadata_int32(m, comp_type);
319
fields[8] = dxil_get_metadata_node(m, metadata_tag_nodes, ARRAY_SIZE(metadata_tag_nodes)); // metadata
320
} else if (res_kind == DXIL_RESOURCE_KIND_RAW_BUFFER)
321
fields[8] = NULL;
322
else
323
unreachable("Structured buffers not supported yet");
324
325
return dxil_get_metadata_node(m, fields, ARRAY_SIZE(fields));
326
}
327
328
static const struct dxil_mdnode *
329
emit_uav_metadata(struct dxil_module *m, const struct dxil_type *struct_type,
330
const char *name, const resource_array_layout *layout,
331
enum dxil_component_type comp_type,
332
enum dxil_resource_kind res_kind)
333
{
334
const struct dxil_mdnode *fields[11];
335
336
const struct dxil_mdnode *metadata_tag_nodes[2];
337
338
fill_resource_metadata(m, fields, struct_type, name, layout);
339
fields[6] = dxil_get_metadata_int32(m, res_kind); // resource shape
340
fields[7] = dxil_get_metadata_int1(m, false); // globally-coherent
341
fields[8] = dxil_get_metadata_int1(m, false); // has counter
342
fields[9] = dxil_get_metadata_int1(m, false); // is ROV
343
if (res_kind != DXIL_RESOURCE_KIND_RAW_BUFFER &&
344
res_kind != DXIL_RESOURCE_KIND_STRUCTURED_BUFFER) {
345
metadata_tag_nodes[0] = dxil_get_metadata_int32(m, DXIL_TYPED_BUFFER_ELEMENT_TYPE_TAG);
346
metadata_tag_nodes[1] = dxil_get_metadata_int32(m, comp_type);
347
fields[10] = dxil_get_metadata_node(m, metadata_tag_nodes, ARRAY_SIZE(metadata_tag_nodes)); // metadata
348
} else if (res_kind == DXIL_RESOURCE_KIND_RAW_BUFFER)
349
fields[10] = NULL;
350
else
351
unreachable("Structured buffers not supported yet");
352
353
return dxil_get_metadata_node(m, fields, ARRAY_SIZE(fields));
354
}
355
356
static const struct dxil_mdnode *
357
emit_cbv_metadata(struct dxil_module *m, const struct dxil_type *struct_type,
358
const char *name, const resource_array_layout *layout,
359
unsigned size)
360
{
361
const struct dxil_mdnode *fields[8];
362
363
fill_resource_metadata(m, fields, struct_type, name, layout);
364
fields[6] = dxil_get_metadata_int32(m, size); // constant buffer size
365
fields[7] = NULL; // metadata
366
367
return dxil_get_metadata_node(m, fields, ARRAY_SIZE(fields));
368
}
369
370
static const struct dxil_mdnode *
371
emit_sampler_metadata(struct dxil_module *m, const struct dxil_type *struct_type,
372
nir_variable *var, const resource_array_layout *layout)
373
{
374
const struct dxil_mdnode *fields[8];
375
const struct glsl_type *type = glsl_without_array(var->type);
376
377
fill_resource_metadata(m, fields, struct_type, var->name, layout);
378
fields[6] = dxil_get_metadata_int32(m, DXIL_SAMPLER_KIND_DEFAULT); // sampler kind
379
enum dxil_sampler_kind sampler_kind = glsl_sampler_type_is_shadow(type) ?
380
DXIL_SAMPLER_KIND_COMPARISON : DXIL_SAMPLER_KIND_DEFAULT;
381
fields[6] = dxil_get_metadata_int32(m, sampler_kind); // sampler kind
382
fields[7] = NULL; // metadata
383
384
return dxil_get_metadata_node(m, fields, ARRAY_SIZE(fields));
385
}
386
387
388
#define MAX_SRVS 128
389
#define MAX_UAVS 64
390
#define MAX_CBVS 64 // ??
391
#define MAX_SAMPLERS 64 // ??
392
393
struct dxil_def {
394
const struct dxil_value *chans[NIR_MAX_VEC_COMPONENTS];
395
};
396
397
struct ntd_context {
398
void *ralloc_ctx;
399
const struct nir_to_dxil_options *opts;
400
struct nir_shader *shader;
401
402
struct dxil_module mod;
403
404
struct util_dynarray srv_metadata_nodes;
405
const struct dxil_value *srv_handles[MAX_SRVS];
406
407
struct util_dynarray uav_metadata_nodes;
408
const struct dxil_value *uav_handles[MAX_UAVS];
409
410
struct util_dynarray cbv_metadata_nodes;
411
const struct dxil_value *cbv_handles[MAX_CBVS];
412
413
struct util_dynarray sampler_metadata_nodes;
414
const struct dxil_value *sampler_handles[MAX_SAMPLERS];
415
416
struct util_dynarray resources;
417
418
const struct dxil_mdnode *shader_property_nodes[6];
419
size_t num_shader_property_nodes;
420
421
struct dxil_def *defs;
422
unsigned num_defs;
423
struct hash_table *phis;
424
425
const struct dxil_value *sharedvars;
426
const struct dxil_value *scratchvars;
427
struct hash_table *consts;
428
429
nir_variable *ps_front_face;
430
nir_variable *system_value[SYSTEM_VALUE_MAX];
431
};
432
433
static const char*
434
unary_func_name(enum dxil_intr intr)
435
{
436
switch (intr) {
437
case DXIL_INTR_COUNTBITS:
438
case DXIL_INTR_FIRSTBIT_HI:
439
return "dx.op.unaryBits";
440
case DXIL_INTR_ISFINITE:
441
case DXIL_INTR_ISNORMAL:
442
return "dx.op.isSpecialFloat";
443
default:
444
return "dx.op.unary";
445
}
446
}
447
448
static const struct dxil_value *
449
emit_unary_call(struct ntd_context *ctx, enum overload_type overload,
450
enum dxil_intr intr,
451
const struct dxil_value *op0)
452
{
453
const struct dxil_func *func = dxil_get_function(&ctx->mod,
454
unary_func_name(intr),
455
overload);
456
if (!func)
457
return NULL;
458
459
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, intr);
460
if (!opcode)
461
return NULL;
462
463
const struct dxil_value *args[] = {
464
opcode,
465
op0
466
};
467
468
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
469
}
470
471
static const struct dxil_value *
472
emit_binary_call(struct ntd_context *ctx, enum overload_type overload,
473
enum dxil_intr intr,
474
const struct dxil_value *op0, const struct dxil_value *op1)
475
{
476
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.binary", overload);
477
if (!func)
478
return NULL;
479
480
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, intr);
481
if (!opcode)
482
return NULL;
483
484
const struct dxil_value *args[] = {
485
opcode,
486
op0,
487
op1
488
};
489
490
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
491
}
492
493
static const struct dxil_value *
494
emit_tertiary_call(struct ntd_context *ctx, enum overload_type overload,
495
enum dxil_intr intr,
496
const struct dxil_value *op0,
497
const struct dxil_value *op1,
498
const struct dxil_value *op2)
499
{
500
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.tertiary", overload);
501
if (!func)
502
return NULL;
503
504
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, intr);
505
if (!opcode)
506
return NULL;
507
508
const struct dxil_value *args[] = {
509
opcode,
510
op0,
511
op1,
512
op2
513
};
514
515
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
516
}
517
518
static const struct dxil_value *
519
emit_threadid_call(struct ntd_context *ctx, const struct dxil_value *comp)
520
{
521
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.threadId", DXIL_I32);
522
if (!func)
523
return NULL;
524
525
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
526
DXIL_INTR_THREAD_ID);
527
if (!opcode)
528
return NULL;
529
530
const struct dxil_value *args[] = {
531
opcode,
532
comp
533
};
534
535
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
536
}
537
538
static const struct dxil_value *
539
emit_threadidingroup_call(struct ntd_context *ctx,
540
const struct dxil_value *comp)
541
{
542
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.threadIdInGroup", DXIL_I32);
543
544
if (!func)
545
return NULL;
546
547
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
548
DXIL_INTR_THREAD_ID_IN_GROUP);
549
if (!opcode)
550
return NULL;
551
552
const struct dxil_value *args[] = {
553
opcode,
554
comp
555
};
556
557
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
558
}
559
560
static const struct dxil_value *
561
emit_groupid_call(struct ntd_context *ctx, const struct dxil_value *comp)
562
{
563
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.groupId", DXIL_I32);
564
565
if (!func)
566
return NULL;
567
568
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
569
DXIL_INTR_GROUP_ID);
570
if (!opcode)
571
return NULL;
572
573
const struct dxil_value *args[] = {
574
opcode,
575
comp
576
};
577
578
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
579
}
580
581
static const struct dxil_value *
582
emit_bufferload_call(struct ntd_context *ctx,
583
const struct dxil_value *handle,
584
const struct dxil_value *coord[2])
585
{
586
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferLoad", DXIL_I32);
587
if (!func)
588
return NULL;
589
590
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
591
DXIL_INTR_BUFFER_LOAD);
592
const struct dxil_value *args[] = { opcode, handle, coord[0], coord[1] };
593
594
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
595
}
596
597
static bool
598
emit_bufferstore_call(struct ntd_context *ctx,
599
const struct dxil_value *handle,
600
const struct dxil_value *coord[2],
601
const struct dxil_value *value[4],
602
const struct dxil_value *write_mask,
603
enum overload_type overload)
604
{
605
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferStore", overload);
606
607
if (!func)
608
return false;
609
610
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
611
DXIL_INTR_BUFFER_STORE);
612
const struct dxil_value *args[] = {
613
opcode, handle, coord[0], coord[1],
614
value[0], value[1], value[2], value[3],
615
write_mask
616
};
617
618
return dxil_emit_call_void(&ctx->mod, func,
619
args, ARRAY_SIZE(args));
620
}
621
622
static bool
623
emit_texturestore_call(struct ntd_context *ctx,
624
const struct dxil_value *handle,
625
const struct dxil_value *coord[3],
626
const struct dxil_value *value[4],
627
const struct dxil_value *write_mask,
628
enum overload_type overload)
629
{
630
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.textureStore", overload);
631
632
if (!func)
633
return false;
634
635
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
636
DXIL_INTR_TEXTURE_STORE);
637
const struct dxil_value *args[] = {
638
opcode, handle, coord[0], coord[1], coord[2],
639
value[0], value[1], value[2], value[3],
640
write_mask
641
};
642
643
return dxil_emit_call_void(&ctx->mod, func,
644
args, ARRAY_SIZE(args));
645
}
646
647
static const struct dxil_value *
648
emit_atomic_binop(struct ntd_context *ctx,
649
const struct dxil_value *handle,
650
enum dxil_atomic_op atomic_op,
651
const struct dxil_value *coord[3],
652
const struct dxil_value *value)
653
{
654
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.atomicBinOp", DXIL_I32);
655
656
if (!func)
657
return false;
658
659
const struct dxil_value *opcode =
660
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_ATOMIC_BINOP);
661
const struct dxil_value *atomic_op_value =
662
dxil_module_get_int32_const(&ctx->mod, atomic_op);
663
const struct dxil_value *args[] = {
664
opcode, handle, atomic_op_value,
665
coord[0], coord[1], coord[2], value
666
};
667
668
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
669
}
670
671
static const struct dxil_value *
672
emit_atomic_cmpxchg(struct ntd_context *ctx,
673
const struct dxil_value *handle,
674
const struct dxil_value *coord[3],
675
const struct dxil_value *cmpval,
676
const struct dxil_value *newval)
677
{
678
const struct dxil_func *func =
679
dxil_get_function(&ctx->mod, "dx.op.atomicCompareExchange", DXIL_I32);
680
681
if (!func)
682
return false;
683
684
const struct dxil_value *opcode =
685
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_ATOMIC_CMPXCHG);
686
const struct dxil_value *args[] = {
687
opcode, handle, coord[0], coord[1], coord[2], cmpval, newval
688
};
689
690
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
691
}
692
693
static const struct dxil_value *
694
emit_createhandle_call(struct ntd_context *ctx,
695
enum dxil_resource_class resource_class,
696
unsigned resource_range_id,
697
const struct dxil_value *resource_range_index,
698
bool non_uniform_resource_index)
699
{
700
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_CREATE_HANDLE);
701
const struct dxil_value *resource_class_value = dxil_module_get_int8_const(&ctx->mod, resource_class);
702
const struct dxil_value *resource_range_id_value = dxil_module_get_int32_const(&ctx->mod, resource_range_id);
703
const struct dxil_value *non_uniform_resource_index_value = dxil_module_get_int1_const(&ctx->mod, non_uniform_resource_index);
704
if (!opcode || !resource_class_value || !resource_range_id_value ||
705
!non_uniform_resource_index_value)
706
return NULL;
707
708
const struct dxil_value *args[] = {
709
opcode,
710
resource_class_value,
711
resource_range_id_value,
712
resource_range_index,
713
non_uniform_resource_index_value
714
};
715
716
const struct dxil_func *func =
717
dxil_get_function(&ctx->mod, "dx.op.createHandle", DXIL_NONE);
718
719
if (!func)
720
return NULL;
721
722
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
723
}
724
725
static const struct dxil_value *
726
emit_createhandle_call_const_index(struct ntd_context *ctx,
727
enum dxil_resource_class resource_class,
728
unsigned resource_range_id,
729
unsigned resource_range_index,
730
bool non_uniform_resource_index)
731
{
732
733
const struct dxil_value *resource_range_index_value = dxil_module_get_int32_const(&ctx->mod, resource_range_index);
734
if (!resource_range_index_value)
735
return NULL;
736
737
return emit_createhandle_call(ctx, resource_class, resource_range_id,
738
resource_range_index_value,
739
non_uniform_resource_index);
740
}
741
742
static void
743
add_resource(struct ntd_context *ctx, enum dxil_resource_type type,
744
const resource_array_layout *layout)
745
{
746
struct dxil_resource *resource = util_dynarray_grow(&ctx->resources, struct dxil_resource, 1);
747
resource->resource_type = type;
748
resource->space = layout->space;
749
resource->lower_bound = layout->binding;
750
if (layout->size == 0 || (uint64_t)layout->size + layout->binding >= UINT_MAX)
751
resource->upper_bound = UINT_MAX;
752
else
753
resource->upper_bound = layout->binding + layout->size - 1;
754
}
755
756
static unsigned
757
get_resource_id(struct ntd_context *ctx, enum dxil_resource_class class,
758
unsigned space, unsigned binding)
759
{
760
unsigned offset = 0;
761
unsigned count = 0;
762
763
unsigned num_srvs = util_dynarray_num_elements(&ctx->srv_metadata_nodes, const struct dxil_mdnode *);
764
unsigned num_uavs = util_dynarray_num_elements(&ctx->uav_metadata_nodes, const struct dxil_mdnode *);
765
unsigned num_cbvs = util_dynarray_num_elements(&ctx->cbv_metadata_nodes, const struct dxil_mdnode *);
766
unsigned num_samplers = util_dynarray_num_elements(&ctx->sampler_metadata_nodes, const struct dxil_mdnode *);
767
768
switch (class) {
769
case DXIL_RESOURCE_CLASS_UAV:
770
offset = num_srvs + num_samplers + num_cbvs;
771
count = num_uavs;
772
break;
773
case DXIL_RESOURCE_CLASS_SRV:
774
offset = num_samplers + num_cbvs;
775
count = num_srvs;
776
break;
777
case DXIL_RESOURCE_CLASS_SAMPLER:
778
offset = num_cbvs;
779
count = num_samplers;
780
break;
781
case DXIL_RESOURCE_CLASS_CBV:
782
offset = 0;
783
count = num_cbvs;
784
break;
785
}
786
787
assert(offset + count <= util_dynarray_num_elements(&ctx->resources, struct dxil_resource));
788
for (unsigned i = offset; i < offset + count; ++i) {
789
const struct dxil_resource *resource = util_dynarray_element(&ctx->resources, struct dxil_resource, i);
790
if (resource->space == space &&
791
resource->lower_bound <= binding &&
792
resource->upper_bound >= binding) {
793
return i - offset;
794
}
795
}
796
797
unreachable("Resource access for undeclared range");
798
return 0;
799
}
800
801
static bool
802
emit_srv(struct ntd_context *ctx, nir_variable *var, unsigned count)
803
{
804
unsigned id = util_dynarray_num_elements(&ctx->srv_metadata_nodes, const struct dxil_mdnode *);
805
unsigned binding = var->data.binding;
806
resource_array_layout layout = {id, binding, count, var->data.descriptor_set};
807
808
enum dxil_component_type comp_type;
809
enum dxil_resource_kind res_kind;
810
enum dxil_resource_type res_type;
811
if (var->data.mode == nir_var_mem_ssbo) {
812
comp_type = DXIL_COMP_TYPE_INVALID;
813
res_kind = DXIL_RESOURCE_KIND_RAW_BUFFER;
814
res_type = DXIL_RES_SRV_RAW;
815
} else {
816
comp_type = dxil_get_comp_type(var->type);
817
res_kind = dxil_get_resource_kind(var->type);
818
res_type = DXIL_RES_SRV_TYPED;
819
}
820
const struct dxil_type *res_type_as_type = dxil_module_get_res_type(&ctx->mod, res_kind, comp_type, false /* readwrite */);
821
const struct dxil_mdnode *srv_meta = emit_srv_metadata(&ctx->mod, res_type_as_type, var->name,
822
&layout, comp_type, res_kind);
823
824
if (!srv_meta)
825
return false;
826
827
util_dynarray_append(&ctx->srv_metadata_nodes, const struct dxil_mdnode *, srv_meta);
828
add_resource(ctx, res_type, &layout);
829
830
if (!ctx->opts->vulkan_environment) {
831
for (unsigned i = 0; i < count; ++i) {
832
const struct dxil_value *handle =
833
emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_SRV,
834
id, binding + i, false);
835
if (!handle)
836
return false;
837
838
int idx = var->data.binding + i;
839
ctx->srv_handles[idx] = handle;
840
}
841
}
842
843
return true;
844
}
845
846
static bool
847
emit_globals(struct ntd_context *ctx, unsigned size)
848
{
849
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ssbo)
850
size++;
851
852
if (!size)
853
return true;
854
855
const struct dxil_type *struct_type = dxil_module_get_res_type(&ctx->mod,
856
DXIL_RESOURCE_KIND_RAW_BUFFER, DXIL_COMP_TYPE_INVALID, true /* readwrite */);
857
if (!struct_type)
858
return false;
859
860
const struct dxil_type *array_type =
861
dxil_module_get_array_type(&ctx->mod, struct_type, size);
862
if (!array_type)
863
return false;
864
865
resource_array_layout layout = {0, 0, size, 0};
866
const struct dxil_mdnode *uav_meta =
867
emit_uav_metadata(&ctx->mod, array_type,
868
"globals", &layout,
869
DXIL_COMP_TYPE_INVALID,
870
DXIL_RESOURCE_KIND_RAW_BUFFER);
871
if (!uav_meta)
872
return false;
873
874
util_dynarray_append(&ctx->uav_metadata_nodes, const struct dxil_mdnode *, uav_meta);
875
if (util_dynarray_num_elements(&ctx->uav_metadata_nodes, const struct dxil_mdnode *) > 8)
876
ctx->mod.feats.use_64uavs = 1;
877
/* Handles to UAVs used for kernel globals are created on-demand */
878
add_resource(ctx, DXIL_RES_UAV_RAW, &layout);
879
ctx->mod.raw_and_structured_buffers = true;
880
return true;
881
}
882
883
static bool
884
emit_uav(struct ntd_context *ctx, unsigned binding, unsigned space, unsigned count,
885
enum dxil_component_type comp_type, enum dxil_resource_kind res_kind, const char *name)
886
{
887
unsigned id = util_dynarray_num_elements(&ctx->uav_metadata_nodes, const struct dxil_mdnode *);
888
resource_array_layout layout = { id, binding, count, space };
889
890
const struct dxil_type *res_type = dxil_module_get_res_type(&ctx->mod, res_kind, comp_type, true /* readwrite */);
891
const struct dxil_mdnode *uav_meta = emit_uav_metadata(&ctx->mod, res_type, name,
892
&layout, comp_type, res_kind);
893
894
if (!uav_meta)
895
return false;
896
897
util_dynarray_append(&ctx->uav_metadata_nodes, const struct dxil_mdnode *, uav_meta);
898
if (util_dynarray_num_elements(&ctx->uav_metadata_nodes, const struct dxil_mdnode *) > 8)
899
ctx->mod.feats.use_64uavs = 1;
900
901
add_resource(ctx, res_kind == DXIL_RESOURCE_KIND_RAW_BUFFER ? DXIL_RES_UAV_RAW : DXIL_RES_UAV_TYPED, &layout);
902
903
if (!ctx->opts->vulkan_environment) {
904
for (unsigned i = 0; i < count; ++i) {
905
const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_UAV,
906
id, binding + i, false);
907
if (!handle)
908
return false;
909
910
ctx->uav_handles[binding + i] = handle;
911
}
912
}
913
914
return true;
915
}
916
917
static bool
918
emit_uav_var(struct ntd_context *ctx, nir_variable *var, unsigned count)
919
{
920
unsigned binding = var->data.binding;
921
unsigned space = var->data.descriptor_set;
922
enum dxil_component_type comp_type = dxil_get_comp_type(var->type);
923
enum dxil_resource_kind res_kind = dxil_get_resource_kind(var->type);
924
const char *name = var->name;
925
926
return emit_uav(ctx, binding, space, count, comp_type, res_kind, name);
927
}
928
929
static unsigned get_dword_size(const struct glsl_type *type)
930
{
931
if (glsl_type_is_array(type)) {
932
type = glsl_without_array(type);
933
}
934
assert(glsl_type_is_struct(type) || glsl_type_is_interface(type));
935
return glsl_get_explicit_size(type, false);
936
}
937
938
static bool
939
var_fill_const_array_with_vector_or_scalar(struct ntd_context *ctx,
940
const struct nir_constant *c,
941
const struct glsl_type *type,
942
void *const_vals,
943
unsigned int offset)
944
{
945
assert(glsl_type_is_vector_or_scalar(type));
946
unsigned int components = glsl_get_vector_elements(type);
947
unsigned bit_size = glsl_get_bit_size(type);
948
unsigned int increment = bit_size / 8;
949
950
for (unsigned int comp = 0; comp < components; comp++) {
951
uint8_t *dst = (uint8_t *)const_vals + offset;
952
953
switch (bit_size) {
954
case 64:
955
memcpy(dst, &c->values[comp].u64, sizeof(c->values[0].u64));
956
break;
957
case 32:
958
memcpy(dst, &c->values[comp].u32, sizeof(c->values[0].u32));
959
break;
960
case 16:
961
memcpy(dst, &c->values[comp].u16, sizeof(c->values[0].u16));
962
break;
963
case 8:
964
assert(glsl_base_type_is_integer(glsl_get_base_type(type)));
965
memcpy(dst, &c->values[comp].u8, sizeof(c->values[0].u8));
966
break;
967
default:
968
unreachable("unexpeted bit-size");
969
}
970
971
offset += increment;
972
}
973
974
return true;
975
}
976
977
static bool
978
var_fill_const_array(struct ntd_context *ctx, const struct nir_constant *c,
979
const struct glsl_type *type, void *const_vals,
980
unsigned int offset)
981
{
982
assert(!glsl_type_is_interface(type));
983
984
if (glsl_type_is_vector_or_scalar(type)) {
985
return var_fill_const_array_with_vector_or_scalar(ctx, c, type,
986
const_vals,
987
offset);
988
} else if (glsl_type_is_array(type)) {
989
assert(!glsl_type_is_unsized_array(type));
990
const struct glsl_type *without = glsl_without_array(type);
991
unsigned stride = glsl_get_explicit_stride(without);
992
993
for (unsigned elt = 0; elt < glsl_get_length(type); elt++) {
994
if (!var_fill_const_array(ctx, c->elements[elt], without,
995
const_vals, offset + (elt * stride))) {
996
return false;
997
}
998
offset += glsl_get_cl_size(without);
999
}
1000
return true;
1001
} else if (glsl_type_is_struct(type)) {
1002
for (unsigned int elt = 0; elt < glsl_get_length(type); elt++) {
1003
const struct glsl_type *elt_type = glsl_get_struct_field(type, elt);
1004
unsigned field_offset = glsl_get_struct_field_offset(type, elt);
1005
1006
if (!var_fill_const_array(ctx, c->elements[elt],
1007
elt_type, const_vals,
1008
offset + field_offset)) {
1009
return false;
1010
}
1011
}
1012
return true;
1013
}
1014
1015
unreachable("unknown GLSL type in var_fill_const_array");
1016
}
1017
1018
static bool
1019
emit_global_consts(struct ntd_context *ctx)
1020
{
1021
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_shader_temp) {
1022
bool err;
1023
1024
assert(var->constant_initializer);
1025
1026
unsigned int num_members = DIV_ROUND_UP(glsl_get_cl_size(var->type), 4);
1027
uint32_t *const_ints = ralloc_array(ctx->ralloc_ctx, uint32_t, num_members);
1028
err = var_fill_const_array(ctx, var->constant_initializer, var->type,
1029
const_ints, 0);
1030
if (!err)
1031
return false;
1032
const struct dxil_value **const_vals =
1033
ralloc_array(ctx->ralloc_ctx, const struct dxil_value *, num_members);
1034
if (!const_vals)
1035
return false;
1036
for (int i = 0; i < num_members; i++)
1037
const_vals[i] = dxil_module_get_int32_const(&ctx->mod, const_ints[i]);
1038
1039
const struct dxil_type *elt_type = dxil_module_get_int_type(&ctx->mod, 32);
1040
if (!elt_type)
1041
return false;
1042
const struct dxil_type *type =
1043
dxil_module_get_array_type(&ctx->mod, elt_type, num_members);
1044
if (!type)
1045
return false;
1046
const struct dxil_value *agg_vals =
1047
dxil_module_get_array_const(&ctx->mod, type, const_vals);
1048
if (!agg_vals)
1049
return false;
1050
1051
const struct dxil_value *gvar = dxil_add_global_ptr_var(&ctx->mod, var->name, type,
1052
DXIL_AS_DEFAULT, 4,
1053
agg_vals);
1054
if (!gvar)
1055
return false;
1056
1057
if (!_mesa_hash_table_insert(ctx->consts, var, (void *)gvar))
1058
return false;
1059
}
1060
1061
return true;
1062
}
1063
1064
static bool
1065
emit_cbv(struct ntd_context *ctx, unsigned binding, unsigned space,
1066
unsigned size, unsigned count, char *name)
1067
{
1068
unsigned idx = util_dynarray_num_elements(&ctx->cbv_metadata_nodes, const struct dxil_mdnode *);
1069
1070
const struct dxil_type *float32 = dxil_module_get_float_type(&ctx->mod, 32);
1071
const struct dxil_type *array_type = dxil_module_get_array_type(&ctx->mod, float32, size);
1072
const struct dxil_type *buffer_type = dxil_module_get_struct_type(&ctx->mod, name,
1073
&array_type, 1);
1074
const struct dxil_type *final_type = count != 1 ? dxil_module_get_array_type(&ctx->mod, buffer_type, count) : buffer_type;
1075
resource_array_layout layout = {idx, binding, count, space};
1076
const struct dxil_mdnode *cbv_meta = emit_cbv_metadata(&ctx->mod, final_type,
1077
name, &layout, 4 * size);
1078
1079
if (!cbv_meta)
1080
return false;
1081
1082
util_dynarray_append(&ctx->cbv_metadata_nodes, const struct dxil_mdnode *, cbv_meta);
1083
add_resource(ctx, DXIL_RES_CBV, &layout);
1084
1085
if (!ctx->opts->vulkan_environment) {
1086
for (unsigned i = 0; i < count; ++i) {
1087
const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_CBV,
1088
idx, binding + i, false);
1089
if (!handle)
1090
return false;
1091
1092
assert(!ctx->cbv_handles[binding + i]);
1093
ctx->cbv_handles[binding + i] = handle;
1094
}
1095
}
1096
1097
return true;
1098
}
1099
1100
static bool
1101
emit_ubo_var(struct ntd_context *ctx, nir_variable *var)
1102
{
1103
unsigned count = 1;
1104
if (glsl_type_is_array(var->type))
1105
count = glsl_get_length(var->type);
1106
return emit_cbv(ctx, var->data.binding, var->data.descriptor_set, get_dword_size(var->type), count, var->name);
1107
}
1108
1109
static bool
1110
emit_sampler(struct ntd_context *ctx, nir_variable *var, unsigned count)
1111
{
1112
unsigned id = util_dynarray_num_elements(&ctx->sampler_metadata_nodes, const struct dxil_mdnode *);
1113
unsigned binding = var->data.binding;
1114
resource_array_layout layout = {id, binding, count, var->data.descriptor_set};
1115
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
1116
const struct dxil_type *sampler_type = dxil_module_get_struct_type(&ctx->mod, "struct.SamplerState", &int32_type, 1);
1117
const struct dxil_mdnode *sampler_meta = emit_sampler_metadata(&ctx->mod, sampler_type, var, &layout);
1118
1119
if (!sampler_meta)
1120
return false;
1121
1122
util_dynarray_append(&ctx->sampler_metadata_nodes, const struct dxil_mdnode *, sampler_meta);
1123
add_resource(ctx, DXIL_RES_SAMPLER, &layout);
1124
1125
if (!ctx->opts->vulkan_environment) {
1126
for (unsigned i = 0; i < count; ++i) {
1127
const struct dxil_value *handle =
1128
emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_SAMPLER,
1129
id, binding + i, false);
1130
if (!handle)
1131
return false;
1132
1133
unsigned idx = var->data.binding + i;
1134
ctx->sampler_handles[idx] = handle;
1135
}
1136
}
1137
1138
return true;
1139
}
1140
1141
static const struct dxil_mdnode *
1142
emit_gs_state(struct ntd_context *ctx)
1143
{
1144
const struct dxil_mdnode *gs_state_nodes[5];
1145
const nir_shader *s = ctx->shader;
1146
1147
gs_state_nodes[0] = dxil_get_metadata_int32(&ctx->mod, dxil_get_input_primitive(s->info.gs.input_primitive));
1148
gs_state_nodes[1] = dxil_get_metadata_int32(&ctx->mod, s->info.gs.vertices_out);
1149
gs_state_nodes[2] = dxil_get_metadata_int32(&ctx->mod, s->info.gs.active_stream_mask);
1150
gs_state_nodes[3] = dxil_get_metadata_int32(&ctx->mod, dxil_get_primitive_topology(s->info.gs.output_primitive));
1151
gs_state_nodes[4] = dxil_get_metadata_int32(&ctx->mod, s->info.gs.invocations);
1152
1153
for (unsigned i = 0; i < ARRAY_SIZE(gs_state_nodes); ++i) {
1154
if (!gs_state_nodes[i])
1155
return NULL;
1156
}
1157
1158
return dxil_get_metadata_node(&ctx->mod, gs_state_nodes, ARRAY_SIZE(gs_state_nodes));
1159
}
1160
1161
static const struct dxil_mdnode *
1162
emit_threads(struct ntd_context *ctx)
1163
{
1164
const nir_shader *s = ctx->shader;
1165
const struct dxil_mdnode *threads_x = dxil_get_metadata_int32(&ctx->mod, MAX2(s->info.workgroup_size[0], 1));
1166
const struct dxil_mdnode *threads_y = dxil_get_metadata_int32(&ctx->mod, MAX2(s->info.workgroup_size[1], 1));
1167
const struct dxil_mdnode *threads_z = dxil_get_metadata_int32(&ctx->mod, MAX2(s->info.workgroup_size[2], 1));
1168
if (!threads_x || !threads_y || !threads_z)
1169
return false;
1170
1171
const struct dxil_mdnode *threads_nodes[] = { threads_x, threads_y, threads_z };
1172
return dxil_get_metadata_node(&ctx->mod, threads_nodes, ARRAY_SIZE(threads_nodes));
1173
}
1174
1175
static int64_t
1176
get_module_flags(struct ntd_context *ctx)
1177
{
1178
/* See the DXIL documentation for the definition of these flags:
1179
*
1180
* https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst#shader-flags
1181
*/
1182
1183
uint64_t flags = 0;
1184
if (ctx->mod.feats.doubles)
1185
flags |= (1 << 2);
1186
if (ctx->mod.raw_and_structured_buffers)
1187
flags |= (1 << 4);
1188
if (ctx->mod.feats.min_precision)
1189
flags |= (1 << 5);
1190
if (ctx->mod.feats.dx11_1_double_extensions)
1191
flags |= (1 << 6);
1192
if (ctx->mod.feats.inner_coverage)
1193
flags |= (1 << 10);
1194
if (ctx->mod.feats.typed_uav_load_additional_formats)
1195
flags |= (1 << 13);
1196
if (ctx->mod.feats.use_64uavs)
1197
flags |= (1 << 15);
1198
if (ctx->mod.feats.cs_4x_raw_sb)
1199
flags |= (1 << 17);
1200
if (ctx->mod.feats.wave_ops)
1201
flags |= (1 << 19);
1202
if (ctx->mod.feats.int64_ops)
1203
flags |= (1 << 20);
1204
if (ctx->mod.feats.stencil_ref)
1205
flags |= (1 << 11);
1206
if (ctx->mod.feats.native_low_precision)
1207
flags |= (1 << 23) | (1 << 5);
1208
1209
if (ctx->opts->disable_math_refactoring)
1210
flags |= (1 << 1);
1211
1212
return flags;
1213
}
1214
1215
static const struct dxil_mdnode *
1216
emit_entrypoint(struct ntd_context *ctx,
1217
const struct dxil_func *func, const char *name,
1218
const struct dxil_mdnode *signatures,
1219
const struct dxil_mdnode *resources,
1220
const struct dxil_mdnode *shader_props)
1221
{
1222
const struct dxil_mdnode *func_md = dxil_get_metadata_func(&ctx->mod, func);
1223
const struct dxil_mdnode *name_md = dxil_get_metadata_string(&ctx->mod, name);
1224
const struct dxil_mdnode *nodes[] = {
1225
func_md,
1226
name_md,
1227
signatures,
1228
resources,
1229
shader_props
1230
};
1231
return dxil_get_metadata_node(&ctx->mod, nodes,
1232
ARRAY_SIZE(nodes));
1233
}
1234
1235
static const struct dxil_mdnode *
1236
emit_resources(struct ntd_context *ctx)
1237
{
1238
bool emit_resources = false;
1239
const struct dxil_mdnode *resources_nodes[] = {
1240
NULL, NULL, NULL, NULL
1241
};
1242
1243
#define ARRAY_AND_SIZE(arr) arr.data, util_dynarray_num_elements(&arr, const struct dxil_mdnode *)
1244
1245
if (ctx->srv_metadata_nodes.size) {
1246
resources_nodes[0] = dxil_get_metadata_node(&ctx->mod, ARRAY_AND_SIZE(ctx->srv_metadata_nodes));
1247
emit_resources = true;
1248
}
1249
1250
if (ctx->uav_metadata_nodes.size) {
1251
resources_nodes[1] = dxil_get_metadata_node(&ctx->mod, ARRAY_AND_SIZE(ctx->uav_metadata_nodes));
1252
emit_resources = true;
1253
}
1254
1255
if (ctx->cbv_metadata_nodes.size) {
1256
resources_nodes[2] = dxil_get_metadata_node(&ctx->mod, ARRAY_AND_SIZE(ctx->cbv_metadata_nodes));
1257
emit_resources = true;
1258
}
1259
1260
if (ctx->sampler_metadata_nodes.size) {
1261
resources_nodes[3] = dxil_get_metadata_node(&ctx->mod, ARRAY_AND_SIZE(ctx->sampler_metadata_nodes));
1262
emit_resources = true;
1263
}
1264
1265
#undef ARRAY_AND_SIZE
1266
1267
return emit_resources ?
1268
dxil_get_metadata_node(&ctx->mod, resources_nodes, ARRAY_SIZE(resources_nodes)): NULL;
1269
}
1270
1271
static boolean
1272
emit_tag(struct ntd_context *ctx, enum dxil_shader_tag tag,
1273
const struct dxil_mdnode *value_node)
1274
{
1275
const struct dxil_mdnode *tag_node = dxil_get_metadata_int32(&ctx->mod, tag);
1276
if (!tag_node || !value_node)
1277
return false;
1278
assert(ctx->num_shader_property_nodes <= ARRAY_SIZE(ctx->shader_property_nodes) - 2);
1279
ctx->shader_property_nodes[ctx->num_shader_property_nodes++] = tag_node;
1280
ctx->shader_property_nodes[ctx->num_shader_property_nodes++] = value_node;
1281
1282
return true;
1283
}
1284
1285
static bool
1286
emit_metadata(struct ntd_context *ctx)
1287
{
1288
unsigned dxilMinor = ctx->mod.minor_version;
1289
if (!emit_llvm_ident(&ctx->mod) ||
1290
!emit_named_version(&ctx->mod, "dx.version", 1, dxilMinor) ||
1291
!emit_named_version(&ctx->mod, "dx.valver", 1, 4) ||
1292
!emit_dx_shader_model(&ctx->mod))
1293
return false;
1294
1295
const struct dxil_type *void_type = dxil_module_get_void_type(&ctx->mod);
1296
const struct dxil_type *main_func_type = dxil_module_add_function_type(&ctx->mod, void_type, NULL, 0);
1297
const struct dxil_func *main_func = dxil_add_function_def(&ctx->mod, "main", main_func_type);
1298
if (!main_func)
1299
return false;
1300
1301
const struct dxil_mdnode *resources_node = emit_resources(ctx);
1302
1303
const struct dxil_mdnode *main_entrypoint = dxil_get_metadata_func(&ctx->mod, main_func);
1304
const struct dxil_mdnode *node27 = dxil_get_metadata_node(&ctx->mod, NULL, 0);
1305
1306
const struct dxil_mdnode *node4 = dxil_get_metadata_int32(&ctx->mod, 0);
1307
const struct dxil_mdnode *nodes_4_27_27[] = {
1308
node4, node27, node27
1309
};
1310
const struct dxil_mdnode *node28 = dxil_get_metadata_node(&ctx->mod, nodes_4_27_27,
1311
ARRAY_SIZE(nodes_4_27_27));
1312
1313
const struct dxil_mdnode *node29 = dxil_get_metadata_node(&ctx->mod, &node28, 1);
1314
1315
const struct dxil_mdnode *node3 = dxil_get_metadata_int32(&ctx->mod, 1);
1316
const struct dxil_mdnode *main_type_annotation_nodes[] = {
1317
node3, main_entrypoint, node29
1318
};
1319
const struct dxil_mdnode *main_type_annotation = dxil_get_metadata_node(&ctx->mod, main_type_annotation_nodes,
1320
ARRAY_SIZE(main_type_annotation_nodes));
1321
1322
if (ctx->mod.shader_kind == DXIL_GEOMETRY_SHADER) {
1323
if (!emit_tag(ctx, DXIL_SHADER_TAG_GS_STATE, emit_gs_state(ctx)))
1324
return false;
1325
} else if (ctx->mod.shader_kind == DXIL_COMPUTE_SHADER) {
1326
if (!emit_tag(ctx, DXIL_SHADER_TAG_NUM_THREADS, emit_threads(ctx)))
1327
return false;
1328
}
1329
1330
uint64_t flags = get_module_flags(ctx);
1331
if (flags != 0) {
1332
if (!emit_tag(ctx, DXIL_SHADER_TAG_FLAGS, dxil_get_metadata_int64(&ctx->mod, flags)))
1333
return false;
1334
}
1335
const struct dxil_mdnode *shader_properties = NULL;
1336
if (ctx->num_shader_property_nodes > 0) {
1337
shader_properties = dxil_get_metadata_node(&ctx->mod, ctx->shader_property_nodes,
1338
ctx->num_shader_property_nodes);
1339
if (!shader_properties)
1340
return false;
1341
}
1342
1343
const struct dxil_mdnode *signatures = get_signatures(&ctx->mod, ctx->shader,
1344
ctx->opts->vulkan_environment);
1345
1346
const struct dxil_mdnode *dx_entry_point = emit_entrypoint(ctx, main_func,
1347
"main", signatures, resources_node, shader_properties);
1348
if (!dx_entry_point)
1349
return false;
1350
1351
if (resources_node) {
1352
const struct dxil_mdnode *dx_resources = resources_node;
1353
dxil_add_metadata_named_node(&ctx->mod, "dx.resources",
1354
&dx_resources, 1);
1355
}
1356
1357
const struct dxil_mdnode *dx_type_annotations[] = { main_type_annotation };
1358
return dxil_add_metadata_named_node(&ctx->mod, "dx.typeAnnotations",
1359
dx_type_annotations,
1360
ARRAY_SIZE(dx_type_annotations)) &&
1361
dxil_add_metadata_named_node(&ctx->mod, "dx.entryPoints",
1362
&dx_entry_point, 1);
1363
}
1364
1365
static const struct dxil_value *
1366
bitcast_to_int(struct ntd_context *ctx, unsigned bit_size,
1367
const struct dxil_value *value)
1368
{
1369
const struct dxil_type *type = dxil_module_get_int_type(&ctx->mod, bit_size);
1370
if (!type)
1371
return NULL;
1372
1373
return dxil_emit_cast(&ctx->mod, DXIL_CAST_BITCAST, type, value);
1374
}
1375
1376
static const struct dxil_value *
1377
bitcast_to_float(struct ntd_context *ctx, unsigned bit_size,
1378
const struct dxil_value *value)
1379
{
1380
const struct dxil_type *type = dxil_module_get_float_type(&ctx->mod, bit_size);
1381
if (!type)
1382
return NULL;
1383
1384
return dxil_emit_cast(&ctx->mod, DXIL_CAST_BITCAST, type, value);
1385
}
1386
1387
static void
1388
store_ssa_def(struct ntd_context *ctx, nir_ssa_def *ssa, unsigned chan,
1389
const struct dxil_value *value)
1390
{
1391
assert(ssa->index < ctx->num_defs);
1392
assert(chan < ssa->num_components);
1393
/* We pre-defined the dest value because of a phi node, so bitcast while storing if the
1394
* base type differs */
1395
if (ctx->defs[ssa->index].chans[chan]) {
1396
const struct dxil_type *expect_type = dxil_value_get_type(ctx->defs[ssa->index].chans[chan]);
1397
const struct dxil_type *value_type = dxil_value_get_type(value);
1398
if (dxil_type_to_nir_type(expect_type) != dxil_type_to_nir_type(value_type))
1399
value = dxil_emit_cast(&ctx->mod, DXIL_CAST_BITCAST, expect_type, value);
1400
}
1401
ctx->defs[ssa->index].chans[chan] = value;
1402
}
1403
1404
static void
1405
store_dest_value(struct ntd_context *ctx, nir_dest *dest, unsigned chan,
1406
const struct dxil_value *value)
1407
{
1408
assert(dest->is_ssa);
1409
assert(value);
1410
store_ssa_def(ctx, &dest->ssa, chan, value);
1411
}
1412
1413
static void
1414
store_dest(struct ntd_context *ctx, nir_dest *dest, unsigned chan,
1415
const struct dxil_value *value, nir_alu_type type)
1416
{
1417
switch (nir_alu_type_get_base_type(type)) {
1418
case nir_type_float:
1419
if (nir_dest_bit_size(*dest) == 64)
1420
ctx->mod.feats.doubles = true;
1421
FALLTHROUGH;
1422
case nir_type_uint:
1423
case nir_type_int:
1424
if (nir_dest_bit_size(*dest) == 16)
1425
ctx->mod.feats.native_low_precision = true;
1426
if (nir_dest_bit_size(*dest) == 64)
1427
ctx->mod.feats.int64_ops = true;
1428
FALLTHROUGH;
1429
case nir_type_bool:
1430
store_dest_value(ctx, dest, chan, value);
1431
break;
1432
default:
1433
unreachable("unexpected nir_alu_type");
1434
}
1435
}
1436
1437
static void
1438
store_alu_dest(struct ntd_context *ctx, nir_alu_instr *alu, unsigned chan,
1439
const struct dxil_value *value)
1440
{
1441
assert(!alu->dest.saturate);
1442
store_dest(ctx, &alu->dest.dest, chan, value,
1443
nir_op_infos[alu->op].output_type);
1444
}
1445
1446
static const struct dxil_value *
1447
get_src_ssa(struct ntd_context *ctx, const nir_ssa_def *ssa, unsigned chan)
1448
{
1449
assert(ssa->index < ctx->num_defs);
1450
assert(chan < ssa->num_components);
1451
assert(ctx->defs[ssa->index].chans[chan]);
1452
return ctx->defs[ssa->index].chans[chan];
1453
}
1454
1455
static const struct dxil_value *
1456
get_src(struct ntd_context *ctx, nir_src *src, unsigned chan,
1457
nir_alu_type type)
1458
{
1459
assert(src->is_ssa);
1460
const struct dxil_value *value = get_src_ssa(ctx, src->ssa, chan);
1461
1462
const int bit_size = nir_src_bit_size(*src);
1463
1464
switch (nir_alu_type_get_base_type(type)) {
1465
case nir_type_int:
1466
case nir_type_uint: {
1467
assert(bit_size != 64 || ctx->mod.feats.int64_ops);
1468
const struct dxil_type *expect_type = dxil_module_get_int_type(&ctx->mod, bit_size);
1469
/* nohing to do */
1470
if (dxil_value_type_equal_to(value, expect_type))
1471
return value;
1472
assert(dxil_value_type_bitsize_equal_to(value, bit_size));
1473
return bitcast_to_int(ctx, bit_size, value);
1474
}
1475
1476
case nir_type_float:
1477
assert(nir_src_bit_size(*src) >= 16);
1478
assert(nir_src_bit_size(*src) != 64 || (ctx->mod.feats.doubles &&
1479
ctx->mod.feats.int64_ops));
1480
if (dxil_value_type_equal_to(value, dxil_module_get_float_type(&ctx->mod, bit_size)))
1481
return value;
1482
assert(dxil_value_type_bitsize_equal_to(value, bit_size));
1483
return bitcast_to_float(ctx, bit_size, value);
1484
1485
case nir_type_bool:
1486
if (!dxil_value_type_bitsize_equal_to(value, 1)) {
1487
return dxil_emit_cast(&ctx->mod, DXIL_CAST_TRUNC,
1488
dxil_module_get_int_type(&ctx->mod, 1), value);
1489
}
1490
return value;
1491
1492
default:
1493
unreachable("unexpected nir_alu_type");
1494
}
1495
}
1496
1497
static const struct dxil_type *
1498
get_alu_src_type(struct ntd_context *ctx, nir_alu_instr *alu, unsigned src)
1499
{
1500
assert(!alu->src[src].abs);
1501
assert(!alu->src[src].negate);
1502
nir_ssa_def *ssa_src = alu->src[src].src.ssa;
1503
unsigned chan = alu->src[src].swizzle[0];
1504
const struct dxil_value *value = get_src_ssa(ctx, ssa_src, chan);
1505
return dxil_value_get_type(value);
1506
}
1507
1508
static const struct dxil_value *
1509
get_alu_src(struct ntd_context *ctx, nir_alu_instr *alu, unsigned src)
1510
{
1511
assert(!alu->src[src].abs);
1512
assert(!alu->src[src].negate);
1513
1514
unsigned chan = alu->src[src].swizzle[0];
1515
return get_src(ctx, &alu->src[src].src, chan,
1516
nir_op_infos[alu->op].input_types[src]);
1517
}
1518
1519
static bool
1520
emit_binop(struct ntd_context *ctx, nir_alu_instr *alu,
1521
enum dxil_bin_opcode opcode,
1522
const struct dxil_value *op0, const struct dxil_value *op1)
1523
{
1524
bool is_float_op = nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) == nir_type_float;
1525
1526
enum dxil_opt_flags flags = 0;
1527
if (is_float_op && !alu->exact)
1528
flags |= DXIL_UNSAFE_ALGEBRA;
1529
1530
const struct dxil_value *v = dxil_emit_binop(&ctx->mod, opcode, op0, op1, flags);
1531
if (!v)
1532
return false;
1533
store_alu_dest(ctx, alu, 0, v);
1534
return true;
1535
}
1536
1537
static bool
1538
emit_shift(struct ntd_context *ctx, nir_alu_instr *alu,
1539
enum dxil_bin_opcode opcode,
1540
const struct dxil_value *op0, const struct dxil_value *op1)
1541
{
1542
unsigned op0_bit_size = nir_src_bit_size(alu->src[0].src);
1543
unsigned op1_bit_size = nir_src_bit_size(alu->src[1].src);
1544
if (op0_bit_size != op1_bit_size) {
1545
const struct dxil_type *type =
1546
dxil_module_get_int_type(&ctx->mod, op0_bit_size);
1547
enum dxil_cast_opcode cast_op =
1548
op1_bit_size < op0_bit_size ? DXIL_CAST_ZEXT : DXIL_CAST_TRUNC;
1549
op1 = dxil_emit_cast(&ctx->mod, cast_op, type, op1);
1550
}
1551
1552
const struct dxil_value *v =
1553
dxil_emit_binop(&ctx->mod, opcode, op0, op1, 0);
1554
if (!v)
1555
return false;
1556
store_alu_dest(ctx, alu, 0, v);
1557
return true;
1558
}
1559
1560
static bool
1561
emit_cmp(struct ntd_context *ctx, nir_alu_instr *alu,
1562
enum dxil_cmp_pred pred,
1563
const struct dxil_value *op0, const struct dxil_value *op1)
1564
{
1565
const struct dxil_value *v = dxil_emit_cmp(&ctx->mod, pred, op0, op1);
1566
if (!v)
1567
return false;
1568
store_alu_dest(ctx, alu, 0, v);
1569
return true;
1570
}
1571
1572
static enum dxil_cast_opcode
1573
get_cast_op(nir_alu_instr *alu)
1574
{
1575
unsigned dst_bits = nir_dest_bit_size(alu->dest.dest);
1576
unsigned src_bits = nir_src_bit_size(alu->src[0].src);
1577
1578
switch (alu->op) {
1579
/* bool -> int */
1580
case nir_op_b2i16:
1581
case nir_op_b2i32:
1582
case nir_op_b2i64:
1583
return DXIL_CAST_ZEXT;
1584
1585
/* float -> float */
1586
case nir_op_f2f16_rtz:
1587
case nir_op_f2f32:
1588
case nir_op_f2f64:
1589
assert(dst_bits != src_bits);
1590
if (dst_bits < src_bits)
1591
return DXIL_CAST_FPTRUNC;
1592
else
1593
return DXIL_CAST_FPEXT;
1594
1595
/* int -> int */
1596
case nir_op_i2i16:
1597
case nir_op_i2i32:
1598
case nir_op_i2i64:
1599
assert(dst_bits != src_bits);
1600
if (dst_bits < src_bits)
1601
return DXIL_CAST_TRUNC;
1602
else
1603
return DXIL_CAST_SEXT;
1604
1605
/* uint -> uint */
1606
case nir_op_u2u16:
1607
case nir_op_u2u32:
1608
case nir_op_u2u64:
1609
assert(dst_bits != src_bits);
1610
if (dst_bits < src_bits)
1611
return DXIL_CAST_TRUNC;
1612
else
1613
return DXIL_CAST_ZEXT;
1614
1615
/* float -> int */
1616
case nir_op_f2i16:
1617
case nir_op_f2i32:
1618
case nir_op_f2i64:
1619
return DXIL_CAST_FPTOSI;
1620
1621
/* float -> uint */
1622
case nir_op_f2u16:
1623
case nir_op_f2u32:
1624
case nir_op_f2u64:
1625
return DXIL_CAST_FPTOUI;
1626
1627
/* int -> float */
1628
case nir_op_i2f16:
1629
case nir_op_i2f32:
1630
case nir_op_i2f64:
1631
return DXIL_CAST_SITOFP;
1632
1633
/* uint -> float */
1634
case nir_op_u2f16:
1635
case nir_op_u2f32:
1636
case nir_op_u2f64:
1637
return DXIL_CAST_UITOFP;
1638
1639
default:
1640
unreachable("unexpected cast op");
1641
}
1642
}
1643
1644
static const struct dxil_type *
1645
get_cast_dest_type(struct ntd_context *ctx, nir_alu_instr *alu)
1646
{
1647
unsigned dst_bits = nir_dest_bit_size(alu->dest.dest);
1648
switch (nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type)) {
1649
case nir_type_bool:
1650
assert(dst_bits == 1);
1651
FALLTHROUGH;
1652
case nir_type_int:
1653
case nir_type_uint:
1654
return dxil_module_get_int_type(&ctx->mod, dst_bits);
1655
1656
case nir_type_float:
1657
return dxil_module_get_float_type(&ctx->mod, dst_bits);
1658
1659
default:
1660
unreachable("unknown nir_alu_type");
1661
}
1662
}
1663
1664
static bool
1665
is_double(nir_alu_type alu_type, unsigned bit_size)
1666
{
1667
return nir_alu_type_get_base_type(alu_type) == nir_type_float &&
1668
bit_size == 64;
1669
}
1670
1671
static bool
1672
emit_cast(struct ntd_context *ctx, nir_alu_instr *alu,
1673
const struct dxil_value *value)
1674
{
1675
enum dxil_cast_opcode opcode = get_cast_op(alu);
1676
const struct dxil_type *type = get_cast_dest_type(ctx, alu);
1677
if (!type)
1678
return false;
1679
1680
const nir_op_info *info = &nir_op_infos[alu->op];
1681
switch (opcode) {
1682
case DXIL_CAST_UITOFP:
1683
case DXIL_CAST_SITOFP:
1684
if (is_double(info->output_type, nir_dest_bit_size(alu->dest.dest)))
1685
ctx->mod.feats.dx11_1_double_extensions = true;
1686
break;
1687
case DXIL_CAST_FPTOUI:
1688
case DXIL_CAST_FPTOSI:
1689
if (is_double(info->input_types[0], nir_src_bit_size(alu->src[0].src)))
1690
ctx->mod.feats.dx11_1_double_extensions = true;
1691
break;
1692
default:
1693
break;
1694
}
1695
1696
const struct dxil_value *v = dxil_emit_cast(&ctx->mod, opcode, type,
1697
value);
1698
if (!v)
1699
return false;
1700
store_alu_dest(ctx, alu, 0, v);
1701
return true;
1702
}
1703
1704
static enum overload_type
1705
get_overload(nir_alu_type alu_type, unsigned bit_size)
1706
{
1707
switch (nir_alu_type_get_base_type(alu_type)) {
1708
case nir_type_int:
1709
case nir_type_uint:
1710
switch (bit_size) {
1711
case 16: return DXIL_I16;
1712
case 32: return DXIL_I32;
1713
case 64: return DXIL_I64;
1714
default:
1715
unreachable("unexpected bit_size");
1716
}
1717
case nir_type_float:
1718
switch (bit_size) {
1719
case 16: return DXIL_F16;
1720
case 32: return DXIL_F32;
1721
case 64: return DXIL_F64;
1722
default:
1723
unreachable("unexpected bit_size");
1724
}
1725
default:
1726
unreachable("unexpected output type");
1727
}
1728
}
1729
1730
static bool
1731
emit_unary_intin(struct ntd_context *ctx, nir_alu_instr *alu,
1732
enum dxil_intr intr, const struct dxil_value *op)
1733
{
1734
const nir_op_info *info = &nir_op_infos[alu->op];
1735
unsigned src_bits = nir_src_bit_size(alu->src[0].src);
1736
enum overload_type overload = get_overload(info->input_types[0], src_bits);
1737
1738
const struct dxil_value *v = emit_unary_call(ctx, overload, intr, op);
1739
if (!v)
1740
return false;
1741
store_alu_dest(ctx, alu, 0, v);
1742
return true;
1743
}
1744
1745
static bool
1746
emit_binary_intin(struct ntd_context *ctx, nir_alu_instr *alu,
1747
enum dxil_intr intr,
1748
const struct dxil_value *op0, const struct dxil_value *op1)
1749
{
1750
const nir_op_info *info = &nir_op_infos[alu->op];
1751
assert(info->output_type == info->input_types[0]);
1752
assert(info->output_type == info->input_types[1]);
1753
unsigned dst_bits = nir_dest_bit_size(alu->dest.dest);
1754
assert(nir_src_bit_size(alu->src[0].src) == dst_bits);
1755
assert(nir_src_bit_size(alu->src[1].src) == dst_bits);
1756
enum overload_type overload = get_overload(info->output_type, dst_bits);
1757
1758
const struct dxil_value *v = emit_binary_call(ctx, overload, intr,
1759
op0, op1);
1760
if (!v)
1761
return false;
1762
store_alu_dest(ctx, alu, 0, v);
1763
return true;
1764
}
1765
1766
static bool
1767
emit_tertiary_intin(struct ntd_context *ctx, nir_alu_instr *alu,
1768
enum dxil_intr intr,
1769
const struct dxil_value *op0,
1770
const struct dxil_value *op1,
1771
const struct dxil_value *op2)
1772
{
1773
const nir_op_info *info = &nir_op_infos[alu->op];
1774
assert(info->output_type == info->input_types[0]);
1775
assert(info->output_type == info->input_types[1]);
1776
assert(info->output_type == info->input_types[2]);
1777
1778
unsigned dst_bits = nir_dest_bit_size(alu->dest.dest);
1779
assert(nir_src_bit_size(alu->src[0].src) == dst_bits);
1780
assert(nir_src_bit_size(alu->src[1].src) == dst_bits);
1781
assert(nir_src_bit_size(alu->src[2].src) == dst_bits);
1782
1783
enum overload_type overload = get_overload(info->output_type, dst_bits);
1784
1785
const struct dxil_value *v = emit_tertiary_call(ctx, overload, intr,
1786
op0, op1, op2);
1787
if (!v)
1788
return false;
1789
store_alu_dest(ctx, alu, 0, v);
1790
return true;
1791
}
1792
1793
static bool emit_select(struct ntd_context *ctx, nir_alu_instr *alu,
1794
const struct dxil_value *sel,
1795
const struct dxil_value *val_true,
1796
const struct dxil_value *val_false)
1797
{
1798
assert(sel);
1799
assert(val_true);
1800
assert(val_false);
1801
1802
const struct dxil_value *v = dxil_emit_select(&ctx->mod, sel, val_true, val_false);
1803
if (!v)
1804
return false;
1805
1806
store_alu_dest(ctx, alu, 0, v);
1807
return true;
1808
}
1809
1810
static bool
1811
emit_b2f16(struct ntd_context *ctx, nir_alu_instr *alu, const struct dxil_value *val)
1812
{
1813
assert(val);
1814
1815
struct dxil_module *m = &ctx->mod;
1816
1817
const struct dxil_value *c1 = dxil_module_get_float16_const(m, 0x3C00);
1818
const struct dxil_value *c0 = dxil_module_get_float16_const(m, 0);
1819
1820
if (!c0 || !c1)
1821
return false;
1822
1823
return emit_select(ctx, alu, val, c1, c0);
1824
}
1825
1826
static bool
1827
emit_b2f32(struct ntd_context *ctx, nir_alu_instr *alu, const struct dxil_value *val)
1828
{
1829
assert(val);
1830
1831
struct dxil_module *m = &ctx->mod;
1832
1833
const struct dxil_value *c1 = dxil_module_get_float_const(m, 1.0f);
1834
const struct dxil_value *c0 = dxil_module_get_float_const(m, 0.0f);
1835
1836
if (!c0 || !c1)
1837
return false;
1838
1839
return emit_select(ctx, alu, val, c1, c0);
1840
}
1841
1842
static bool
1843
emit_f2b32(struct ntd_context *ctx, nir_alu_instr *alu, const struct dxil_value *val)
1844
{
1845
assert(val);
1846
1847
const struct dxil_value *zero = dxil_module_get_float_const(&ctx->mod, 0.0f);
1848
return emit_cmp(ctx, alu, DXIL_FCMP_UNE, val, zero);
1849
}
1850
1851
static bool
1852
emit_ufind_msb(struct ntd_context *ctx, nir_alu_instr *alu,
1853
const struct dxil_value *val)
1854
{
1855
const nir_op_info *info = &nir_op_infos[alu->op];
1856
unsigned dst_bits = nir_dest_bit_size(alu->dest.dest);
1857
unsigned src_bits = nir_src_bit_size(alu->src[0].src);
1858
enum overload_type overload = get_overload(info->output_type, src_bits);
1859
1860
const struct dxil_value *v = emit_unary_call(ctx, overload,
1861
DXIL_INTR_FIRSTBIT_HI, val);
1862
if (!v)
1863
return false;
1864
1865
const struct dxil_value *size = dxil_module_get_int32_const(&ctx->mod,
1866
src_bits - 1);
1867
const struct dxil_value *zero = dxil_module_get_int_const(&ctx->mod, 0,
1868
src_bits);
1869
if (!size || !zero)
1870
return false;
1871
1872
v = dxil_emit_binop(&ctx->mod, DXIL_BINOP_SUB, size, v, 0);
1873
const struct dxil_value *cnd = dxil_emit_cmp(&ctx->mod, DXIL_ICMP_NE,
1874
val, zero);
1875
if (!v || !cnd)
1876
return false;
1877
1878
const struct dxil_value *minus_one =
1879
dxil_module_get_int_const(&ctx->mod, -1, dst_bits);
1880
if (!minus_one)
1881
return false;
1882
1883
v = dxil_emit_select(&ctx->mod, cnd, v, minus_one);
1884
if (!v)
1885
return false;
1886
1887
store_alu_dest(ctx, alu, 0, v);
1888
return true;
1889
}
1890
1891
static bool
1892
emit_f16tof32(struct ntd_context *ctx, nir_alu_instr *alu, const struct dxil_value *val)
1893
{
1894
const struct dxil_func *func = dxil_get_function(&ctx->mod,
1895
"dx.op.legacyF16ToF32",
1896
DXIL_NONE);
1897
if (!func)
1898
return false;
1899
1900
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LEGACY_F16TOF32);
1901
if (!opcode)
1902
return false;
1903
1904
const struct dxil_value *args[] = {
1905
opcode,
1906
val
1907
};
1908
1909
const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
1910
if (!v)
1911
return false;
1912
store_alu_dest(ctx, alu, 0, v);
1913
return true;
1914
}
1915
1916
static bool
1917
emit_f32tof16(struct ntd_context *ctx, nir_alu_instr *alu, const struct dxil_value *val)
1918
{
1919
const struct dxil_func *func = dxil_get_function(&ctx->mod,
1920
"dx.op.legacyF32ToF16",
1921
DXIL_NONE);
1922
if (!func)
1923
return false;
1924
1925
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LEGACY_F32TOF16);
1926
if (!opcode)
1927
return false;
1928
1929
const struct dxil_value *args[] = {
1930
opcode,
1931
val
1932
};
1933
1934
const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
1935
if (!v)
1936
return false;
1937
store_alu_dest(ctx, alu, 0, v);
1938
return true;
1939
}
1940
1941
static bool
1942
emit_vec(struct ntd_context *ctx, nir_alu_instr *alu, unsigned num_inputs)
1943
{
1944
const struct dxil_type *type = get_alu_src_type(ctx, alu, 0);
1945
nir_alu_type t = dxil_type_to_nir_type(type);
1946
1947
for (unsigned i = 0; i < num_inputs; i++)
1948
store_alu_dest(ctx, alu, i, get_src(ctx, &alu->src[i].src,
1949
alu->src[i].swizzle[0], t));
1950
return true;
1951
}
1952
1953
static bool
1954
emit_make_double(struct ntd_context *ctx, nir_alu_instr *alu)
1955
{
1956
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.makeDouble", DXIL_F64);
1957
if (!func)
1958
return false;
1959
1960
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_MAKE_DOUBLE);
1961
if (!opcode)
1962
return false;
1963
1964
const struct dxil_value *args[3] = {
1965
opcode,
1966
get_src(ctx, &alu->src[0].src, 0, nir_type_uint32),
1967
get_src(ctx, &alu->src[0].src, 1, nir_type_uint32),
1968
};
1969
if (!args[1] || !args[2])
1970
return false;
1971
1972
const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
1973
if (!v)
1974
return false;
1975
store_dest(ctx, &alu->dest.dest, 0, v, nir_type_float64);
1976
return true;
1977
}
1978
1979
static bool
1980
emit_split_double(struct ntd_context *ctx, nir_alu_instr *alu)
1981
{
1982
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.splitDouble", DXIL_F64);
1983
if (!func)
1984
return false;
1985
1986
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SPLIT_DOUBLE);
1987
if (!opcode)
1988
return false;
1989
1990
const struct dxil_value *args[] = {
1991
opcode,
1992
get_src(ctx, &alu->src[0].src, 0, nir_type_float64)
1993
};
1994
if (!args[1])
1995
return false;
1996
1997
const struct dxil_value *v = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
1998
if (!v)
1999
return false;
2000
2001
const struct dxil_value *hi = dxil_emit_extractval(&ctx->mod, v, 0);
2002
const struct dxil_value *lo = dxil_emit_extractval(&ctx->mod, v, 1);
2003
if (!hi || !lo)
2004
return false;
2005
2006
store_dest_value(ctx, &alu->dest.dest, 0, hi);
2007
store_dest_value(ctx, &alu->dest.dest, 1, lo);
2008
return true;
2009
}
2010
2011
static bool
2012
emit_alu(struct ntd_context *ctx, nir_alu_instr *alu)
2013
{
2014
/* handle vec-instructions first; they are the only ones that produce
2015
* vector results.
2016
*/
2017
switch (alu->op) {
2018
case nir_op_vec2:
2019
case nir_op_vec3:
2020
case nir_op_vec4:
2021
case nir_op_vec8:
2022
case nir_op_vec16:
2023
return emit_vec(ctx, alu, nir_op_infos[alu->op].num_inputs);
2024
case nir_op_mov: {
2025
assert(nir_dest_num_components(alu->dest.dest) == 1);
2026
store_ssa_def(ctx, &alu->dest.dest.ssa, 0, get_src_ssa(ctx,
2027
alu->src->src.ssa, alu->src->swizzle[0]));
2028
return true;
2029
}
2030
case nir_op_pack_double_2x32_dxil:
2031
return emit_make_double(ctx, alu);
2032
case nir_op_unpack_double_2x32_dxil:
2033
return emit_split_double(ctx, alu);
2034
default:
2035
/* silence warnings */
2036
;
2037
}
2038
2039
/* other ops should be scalar */
2040
assert(alu->dest.write_mask == 1);
2041
const struct dxil_value *src[4];
2042
assert(nir_op_infos[alu->op].num_inputs <= 4);
2043
for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
2044
src[i] = get_alu_src(ctx, alu, i);
2045
2046
switch (alu->op) {
2047
case nir_op_iadd:
2048
case nir_op_fadd: return emit_binop(ctx, alu, DXIL_BINOP_ADD, src[0], src[1]);
2049
2050
case nir_op_isub:
2051
case nir_op_fsub: return emit_binop(ctx, alu, DXIL_BINOP_SUB, src[0], src[1]);
2052
2053
case nir_op_imul:
2054
case nir_op_fmul: return emit_binop(ctx, alu, DXIL_BINOP_MUL, src[0], src[1]);
2055
2056
case nir_op_idiv:
2057
case nir_op_fdiv: return emit_binop(ctx, alu, DXIL_BINOP_SDIV, src[0], src[1]);
2058
2059
case nir_op_udiv: return emit_binop(ctx, alu, DXIL_BINOP_UDIV, src[0], src[1]);
2060
case nir_op_irem: return emit_binop(ctx, alu, DXIL_BINOP_SREM, src[0], src[1]);
2061
case nir_op_imod: return emit_binop(ctx, alu, DXIL_BINOP_UREM, src[0], src[1]);
2062
case nir_op_umod: return emit_binop(ctx, alu, DXIL_BINOP_UREM, src[0], src[1]);
2063
case nir_op_ishl: return emit_shift(ctx, alu, DXIL_BINOP_SHL, src[0], src[1]);
2064
case nir_op_ishr: return emit_shift(ctx, alu, DXIL_BINOP_ASHR, src[0], src[1]);
2065
case nir_op_ushr: return emit_shift(ctx, alu, DXIL_BINOP_LSHR, src[0], src[1]);
2066
case nir_op_iand: return emit_binop(ctx, alu, DXIL_BINOP_AND, src[0], src[1]);
2067
case nir_op_ior: return emit_binop(ctx, alu, DXIL_BINOP_OR, src[0], src[1]);
2068
case nir_op_ixor: return emit_binop(ctx, alu, DXIL_BINOP_XOR, src[0], src[1]);
2069
case nir_op_ieq: return emit_cmp(ctx, alu, DXIL_ICMP_EQ, src[0], src[1]);
2070
case nir_op_ine: return emit_cmp(ctx, alu, DXIL_ICMP_NE, src[0], src[1]);
2071
case nir_op_ige: return emit_cmp(ctx, alu, DXIL_ICMP_SGE, src[0], src[1]);
2072
case nir_op_uge: return emit_cmp(ctx, alu, DXIL_ICMP_UGE, src[0], src[1]);
2073
case nir_op_ilt: return emit_cmp(ctx, alu, DXIL_ICMP_SLT, src[0], src[1]);
2074
case nir_op_ult: return emit_cmp(ctx, alu, DXIL_ICMP_ULT, src[0], src[1]);
2075
case nir_op_feq: return emit_cmp(ctx, alu, DXIL_FCMP_OEQ, src[0], src[1]);
2076
case nir_op_fneu: return emit_cmp(ctx, alu, DXIL_FCMP_UNE, src[0], src[1]);
2077
case nir_op_flt: return emit_cmp(ctx, alu, DXIL_FCMP_OLT, src[0], src[1]);
2078
case nir_op_fge: return emit_cmp(ctx, alu, DXIL_FCMP_OGE, src[0], src[1]);
2079
case nir_op_bcsel: return emit_select(ctx, alu, src[0], src[1], src[2]);
2080
case nir_op_ftrunc: return emit_unary_intin(ctx, alu, DXIL_INTR_ROUND_Z, src[0]);
2081
case nir_op_fabs: return emit_unary_intin(ctx, alu, DXIL_INTR_FABS, src[0]);
2082
case nir_op_fcos: return emit_unary_intin(ctx, alu, DXIL_INTR_FCOS, src[0]);
2083
case nir_op_fsin: return emit_unary_intin(ctx, alu, DXIL_INTR_FSIN, src[0]);
2084
case nir_op_fceil: return emit_unary_intin(ctx, alu, DXIL_INTR_ROUND_PI, src[0]);
2085
case nir_op_fexp2: return emit_unary_intin(ctx, alu, DXIL_INTR_FEXP2, src[0]);
2086
case nir_op_flog2: return emit_unary_intin(ctx, alu, DXIL_INTR_FLOG2, src[0]);
2087
case nir_op_ffloor: return emit_unary_intin(ctx, alu, DXIL_INTR_ROUND_NI, src[0]);
2088
case nir_op_ffract: return emit_unary_intin(ctx, alu, DXIL_INTR_FRC, src[0]);
2089
case nir_op_fisnormal: return emit_unary_intin(ctx, alu, DXIL_INTR_ISNORMAL, src[0]);
2090
case nir_op_fisfinite: return emit_unary_intin(ctx, alu, DXIL_INTR_ISFINITE, src[0]);
2091
2092
case nir_op_fddx:
2093
case nir_op_fddx_coarse: return emit_unary_intin(ctx, alu, DXIL_INTR_DDX_COARSE, src[0]);
2094
case nir_op_fddx_fine: return emit_unary_intin(ctx, alu, DXIL_INTR_DDX_FINE, src[0]);
2095
case nir_op_fddy:
2096
case nir_op_fddy_coarse: return emit_unary_intin(ctx, alu, DXIL_INTR_DDY_COARSE, src[0]);
2097
case nir_op_fddy_fine: return emit_unary_intin(ctx, alu, DXIL_INTR_DDY_FINE, src[0]);
2098
2099
case nir_op_fround_even: return emit_unary_intin(ctx, alu, DXIL_INTR_ROUND_NE, src[0]);
2100
case nir_op_frcp: {
2101
const struct dxil_value *one = dxil_module_get_float_const(&ctx->mod, 1.0f);
2102
return emit_binop(ctx, alu, DXIL_BINOP_SDIV, one, src[0]);
2103
}
2104
case nir_op_fsat: return emit_unary_intin(ctx, alu, DXIL_INTR_SATURATE, src[0]);
2105
case nir_op_bit_count: return emit_unary_intin(ctx, alu, DXIL_INTR_COUNTBITS, src[0]);
2106
case nir_op_ufind_msb: return emit_ufind_msb(ctx, alu, src[0]);
2107
case nir_op_imax: return emit_binary_intin(ctx, alu, DXIL_INTR_IMAX, src[0], src[1]);
2108
case nir_op_imin: return emit_binary_intin(ctx, alu, DXIL_INTR_IMIN, src[0], src[1]);
2109
case nir_op_umax: return emit_binary_intin(ctx, alu, DXIL_INTR_UMAX, src[0], src[1]);
2110
case nir_op_umin: return emit_binary_intin(ctx, alu, DXIL_INTR_UMIN, src[0], src[1]);
2111
case nir_op_frsq: return emit_unary_intin(ctx, alu, DXIL_INTR_RSQRT, src[0]);
2112
case nir_op_fsqrt: return emit_unary_intin(ctx, alu, DXIL_INTR_SQRT, src[0]);
2113
case nir_op_fmax: return emit_binary_intin(ctx, alu, DXIL_INTR_FMAX, src[0], src[1]);
2114
case nir_op_fmin: return emit_binary_intin(ctx, alu, DXIL_INTR_FMIN, src[0], src[1]);
2115
case nir_op_ffma: return emit_tertiary_intin(ctx, alu, DXIL_INTR_FMA, src[0], src[1], src[2]);
2116
2117
case nir_op_unpack_half_2x16_split_x: return emit_f16tof32(ctx, alu, src[0]);
2118
case nir_op_pack_half_2x16_split: return emit_f32tof16(ctx, alu, src[0]);
2119
2120
case nir_op_b2i16:
2121
case nir_op_i2i16:
2122
case nir_op_f2i16:
2123
case nir_op_f2u16:
2124
case nir_op_u2u16:
2125
case nir_op_u2f16:
2126
case nir_op_i2f16:
2127
case nir_op_f2f16_rtz:
2128
case nir_op_b2i32:
2129
case nir_op_f2f32:
2130
case nir_op_f2i32:
2131
case nir_op_f2u32:
2132
case nir_op_i2f32:
2133
case nir_op_i2i32:
2134
case nir_op_u2f32:
2135
case nir_op_u2u32:
2136
case nir_op_b2i64:
2137
case nir_op_f2f64:
2138
case nir_op_f2i64:
2139
case nir_op_f2u64:
2140
case nir_op_i2f64:
2141
case nir_op_i2i64:
2142
case nir_op_u2f64:
2143
case nir_op_u2u64:
2144
return emit_cast(ctx, alu, src[0]);
2145
2146
case nir_op_f2b32: return emit_f2b32(ctx, alu, src[0]);
2147
case nir_op_b2f16: return emit_b2f16(ctx, alu, src[0]);
2148
case nir_op_b2f32: return emit_b2f32(ctx, alu, src[0]);
2149
default:
2150
NIR_INSTR_UNSUPPORTED(&alu->instr);
2151
assert("Unimplemented ALU instruction");
2152
return false;
2153
}
2154
}
2155
2156
static const struct dxil_value *
2157
load_ubo(struct ntd_context *ctx, const struct dxil_value *handle,
2158
const struct dxil_value *offset, enum overload_type overload)
2159
{
2160
assert(handle && offset);
2161
2162
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_CBUFFER_LOAD_LEGACY);
2163
if (!opcode)
2164
return NULL;
2165
2166
const struct dxil_value *args[] = {
2167
opcode, handle, offset
2168
};
2169
2170
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.cbufferLoadLegacy", overload);
2171
if (!func)
2172
return NULL;
2173
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2174
}
2175
2176
static bool
2177
emit_barrier(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2178
{
2179
const struct dxil_value *opcode, *mode;
2180
const struct dxil_func *func;
2181
uint32_t flags = 0;
2182
2183
if (nir_intrinsic_execution_scope(intr) == NIR_SCOPE_WORKGROUP)
2184
flags |= DXIL_BARRIER_MODE_SYNC_THREAD_GROUP;
2185
2186
nir_variable_mode modes = nir_intrinsic_memory_modes(intr);
2187
nir_scope mem_scope = nir_intrinsic_memory_scope(intr);
2188
2189
/* Currently vtn uses uniform to indicate image memory, which DXIL considers global */
2190
if (modes & nir_var_uniform)
2191
modes |= nir_var_mem_global;
2192
2193
if (modes & (nir_var_mem_ssbo | nir_var_mem_global)) {
2194
if (mem_scope > NIR_SCOPE_WORKGROUP)
2195
flags |= DXIL_BARRIER_MODE_UAV_FENCE_GLOBAL;
2196
else
2197
flags |= DXIL_BARRIER_MODE_UAV_FENCE_THREAD_GROUP;
2198
}
2199
2200
if (modes & nir_var_mem_shared)
2201
flags |= DXIL_BARRIER_MODE_GROUPSHARED_MEM_FENCE;
2202
2203
func = dxil_get_function(&ctx->mod, "dx.op.barrier", DXIL_NONE);
2204
if (!func)
2205
return false;
2206
2207
opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_BARRIER);
2208
if (!opcode)
2209
return false;
2210
2211
mode = dxil_module_get_int32_const(&ctx->mod, flags);
2212
if (!mode)
2213
return false;
2214
2215
const struct dxil_value *args[] = { opcode, mode };
2216
2217
return dxil_emit_call_void(&ctx->mod, func,
2218
args, ARRAY_SIZE(args));
2219
}
2220
2221
static bool
2222
emit_load_global_invocation_id(struct ntd_context *ctx,
2223
nir_intrinsic_instr *intr)
2224
{
2225
assert(intr->dest.is_ssa);
2226
nir_component_mask_t comps = nir_ssa_def_components_read(&intr->dest.ssa);
2227
2228
for (int i = 0; i < nir_intrinsic_dest_components(intr); i++) {
2229
if (comps & (1 << i)) {
2230
const struct dxil_value *idx = dxil_module_get_int32_const(&ctx->mod, i);
2231
if (!idx)
2232
return false;
2233
const struct dxil_value *globalid = emit_threadid_call(ctx, idx);
2234
2235
if (!globalid)
2236
return false;
2237
2238
store_dest_value(ctx, &intr->dest, i, globalid);
2239
}
2240
}
2241
return true;
2242
}
2243
2244
static bool
2245
emit_load_local_invocation_id(struct ntd_context *ctx,
2246
nir_intrinsic_instr *intr)
2247
{
2248
assert(intr->dest.is_ssa);
2249
nir_component_mask_t comps = nir_ssa_def_components_read(&intr->dest.ssa);
2250
2251
for (int i = 0; i < nir_intrinsic_dest_components(intr); i++) {
2252
if (comps & (1 << i)) {
2253
const struct dxil_value
2254
*idx = dxil_module_get_int32_const(&ctx->mod, i);
2255
if (!idx)
2256
return false;
2257
const struct dxil_value
2258
*threadidingroup = emit_threadidingroup_call(ctx, idx);
2259
if (!threadidingroup)
2260
return false;
2261
store_dest_value(ctx, &intr->dest, i, threadidingroup);
2262
}
2263
}
2264
return true;
2265
}
2266
2267
static bool
2268
emit_load_local_workgroup_id(struct ntd_context *ctx,
2269
nir_intrinsic_instr *intr)
2270
{
2271
assert(intr->dest.is_ssa);
2272
nir_component_mask_t comps = nir_ssa_def_components_read(&intr->dest.ssa);
2273
2274
for (int i = 0; i < nir_intrinsic_dest_components(intr); i++) {
2275
if (comps & (1 << i)) {
2276
const struct dxil_value *idx = dxil_module_get_int32_const(&ctx->mod, i);
2277
if (!idx)
2278
return false;
2279
const struct dxil_value *groupid = emit_groupid_call(ctx, idx);
2280
if (!groupid)
2281
return false;
2282
store_dest_value(ctx, &intr->dest, i, groupid);
2283
}
2284
}
2285
return true;
2286
}
2287
2288
static bool
2289
emit_load_primitiveid(struct ntd_context *ctx,
2290
nir_intrinsic_instr *intr)
2291
{
2292
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.primitiveID", DXIL_I32);
2293
if (!func)
2294
return false;
2295
2296
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
2297
DXIL_INTR_PRIMITIVE_ID);
2298
if (!opcode)
2299
return false;
2300
2301
const struct dxil_value *args[] = {
2302
opcode
2303
};
2304
2305
const struct dxil_value *primid = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2306
store_dest_value(ctx, &intr->dest, 0, primid);
2307
2308
return true;
2309
}
2310
2311
static const struct dxil_value *
2312
get_int32_undef(struct dxil_module *m)
2313
{
2314
const struct dxil_type *int32_type =
2315
dxil_module_get_int_type(m, 32);
2316
if (!int32_type)
2317
return NULL;
2318
2319
return dxil_module_get_undef(m, int32_type);
2320
}
2321
2322
static const struct dxil_value *
2323
emit_gep_for_index(struct ntd_context *ctx, const nir_variable *var,
2324
const struct dxil_value *index)
2325
{
2326
assert(var->data.mode == nir_var_shader_temp);
2327
2328
struct hash_entry *he = _mesa_hash_table_search(ctx->consts, var);
2329
assert(he != NULL);
2330
const struct dxil_value *ptr = he->data;
2331
2332
const struct dxil_value *zero = dxil_module_get_int32_const(&ctx->mod, 0);
2333
if (!zero)
2334
return NULL;
2335
2336
const struct dxil_value *ops[] = { ptr, zero, index };
2337
return dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
2338
}
2339
2340
static const struct dxil_value *
2341
get_ubo_ssbo_handle(struct ntd_context *ctx, nir_src *src, enum dxil_resource_class class, unsigned base_binding)
2342
{
2343
/* This source might be one of:
2344
* 1. Constant resource index - just look it up in precomputed handle arrays
2345
* If it's null in that array, create a handle, and store the result
2346
* 2. A handle from load_vulkan_descriptor - just get the stored SSA value
2347
* 3. Dynamic resource index - create a handle for it here
2348
*/
2349
assert(src->ssa->num_components == 1 && src->ssa->bit_size == 32);
2350
nir_const_value *const_block_index = nir_src_as_const_value(*src);
2351
const struct dxil_value **handle_entry = NULL;
2352
if (const_block_index) {
2353
assert(!ctx->opts->vulkan_environment);
2354
switch (class) {
2355
case DXIL_RESOURCE_CLASS_CBV:
2356
handle_entry = &ctx->cbv_handles[const_block_index->u32];
2357
break;
2358
case DXIL_RESOURCE_CLASS_UAV:
2359
handle_entry = &ctx->uav_handles[const_block_index->u32];
2360
break;
2361
case DXIL_RESOURCE_CLASS_SRV:
2362
handle_entry = &ctx->srv_handles[const_block_index->u32];
2363
break;
2364
default:
2365
unreachable("Unexpected resource class");
2366
}
2367
}
2368
2369
if (handle_entry && *handle_entry)
2370
return *handle_entry;
2371
2372
const struct dxil_value *value = get_src_ssa(ctx, src->ssa, 0);
2373
if (ctx->opts->vulkan_environment) {
2374
return value;
2375
}
2376
2377
const struct dxil_value *handle = emit_createhandle_call(ctx, class,
2378
get_resource_id(ctx, class, 0, base_binding), value, !const_block_index);
2379
if (handle_entry)
2380
*handle_entry = handle;
2381
2382
return handle;
2383
}
2384
2385
static bool
2386
emit_load_ssbo(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2387
{
2388
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
2389
2390
nir_variable *var = nir_get_binding_variable(ctx->shader, nir_chase_binding(intr->src[0]));
2391
enum dxil_resource_class class = DXIL_RESOURCE_CLASS_UAV;
2392
if (var && var->data.access & ACCESS_NON_WRITEABLE)
2393
class = DXIL_RESOURCE_CLASS_SRV;
2394
2395
const struct dxil_value *handle = get_ubo_ssbo_handle(ctx, &intr->src[0], class, 0);
2396
const struct dxil_value *offset =
2397
get_src(ctx, &intr->src[1], 0, nir_type_uint);
2398
if (!int32_undef || !handle || !offset)
2399
return false;
2400
2401
assert(nir_src_bit_size(intr->src[0]) == 32);
2402
assert(nir_intrinsic_dest_components(intr) <= 4);
2403
2404
const struct dxil_value *coord[2] = {
2405
offset,
2406
int32_undef
2407
};
2408
2409
const struct dxil_value *load = emit_bufferload_call(ctx, handle, coord);
2410
if (!load)
2411
return false;
2412
2413
for (int i = 0; i < nir_intrinsic_dest_components(intr); i++) {
2414
const struct dxil_value *val =
2415
dxil_emit_extractval(&ctx->mod, load, i);
2416
if (!val)
2417
return false;
2418
store_dest_value(ctx, &intr->dest, i, val);
2419
}
2420
return true;
2421
}
2422
2423
static bool
2424
emit_store_ssbo(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2425
{
2426
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[1], DXIL_RESOURCE_CLASS_UAV, 0);
2427
const struct dxil_value *offset =
2428
get_src(ctx, &intr->src[2], 0, nir_type_uint);
2429
if (!handle || !offset)
2430
return false;
2431
2432
assert(nir_src_bit_size(intr->src[0]) == 32);
2433
unsigned num_components = nir_src_num_components(intr->src[0]);
2434
assert(num_components <= 4);
2435
const struct dxil_value *value[4];
2436
for (unsigned i = 0; i < num_components; ++i) {
2437
value[i] = get_src(ctx, &intr->src[0], i, nir_type_uint);
2438
if (!value[i])
2439
return false;
2440
}
2441
2442
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
2443
if (!int32_undef)
2444
return false;
2445
2446
const struct dxil_value *coord[2] = {
2447
offset,
2448
int32_undef
2449
};
2450
2451
for (int i = num_components; i < 4; ++i)
2452
value[i] = int32_undef;
2453
2454
const struct dxil_value *write_mask =
2455
dxil_module_get_int8_const(&ctx->mod, (1u << num_components) - 1);
2456
if (!write_mask)
2457
return false;
2458
2459
return emit_bufferstore_call(ctx, handle, coord, value, write_mask, DXIL_I32);
2460
}
2461
2462
static bool
2463
emit_store_ssbo_masked(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2464
{
2465
const struct dxil_value *value =
2466
get_src(ctx, &intr->src[0], 0, nir_type_uint);
2467
const struct dxil_value *mask =
2468
get_src(ctx, &intr->src[1], 0, nir_type_uint);
2469
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[2], DXIL_RESOURCE_CLASS_UAV, 0);
2470
const struct dxil_value *offset =
2471
get_src(ctx, &intr->src[3], 0, nir_type_uint);
2472
if (!value || !mask || !handle || !offset)
2473
return false;
2474
2475
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
2476
if (!int32_undef)
2477
return false;
2478
2479
const struct dxil_value *coord[3] = {
2480
offset, int32_undef, int32_undef
2481
};
2482
2483
return
2484
emit_atomic_binop(ctx, handle, DXIL_ATOMIC_AND, coord, mask) != NULL &&
2485
emit_atomic_binop(ctx, handle, DXIL_ATOMIC_OR, coord, value) != NULL;
2486
}
2487
2488
static bool
2489
emit_store_shared(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2490
{
2491
const struct dxil_value *zero, *index;
2492
2493
/* All shared mem accesses should have been lowered to scalar 32bit
2494
* accesses.
2495
*/
2496
assert(nir_src_bit_size(intr->src[0]) == 32);
2497
assert(nir_src_num_components(intr->src[0]) == 1);
2498
2499
zero = dxil_module_get_int32_const(&ctx->mod, 0);
2500
if (!zero)
2501
return false;
2502
2503
if (intr->intrinsic == nir_intrinsic_store_shared_dxil)
2504
index = get_src(ctx, &intr->src[1], 0, nir_type_uint);
2505
else
2506
index = get_src(ctx, &intr->src[2], 0, nir_type_uint);
2507
if (!index)
2508
return false;
2509
2510
const struct dxil_value *ops[] = { ctx->sharedvars, zero, index };
2511
const struct dxil_value *ptr, *value;
2512
2513
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
2514
if (!ptr)
2515
return false;
2516
2517
value = get_src(ctx, &intr->src[0], 0, nir_type_uint);
2518
2519
if (intr->intrinsic == nir_intrinsic_store_shared_dxil)
2520
return dxil_emit_store(&ctx->mod, value, ptr, 4, false);
2521
2522
const struct dxil_value *mask = get_src(ctx, &intr->src[1], 0, nir_type_uint);
2523
2524
if (!dxil_emit_atomicrmw(&ctx->mod, mask, ptr, DXIL_RMWOP_AND, false,
2525
DXIL_ATOMIC_ORDERING_ACQREL,
2526
DXIL_SYNC_SCOPE_CROSSTHREAD))
2527
return false;
2528
2529
if (!dxil_emit_atomicrmw(&ctx->mod, value, ptr, DXIL_RMWOP_OR, false,
2530
DXIL_ATOMIC_ORDERING_ACQREL,
2531
DXIL_SYNC_SCOPE_CROSSTHREAD))
2532
return false;
2533
2534
return true;
2535
}
2536
2537
static bool
2538
emit_store_scratch(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2539
{
2540
const struct dxil_value *zero, *index;
2541
2542
/* All scratch mem accesses should have been lowered to scalar 32bit
2543
* accesses.
2544
*/
2545
assert(nir_src_bit_size(intr->src[0]) == 32);
2546
assert(nir_src_num_components(intr->src[0]) == 1);
2547
2548
zero = dxil_module_get_int32_const(&ctx->mod, 0);
2549
if (!zero)
2550
return false;
2551
2552
index = get_src(ctx, &intr->src[1], 0, nir_type_uint);
2553
if (!index)
2554
return false;
2555
2556
const struct dxil_value *ops[] = { ctx->scratchvars, zero, index };
2557
const struct dxil_value *ptr, *value;
2558
2559
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
2560
if (!ptr)
2561
return false;
2562
2563
value = get_src(ctx, &intr->src[0], 0, nir_type_uint);
2564
return dxil_emit_store(&ctx->mod, value, ptr, 4, false);
2565
}
2566
2567
static bool
2568
emit_load_ubo(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2569
{
2570
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[0], DXIL_RESOURCE_CLASS_CBV, 0);
2571
if (!handle)
2572
return false;
2573
2574
const struct dxil_value *offset;
2575
nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]);
2576
if (const_offset) {
2577
offset = dxil_module_get_int32_const(&ctx->mod, const_offset->i32 >> 4);
2578
} else {
2579
const struct dxil_value *offset_src = get_src(ctx, &intr->src[1], 0, nir_type_uint);
2580
const struct dxil_value *c4 = dxil_module_get_int32_const(&ctx->mod, 4);
2581
offset = dxil_emit_binop(&ctx->mod, DXIL_BINOP_ASHR, offset_src, c4, 0);
2582
}
2583
2584
const struct dxil_value *agg = load_ubo(ctx, handle, offset, DXIL_F32);
2585
2586
if (!agg)
2587
return false;
2588
2589
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); ++i) {
2590
const struct dxil_value *retval = dxil_emit_extractval(&ctx->mod, agg, i);
2591
store_dest(ctx, &intr->dest, i, retval,
2592
nir_dest_bit_size(intr->dest) > 1 ? nir_type_float : nir_type_bool);
2593
}
2594
return true;
2595
}
2596
2597
static bool
2598
emit_load_ubo_dxil(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2599
{
2600
assert(nir_dest_num_components(intr->dest) <= 4);
2601
assert(nir_dest_bit_size(intr->dest) == 32);
2602
2603
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[0], DXIL_RESOURCE_CLASS_CBV, 0);
2604
const struct dxil_value *offset =
2605
get_src(ctx, &intr->src[1], 0, nir_type_uint);
2606
2607
if (!handle || !offset)
2608
return false;
2609
2610
const struct dxil_value *agg = load_ubo(ctx, handle, offset, DXIL_I32);
2611
if (!agg)
2612
return false;
2613
2614
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); i++)
2615
store_dest_value(ctx, &intr->dest, i,
2616
dxil_emit_extractval(&ctx->mod, agg, i));
2617
2618
return true;
2619
}
2620
2621
static bool
2622
emit_store_output(struct ntd_context *ctx, nir_intrinsic_instr *intr,
2623
nir_variable *output)
2624
{
2625
nir_alu_type out_type = nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(output->type));
2626
enum overload_type overload = DXIL_F32;
2627
if (output->data.compact)
2628
out_type = nir_type_float;
2629
else
2630
overload = get_overload(out_type, glsl_get_bit_size(output->type));
2631
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.storeOutput", overload);
2632
2633
if (!func)
2634
return false;
2635
2636
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_STORE_OUTPUT);
2637
const struct dxil_value *output_id = dxil_module_get_int32_const(&ctx->mod, (int)output->data.driver_location);
2638
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
2639
2640
bool success = true;
2641
if (output->data.compact) {
2642
nir_deref_instr *array_deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
2643
unsigned array_index = nir_src_as_uint(array_deref->arr.index);
2644
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, array_index);
2645
const struct dxil_value *value = get_src(ctx, &intr->src[1], 0, out_type);
2646
const struct dxil_value *args[] = {
2647
opcode, output_id, row, col, value
2648
};
2649
success = dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
2650
} else {
2651
uint32_t writemask = nir_intrinsic_write_mask(intr);
2652
for (unsigned i = 0; i < nir_src_num_components(intr->src[1]) && success; ++i) {
2653
if (writemask & (1 << i)) {
2654
const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, i);
2655
const struct dxil_value *value = get_src(ctx, &intr->src[1], i, out_type);
2656
const struct dxil_value *args[] = {
2657
opcode, output_id, row, col, value
2658
};
2659
success &= dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
2660
}
2661
}
2662
}
2663
return success;
2664
}
2665
2666
static bool
2667
emit_store_deref(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2668
{
2669
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
2670
nir_variable *var = nir_deref_instr_get_variable(deref);
2671
2672
switch (var->data.mode) {
2673
case nir_var_shader_out:
2674
return emit_store_output(ctx, intr, var);
2675
2676
default:
2677
unreachable("unsupported nir_variable_mode");
2678
}
2679
}
2680
2681
static bool
2682
emit_load_input_array(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var, nir_src *index)
2683
{
2684
assert(var);
2685
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LOAD_INPUT);
2686
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, var->data.driver_location);
2687
const struct dxil_value *vertex_id;
2688
const struct dxil_value *row;
2689
2690
if (ctx->mod.shader_kind == DXIL_GEOMETRY_SHADER) {
2691
vertex_id = get_src(ctx, index, 0, nir_type_int);
2692
row = dxil_module_get_int32_const(&ctx->mod, 0);
2693
} else {
2694
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
2695
vertex_id = dxil_module_get_undef(&ctx->mod, int32_type);
2696
row = get_src(ctx, index, 0, nir_type_int);
2697
}
2698
2699
nir_alu_type out_type = nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(glsl_get_array_element(var->type)));
2700
enum overload_type overload = get_overload(out_type, glsl_get_bit_size(glsl_get_array_element(var->type)));
2701
2702
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.loadInput", overload);
2703
2704
if (!func)
2705
return false;
2706
2707
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); ++i) {
2708
const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, i);
2709
2710
const struct dxil_value *args[] = {
2711
opcode, input_id, row, comp, vertex_id
2712
};
2713
2714
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2715
if (!retval)
2716
return false;
2717
store_dest(ctx, &intr->dest, i, retval, out_type);
2718
}
2719
return true;
2720
}
2721
2722
static bool
2723
emit_load_compact_input_array(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var, nir_deref_instr *deref)
2724
{
2725
assert(var);
2726
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LOAD_INPUT);
2727
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, var->data.driver_location);
2728
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
2729
const struct dxil_value *vertex_id;
2730
2731
nir_src *col = &deref->arr.index;
2732
nir_src_is_const(*col);
2733
2734
if (ctx->mod.shader_kind == DXIL_GEOMETRY_SHADER) {
2735
nir_deref_instr *deref_parent = nir_deref_instr_parent(deref);
2736
assert(deref_parent->deref_type == nir_deref_type_array);
2737
2738
vertex_id = get_src(ctx, &deref_parent->arr.index, 0, nir_type_int);
2739
} else {
2740
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
2741
vertex_id = dxil_module_get_undef(&ctx->mod, int32_type);
2742
}
2743
2744
nir_alu_type out_type = nir_type_float;
2745
enum overload_type overload = get_overload(out_type, 32);
2746
2747
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.loadInput", overload);
2748
2749
if (!func)
2750
return false;
2751
2752
const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, nir_src_as_int(*col));
2753
2754
const struct dxil_value *args[] = {
2755
opcode, input_id, row, comp, vertex_id
2756
};
2757
2758
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2759
if (!retval)
2760
return false;
2761
store_dest(ctx, &intr->dest, 0, retval, out_type);
2762
return true;
2763
}
2764
2765
static bool
2766
emit_load_input_interpolated(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var)
2767
{
2768
assert(var);
2769
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_LOAD_INPUT);
2770
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, var->data.driver_location);
2771
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
2772
const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
2773
const struct dxil_value *vertex_id = dxil_module_get_undef(&ctx->mod, int32_type);
2774
2775
nir_alu_type out_type = nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(var->type));
2776
enum overload_type overload = get_overload(out_type, glsl_get_bit_size(var->type));
2777
2778
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.loadInput", overload);
2779
2780
if (!func)
2781
return false;
2782
2783
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); ++i) {
2784
const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, i);
2785
2786
const struct dxil_value *args[] = {
2787
opcode, input_id, row, comp, vertex_id
2788
};
2789
2790
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2791
if (!retval)
2792
return false;
2793
store_dest(ctx, &intr->dest, i, retval, out_type);
2794
}
2795
return true;
2796
}
2797
2798
static bool
2799
emit_load_input_flat(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable* var)
2800
{
2801
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_ATTRIBUTE_AT_VERTEX);
2802
const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, (int)var->data.driver_location);
2803
const struct dxil_value *row = dxil_module_get_int32_const(&ctx->mod, 0);
2804
const struct dxil_value *vertex_id = dxil_module_get_int8_const(&ctx->mod, ctx->opts->provoking_vertex);
2805
2806
nir_alu_type out_type = nir_get_nir_type_for_glsl_base_type(glsl_get_base_type(var->type));
2807
enum overload_type overload = get_overload(out_type, glsl_get_bit_size(var->type));
2808
2809
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.attributeAtVertex", overload);
2810
if (!func)
2811
return false;
2812
2813
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); ++i) {
2814
const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, i);
2815
const struct dxil_value *args[] = {
2816
opcode, input_id, row, comp, vertex_id
2817
};
2818
2819
const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
2820
if (!retval)
2821
return false;
2822
2823
store_dest(ctx, &intr->dest, i, retval, out_type);
2824
}
2825
return true;
2826
}
2827
2828
static bool
2829
emit_load_input(struct ntd_context *ctx, nir_intrinsic_instr *intr,
2830
nir_variable *input)
2831
{
2832
if (ctx->mod.shader_kind != DXIL_PIXEL_SHADER ||
2833
input->data.interpolation != INTERP_MODE_FLAT ||
2834
!ctx->opts->interpolate_at_vertex ||
2835
ctx->opts->provoking_vertex == 0 ||
2836
glsl_type_is_integer(input->type))
2837
return emit_load_input_interpolated(ctx, intr, input);
2838
else
2839
return emit_load_input_flat(ctx, intr, input);
2840
}
2841
2842
static bool
2843
emit_load_ptr(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2844
{
2845
struct nir_variable *var =
2846
nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0]));
2847
const struct dxil_value *index =
2848
get_src(ctx, &intr->src[1], 0, nir_type_uint);
2849
2850
const struct dxil_value *ptr = emit_gep_for_index(ctx, var, index);
2851
if (!ptr)
2852
return false;
2853
2854
const struct dxil_value *retval =
2855
dxil_emit_load(&ctx->mod, ptr, 4, false);
2856
2857
store_dest(ctx, &intr->dest, 0, retval, nir_type_uint);
2858
return true;
2859
}
2860
2861
static bool
2862
emit_load_shared(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2863
{
2864
const struct dxil_value *zero, *index;
2865
unsigned bit_size = nir_dest_bit_size(intr->dest);
2866
unsigned align = bit_size / 8;
2867
2868
/* All shared mem accesses should have been lowered to scalar 32bit
2869
* accesses.
2870
*/
2871
assert(bit_size == 32);
2872
assert(nir_dest_num_components(intr->dest) == 1);
2873
2874
zero = dxil_module_get_int32_const(&ctx->mod, 0);
2875
if (!zero)
2876
return false;
2877
2878
index = get_src(ctx, &intr->src[0], 0, nir_type_uint);
2879
if (!index)
2880
return false;
2881
2882
const struct dxil_value *ops[] = { ctx->sharedvars, zero, index };
2883
const struct dxil_value *ptr, *retval;
2884
2885
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
2886
if (!ptr)
2887
return false;
2888
2889
retval = dxil_emit_load(&ctx->mod, ptr, align, false);
2890
if (!retval)
2891
return false;
2892
2893
store_dest(ctx, &intr->dest, 0, retval, nir_type_uint);
2894
return true;
2895
}
2896
2897
static bool
2898
emit_load_scratch(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2899
{
2900
const struct dxil_value *zero, *index;
2901
unsigned bit_size = nir_dest_bit_size(intr->dest);
2902
unsigned align = bit_size / 8;
2903
2904
/* All scratch mem accesses should have been lowered to scalar 32bit
2905
* accesses.
2906
*/
2907
assert(bit_size == 32);
2908
assert(nir_dest_num_components(intr->dest) == 1);
2909
2910
zero = dxil_module_get_int32_const(&ctx->mod, 0);
2911
if (!zero)
2912
return false;
2913
2914
index = get_src(ctx, &intr->src[0], 0, nir_type_uint);
2915
if (!index)
2916
return false;
2917
2918
const struct dxil_value *ops[] = { ctx->scratchvars, zero, index };
2919
const struct dxil_value *ptr, *retval;
2920
2921
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
2922
if (!ptr)
2923
return false;
2924
2925
retval = dxil_emit_load(&ctx->mod, ptr, align, false);
2926
if (!retval)
2927
return false;
2928
2929
store_dest(ctx, &intr->dest, 0, retval, nir_type_uint);
2930
return true;
2931
}
2932
2933
static bool
2934
emit_load_deref(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2935
{
2936
assert(intr->src[0].is_ssa);
2937
nir_deref_instr *deref = nir_instr_as_deref(intr->src[0].ssa->parent_instr);
2938
nir_variable *var = nir_deref_instr_get_variable(deref);
2939
2940
switch (var->data.mode) {
2941
case nir_var_shader_in:
2942
if (glsl_type_is_array(var->type)) {
2943
if (var->data.compact)
2944
return emit_load_compact_input_array(ctx, intr, var, deref);
2945
else
2946
return emit_load_input_array(ctx, intr, var, &deref->arr.index);
2947
}
2948
return emit_load_input(ctx, intr, var);
2949
2950
default:
2951
unreachable("unsupported nir_variable_mode");
2952
}
2953
}
2954
2955
static bool
2956
emit_discard_if_with_value(struct ntd_context *ctx, const struct dxil_value *value)
2957
{
2958
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_DISCARD);
2959
if (!opcode)
2960
return false;
2961
2962
const struct dxil_value *args[] = {
2963
opcode,
2964
value
2965
};
2966
2967
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.discard", DXIL_NONE);
2968
if (!func)
2969
return false;
2970
2971
return dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
2972
}
2973
2974
static bool
2975
emit_discard_if(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2976
{
2977
const struct dxil_value *value = get_src(ctx, &intr->src[0], 0, nir_type_bool);
2978
return emit_discard_if_with_value(ctx, value);
2979
}
2980
2981
static bool
2982
emit_discard(struct ntd_context *ctx)
2983
{
2984
const struct dxil_value *value = dxil_module_get_int1_const(&ctx->mod, true);
2985
return emit_discard_if_with_value(ctx, value);
2986
}
2987
2988
static bool
2989
emit_emit_vertex(struct ntd_context *ctx, nir_intrinsic_instr *intr)
2990
{
2991
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_EMIT_STREAM);
2992
const struct dxil_value *stream_id = dxil_module_get_int8_const(&ctx->mod, nir_intrinsic_stream_id(intr));
2993
if (!opcode || !stream_id)
2994
return false;
2995
2996
const struct dxil_value *args[] = {
2997
opcode,
2998
stream_id
2999
};
3000
3001
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.emitStream", DXIL_NONE);
3002
if (!func)
3003
return false;
3004
3005
return dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
3006
}
3007
3008
static bool
3009
emit_end_primitive(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3010
{
3011
const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_CUT_STREAM);
3012
const struct dxil_value *stream_id = dxil_module_get_int8_const(&ctx->mod, nir_intrinsic_stream_id(intr));
3013
if (!opcode || !stream_id)
3014
return false;
3015
3016
const struct dxil_value *args[] = {
3017
opcode,
3018
stream_id
3019
};
3020
3021
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.cutStream", DXIL_NONE);
3022
if (!func)
3023
return false;
3024
3025
return dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
3026
}
3027
3028
static bool
3029
emit_image_store(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3030
{
3031
const struct dxil_value *handle;
3032
if (ctx->opts->vulkan_environment) {
3033
assert(intr->intrinsic == nir_intrinsic_image_deref_store);
3034
handle = get_src_ssa(ctx, intr->src[0].ssa, 0);
3035
} else {
3036
assert(intr->intrinsic == nir_intrinsic_image_store);
3037
int binding = nir_src_as_int(intr->src[0]);
3038
handle = ctx->uav_handles[binding];
3039
}
3040
if (!handle)
3041
return false;
3042
3043
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
3044
if (!int32_undef)
3045
return false;
3046
3047
const struct dxil_value *coord[3] = { int32_undef, int32_undef, int32_undef };
3048
enum glsl_sampler_dim image_dim = intr->intrinsic == nir_intrinsic_image_store ?
3049
nir_intrinsic_image_dim(intr) :
3050
glsl_get_sampler_dim(nir_src_as_deref(intr->src[0])->type);
3051
unsigned num_coords = glsl_get_sampler_dim_coordinate_components(image_dim);
3052
assert(num_coords <= nir_src_num_components(intr->src[1]));
3053
for (unsigned i = 0; i < num_coords; ++i) {
3054
coord[i] = get_src(ctx, &intr->src[1], i, nir_type_uint);
3055
if (!coord[i])
3056
return false;
3057
}
3058
3059
nir_alu_type in_type = nir_intrinsic_src_type(intr);
3060
enum overload_type overload = get_overload(in_type, 32);
3061
3062
assert(nir_src_bit_size(intr->src[3]) == 32);
3063
unsigned num_components = nir_src_num_components(intr->src[3]);
3064
assert(num_components <= 4);
3065
const struct dxil_value *value[4];
3066
for (unsigned i = 0; i < num_components; ++i) {
3067
value[i] = get_src(ctx, &intr->src[3], i, in_type);
3068
if (!value[i])
3069
return false;
3070
}
3071
3072
for (int i = num_components; i < 4; ++i)
3073
value[i] = int32_undef;
3074
3075
const struct dxil_value *write_mask =
3076
dxil_module_get_int8_const(&ctx->mod, (1u << num_components) - 1);
3077
if (!write_mask)
3078
return false;
3079
3080
if (image_dim == GLSL_SAMPLER_DIM_BUF) {
3081
coord[1] = int32_undef;
3082
return emit_bufferstore_call(ctx, handle, coord, value, write_mask, overload);
3083
} else
3084
return emit_texturestore_call(ctx, handle, coord, value, write_mask, overload);
3085
}
3086
3087
struct texop_parameters {
3088
const struct dxil_value *tex;
3089
const struct dxil_value *sampler;
3090
const struct dxil_value *bias, *lod_or_sample, *min_lod;
3091
const struct dxil_value *coord[4], *offset[3], *dx[3], *dy[3];
3092
const struct dxil_value *cmp;
3093
enum overload_type overload;
3094
};
3095
3096
static const struct dxil_value *
3097
emit_texture_size(struct ntd_context *ctx, struct texop_parameters *params)
3098
{
3099
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.getDimensions", DXIL_NONE);
3100
if (!func)
3101
return false;
3102
3103
const struct dxil_value *args[] = {
3104
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_TEXTURE_SIZE),
3105
params->tex,
3106
params->lod_or_sample
3107
};
3108
3109
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3110
}
3111
3112
static bool
3113
emit_image_size(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3114
{
3115
const struct dxil_value *handle;
3116
if (ctx->opts->vulkan_environment) {
3117
assert(intr->intrinsic == nir_intrinsic_image_deref_size);
3118
handle = get_src_ssa(ctx, intr->src[0].ssa, 0);
3119
}
3120
else {
3121
assert(intr->intrinsic == nir_intrinsic_image_size);
3122
int binding = nir_src_as_int(intr->src[0]);
3123
handle = ctx->uav_handles[binding];
3124
}
3125
if (!handle)
3126
return false;
3127
3128
const struct dxil_value *lod = get_src(ctx, &intr->src[1], 0, nir_type_uint);
3129
if (!lod)
3130
return false;
3131
3132
struct texop_parameters params = {
3133
.tex = handle,
3134
.lod_or_sample = lod
3135
};
3136
const struct dxil_value *dimensions = emit_texture_size(ctx, &params);
3137
if (!dimensions)
3138
return false;
3139
3140
for (unsigned i = 0; i < nir_dest_num_components(intr->dest); ++i) {
3141
const struct dxil_value *retval = dxil_emit_extractval(&ctx->mod, dimensions, i);
3142
store_dest(ctx, &intr->dest, i, retval, nir_type_uint);
3143
}
3144
3145
return true;
3146
}
3147
3148
static bool
3149
emit_get_ssbo_size(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3150
{
3151
const struct dxil_value* handle = NULL;
3152
if (ctx->opts->vulkan_environment) {
3153
handle = get_src_ssa(ctx, intr->src[0].ssa, 0);
3154
} else {
3155
int binding = nir_src_as_int(intr->src[0]);
3156
handle = ctx->uav_handles[binding];
3157
}
3158
3159
if (!handle)
3160
return false;
3161
3162
struct texop_parameters params = {
3163
.tex = handle,
3164
.lod_or_sample = dxil_module_get_undef(
3165
&ctx->mod, dxil_module_get_int_type(&ctx->mod, 32))
3166
};
3167
3168
const struct dxil_value *dimensions = emit_texture_size(ctx, &params);
3169
if (!dimensions)
3170
return false;
3171
3172
const struct dxil_value *retval = dxil_emit_extractval(&ctx->mod, dimensions, 0);
3173
store_dest(ctx, &intr->dest, 0, retval, nir_type_uint);
3174
3175
return true;
3176
}
3177
3178
static bool
3179
emit_ssbo_atomic(struct ntd_context *ctx, nir_intrinsic_instr *intr,
3180
enum dxil_atomic_op op, nir_alu_type type)
3181
{
3182
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[0], DXIL_RESOURCE_CLASS_UAV, 0);
3183
const struct dxil_value *offset =
3184
get_src(ctx, &intr->src[1], 0, nir_type_uint);
3185
const struct dxil_value *value =
3186
get_src(ctx, &intr->src[2], 0, type);
3187
3188
if (!value || !handle || !offset)
3189
return false;
3190
3191
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
3192
if (!int32_undef)
3193
return false;
3194
3195
const struct dxil_value *coord[3] = {
3196
offset, int32_undef, int32_undef
3197
};
3198
3199
const struct dxil_value *retval =
3200
emit_atomic_binop(ctx, handle, op, coord, value);
3201
3202
if (!retval)
3203
return false;
3204
3205
store_dest(ctx, &intr->dest, 0, retval, type);
3206
return true;
3207
}
3208
3209
static bool
3210
emit_ssbo_atomic_comp_swap(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3211
{
3212
const struct dxil_value* handle = get_ubo_ssbo_handle(ctx, &intr->src[0], DXIL_RESOURCE_CLASS_UAV, 0);
3213
const struct dxil_value *offset =
3214
get_src(ctx, &intr->src[1], 0, nir_type_uint);
3215
const struct dxil_value *cmpval =
3216
get_src(ctx, &intr->src[2], 0, nir_type_int);
3217
const struct dxil_value *newval =
3218
get_src(ctx, &intr->src[3], 0, nir_type_int);
3219
3220
if (!cmpval || !newval || !handle || !offset)
3221
return false;
3222
3223
const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
3224
if (!int32_undef)
3225
return false;
3226
3227
const struct dxil_value *coord[3] = {
3228
offset, int32_undef, int32_undef
3229
};
3230
3231
const struct dxil_value *retval =
3232
emit_atomic_cmpxchg(ctx, handle, coord, cmpval, newval);
3233
3234
if (!retval)
3235
return false;
3236
3237
store_dest(ctx, &intr->dest, 0, retval, nir_type_int);
3238
return true;
3239
}
3240
3241
static bool
3242
emit_shared_atomic(struct ntd_context *ctx, nir_intrinsic_instr *intr,
3243
enum dxil_rmw_op op, nir_alu_type type)
3244
{
3245
const struct dxil_value *zero, *index;
3246
3247
assert(nir_src_bit_size(intr->src[1]) == 32);
3248
3249
zero = dxil_module_get_int32_const(&ctx->mod, 0);
3250
if (!zero)
3251
return false;
3252
3253
index = get_src(ctx, &intr->src[0], 0, nir_type_uint);
3254
if (!index)
3255
return false;
3256
3257
const struct dxil_value *ops[] = { ctx->sharedvars, zero, index };
3258
const struct dxil_value *ptr, *value, *retval;
3259
3260
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
3261
if (!ptr)
3262
return false;
3263
3264
value = get_src(ctx, &intr->src[1], 0, type);
3265
3266
retval = dxil_emit_atomicrmw(&ctx->mod, value, ptr, op, false,
3267
DXIL_ATOMIC_ORDERING_ACQREL,
3268
DXIL_SYNC_SCOPE_CROSSTHREAD);
3269
if (!retval)
3270
return false;
3271
3272
store_dest(ctx, &intr->dest, 0, retval, type);
3273
return true;
3274
}
3275
3276
static bool
3277
emit_shared_atomic_comp_swap(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3278
{
3279
const struct dxil_value *zero, *index;
3280
3281
assert(nir_src_bit_size(intr->src[1]) == 32);
3282
3283
zero = dxil_module_get_int32_const(&ctx->mod, 0);
3284
if (!zero)
3285
return false;
3286
3287
index = get_src(ctx, &intr->src[0], 0, nir_type_uint);
3288
if (!index)
3289
return false;
3290
3291
const struct dxil_value *ops[] = { ctx->sharedvars, zero, index };
3292
const struct dxil_value *ptr, *cmpval, *newval, *retval;
3293
3294
ptr = dxil_emit_gep_inbounds(&ctx->mod, ops, ARRAY_SIZE(ops));
3295
if (!ptr)
3296
return false;
3297
3298
cmpval = get_src(ctx, &intr->src[1], 0, nir_type_uint);
3299
newval = get_src(ctx, &intr->src[2], 0, nir_type_uint);
3300
3301
retval = dxil_emit_cmpxchg(&ctx->mod, cmpval, newval, ptr, false,
3302
DXIL_ATOMIC_ORDERING_ACQREL,
3303
DXIL_SYNC_SCOPE_CROSSTHREAD);
3304
if (!retval)
3305
return false;
3306
3307
store_dest(ctx, &intr->dest, 0, retval, nir_type_uint);
3308
return true;
3309
}
3310
3311
static bool
3312
emit_vulkan_resource_index(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3313
{
3314
unsigned int binding = nir_intrinsic_binding(intr);
3315
3316
bool const_index = nir_src_is_const(intr->src[0]);
3317
if (const_index) {
3318
binding += nir_src_as_const_value(intr->src[0])->u32;
3319
}
3320
3321
const struct dxil_value *index_value = dxil_module_get_int32_const(&ctx->mod, binding);
3322
if (!index_value)
3323
return false;
3324
if (!const_index) {
3325
index_value = dxil_emit_binop(&ctx->mod, DXIL_BINOP_ADD,
3326
index_value, get_src(ctx, &intr->src[0], 0, nir_type_uint32), 0);
3327
if (!index_value)
3328
return false;
3329
}
3330
3331
store_dest(ctx, &intr->dest, 0, index_value, nir_type_uint32);
3332
store_dest(ctx, &intr->dest, 1, dxil_module_get_int32_const(&ctx->mod, 0), nir_type_uint32);
3333
return true;
3334
}
3335
3336
static bool
3337
emit_load_vulkan_descriptor(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3338
{
3339
nir_intrinsic_instr* index = nir_src_as_intrinsic(intr->src[0]);
3340
/* We currently do not support reindex */
3341
assert(index && index->intrinsic == nir_intrinsic_vulkan_resource_index);
3342
3343
unsigned binding = nir_intrinsic_binding(index);
3344
unsigned space = nir_intrinsic_desc_set(index);
3345
3346
/* The descriptor_set field for variables is only 5 bits. We shouldn't have intrinsics trying to go beyond that. */
3347
assert(space < 32);
3348
3349
nir_variable *var = nir_get_binding_variable(ctx->shader, nir_chase_binding(intr->src[0]));
3350
3351
const struct dxil_value *handle = NULL;
3352
enum dxil_resource_class resource_class;
3353
3354
switch (nir_intrinsic_desc_type(intr)) {
3355
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3356
resource_class = DXIL_RESOURCE_CLASS_CBV;
3357
break;
3358
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3359
if (var->data.access & ACCESS_NON_WRITEABLE)
3360
resource_class = DXIL_RESOURCE_CLASS_SRV;
3361
else
3362
resource_class = DXIL_RESOURCE_CLASS_UAV;
3363
break;
3364
default:
3365
unreachable("unknown descriptor type");
3366
return false;
3367
}
3368
3369
handle = emit_createhandle_call(ctx, resource_class,
3370
get_resource_id(ctx, resource_class, space, binding),
3371
get_src(ctx, &intr->src[0], 0, nir_type_uint32), false);
3372
3373
store_dest_value(ctx, &intr->dest, 0, handle);
3374
store_dest(ctx, &intr->dest, 1, get_src(ctx, &intr->src[0], 1, nir_type_uint32), nir_type_uint32);
3375
3376
return true;
3377
}
3378
3379
static bool
3380
emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
3381
{
3382
switch (intr->intrinsic) {
3383
case nir_intrinsic_load_global_invocation_id:
3384
case nir_intrinsic_load_global_invocation_id_zero_base:
3385
return emit_load_global_invocation_id(ctx, intr);
3386
case nir_intrinsic_load_local_invocation_id:
3387
return emit_load_local_invocation_id(ctx, intr);
3388
case nir_intrinsic_load_workgroup_id:
3389
case nir_intrinsic_load_workgroup_id_zero_base:
3390
return emit_load_local_workgroup_id(ctx, intr);
3391
case nir_intrinsic_load_ssbo:
3392
return emit_load_ssbo(ctx, intr);
3393
case nir_intrinsic_store_ssbo:
3394
return emit_store_ssbo(ctx, intr);
3395
case nir_intrinsic_store_ssbo_masked_dxil:
3396
return emit_store_ssbo_masked(ctx, intr);
3397
case nir_intrinsic_store_deref:
3398
return emit_store_deref(ctx, intr);
3399
case nir_intrinsic_store_shared_dxil:
3400
case nir_intrinsic_store_shared_masked_dxil:
3401
return emit_store_shared(ctx, intr);
3402
case nir_intrinsic_store_scratch_dxil:
3403
return emit_store_scratch(ctx, intr);
3404
case nir_intrinsic_load_deref:
3405
return emit_load_deref(ctx, intr);
3406
case nir_intrinsic_load_ptr_dxil:
3407
return emit_load_ptr(ctx, intr);
3408
case nir_intrinsic_load_ubo:
3409
return emit_load_ubo(ctx, intr);
3410
case nir_intrinsic_load_ubo_dxil:
3411
return emit_load_ubo_dxil(ctx, intr);
3412
case nir_intrinsic_load_front_face:
3413
return emit_load_input_interpolated(ctx, intr,
3414
ctx->system_value[SYSTEM_VALUE_FRONT_FACE]);
3415
case nir_intrinsic_load_vertex_id_zero_base:
3416
return emit_load_input_interpolated(ctx, intr,
3417
ctx->system_value[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE]);
3418
case nir_intrinsic_load_instance_id:
3419
return emit_load_input_interpolated(ctx, intr,
3420
ctx->system_value[SYSTEM_VALUE_INSTANCE_ID]);
3421
case nir_intrinsic_load_primitive_id:
3422
return emit_load_primitiveid(ctx, intr);
3423
case nir_intrinsic_load_shared_dxil:
3424
return emit_load_shared(ctx, intr);
3425
case nir_intrinsic_load_scratch_dxil:
3426
return emit_load_scratch(ctx, intr);
3427
case nir_intrinsic_discard_if:
3428
return emit_discard_if(ctx, intr);
3429
case nir_intrinsic_discard:
3430
return emit_discard(ctx);
3431
case nir_intrinsic_emit_vertex:
3432
return emit_emit_vertex(ctx, intr);
3433
case nir_intrinsic_end_primitive:
3434
return emit_end_primitive(ctx, intr);
3435
case nir_intrinsic_scoped_barrier:
3436
return emit_barrier(ctx, intr);
3437
case nir_intrinsic_ssbo_atomic_add:
3438
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_ADD, nir_type_int);
3439
case nir_intrinsic_ssbo_atomic_imin:
3440
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_IMIN, nir_type_int);
3441
case nir_intrinsic_ssbo_atomic_umin:
3442
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_UMIN, nir_type_uint);
3443
case nir_intrinsic_ssbo_atomic_imax:
3444
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_IMAX, nir_type_int);
3445
case nir_intrinsic_ssbo_atomic_umax:
3446
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_UMAX, nir_type_uint);
3447
case nir_intrinsic_ssbo_atomic_and:
3448
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_AND, nir_type_uint);
3449
case nir_intrinsic_ssbo_atomic_or:
3450
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_OR, nir_type_uint);
3451
case nir_intrinsic_ssbo_atomic_xor:
3452
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_XOR, nir_type_uint);
3453
case nir_intrinsic_ssbo_atomic_exchange:
3454
return emit_ssbo_atomic(ctx, intr, DXIL_ATOMIC_EXCHANGE, nir_type_int);
3455
case nir_intrinsic_ssbo_atomic_comp_swap:
3456
return emit_ssbo_atomic_comp_swap(ctx, intr);
3457
case nir_intrinsic_shared_atomic_add_dxil:
3458
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_ADD, nir_type_int);
3459
case nir_intrinsic_shared_atomic_imin_dxil:
3460
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_MIN, nir_type_int);
3461
case nir_intrinsic_shared_atomic_umin_dxil:
3462
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_UMIN, nir_type_uint);
3463
case nir_intrinsic_shared_atomic_imax_dxil:
3464
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_MAX, nir_type_int);
3465
case nir_intrinsic_shared_atomic_umax_dxil:
3466
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_UMAX, nir_type_uint);
3467
case nir_intrinsic_shared_atomic_and_dxil:
3468
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_AND, nir_type_uint);
3469
case nir_intrinsic_shared_atomic_or_dxil:
3470
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_OR, nir_type_uint);
3471
case nir_intrinsic_shared_atomic_xor_dxil:
3472
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_XOR, nir_type_uint);
3473
case nir_intrinsic_shared_atomic_exchange_dxil:
3474
return emit_shared_atomic(ctx, intr, DXIL_RMWOP_XCHG, nir_type_int);
3475
case nir_intrinsic_shared_atomic_comp_swap_dxil:
3476
return emit_shared_atomic_comp_swap(ctx, intr);
3477
case nir_intrinsic_image_store:
3478
case nir_intrinsic_image_deref_store:
3479
return emit_image_store(ctx, intr);
3480
case nir_intrinsic_image_deref_size:
3481
case nir_intrinsic_image_size:
3482
return emit_image_size(ctx, intr);
3483
case nir_intrinsic_get_ssbo_size:
3484
return emit_get_ssbo_size(ctx, intr);
3485
3486
case nir_intrinsic_vulkan_resource_index:
3487
return emit_vulkan_resource_index(ctx, intr);
3488
case nir_intrinsic_load_vulkan_descriptor:
3489
return emit_load_vulkan_descriptor(ctx, intr);
3490
3491
case nir_intrinsic_load_num_workgroups:
3492
case nir_intrinsic_load_workgroup_size:
3493
default:
3494
NIR_INSTR_UNSUPPORTED(&intr->instr);
3495
assert("Unimplemented intrinsic instruction");
3496
return false;
3497
}
3498
}
3499
3500
static bool
3501
emit_load_const(struct ntd_context *ctx, nir_load_const_instr *load_const)
3502
{
3503
for (int i = 0; i < load_const->def.num_components; ++i) {
3504
const struct dxil_value *value;
3505
switch (load_const->def.bit_size) {
3506
case 1:
3507
value = dxil_module_get_int1_const(&ctx->mod,
3508
load_const->value[i].b);
3509
break;
3510
case 16:
3511
ctx->mod.feats.native_low_precision = true;
3512
value = dxil_module_get_int16_const(&ctx->mod,
3513
load_const->value[i].u16);
3514
break;
3515
case 32:
3516
value = dxil_module_get_int32_const(&ctx->mod,
3517
load_const->value[i].u32);
3518
break;
3519
case 64:
3520
ctx->mod.feats.int64_ops = true;
3521
value = dxil_module_get_int64_const(&ctx->mod,
3522
load_const->value[i].u64);
3523
break;
3524
default:
3525
unreachable("unexpected bit_size");
3526
}
3527
if (!value)
3528
return false;
3529
3530
store_ssa_def(ctx, &load_const->def, i, value);
3531
}
3532
return true;
3533
}
3534
3535
static bool
3536
emit_deref(struct ntd_context* ctx, nir_deref_instr* instr)
3537
{
3538
assert(instr->deref_type == nir_deref_type_var ||
3539
instr->deref_type == nir_deref_type_array);
3540
3541
/* In the non-Vulkan environment, there's nothing to emit. Any references to
3542
* derefs will emit the necessary logic to handle scratch/shared GEP addressing
3543
*/
3544
if (!ctx->opts->vulkan_environment)
3545
return true;
3546
3547
/* In the Vulkan environment, we don't have cached handles for textures or
3548
* samplers, so let's use the opportunity of walking through the derefs to
3549
* emit those.
3550
*/
3551
nir_variable *var = nir_deref_instr_get_variable(instr);
3552
assert(var);
3553
3554
if (!glsl_type_is_sampler(glsl_without_array(var->type)) &&
3555
!glsl_type_is_image(glsl_without_array(var->type)))
3556
return true;
3557
3558
const struct glsl_type *type = instr->type;
3559
const struct dxil_value *binding;
3560
3561
if (instr->deref_type == nir_deref_type_var) {
3562
binding = dxil_module_get_int32_const(&ctx->mod, var->data.binding);
3563
} else {
3564
const struct dxil_value *base = get_src(ctx, &instr->parent, 0, nir_type_uint32);
3565
const struct dxil_value *offset = get_src(ctx, &instr->arr.index, 0, nir_type_uint32);
3566
if (!base || !offset)
3567
return false;
3568
3569
binding = dxil_emit_binop(&ctx->mod, DXIL_BINOP_ADD, base, offset, 0);
3570
}
3571
3572
if (!binding)
3573
return false;
3574
3575
/* Haven't finished chasing the deref chain yet, just store the value */
3576
if (glsl_type_is_array(type)) {
3577
store_dest(ctx, &instr->dest, 0, binding, nir_type_uint32);
3578
return true;
3579
}
3580
3581
assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
3582
enum dxil_resource_class res_class;
3583
if (glsl_type_is_image(type))
3584
res_class = DXIL_RESOURCE_CLASS_UAV;
3585
else if (glsl_get_sampler_result_type(type) == GLSL_TYPE_VOID)
3586
res_class = DXIL_RESOURCE_CLASS_SAMPLER;
3587
else
3588
res_class = DXIL_RESOURCE_CLASS_SRV;
3589
3590
const struct dxil_value *handle = emit_createhandle_call(ctx, res_class,
3591
get_resource_id(ctx, res_class, var->data.descriptor_set, var->data.binding), binding, false);
3592
if (!handle)
3593
return false;
3594
3595
store_dest_value(ctx, &instr->dest, 0, handle);
3596
return true;
3597
}
3598
3599
static bool
3600
emit_cond_branch(struct ntd_context *ctx, const struct dxil_value *cond,
3601
int true_block, int false_block)
3602
{
3603
assert(cond);
3604
assert(true_block >= 0);
3605
assert(false_block >= 0);
3606
return dxil_emit_branch(&ctx->mod, cond, true_block, false_block);
3607
}
3608
3609
static bool
3610
emit_branch(struct ntd_context *ctx, int block)
3611
{
3612
assert(block >= 0);
3613
return dxil_emit_branch(&ctx->mod, NULL, block, -1);
3614
}
3615
3616
static bool
3617
emit_jump(struct ntd_context *ctx, nir_jump_instr *instr)
3618
{
3619
switch (instr->type) {
3620
case nir_jump_break:
3621
case nir_jump_continue:
3622
assert(instr->instr.block->successors[0]);
3623
assert(!instr->instr.block->successors[1]);
3624
return emit_branch(ctx, instr->instr.block->successors[0]->index);
3625
3626
default:
3627
unreachable("Unsupported jump type\n");
3628
}
3629
}
3630
3631
struct phi_block {
3632
unsigned num_components;
3633
struct dxil_instr *comp[NIR_MAX_VEC_COMPONENTS];
3634
};
3635
3636
static bool
3637
emit_phi(struct ntd_context *ctx, nir_phi_instr *instr)
3638
{
3639
unsigned bit_size = nir_dest_bit_size(instr->dest);
3640
const struct dxil_type *type = dxil_module_get_int_type(&ctx->mod,
3641
bit_size);
3642
3643
struct phi_block *vphi = ralloc(ctx->phis, struct phi_block);
3644
vphi->num_components = nir_dest_num_components(instr->dest);
3645
3646
for (unsigned i = 0; i < vphi->num_components; ++i) {
3647
struct dxil_instr *phi = vphi->comp[i] = dxil_emit_phi(&ctx->mod, type);
3648
if (!phi)
3649
return false;
3650
store_dest_value(ctx, &instr->dest, i, dxil_instr_get_return_value(phi));
3651
}
3652
_mesa_hash_table_insert(ctx->phis, instr, vphi);
3653
return true;
3654
}
3655
3656
static void
3657
fixup_phi(struct ntd_context *ctx, nir_phi_instr *instr,
3658
struct phi_block *vphi)
3659
{
3660
const struct dxil_value *values[128];
3661
unsigned blocks[128];
3662
for (unsigned i = 0; i < vphi->num_components; ++i) {
3663
size_t num_incoming = 0;
3664
nir_foreach_phi_src(src, instr) {
3665
assert(src->src.is_ssa);
3666
const struct dxil_value *val = get_src_ssa(ctx, src->src.ssa, i);
3667
assert(num_incoming < ARRAY_SIZE(values));
3668
values[num_incoming] = val;
3669
assert(num_incoming < ARRAY_SIZE(blocks));
3670
blocks[num_incoming] = src->pred->index;
3671
++num_incoming;
3672
}
3673
dxil_phi_set_incoming(vphi->comp[i], values, blocks, num_incoming);
3674
}
3675
}
3676
3677
static unsigned
3678
get_n_src(struct ntd_context *ctx, const struct dxil_value **values,
3679
unsigned max_components, nir_tex_src *src, nir_alu_type type)
3680
{
3681
unsigned num_components = nir_src_num_components(src->src);
3682
unsigned i = 0;
3683
3684
assert(num_components <= max_components);
3685
3686
for (i = 0; i < num_components; ++i) {
3687
values[i] = get_src(ctx, &src->src, i, type);
3688
assert(values[i] != NULL);
3689
}
3690
3691
return num_components;
3692
}
3693
3694
#define PAD_SRC(ctx, array, components, undef) \
3695
for (unsigned i = components; i < ARRAY_SIZE(array); ++i) { \
3696
array[i] = undef; \
3697
}
3698
3699
static const struct dxil_value *
3700
emit_sample(struct ntd_context *ctx, struct texop_parameters *params)
3701
{
3702
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sample", params->overload);
3703
if (!func)
3704
return NULL;
3705
3706
const struct dxil_value *args[11] = {
3707
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE),
3708
params->tex, params->sampler,
3709
params->coord[0], params->coord[1], params->coord[2], params->coord[3],
3710
params->offset[0], params->offset[1], params->offset[2],
3711
params->min_lod
3712
};
3713
3714
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3715
}
3716
3717
static const struct dxil_value *
3718
emit_sample_bias(struct ntd_context *ctx, struct texop_parameters *params)
3719
{
3720
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sampleBias", params->overload);
3721
if (!func)
3722
return NULL;
3723
3724
assert(params->bias != NULL);
3725
3726
const struct dxil_value *args[12] = {
3727
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE_BIAS),
3728
params->tex, params->sampler,
3729
params->coord[0], params->coord[1], params->coord[2], params->coord[3],
3730
params->offset[0], params->offset[1], params->offset[2],
3731
params->bias, params->min_lod
3732
};
3733
3734
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3735
}
3736
3737
static const struct dxil_value *
3738
emit_sample_level(struct ntd_context *ctx, struct texop_parameters *params)
3739
{
3740
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sampleLevel", params->overload);
3741
if (!func)
3742
return NULL;
3743
3744
assert(params->lod_or_sample != NULL);
3745
3746
const struct dxil_value *args[11] = {
3747
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE_LEVEL),
3748
params->tex, params->sampler,
3749
params->coord[0], params->coord[1], params->coord[2], params->coord[3],
3750
params->offset[0], params->offset[1], params->offset[2],
3751
params->lod_or_sample
3752
};
3753
3754
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3755
}
3756
3757
static const struct dxil_value *
3758
emit_sample_cmp(struct ntd_context *ctx, struct texop_parameters *params)
3759
{
3760
const struct dxil_func *func;
3761
enum dxil_intr opcode;
3762
int numparam;
3763
3764
if (ctx->mod.shader_kind == DXIL_PIXEL_SHADER) {
3765
func = dxil_get_function(&ctx->mod, "dx.op.sampleCmp", DXIL_F32);
3766
opcode = DXIL_INTR_SAMPLE_CMP;
3767
numparam = 12;
3768
} else {
3769
func = dxil_get_function(&ctx->mod, "dx.op.sampleCmpLevelZero", DXIL_F32);
3770
opcode = DXIL_INTR_SAMPLE_CMP_LVL_ZERO;
3771
numparam = 11;
3772
}
3773
3774
if (!func)
3775
return NULL;
3776
3777
const struct dxil_value *args[12] = {
3778
dxil_module_get_int32_const(&ctx->mod, opcode),
3779
params->tex, params->sampler,
3780
params->coord[0], params->coord[1], params->coord[2], params->coord[3],
3781
params->offset[0], params->offset[1], params->offset[2],
3782
params->cmp, params->min_lod
3783
};
3784
3785
return dxil_emit_call(&ctx->mod, func, args, numparam);
3786
}
3787
3788
static const struct dxil_value *
3789
emit_sample_grad(struct ntd_context *ctx, struct texop_parameters *params)
3790
{
3791
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.sampleGrad", params->overload);
3792
if (!func)
3793
return false;
3794
3795
const struct dxil_value *args[17] = {
3796
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_SAMPLE_GRAD),
3797
params->tex, params->sampler,
3798
params->coord[0], params->coord[1], params->coord[2], params->coord[3],
3799
params->offset[0], params->offset[1], params->offset[2],
3800
params->dx[0], params->dx[1], params->dx[2],
3801
params->dy[0], params->dy[1], params->dy[2],
3802
params->min_lod
3803
};
3804
3805
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3806
}
3807
3808
static const struct dxil_value *
3809
emit_texel_fetch(struct ntd_context *ctx, struct texop_parameters *params)
3810
{
3811
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.textureLoad", params->overload);
3812
if (!func)
3813
return false;
3814
3815
if (!params->lod_or_sample)
3816
params->lod_or_sample = dxil_module_get_undef(&ctx->mod, dxil_module_get_int_type(&ctx->mod, 32));
3817
3818
const struct dxil_value *args[] = {
3819
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_TEXTURE_LOAD),
3820
params->tex,
3821
params->lod_or_sample, params->coord[0], params->coord[1], params->coord[2],
3822
params->offset[0], params->offset[1], params->offset[2]
3823
};
3824
3825
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3826
}
3827
3828
static const struct dxil_value *
3829
emit_texture_lod(struct ntd_context *ctx, struct texop_parameters *params)
3830
{
3831
const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.calculateLOD", DXIL_F32);
3832
if (!func)
3833
return false;
3834
3835
const struct dxil_value *args[] = {
3836
dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_TEXTURE_LOD),
3837
params->tex,
3838
params->sampler,
3839
params->coord[0],
3840
params->coord[1],
3841
params->coord[2],
3842
dxil_module_get_int1_const(&ctx->mod, 1)
3843
};
3844
3845
return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
3846
}
3847
3848
static bool
3849
emit_tex(struct ntd_context *ctx, nir_tex_instr *instr)
3850
{
3851
struct texop_parameters params;
3852
memset(&params, 0, sizeof(struct texop_parameters));
3853
if (!ctx->opts->vulkan_environment) {
3854
params.tex = ctx->srv_handles[instr->texture_index];
3855
params.sampler = ctx->sampler_handles[instr->sampler_index];
3856
}
3857
3858
const struct dxil_type *int_type = dxil_module_get_int_type(&ctx->mod, 32);
3859
const struct dxil_type *float_type = dxil_module_get_float_type(&ctx->mod, 32);
3860
const struct dxil_value *int_undef = dxil_module_get_undef(&ctx->mod, int_type);
3861
const struct dxil_value *float_undef = dxil_module_get_undef(&ctx->mod, float_type);
3862
3863
unsigned coord_components = 0, offset_components = 0, dx_components = 0, dy_components = 0;
3864
params.overload = get_overload(instr->dest_type, 32);
3865
3866
for (unsigned i = 0; i < instr->num_srcs; i++) {
3867
nir_alu_type type = nir_tex_instr_src_type(instr, i);
3868
3869
switch (instr->src[i].src_type) {
3870
case nir_tex_src_coord:
3871
coord_components = get_n_src(ctx, params.coord, ARRAY_SIZE(params.coord),
3872
&instr->src[i], type);
3873
break;
3874
3875
case nir_tex_src_offset:
3876
offset_components = get_n_src(ctx, params.offset, ARRAY_SIZE(params.offset),
3877
&instr->src[i], nir_type_int);
3878
break;
3879
3880
case nir_tex_src_bias:
3881
assert(instr->op == nir_texop_txb);
3882
assert(nir_src_num_components(instr->src[i].src) == 1);
3883
params.bias = get_src(ctx, &instr->src[i].src, 0, nir_type_float);
3884
assert(params.bias != NULL);
3885
break;
3886
3887
case nir_tex_src_lod:
3888
assert(nir_src_num_components(instr->src[i].src) == 1);
3889
/* Buffers don't have a LOD */
3890
if (instr->sampler_dim != GLSL_SAMPLER_DIM_BUF)
3891
params.lod_or_sample = get_src(ctx, &instr->src[i].src, 0, type);
3892
else
3893
params.lod_or_sample = int_undef;
3894
assert(params.lod_or_sample != NULL);
3895
break;
3896
3897
case nir_tex_src_min_lod:
3898
assert(nir_src_num_components(instr->src[i].src) == 1);
3899
params.min_lod = get_src(ctx, &instr->src[i].src, 0, type);
3900
assert(params.min_lod != NULL);
3901
break;
3902
3903
case nir_tex_src_comparator:
3904
assert(nir_src_num_components(instr->src[i].src) == 1);
3905
params.cmp = get_src(ctx, &instr->src[i].src, 0, nir_type_float);
3906
assert(params.cmp != NULL);
3907
break;
3908
3909
case nir_tex_src_ddx:
3910
dx_components = get_n_src(ctx, params.dx, ARRAY_SIZE(params.dx),
3911
&instr->src[i], nir_type_float);
3912
assert(dx_components != 0);
3913
break;
3914
3915
case nir_tex_src_ddy:
3916
dy_components = get_n_src(ctx, params.dy, ARRAY_SIZE(params.dy),
3917
&instr->src[i], nir_type_float);
3918
assert(dy_components != 0);
3919
break;
3920
3921
case nir_tex_src_ms_index:
3922
params.lod_or_sample = get_src(ctx, &instr->src[i].src, 0, nir_type_int);
3923
assert(params.lod_or_sample != NULL);
3924
break;
3925
3926
case nir_tex_src_texture_deref:
3927
assert(ctx->opts->vulkan_environment);
3928
params.tex = get_src_ssa(ctx, instr->src[i].src.ssa, 0);
3929
break;
3930
3931
case nir_tex_src_sampler_deref:
3932
assert(ctx->opts->vulkan_environment);
3933
params.sampler = get_src_ssa(ctx, instr->src[i].src.ssa, 0);
3934
break;
3935
3936
case nir_tex_src_projector:
3937
unreachable("Texture projector should have been lowered");
3938
3939
default:
3940
fprintf(stderr, "texture source: %d\n", instr->src[i].src_type);
3941
unreachable("unknown texture source");
3942
}
3943
}
3944
3945
assert(params.tex != NULL);
3946
assert(instr->op == nir_texop_txf ||
3947
instr->op == nir_texop_txf_ms ||
3948
nir_tex_instr_is_query(instr) ||
3949
params.sampler != NULL);
3950
3951
PAD_SRC(ctx, params.coord, coord_components, float_undef);
3952
PAD_SRC(ctx, params.offset, offset_components, int_undef);
3953
if (!params.min_lod) params.min_lod = float_undef;
3954
3955
const struct dxil_value *sample = NULL;
3956
switch (instr->op) {
3957
case nir_texop_txb:
3958
sample = emit_sample_bias(ctx, &params);
3959
break;
3960
3961
case nir_texop_tex:
3962
if (params.cmp != NULL) {
3963
sample = emit_sample_cmp(ctx, &params);
3964
break;
3965
} else if (ctx->mod.shader_kind == DXIL_PIXEL_SHADER) {
3966
sample = emit_sample(ctx, &params);
3967
break;
3968
}
3969
params.lod_or_sample = dxil_module_get_float_const(&ctx->mod, 0);
3970
FALLTHROUGH;
3971
case nir_texop_txl:
3972
sample = emit_sample_level(ctx, &params);
3973
break;
3974
3975
case nir_texop_txd:
3976
PAD_SRC(ctx, params.dx, dx_components, float_undef);
3977
PAD_SRC(ctx, params.dy, dy_components,float_undef);
3978
sample = emit_sample_grad(ctx, &params);
3979
break;
3980
3981
case nir_texop_txf:
3982
case nir_texop_txf_ms:
3983
if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) {
3984
params.coord[1] = int_undef;
3985
sample = emit_bufferload_call(ctx, params.tex, params.coord);
3986
}
3987
else {
3988
PAD_SRC(ctx, params.coord, coord_components, int_undef);
3989
sample = emit_texel_fetch(ctx, &params);
3990
}
3991
break;
3992
3993
case nir_texop_txs:
3994
sample = emit_texture_size(ctx, &params);
3995
break;
3996
3997
case nir_texop_lod:
3998
sample = emit_texture_lod(ctx, &params);
3999
store_dest(ctx, &instr->dest, 0, sample, nir_alu_type_get_base_type(instr->dest_type));
4000
return true;
4001
4002
case nir_texop_query_levels:
4003
params.lod_or_sample = dxil_module_get_int_const(&ctx->mod, 0, 32);
4004
sample = emit_texture_size(ctx, &params);
4005
const struct dxil_value *retval = dxil_emit_extractval(&ctx->mod, sample, 3);
4006
store_dest(ctx, &instr->dest, 0, retval, nir_alu_type_get_base_type(instr->dest_type));
4007
return true;
4008
4009
default:
4010
fprintf(stderr, "texture op: %d\n", instr->op);
4011
unreachable("unknown texture op");
4012
}
4013
4014
if (!sample)
4015
return false;
4016
4017
for (unsigned i = 0; i < nir_dest_num_components(instr->dest); ++i) {
4018
const struct dxil_value *retval = dxil_emit_extractval(&ctx->mod, sample, i);
4019
store_dest(ctx, &instr->dest, i, retval, nir_alu_type_get_base_type(instr->dest_type));
4020
}
4021
4022
return true;
4023
}
4024
4025
static bool
4026
emit_undefined(struct ntd_context *ctx, nir_ssa_undef_instr *undef)
4027
{
4028
for (unsigned i = 0; i < undef->def.num_components; ++i)
4029
store_ssa_def(ctx, &undef->def, i, dxil_module_get_int32_const(&ctx->mod, 0));
4030
return true;
4031
}
4032
4033
static bool emit_instr(struct ntd_context *ctx, struct nir_instr* instr)
4034
{
4035
switch (instr->type) {
4036
case nir_instr_type_alu:
4037
return emit_alu(ctx, nir_instr_as_alu(instr));
4038
case nir_instr_type_intrinsic:
4039
return emit_intrinsic(ctx, nir_instr_as_intrinsic(instr));
4040
case nir_instr_type_load_const:
4041
return emit_load_const(ctx, nir_instr_as_load_const(instr));
4042
case nir_instr_type_deref:
4043
return emit_deref(ctx, nir_instr_as_deref(instr));
4044
case nir_instr_type_jump:
4045
return emit_jump(ctx, nir_instr_as_jump(instr));
4046
case nir_instr_type_phi:
4047
return emit_phi(ctx, nir_instr_as_phi(instr));
4048
case nir_instr_type_tex:
4049
return emit_tex(ctx, nir_instr_as_tex(instr));
4050
case nir_instr_type_ssa_undef:
4051
return emit_undefined(ctx, nir_instr_as_ssa_undef(instr));
4052
default:
4053
NIR_INSTR_UNSUPPORTED(instr);
4054
unreachable("Unimplemented instruction type");
4055
return false;
4056
}
4057
}
4058
4059
4060
static bool
4061
emit_block(struct ntd_context *ctx, struct nir_block *block)
4062
{
4063
assert(block->index < ctx->mod.num_basic_block_ids);
4064
ctx->mod.basic_block_ids[block->index] = ctx->mod.curr_block;
4065
4066
nir_foreach_instr(instr, block) {
4067
TRACE_CONVERSION(instr);
4068
4069
if (!emit_instr(ctx, instr)) {
4070
return false;
4071
}
4072
}
4073
return true;
4074
}
4075
4076
static bool
4077
emit_cf_list(struct ntd_context *ctx, struct exec_list *list);
4078
4079
static bool
4080
emit_if(struct ntd_context *ctx, struct nir_if *if_stmt)
4081
{
4082
assert(nir_src_num_components(if_stmt->condition) == 1);
4083
const struct dxil_value *cond = get_src(ctx, &if_stmt->condition, 0,
4084
nir_type_bool);
4085
4086
/* prepare blocks */
4087
nir_block *then_block = nir_if_first_then_block(if_stmt);
4088
assert(nir_if_last_then_block(if_stmt)->successors[0]);
4089
assert(!nir_if_last_then_block(if_stmt)->successors[1]);
4090
int then_succ = nir_if_last_then_block(if_stmt)->successors[0]->index;
4091
4092
nir_block *else_block = NULL;
4093
int else_succ = -1;
4094
if (!exec_list_is_empty(&if_stmt->else_list)) {
4095
else_block = nir_if_first_else_block(if_stmt);
4096
assert(nir_if_last_else_block(if_stmt)->successors[0]);
4097
assert(!nir_if_last_else_block(if_stmt)->successors[1]);
4098
else_succ = nir_if_last_else_block(if_stmt)->successors[0]->index;
4099
}
4100
4101
if (!emit_cond_branch(ctx, cond, then_block->index,
4102
else_block ? else_block->index : then_succ))
4103
return false;
4104
4105
/* handle then-block */
4106
if (!emit_cf_list(ctx, &if_stmt->then_list) ||
4107
(!nir_block_ends_in_jump(nir_if_last_then_block(if_stmt)) &&
4108
!emit_branch(ctx, then_succ)))
4109
return false;
4110
4111
if (else_block) {
4112
/* handle else-block */
4113
if (!emit_cf_list(ctx, &if_stmt->else_list) ||
4114
(!nir_block_ends_in_jump(nir_if_last_else_block(if_stmt)) &&
4115
!emit_branch(ctx, else_succ)))
4116
return false;
4117
}
4118
4119
return true;
4120
}
4121
4122
static bool
4123
emit_loop(struct ntd_context *ctx, nir_loop *loop)
4124
{
4125
nir_block *first_block = nir_loop_first_block(loop);
4126
4127
assert(nir_loop_last_block(loop)->successors[0]);
4128
assert(!nir_loop_last_block(loop)->successors[1]);
4129
4130
if (!emit_branch(ctx, first_block->index))
4131
return false;
4132
4133
if (!emit_cf_list(ctx, &loop->body))
4134
return false;
4135
4136
if (!emit_branch(ctx, first_block->index))
4137
return false;
4138
4139
return true;
4140
}
4141
4142
static bool
4143
emit_cf_list(struct ntd_context *ctx, struct exec_list *list)
4144
{
4145
foreach_list_typed(nir_cf_node, node, node, list) {
4146
switch (node->type) {
4147
case nir_cf_node_block:
4148
if (!emit_block(ctx, nir_cf_node_as_block(node)))
4149
return false;
4150
break;
4151
4152
case nir_cf_node_if:
4153
if (!emit_if(ctx, nir_cf_node_as_if(node)))
4154
return false;
4155
break;
4156
4157
case nir_cf_node_loop:
4158
if (!emit_loop(ctx, nir_cf_node_as_loop(node)))
4159
return false;
4160
break;
4161
4162
default:
4163
unreachable("unsupported cf-list node");
4164
break;
4165
}
4166
}
4167
return true;
4168
}
4169
4170
static void
4171
insert_sorted_by_binding(struct exec_list *var_list, nir_variable *new_var)
4172
{
4173
nir_foreach_variable_in_list(var, var_list) {
4174
if (var->data.binding > new_var->data.binding) {
4175
exec_node_insert_node_before(&var->node, &new_var->node);
4176
return;
4177
}
4178
}
4179
exec_list_push_tail(var_list, &new_var->node);
4180
}
4181
4182
4183
static void
4184
sort_uniforms_by_binding_and_remove_structs(nir_shader *s)
4185
{
4186
struct exec_list new_list;
4187
exec_list_make_empty(&new_list);
4188
4189
nir_foreach_variable_with_modes_safe(var, s, nir_var_uniform) {
4190
exec_node_remove(&var->node);
4191
const struct glsl_type *type = glsl_without_array(var->type);
4192
if (!glsl_type_is_struct(type))
4193
insert_sorted_by_binding(&new_list, var);
4194
}
4195
exec_list_append(&s->variables, &new_list);
4196
}
4197
4198
static void
4199
prepare_phi_values(struct ntd_context *ctx)
4200
{
4201
/* PHI nodes are difficult to get right when tracking the types:
4202
* Since the incoming sources are linked to blocks, we can't bitcast
4203
* on the fly while loading. So scan the shader and insert a typed dummy
4204
* value for each phi source, and when storing we convert if the incoming
4205
* value has a different type then the one expected by the phi node.
4206
* We choose int as default, because it supports more bit sizes.
4207
*/
4208
nir_foreach_function(function, ctx->shader) {
4209
if (function->impl) {
4210
nir_foreach_block(block, function->impl) {
4211
nir_foreach_instr(instr, block) {
4212
if (instr->type == nir_instr_type_phi) {
4213
nir_phi_instr *ir = nir_instr_as_phi(instr);
4214
unsigned bitsize = nir_dest_bit_size(ir->dest);
4215
const struct dxil_value *dummy = dxil_module_get_int_const(&ctx->mod, 0, bitsize);
4216
nir_foreach_phi_src(src, ir) {
4217
for(unsigned int i = 0; i < ir->dest.ssa.num_components; ++i)
4218
store_ssa_def(ctx, src->src.ssa, i, dummy);
4219
}
4220
}
4221
}
4222
}
4223
}
4224
}
4225
}
4226
4227
static bool
4228
emit_cbvs(struct ntd_context *ctx)
4229
{
4230
if (ctx->shader->info.stage == MESA_SHADER_KERNEL || ctx->opts->vulkan_environment) {
4231
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ubo) {
4232
if (!emit_ubo_var(ctx, var))
4233
return false;
4234
}
4235
} else {
4236
for (int i = ctx->opts->ubo_binding_offset; i < ctx->shader->info.num_ubos; ++i) {
4237
char name[64];
4238
snprintf(name, sizeof(name), "__ubo%d", i);
4239
if (!emit_cbv(ctx, i, 0, 16384 /*4096 vec4's*/, 1, name))
4240
return false;
4241
}
4242
}
4243
4244
return true;
4245
}
4246
4247
static bool
4248
emit_scratch(struct ntd_context *ctx)
4249
{
4250
if (ctx->shader->scratch_size) {
4251
/*
4252
* We always allocate an u32 array, no matter the actual variable types.
4253
* According to the DXIL spec, the minimum load/store granularity is
4254
* 32-bit, anything smaller requires using a read-extract/read-write-modify
4255
* approach.
4256
*/
4257
unsigned size = ALIGN_POT(ctx->shader->scratch_size, sizeof(uint32_t));
4258
const struct dxil_type *int32 = dxil_module_get_int_type(&ctx->mod, 32);
4259
const struct dxil_value *array_length = dxil_module_get_int32_const(&ctx->mod, size / sizeof(uint32_t));
4260
if (!int32 || !array_length)
4261
return false;
4262
4263
const struct dxil_type *type = dxil_module_get_array_type(
4264
&ctx->mod, int32, size / sizeof(uint32_t));
4265
if (!type)
4266
return false;
4267
4268
ctx->scratchvars = dxil_emit_alloca(&ctx->mod, type, int32, array_length, 4);
4269
if (!ctx->scratchvars)
4270
return false;
4271
}
4272
4273
return true;
4274
}
4275
4276
/* The validator complains if we don't have ops that reference a global variable. */
4277
static bool
4278
shader_has_shared_ops(struct nir_shader *s)
4279
{
4280
nir_foreach_function(func, s) {
4281
if (!func->impl)
4282
continue;
4283
nir_foreach_block(block, func->impl) {
4284
nir_foreach_instr(instr, block) {
4285
if (instr->type != nir_instr_type_intrinsic)
4286
continue;
4287
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
4288
switch (intrin->intrinsic) {
4289
case nir_intrinsic_load_shared_dxil:
4290
case nir_intrinsic_store_shared_dxil:
4291
case nir_intrinsic_shared_atomic_add_dxil:
4292
case nir_intrinsic_shared_atomic_and_dxil:
4293
case nir_intrinsic_shared_atomic_comp_swap_dxil:
4294
case nir_intrinsic_shared_atomic_exchange_dxil:
4295
case nir_intrinsic_shared_atomic_imax_dxil:
4296
case nir_intrinsic_shared_atomic_imin_dxil:
4297
case nir_intrinsic_shared_atomic_or_dxil:
4298
case nir_intrinsic_shared_atomic_umax_dxil:
4299
case nir_intrinsic_shared_atomic_umin_dxil:
4300
case nir_intrinsic_shared_atomic_xor_dxil:
4301
return true;
4302
default: break;
4303
}
4304
}
4305
}
4306
}
4307
return false;
4308
}
4309
4310
static bool
4311
emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts)
4312
{
4313
/* The validator forces us to emit resources in a specific order:
4314
* CBVs, Samplers, SRVs, UAVs. While we are at it also remove
4315
* stale struct uniforms, they are lowered but might not have been removed */
4316
sort_uniforms_by_binding_and_remove_structs(ctx->shader);
4317
4318
/* CBVs */
4319
if (!emit_cbvs(ctx))
4320
return false;
4321
4322
/* Samplers */
4323
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_uniform) {
4324
unsigned count = glsl_type_get_sampler_count(var->type);
4325
const struct glsl_type *without_array = glsl_without_array(var->type);
4326
if (var->data.mode == nir_var_uniform && glsl_type_is_sampler(without_array) &&
4327
glsl_get_sampler_result_type(without_array) == GLSL_TYPE_VOID) {
4328
if (!emit_sampler(ctx, var, count))
4329
return false;
4330
}
4331
}
4332
4333
/* SRVs */
4334
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_uniform) {
4335
unsigned count = glsl_type_get_sampler_count(var->type);
4336
const struct glsl_type *without_array = glsl_without_array(var->type);
4337
if (var->data.mode == nir_var_uniform && glsl_type_is_sampler(without_array) &&
4338
glsl_get_sampler_result_type(without_array) != GLSL_TYPE_VOID) {
4339
if (!emit_srv(ctx, var, count))
4340
return false;
4341
}
4342
}
4343
/* Handle read-only SSBOs as SRVs */
4344
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ssbo) {
4345
if ((var->data.access & ACCESS_NON_WRITEABLE) != 0) {
4346
unsigned count = 1;
4347
if (glsl_type_is_array(var->type))
4348
count = glsl_get_length(var->type);
4349
if (!emit_srv(ctx, var, count))
4350
return false;
4351
}
4352
}
4353
4354
if (ctx->shader->info.shared_size && shader_has_shared_ops(ctx->shader)) {
4355
const struct dxil_type *type;
4356
unsigned size;
4357
4358
/*
4359
* We always allocate an u32 array, no matter the actual variable types.
4360
* According to the DXIL spec, the minimum load/store granularity is
4361
* 32-bit, anything smaller requires using a read-extract/read-write-modify
4362
* approach. Non-atomic 64-bit accesses are allowed, but the
4363
* GEP(cast(gvar, u64[] *), offset) and cast(GEP(gvar, offset), u64 *))
4364
* sequences don't seem to be accepted by the DXIL validator when the
4365
* pointer is in the groupshared address space, making the 32-bit -> 64-bit
4366
* pointer cast impossible.
4367
*/
4368
size = ALIGN_POT(ctx->shader->info.shared_size, sizeof(uint32_t));
4369
type = dxil_module_get_array_type(&ctx->mod,
4370
dxil_module_get_int_type(&ctx->mod, 32),
4371
size / sizeof(uint32_t));
4372
ctx->sharedvars = dxil_add_global_ptr_var(&ctx->mod, "shared", type,
4373
DXIL_AS_GROUPSHARED,
4374
ffs(sizeof(uint64_t)),
4375
NULL);
4376
}
4377
4378
if (!emit_scratch(ctx))
4379
return false;
4380
4381
/* UAVs */
4382
if (ctx->shader->info.stage == MESA_SHADER_KERNEL) {
4383
if (!emit_globals(ctx, opts->num_kernel_globals))
4384
return false;
4385
4386
ctx->consts = _mesa_pointer_hash_table_create(ctx->ralloc_ctx);
4387
if (!ctx->consts)
4388
return false;
4389
if (!emit_global_consts(ctx))
4390
return false;
4391
} else {
4392
/* Handle read/write SSBOs as UAVs */
4393
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ssbo) {
4394
if ((var->data.access & ACCESS_NON_WRITEABLE) == 0) {
4395
unsigned count = 1;
4396
if (glsl_type_is_array(var->type))
4397
count = glsl_get_length(var->type);
4398
if (!emit_uav(ctx, var->data.binding, var->data.descriptor_set,
4399
count, DXIL_COMP_TYPE_INVALID,
4400
DXIL_RESOURCE_KIND_RAW_BUFFER, var->name))
4401
return false;
4402
}
4403
}
4404
}
4405
4406
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_uniform) {
4407
if (var->data.mode == nir_var_uniform && glsl_type_is_image(glsl_without_array(var->type))) {
4408
if (!emit_uav_var(ctx, var, glsl_type_get_image_count(var->type)))
4409
return false;
4410
}
4411
}
4412
4413
nir_function_impl *entry = nir_shader_get_entrypoint(ctx->shader);
4414
nir_metadata_require(entry, nir_metadata_block_index);
4415
4416
assert(entry->num_blocks > 0);
4417
ctx->mod.basic_block_ids = rzalloc_array(ctx->ralloc_ctx, int,
4418
entry->num_blocks);
4419
if (!ctx->mod.basic_block_ids)
4420
return false;
4421
4422
for (int i = 0; i < entry->num_blocks; ++i)
4423
ctx->mod.basic_block_ids[i] = -1;
4424
ctx->mod.num_basic_block_ids = entry->num_blocks;
4425
4426
ctx->defs = rzalloc_array(ctx->ralloc_ctx, struct dxil_def,
4427
entry->ssa_alloc);
4428
if (!ctx->defs)
4429
return false;
4430
ctx->num_defs = entry->ssa_alloc;
4431
4432
ctx->phis = _mesa_pointer_hash_table_create(ctx->ralloc_ctx);
4433
if (!ctx->phis)
4434
return false;
4435
4436
prepare_phi_values(ctx);
4437
4438
if (!emit_cf_list(ctx, &entry->body))
4439
return false;
4440
4441
hash_table_foreach(ctx->phis, entry) {
4442
fixup_phi(ctx, (nir_phi_instr *)entry->key,
4443
(struct phi_block *)entry->data);
4444
}
4445
4446
if (!dxil_emit_ret_void(&ctx->mod))
4447
return false;
4448
4449
if (ctx->shader->info.stage == MESA_SHADER_FRAGMENT) {
4450
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_shader_out) {
4451
if (var->data.location == FRAG_RESULT_STENCIL) {
4452
ctx->mod.feats.stencil_ref = true;
4453
}
4454
}
4455
}
4456
4457
if (ctx->mod.feats.native_low_precision)
4458
ctx->mod.minor_version = MAX2(ctx->mod.minor_version, 2);
4459
4460
return emit_metadata(ctx) &&
4461
dxil_emit_module(&ctx->mod);
4462
}
4463
4464
static unsigned int
4465
get_dxil_shader_kind(struct nir_shader *s)
4466
{
4467
switch (s->info.stage) {
4468
case MESA_SHADER_VERTEX:
4469
return DXIL_VERTEX_SHADER;
4470
case MESA_SHADER_GEOMETRY:
4471
return DXIL_GEOMETRY_SHADER;
4472
case MESA_SHADER_FRAGMENT:
4473
return DXIL_PIXEL_SHADER;
4474
case MESA_SHADER_KERNEL:
4475
case MESA_SHADER_COMPUTE:
4476
return DXIL_COMPUTE_SHADER;
4477
default:
4478
unreachable("unknown shader stage in nir_to_dxil");
4479
return DXIL_COMPUTE_SHADER;
4480
}
4481
}
4482
4483
static unsigned
4484
lower_bit_size_callback(const nir_instr* instr, void *data)
4485
{
4486
if (instr->type != nir_instr_type_alu)
4487
return 0;
4488
const nir_alu_instr *alu = nir_instr_as_alu(instr);
4489
4490
if (nir_op_infos[alu->op].is_conversion)
4491
return 0;
4492
4493
unsigned num_inputs = nir_op_infos[alu->op].num_inputs;
4494
const struct nir_to_dxil_options *opts = (const struct nir_to_dxil_options*)data;
4495
unsigned min_bit_size = opts->lower_int16 ? 32 : 16;
4496
4497
unsigned ret = 0;
4498
for (unsigned i = 0; i < num_inputs; i++) {
4499
unsigned bit_size = nir_src_bit_size(alu->src[i].src);
4500
if (bit_size != 1 && bit_size < min_bit_size)
4501
ret = min_bit_size;
4502
}
4503
4504
return ret;
4505
}
4506
4507
static void
4508
optimize_nir(struct nir_shader *s, const struct nir_to_dxil_options *opts)
4509
{
4510
bool progress;
4511
do {
4512
progress = false;
4513
NIR_PASS_V(s, nir_lower_vars_to_ssa);
4514
NIR_PASS(progress, s, nir_lower_indirect_derefs, nir_var_function_temp, UINT32_MAX);
4515
NIR_PASS(progress, s, nir_lower_alu_to_scalar, NULL, NULL);
4516
NIR_PASS(progress, s, nir_copy_prop);
4517
NIR_PASS(progress, s, nir_opt_copy_prop_vars);
4518
NIR_PASS(progress, s, nir_lower_bit_size, lower_bit_size_callback, (void*)opts);
4519
NIR_PASS(progress, s, dxil_nir_lower_8bit_conv);
4520
if (opts->lower_int16)
4521
NIR_PASS(progress, s, dxil_nir_lower_16bit_conv);
4522
NIR_PASS(progress, s, nir_opt_remove_phis);
4523
NIR_PASS(progress, s, nir_opt_dce);
4524
NIR_PASS(progress, s, nir_opt_if, true);
4525
NIR_PASS(progress, s, nir_opt_dead_cf);
4526
NIR_PASS(progress, s, nir_opt_cse);
4527
NIR_PASS(progress, s, nir_opt_peephole_select, 8, true, true);
4528
NIR_PASS(progress, s, nir_opt_algebraic);
4529
NIR_PASS(progress, s, dxil_nir_lower_x2b);
4530
if (s->options->lower_int64_options)
4531
NIR_PASS(progress, s, nir_lower_int64);
4532
NIR_PASS(progress, s, nir_lower_alu);
4533
NIR_PASS(progress, s, dxil_nir_lower_inot);
4534
NIR_PASS(progress, s, nir_opt_constant_folding);
4535
NIR_PASS(progress, s, nir_opt_undef);
4536
NIR_PASS(progress, s, nir_lower_undef_to_zero);
4537
NIR_PASS(progress, s, nir_opt_deref);
4538
NIR_PASS(progress, s, dxil_nir_lower_upcast_phis, opts->lower_int16 ? 32 : 16);
4539
NIR_PASS(progress, s, nir_lower_64bit_phis);
4540
NIR_PASS_V(s, nir_lower_system_values);
4541
} while (progress);
4542
4543
do {
4544
progress = false;
4545
NIR_PASS(progress, s, nir_opt_algebraic_late);
4546
} while (progress);
4547
}
4548
4549
static
4550
void dxil_fill_validation_state(struct ntd_context *ctx,
4551
struct dxil_validation_state *state)
4552
{
4553
state->num_resources = util_dynarray_num_elements(&ctx->resources, struct dxil_resource);
4554
state->resources = (struct dxil_resource*)ctx->resources.data;
4555
state->state.psv0.max_expected_wave_lane_count = UINT_MAX;
4556
state->state.shader_stage = (uint8_t)ctx->mod.shader_kind;
4557
state->state.sig_input_elements = (uint8_t)ctx->mod.num_sig_inputs;
4558
state->state.sig_output_elements = (uint8_t)ctx->mod.num_sig_outputs;
4559
//state->state.sig_patch_const_or_prim_elements = 0;
4560
4561
switch (ctx->mod.shader_kind) {
4562
case DXIL_VERTEX_SHADER:
4563
state->state.psv0.vs.output_position_present = ctx->mod.info.has_out_position;
4564
break;
4565
case DXIL_PIXEL_SHADER:
4566
/* TODO: handle depth outputs */
4567
state->state.psv0.ps.depth_output = ctx->mod.info.has_out_depth;
4568
/* just guessing */
4569
state->state.psv0.ps.sample_frequency = 0;
4570
break;
4571
case DXIL_COMPUTE_SHADER:
4572
break;
4573
case DXIL_GEOMETRY_SHADER:
4574
state->state.max_vertex_count = ctx->shader->info.gs.vertices_out;
4575
state->state.psv0.gs.input_primitive = dxil_get_input_primitive(ctx->shader->info.gs.input_primitive);
4576
state->state.psv0.gs.output_toplology = dxil_get_primitive_topology(ctx->shader->info.gs.output_primitive);
4577
state->state.psv0.gs.output_stream_mask = ctx->shader->info.gs.active_stream_mask;
4578
state->state.psv0.gs.output_position_present = ctx->mod.info.has_out_position;
4579
break;
4580
default:
4581
assert(0 && "Shader type not (yet) supported");
4582
}
4583
}
4584
4585
static nir_variable *
4586
add_sysvalue(struct ntd_context *ctx,
4587
uint8_t value, char *name,
4588
int driver_location)
4589
{
4590
4591
nir_variable *var = rzalloc(ctx->shader, nir_variable);
4592
if (!var)
4593
return NULL;
4594
var->data.driver_location = driver_location;
4595
var->data.location = value;
4596
var->type = glsl_uint_type();
4597
var->name = name;
4598
var->data.mode = nir_var_system_value;
4599
var->data.interpolation = INTERP_MODE_FLAT;
4600
return var;
4601
}
4602
4603
static bool
4604
append_input_or_sysvalue(struct ntd_context *ctx,
4605
int input_loc, int sv_slot,
4606
char *name, int driver_location)
4607
{
4608
if (input_loc >= 0) {
4609
/* Check inputs whether a variable is available the corresponds
4610
* to the sysvalue */
4611
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_shader_in) {
4612
if (var->data.location == input_loc) {
4613
ctx->system_value[sv_slot] = var;
4614
return true;
4615
}
4616
}
4617
}
4618
4619
ctx->system_value[sv_slot] = add_sysvalue(ctx, sv_slot, name, driver_location);
4620
if (!ctx->system_value[sv_slot])
4621
return false;
4622
4623
nir_shader_add_variable(ctx->shader, ctx->system_value[sv_slot]);
4624
return true;
4625
}
4626
4627
struct sysvalue_name {
4628
gl_system_value value;
4629
int slot;
4630
char *name;
4631
} possible_sysvalues[] = {
4632
{SYSTEM_VALUE_VERTEX_ID_ZERO_BASE, -1, "SV_VertexID"},
4633
{SYSTEM_VALUE_INSTANCE_ID, -1, "SV_InstanceID"},
4634
{SYSTEM_VALUE_FRONT_FACE, VARYING_SLOT_FACE, "SV_IsFrontFace"},
4635
{SYSTEM_VALUE_PRIMITIVE_ID, VARYING_SLOT_PRIMITIVE_ID, "SV_PrimitiveID"},
4636
};
4637
4638
static bool
4639
allocate_sysvalues(struct ntd_context *ctx)
4640
{
4641
unsigned driver_location = 0;
4642
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_shader_in)
4643
driver_location++;
4644
nir_foreach_variable_with_modes(var, ctx->shader, nir_var_system_value)
4645
driver_location++;
4646
4647
for (unsigned i = 0; i < ARRAY_SIZE(possible_sysvalues); ++i) {
4648
struct sysvalue_name *info = &possible_sysvalues[i];
4649
if (BITSET_TEST(ctx->shader->info.system_values_read, info->value)) {
4650
if (!append_input_or_sysvalue(ctx, info->slot,
4651
info->value, info->name,
4652
driver_location++))
4653
return false;
4654
}
4655
}
4656
return true;
4657
}
4658
4659
bool
4660
nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts,
4661
struct blob *blob)
4662
{
4663
assert(opts);
4664
bool retval = true;
4665
debug_dxil = (int)debug_get_option_debug_dxil();
4666
blob_init(blob);
4667
4668
struct ntd_context *ctx = calloc(1, sizeof(*ctx));
4669
if (!ctx)
4670
return false;
4671
4672
ctx->opts = opts;
4673
ctx->shader = s;
4674
4675
ctx->ralloc_ctx = ralloc_context(NULL);
4676
if (!ctx->ralloc_ctx) {
4677
retval = false;
4678
goto out;
4679
}
4680
4681
util_dynarray_init(&ctx->srv_metadata_nodes, ctx->ralloc_ctx);
4682
util_dynarray_init(&ctx->uav_metadata_nodes, ctx->ralloc_ctx);
4683
util_dynarray_init(&ctx->cbv_metadata_nodes, ctx->ralloc_ctx);
4684
util_dynarray_init(&ctx->sampler_metadata_nodes, ctx->ralloc_ctx);
4685
util_dynarray_init(&ctx->resources, ctx->ralloc_ctx);
4686
dxil_module_init(&ctx->mod, ctx->ralloc_ctx);
4687
ctx->mod.shader_kind = get_dxil_shader_kind(s);
4688
ctx->mod.major_version = 6;
4689
ctx->mod.minor_version = 1;
4690
4691
NIR_PASS_V(s, nir_lower_pack);
4692
NIR_PASS_V(s, nir_lower_frexp);
4693
NIR_PASS_V(s, nir_lower_flrp, 16 | 32 | 64, true);
4694
4695
optimize_nir(s, opts);
4696
4697
NIR_PASS_V(s, nir_remove_dead_variables,
4698
nir_var_function_temp | nir_var_shader_temp, NULL);
4699
4700
if (!allocate_sysvalues(ctx))
4701
return false;
4702
4703
if (debug_dxil & DXIL_DEBUG_VERBOSE)
4704
nir_print_shader(s, stderr);
4705
4706
if (!emit_module(ctx, opts)) {
4707
debug_printf("D3D12: dxil_container_add_module failed\n");
4708
retval = false;
4709
goto out;
4710
}
4711
4712
if (debug_dxil & DXIL_DEBUG_DUMP_MODULE) {
4713
struct dxil_dumper *dumper = dxil_dump_create();
4714
dxil_dump_module(dumper, &ctx->mod);
4715
fprintf(stderr, "\n");
4716
dxil_dump_buf_to_file(dumper, stderr);
4717
fprintf(stderr, "\n\n");
4718
dxil_dump_free(dumper);
4719
}
4720
4721
struct dxil_container container;
4722
dxil_container_init(&container);
4723
if (!dxil_container_add_features(&container, &ctx->mod.feats)) {
4724
debug_printf("D3D12: dxil_container_add_features failed\n");
4725
retval = false;
4726
goto out;
4727
}
4728
4729
if (!dxil_container_add_io_signature(&container,
4730
DXIL_ISG1,
4731
ctx->mod.num_sig_inputs,
4732
ctx->mod.inputs)) {
4733
debug_printf("D3D12: failed to write input signature\n");
4734
retval = false;
4735
goto out;
4736
}
4737
4738
if (!dxil_container_add_io_signature(&container,
4739
DXIL_OSG1,
4740
ctx->mod.num_sig_outputs,
4741
ctx->mod.outputs)) {
4742
debug_printf("D3D12: failed to write output signature\n");
4743
retval = false;
4744
goto out;
4745
}
4746
4747
struct dxil_validation_state validation_state;
4748
memset(&validation_state, 0, sizeof(validation_state));
4749
dxil_fill_validation_state(ctx, &validation_state);
4750
4751
if (!dxil_container_add_state_validation(&container,&ctx->mod,
4752
&validation_state)) {
4753
debug_printf("D3D12: failed to write state-validation\n");
4754
retval = false;
4755
goto out;
4756
}
4757
4758
if (!dxil_container_add_module(&container, &ctx->mod)) {
4759
debug_printf("D3D12: failed to write module\n");
4760
retval = false;
4761
goto out;
4762
}
4763
4764
if (!dxil_container_write(&container, blob)) {
4765
debug_printf("D3D12: dxil_container_write failed\n");
4766
retval = false;
4767
goto out;
4768
}
4769
dxil_container_finish(&container);
4770
4771
if (debug_dxil & DXIL_DEBUG_DUMP_BLOB) {
4772
static int shader_id = 0;
4773
char buffer[64];
4774
snprintf(buffer, sizeof(buffer), "shader_%s_%d.blob",
4775
get_shader_kind_str(ctx->mod.shader_kind), shader_id++);
4776
debug_printf("Try to write blob to %s\n", buffer);
4777
FILE *f = fopen(buffer, "wb");
4778
if (f) {
4779
fwrite(blob->data, 1, blob->size, f);
4780
fclose(f);
4781
}
4782
}
4783
4784
out:
4785
dxil_module_release(&ctx->mod);
4786
ralloc_free(ctx->ralloc_ctx);
4787
free(ctx);
4788
return retval;
4789
}
4790
4791
enum dxil_sysvalue_type
4792
nir_var_to_dxil_sysvalue_type(nir_variable *var, uint64_t other_stage_mask)
4793
{
4794
switch (var->data.location) {
4795
case VARYING_SLOT_FACE:
4796
return DXIL_GENERATED_SYSVALUE;
4797
case VARYING_SLOT_POS:
4798
case VARYING_SLOT_PRIMITIVE_ID:
4799
case VARYING_SLOT_CLIP_DIST0:
4800
case VARYING_SLOT_CLIP_DIST1:
4801
case VARYING_SLOT_PSIZ:
4802
if (!((1ull << var->data.location) & other_stage_mask))
4803
return DXIL_SYSVALUE;
4804
FALLTHROUGH;
4805
default:
4806
return DXIL_NO_SYSVALUE;
4807
}
4808
}
4809
4810