Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/microsoft/compiler/dxil_signature.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 "dxil_enums.h"
25
#include "dxil_module.h"
26
#include "dxil_signature.h"
27
28
#include "nir_to_dxil.h"
29
#include "glsl_types.h"
30
#include "util/u_debug.h"
31
32
#include <string.h>
33
34
35
struct semantic_info {
36
enum dxil_semantic_kind kind;
37
char name[64];
38
int index;
39
enum dxil_prog_sig_comp_type comp_type;
40
uint8_t sig_comp_type;
41
int32_t start_row;
42
int32_t rows;
43
uint8_t start_col;
44
uint8_t cols;
45
uint8_t interpolation;
46
const char *sysvalue_name;
47
};
48
49
50
static bool
51
is_depth_output(enum dxil_semantic_kind kind)
52
{
53
return kind == DXIL_SEM_DEPTH ||
54
kind == DXIL_SEM_STENCIL_REF;
55
}
56
57
static uint8_t
58
get_interpolation(nir_variable *var)
59
{
60
if (unlikely(var->data.centroid)) {
61
switch (var->data.interpolation) {
62
case INTERP_MODE_NONE: return DXIL_INTERP_LINEAR_CENTROID;
63
case INTERP_MODE_FLAT: return DXIL_INTERP_CONSTANT;
64
case INTERP_MODE_NOPERSPECTIVE: return DXIL_INTERP_LINEAR_NOPERSPECTIVE_CENTROID;
65
case INTERP_MODE_SMOOTH: return DXIL_INTERP_LINEAR_CENTROID;
66
67
}
68
} else {
69
switch (var->data.interpolation) {
70
case INTERP_MODE_NONE: return DXIL_INTERP_LINEAR;
71
case INTERP_MODE_FLAT: return DXIL_INTERP_CONSTANT;
72
case INTERP_MODE_NOPERSPECTIVE: return DXIL_INTERP_LINEAR_NOPERSPECTIVE;
73
case INTERP_MODE_SMOOTH: return DXIL_INTERP_LINEAR;
74
}
75
}
76
77
return DXIL_INTERP_LINEAR;
78
}
79
80
static const char *
81
in_sysvalue_name(nir_variable *var)
82
{
83
switch (var->data.location) {
84
case VARYING_SLOT_POS:
85
return "POS";
86
case VARYING_SLOT_FACE:
87
return "FACE";
88
default:
89
return "NONE";
90
}
91
}
92
93
/*
94
* The signatures are written into the stream in two pieces:
95
* DxilProgramSignatureElement is a fixes size structure that gets dumped
96
* to the stream in order of the registers and each contains an offset
97
* to the semantic name string. Then these strings are dumped into the stream.
98
*/
99
static unsigned
100
get_additional_semantic_info(nir_shader *s, nir_variable *var, struct semantic_info *info,
101
unsigned next_row, bool is_gs_shader)
102
{
103
const struct glsl_type *type = var->type;
104
105
info->comp_type =
106
dxil_get_prog_sig_comp_type(var->type);
107
108
bool is_depth = is_depth_output(info->kind);
109
info->sig_comp_type = dxil_get_comp_type(var->type);
110
111
info->rows = 1;
112
if (info->kind == DXIL_SEM_TARGET) {
113
info->start_row = info->index;
114
} else if (is_depth || (info->kind == DXIL_SEM_PRIMITIVE_ID && is_gs_shader)) {
115
info->start_row = -1;
116
} else if (var->data.compact) {
117
if (var->data.location_frac) {
118
info->start_row = next_row - 1;
119
} else {
120
info->start_row = next_row;
121
next_row++;
122
}
123
124
assert(glsl_type_is_array(type) && info->kind == DXIL_SEM_CLIP_DISTANCE);
125
unsigned num_floats = glsl_get_aoa_size(type);
126
unsigned start_offset = (var->data.location - VARYING_SLOT_CLIP_DIST0) * 4 +
127
var->data.location_frac;
128
129
if (start_offset >= s->info.clip_distance_array_size) {
130
info->kind = DXIL_SEM_CULL_DISTANCE;
131
snprintf(info->name, 64, "SV_CullDistance");
132
}
133
info->cols = num_floats;
134
} else {
135
info->start_row = next_row;
136
if (glsl_type_is_array(type) && is_gs_shader)
137
type = glsl_without_array(type);
138
139
if (glsl_type_is_array(type)) {
140
info->rows = glsl_get_aoa_size(type);
141
type = glsl_get_array_element(type);
142
assert(info->rows);
143
}
144
next_row += info->rows;
145
}
146
info->start_col = (uint8_t)var->data.location_frac;
147
if (!info->cols) {
148
if (glsl_type_is_array(type))
149
type = glsl_get_array_element(type);
150
info->cols = (uint8_t)glsl_get_components(type);
151
}
152
153
return next_row;
154
}
155
156
typedef void (*semantic_info_proc)(nir_variable *var, struct semantic_info *info, bool vulkan);
157
158
static void
159
get_semantic_vs_in_name(nir_variable *var, struct semantic_info *info, bool vulkan)
160
{
161
strcpy(info->name, "TEXCOORD");
162
if (vulkan) {
163
info->index = var->data.location >= VERT_ATTRIB_GENERIC0 ?
164
var->data.location - VERT_ATTRIB_GENERIC0 :
165
var->data.location;
166
} else {
167
info->index = var->data.driver_location;
168
}
169
info->kind = DXIL_SEM_ARBITRARY;
170
}
171
172
static void
173
get_semantic_sv_name(nir_variable *var, struct semantic_info *info, bool _vulkan)
174
{
175
switch (var->data.location) {
176
case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
177
info->kind = DXIL_SEM_VERTEX_ID;
178
break;
179
case SYSTEM_VALUE_FRONT_FACE:
180
info->kind = DXIL_SEM_IS_FRONT_FACE;
181
break;
182
case SYSTEM_VALUE_INSTANCE_ID:
183
info->kind = DXIL_SEM_INSTANCE_ID;
184
break;
185
case SYSTEM_VALUE_PRIMITIVE_ID:
186
info->kind = DXIL_SEM_PRIMITIVE_ID;
187
break;
188
default:
189
unreachable("unsupported system value");
190
}
191
strncpy(info->name, var->name, ARRAY_SIZE(info->name) - 1);
192
}
193
194
static void
195
get_semantic_ps_outname(nir_variable *var, struct semantic_info *info)
196
{
197
info->kind = DXIL_SEM_INVALID;
198
switch (var->data.location) {
199
case FRAG_RESULT_COLOR:
200
snprintf(info->name, 64, "%s", "SV_Target");
201
info->index = var->data.index;
202
info->kind = DXIL_SEM_TARGET;
203
break;
204
case FRAG_RESULT_DATA0:
205
case FRAG_RESULT_DATA1:
206
case FRAG_RESULT_DATA2:
207
case FRAG_RESULT_DATA3:
208
case FRAG_RESULT_DATA4:
209
case FRAG_RESULT_DATA5:
210
case FRAG_RESULT_DATA6:
211
case FRAG_RESULT_DATA7:
212
snprintf(info->name, 64, "%s", "SV_Target");
213
info->index = var->data.location - FRAG_RESULT_DATA0;
214
if (var->data.location == FRAG_RESULT_DATA0 &&
215
var->data.index > 0)
216
info->index = var->data.index;
217
info->kind = DXIL_SEM_TARGET;
218
break;
219
case FRAG_RESULT_DEPTH:
220
snprintf(info->name, 64, "%s", "SV_Depth");
221
info->kind = DXIL_SEM_DEPTH;
222
break;
223
case FRAG_RESULT_STENCIL:
224
snprintf(info->name, 64, "%s", "SV_StencilRef");
225
info->kind = DXIL_SEM_STENCIL_REF; //??
226
break;
227
case FRAG_RESULT_SAMPLE_MASK:
228
snprintf(info->name, 64, "%s", "SV_Coverage");
229
info->kind = DXIL_SEM_COVERAGE; //??
230
break;
231
default:
232
snprintf(info->name, 64, "%s", "UNDEFINED");
233
break;
234
}
235
}
236
237
static void
238
get_semantic_name(nir_variable *var, struct semantic_info *info,
239
const struct glsl_type *type, bool vulkan)
240
{
241
info->kind = DXIL_SEM_INVALID;
242
info->interpolation = get_interpolation(var);
243
switch (var->data.location) {
244
245
case VARYING_SLOT_POS:
246
assert(glsl_get_components(type) == 4);
247
snprintf(info->name, 64, "%s", "SV_Position");
248
info->kind = DXIL_SEM_POSITION;
249
break;
250
251
case VARYING_SLOT_FACE:
252
assert(glsl_get_components(var->type) == 1);
253
snprintf(info->name, 64, "%s", "SV_IsFrontFace");
254
info->kind = DXIL_SEM_IS_FRONT_FACE;
255
break;
256
257
case VARYING_SLOT_PRIMITIVE_ID:
258
assert(glsl_get_components(var->type) == 1);
259
snprintf(info->name, 64, "%s", "SV_PrimitiveID");
260
info->kind = DXIL_SEM_PRIMITIVE_ID;
261
break;
262
263
case VARYING_SLOT_CLIP_DIST1:
264
info->index = 1;
265
FALLTHROUGH;
266
case VARYING_SLOT_CLIP_DIST0:
267
assert(var->data.location == VARYING_SLOT_CLIP_DIST1 || info->index == 0);
268
snprintf(info->name, 64, "%s", "SV_ClipDistance");
269
info->kind = DXIL_SEM_CLIP_DISTANCE;
270
break;
271
272
default: {
273
info->index = var->data.location -
274
(vulkan ? VARYING_SLOT_VAR0 : VARYING_SLOT_POS);
275
strcpy(info->name, "TEXCOORD");
276
info->kind = DXIL_SEM_ARBITRARY;
277
}
278
}
279
}
280
281
static void
282
get_semantic_in_name(nir_variable *var, struct semantic_info *info, bool vulkan)
283
{
284
get_semantic_name(var, info, var->type, vulkan);
285
info->sysvalue_name = in_sysvalue_name(var);
286
}
287
288
static void
289
get_semantic_gs_in_name(nir_variable *var, struct semantic_info *info, bool vulkan)
290
{
291
/* geometry shader input varyings come as arrays, but we want to use
292
* the element type */
293
const struct glsl_type *type =
294
glsl_type_is_array(var->type) ? glsl_without_array(var->type) : var->type;
295
296
get_semantic_name(var, info, type, vulkan);
297
info->sysvalue_name = in_sysvalue_name(var);
298
}
299
300
301
static enum dxil_prog_sig_semantic
302
prog_semantic_from_kind(enum dxil_semantic_kind kind)
303
{
304
switch (kind) {
305
case DXIL_SEM_ARBITRARY: return DXIL_PROG_SEM_UNDEFINED;
306
case DXIL_SEM_VERTEX_ID: return DXIL_PROG_SEM_VERTEX_ID;
307
case DXIL_SEM_INSTANCE_ID: return DXIL_PROG_SEM_INSTANCE_ID;
308
case DXIL_SEM_POSITION: return DXIL_PROG_SEM_POSITION;
309
case DXIL_SEM_COVERAGE: return DXIL_PROG_SEM_COVERAGE;
310
case DXIL_SEM_INNER_COVERAGE: return DXIL_PROG_SEM_INNER_COVERAGE;
311
case DXIL_SEM_PRIMITIVE_ID: return DXIL_PROG_SEM_PRIMITIVE_ID;
312
case DXIL_SEM_SAMPLE_INDEX: return DXIL_PROG_SEM_SAMPLE_INDEX;
313
case DXIL_SEM_IS_FRONT_FACE: return DXIL_PROG_SEM_IS_FRONTFACE;
314
case DXIL_SEM_RENDERTARGET_ARRAY_INDEX: return DXIL_PROG_SEM_RENDERTARGET_ARRAY_INDEX;
315
case DXIL_SEM_VIEWPORT_ARRAY_INDEX: return DXIL_PROG_SEM_VIEWPORT_ARRAY_INDEX;
316
case DXIL_SEM_CLIP_DISTANCE: return DXIL_PROG_SEM_CLIP_DISTANCE;
317
case DXIL_SEM_CULL_DISTANCE: return DXIL_PROG_SEM_CULL_DISTANCE;
318
case DXIL_SEM_BARYCENTRICS: return DXIL_PROG_SEM_BARYCENTRICS;
319
case DXIL_SEM_SHADING_RATE: return DXIL_PROG_SEM_SHADING_RATE;
320
case DXIL_SEM_CULL_PRIMITIVE: return DXIL_PROG_SEM_CULL_PRIMITIVE;
321
case DXIL_SEM_TARGET: return DXIL_PROG_SEM_TARGET;
322
case DXIL_SEM_DEPTH: return DXIL_PROG_SEM_DEPTH;
323
case DXIL_SEM_DEPTH_LE: return DXIL_PROG_SEM_DEPTH_LE;
324
case DXIL_SEM_DEPTH_GE: return DXIL_PROG_SEM_DEPTH_GE;
325
case DXIL_SEM_STENCIL_REF: return DXIL_PROG_SEM_STENCIL_REF;
326
default:
327
return DXIL_PROG_SEM_UNDEFINED;
328
}
329
}
330
331
static
332
uint32_t
333
copy_semantic_name_to_string(struct _mesa_string_buffer *string_out, const char *name)
334
{
335
/* copy the semantic name */
336
uint32_t retval = string_out->length;
337
size_t name_len = strlen(name) + 1;
338
_mesa_string_buffer_append_len(string_out, name, name_len);
339
return retval;
340
}
341
342
static
343
uint32_t
344
append_semantic_index_to_table(struct dxil_psv_sem_index_table *table, uint32_t index,
345
uint32_t num_rows)
346
{
347
if (num_rows == 1) {
348
for (unsigned i = 0; i < table->size; ++i) {
349
if (table->data[i] == index)
350
return i;
351
}
352
}
353
uint32_t retval = table->size;
354
assert(table->size + num_rows <= 80);
355
for (unsigned i = 0; i < num_rows; ++i)
356
table->data[table->size++] = index + i;
357
return retval;
358
}
359
360
static const struct dxil_mdnode *
361
fill_SV_param_nodes(struct dxil_module *mod, unsigned record_id,
362
struct semantic_info *semantic) {
363
364
const struct dxil_mdnode *SV_params_nodes[11];
365
/* For this to always work we should use vectorize_io, but for FS out and VS in
366
* this is not implemented globally */
367
const struct dxil_mdnode *flattened_semantics[256];
368
369
for (unsigned i = 0; i < semantic->rows; ++i)
370
flattened_semantics[i] = dxil_get_metadata_int32(mod, semantic->index + i);
371
372
SV_params_nodes[0] = dxil_get_metadata_int32(mod, (int)record_id); // Unique element ID
373
SV_params_nodes[1] = dxil_get_metadata_string(mod, semantic->name); // Element name
374
SV_params_nodes[2] = dxil_get_metadata_int8(mod, semantic->sig_comp_type); // Element type
375
SV_params_nodes[3] = dxil_get_metadata_int8(mod, (int8_t)semantic->kind); // Effective system value
376
SV_params_nodes[4] = dxil_get_metadata_node(mod, flattened_semantics,
377
semantic->rows); // Semantic index vector
378
SV_params_nodes[5] = dxil_get_metadata_int8(mod, semantic->interpolation); // Interpolation mode
379
SV_params_nodes[6] = dxil_get_metadata_int32(mod, semantic->rows); // Number of rows
380
SV_params_nodes[7] = dxil_get_metadata_int8(mod, semantic->cols); // Number of columns
381
SV_params_nodes[8] = dxil_get_metadata_int32(mod, semantic->start_row); // Element packing start row
382
SV_params_nodes[9] = dxil_get_metadata_int8(mod, semantic->start_col); // Element packing start column
383
SV_params_nodes[10] = 0; // optional Metadata
384
385
return dxil_get_metadata_node(mod, SV_params_nodes, ARRAY_SIZE(SV_params_nodes));
386
}
387
388
static void
389
fill_signature_element(struct dxil_signature_element *elm,
390
struct semantic_info *semantic,
391
unsigned row)
392
{
393
memset(elm, 0, sizeof(struct dxil_signature_element));
394
// elm->stream = 0;
395
// elm->semantic_name_offset = 0; // Offset needs to be filled out when writing
396
elm->semantic_index = semantic->index + row;
397
elm->system_value = (uint32_t) prog_semantic_from_kind(semantic->kind);
398
elm->comp_type = (uint32_t) semantic->comp_type;
399
elm->reg = semantic->start_row + row;
400
401
assert(semantic->cols + semantic->start_col <= 4);
402
elm->mask = (uint8_t) (((1 << semantic->cols) - 1) << semantic->start_col);
403
// elm->never_writes_mask = 0;
404
elm->min_precision = DXIL_MIN_PREC_DEFAULT;
405
}
406
407
static bool
408
fill_psv_signature_element(struct dxil_psv_signature_element *psv_elm,
409
struct semantic_info *semantic, struct dxil_module *mod)
410
{
411
memset(psv_elm, 0, sizeof(struct dxil_psv_signature_element));
412
psv_elm->rows = semantic->rows;
413
if (semantic->start_row >= 0) {
414
assert(semantic->start_row < 256);
415
psv_elm->start_row = semantic->start_row;
416
psv_elm->cols_and_start = (1u << 6) | (semantic->start_col << 4) | semantic->cols;
417
} else {
418
/* The validation expects that the the start row is not egative
419
* and apparently the extra bit in the cols_and_start indicates that the
420
* row is meant literally, so don't set it in this case.
421
* (Source of information: Comparing with the validation structures
422
* created by dxcompiler)
423
*/
424
psv_elm->start_row = 0;
425
psv_elm->cols_and_start = (semantic->start_col << 4) | semantic->cols;
426
}
427
psv_elm->semantic_kind = (uint8_t)semantic->kind;
428
psv_elm->component_type = semantic->comp_type; //`??
429
psv_elm->interpolation_mode = semantic->interpolation;
430
/* to be filled later
431
psv_elm->dynamic_mask_and_stream = 0;
432
*/
433
if (semantic->kind == DXIL_SEM_ARBITRARY && strlen(semantic->name)) {
434
psv_elm->semantic_name_offset =
435
copy_semantic_name_to_string(mod->sem_string_table, semantic->name);
436
437
/* TODO: clean up memory */
438
if (psv_elm->semantic_name_offset == (uint32_t)-1)
439
return false;
440
}
441
442
psv_elm->semantic_indexes_offset =
443
append_semantic_index_to_table(&mod->sem_index_table, semantic->index, semantic->rows);
444
445
return true;
446
}
447
448
static bool
449
fill_io_signature(struct dxil_module *mod, int id,
450
struct semantic_info *semantic,
451
const struct dxil_mdnode **io,
452
struct dxil_signature_element *elm,
453
struct dxil_psv_signature_element *psv_elm)
454
{
455
456
*io = fill_SV_param_nodes(mod, id, semantic);
457
for (unsigned i = 0; i < semantic->rows; ++i)
458
fill_signature_element(&elm[i], semantic, i);
459
return fill_psv_signature_element(psv_elm, semantic, mod);
460
}
461
462
static unsigned
463
get_input_signature_group(struct dxil_module *mod, const struct dxil_mdnode **inputs,
464
unsigned num_inputs,
465
nir_shader *s, nir_variable_mode modes,
466
semantic_info_proc get_semantics, unsigned *row_iter,
467
bool is_gs_shader, bool vulkan)
468
{
469
nir_foreach_variable_with_modes(var, s, modes) {
470
struct semantic_info semantic = {0};
471
get_semantics(var, &semantic, vulkan);
472
mod->inputs[num_inputs].sysvalue = semantic.sysvalue_name;
473
*row_iter = get_additional_semantic_info(s, var, &semantic, *row_iter, is_gs_shader);
474
475
mod->inputs[num_inputs].name = ralloc_strdup(mod->ralloc_ctx,
476
semantic.name);
477
mod->inputs[num_inputs].num_elements = semantic.rows;
478
struct dxil_signature_element *elm = mod->inputs[num_inputs].elements;
479
struct dxil_psv_signature_element *psv_elm = &mod->psv_inputs[num_inputs];
480
481
if (!fill_io_signature(mod, num_inputs, &semantic,
482
&inputs[num_inputs], elm, psv_elm))
483
return 0;
484
485
++num_inputs;
486
assert(num_inputs < VARYING_SLOT_MAX);
487
}
488
return num_inputs;
489
}
490
491
static const struct dxil_mdnode *
492
get_input_signature(struct dxil_module *mod, nir_shader *s, bool vulkan)
493
{
494
if (s->info.stage == MESA_SHADER_KERNEL)
495
return NULL;
496
497
const struct dxil_mdnode *inputs[VARYING_SLOT_MAX];
498
unsigned next_row = 0;
499
bool is_gs_shader = s->info.stage == MESA_SHADER_GEOMETRY;
500
501
mod->num_sig_inputs = get_input_signature_group(mod, inputs, 0,
502
s, nir_var_shader_in,
503
s->info.stage == MESA_SHADER_VERTEX ?
504
get_semantic_vs_in_name :
505
(s->info.stage == MESA_SHADER_GEOMETRY ?
506
get_semantic_gs_in_name : get_semantic_in_name),
507
&next_row, is_gs_shader,
508
vulkan);
509
510
mod->num_sig_inputs = get_input_signature_group(mod, inputs, mod->num_sig_inputs,
511
s, nir_var_system_value,
512
get_semantic_sv_name,
513
&next_row, is_gs_shader,
514
vulkan);
515
516
if (!mod->num_sig_inputs && !mod->num_sig_inputs)
517
return NULL;
518
519
mod->num_psv_inputs = next_row;
520
521
const struct dxil_mdnode *retval = mod->num_sig_inputs ?
522
dxil_get_metadata_node(mod, inputs, mod->num_sig_inputs) : NULL;
523
524
return retval;
525
}
526
527
static const char *out_sysvalue_name(nir_variable *var)
528
{
529
switch (var->data.location) {
530
case VARYING_SLOT_FACE:
531
return "FACE";
532
case VARYING_SLOT_POS:
533
return "POS";
534
case VARYING_SLOT_CLIP_DIST0:
535
case VARYING_SLOT_CLIP_DIST1:
536
return "CLIPDST";
537
case VARYING_SLOT_PRIMITIVE_ID:
538
return "PRIMID";
539
default:
540
return "NO";
541
}
542
}
543
544
static const struct dxil_mdnode *
545
get_output_signature(struct dxil_module *mod, nir_shader *s, bool vulkan)
546
{
547
const struct dxil_mdnode *outputs[VARYING_SLOT_MAX];
548
unsigned num_outputs = 0;
549
unsigned next_row = 0;
550
nir_foreach_variable_with_modes(var, s, nir_var_shader_out) {
551
struct semantic_info semantic = {0};
552
553
if (s->info.stage == MESA_SHADER_FRAGMENT) {
554
get_semantic_ps_outname(var, &semantic);
555
mod->outputs[num_outputs].sysvalue = "TARGET";
556
} else {
557
get_semantic_name(var, &semantic, var->type, vulkan);
558
mod->outputs[num_outputs].sysvalue = out_sysvalue_name(var);
559
}
560
next_row = get_additional_semantic_info(s, var, &semantic, next_row, false);
561
562
mod->info.has_out_position |= semantic.kind== DXIL_SEM_POSITION;
563
mod->info.has_out_depth |= semantic.kind == DXIL_SEM_DEPTH;
564
565
mod->outputs[num_outputs].name = ralloc_strdup(mod->ralloc_ctx,
566
semantic.name);
567
mod->outputs[num_outputs].num_elements = semantic.rows;
568
struct dxil_signature_element *elm = mod->outputs[num_outputs].elements;
569
570
struct dxil_psv_signature_element *psv_elm = &mod->psv_outputs[num_outputs];
571
572
if (!fill_io_signature(mod, num_outputs, &semantic,
573
&outputs[num_outputs], elm, psv_elm))
574
return NULL;
575
576
/* This is fishy, logic suggests that the LHS should be 0xf, but from the
577
* validation it needs to be 0xff */
578
elm->never_writes_mask = 0xff & ~elm->mask;
579
580
++num_outputs;
581
582
if (!is_depth_output(semantic.kind))
583
++mod->num_psv_outputs;
584
585
assert(num_outputs < ARRAY_SIZE(outputs));
586
}
587
588
if (!num_outputs)
589
return NULL;
590
591
const struct dxil_mdnode *retval = dxil_get_metadata_node(mod, outputs, num_outputs);
592
mod->num_sig_outputs = num_outputs;
593
return retval;
594
}
595
596
const struct dxil_mdnode *
597
get_signatures(struct dxil_module *mod, nir_shader *s, bool vulkan)
598
{
599
/* DXC does the same: Add an empty string before everything else */
600
mod->sem_string_table = _mesa_string_buffer_create(mod->ralloc_ctx, 1024);
601
copy_semantic_name_to_string(mod->sem_string_table, "");
602
603
const struct dxil_mdnode *input_signature = get_input_signature(mod, s, vulkan);
604
const struct dxil_mdnode *output_signature = get_output_signature(mod, s, vulkan);
605
606
const struct dxil_mdnode *SV_nodes[3] = {
607
input_signature,
608
output_signature,
609
NULL
610
};
611
if (output_signature || input_signature)
612
return dxil_get_metadata_node(mod, SV_nodes, ARRAY_SIZE(SV_nodes));
613
else
614
return NULL;
615
}
616
617