Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/microsoft/compiler/dxil_dump.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_dump.h"
25
#include "dxil_internal.h"
26
27
#define DIXL_DUMP_DECL
28
#include "dxil_dump_decls.h"
29
30
#include "dxil_module.h"
31
32
33
#include "util/string_buffer.h"
34
#include "util/list.h"
35
36
#include <stdio.h>
37
38
struct dxil_dumper {
39
struct _mesa_string_buffer *buf;
40
int current_indent;
41
};
42
43
struct dxil_dumper *dxil_dump_create(void)
44
{
45
struct dxil_dumper *d = calloc(1, sizeof(struct dxil_dumper));
46
d->buf = _mesa_string_buffer_create(NULL, 1024);
47
d->current_indent = 0;
48
return d;
49
}
50
51
void dxil_dump_free(struct dxil_dumper *d)
52
{
53
_mesa_string_buffer_destroy(d->buf);
54
d->buf = 0;
55
free(d);
56
}
57
58
void dxil_dump_buf_to_file(struct dxil_dumper *d, FILE *f)
59
{
60
assert(f);
61
assert(d);
62
assert(d->buf);
63
fprintf(f, "%s", d->buf->buf);
64
}
65
66
static
67
void dxil_dump_indention_inc(struct dxil_dumper *d)
68
{
69
++d->current_indent;
70
}
71
72
static
73
void dxil_dump_indention_dec(struct dxil_dumper *d)
74
{
75
--d->current_indent;
76
assert(d->current_indent >= 0);
77
}
78
79
static
80
void dxil_dump_indent(struct dxil_dumper *d)
81
{
82
for (int i = 0; i < 2 * d->current_indent; ++i)
83
_mesa_string_buffer_append_char(d->buf, ' ');
84
}
85
86
void
87
dxil_dump_module(struct dxil_dumper *d, struct dxil_module *m)
88
{
89
assert(m);
90
assert(d);
91
92
_mesa_string_buffer_printf(d->buf, "DXIL MODULE:\n");
93
dump_metadata(d, m);
94
dump_shader_info(d, &m->info);
95
dump_types(d, &m->type_list);
96
dump_gvars(d, &m->gvar_list);
97
dump_funcs(d, &m->func_list);
98
dump_attr_set_list(d, &m->attr_set_list);
99
dump_constants(d, &m->const_list);
100
dump_instrs(d, &m->instr_list);
101
dump_mdnodes(d, &m->mdnode_list);
102
dump_named_nodes(d, &m->md_named_node_list);
103
dump_io_signatures(d->buf, m);
104
dump_psv(d->buf, m);
105
_mesa_string_buffer_printf(d->buf, "END DXIL MODULE\n");
106
}
107
108
static void
109
dump_metadata(struct dxil_dumper *d, struct dxil_module *m)
110
{
111
_mesa_string_buffer_printf(d->buf, "Shader: %s\n",
112
dump_shader_string(m->shader_kind));
113
114
_mesa_string_buffer_printf(d->buf, "Version: %d.%d\n",
115
m->major_version, m->minor_version);
116
117
dump_features(d->buf, &m->feats);
118
}
119
120
static void
121
dump_shader_info(struct dxil_dumper *d, struct dxil_shader_info *info)
122
{
123
_mesa_string_buffer_append(d->buf, "Shader Info:\n");
124
if (info->has_out_position)
125
_mesa_string_buffer_append(d->buf, " has_out_position\n");
126
}
127
128
static const char *
129
dump_shader_string(enum dxil_shader_kind kind)
130
{
131
#define SHADER_STR(X) case DXIL_ ## X ## _SHADER: return #X
132
133
switch (kind) {
134
SHADER_STR(VERTEX);
135
SHADER_STR(PIXEL);
136
SHADER_STR(GEOMETRY);
137
SHADER_STR(COMPUTE);
138
default:
139
return "UNSUPPORTED";
140
}
141
#undef SHADER_STR
142
}
143
144
static void
145
dump_features(struct _mesa_string_buffer *buf, struct dxil_features *feat)
146
{
147
_mesa_string_buffer_printf(buf, "Features:\n");
148
#define PRINT_FEAT(F) if (feat->F) _mesa_string_buffer_printf(buf, " %s\n", #F)
149
PRINT_FEAT(doubles);
150
PRINT_FEAT(cs_4x_raw_sb);
151
PRINT_FEAT(uavs_at_every_stage);
152
PRINT_FEAT(use_64uavs);
153
PRINT_FEAT(min_precision);
154
PRINT_FEAT(dx11_1_double_extensions);
155
PRINT_FEAT(dx11_1_shader_extensions);
156
PRINT_FEAT(dx9_comparison_filtering);
157
PRINT_FEAT(tiled_resources);
158
PRINT_FEAT(stencil_ref);
159
PRINT_FEAT(inner_coverage);
160
PRINT_FEAT(typed_uav_load_additional_formats);
161
PRINT_FEAT(rovs);
162
PRINT_FEAT(array_layer_from_vs_or_ds);
163
PRINT_FEAT(wave_ops);
164
PRINT_FEAT(int64_ops);
165
PRINT_FEAT(view_id);
166
PRINT_FEAT(barycentrics);
167
PRINT_FEAT(native_low_precision);
168
PRINT_FEAT(shading_rate);
169
PRINT_FEAT(raytracing_tier_1_1);
170
PRINT_FEAT(sampler_feedback);
171
#undef PRINT_FEAT
172
}
173
174
static void
175
dump_types(struct dxil_dumper *d, struct list_head *list)
176
{
177
if (!list_length(list))
178
return;
179
180
_mesa_string_buffer_append(d->buf, "Types:\n");
181
dxil_dump_indention_inc(d);
182
list_for_each_entry(struct dxil_type, type, list, head) {
183
dxil_dump_indent(d);
184
dump_type(d, type);
185
_mesa_string_buffer_append(d->buf, "\n");
186
}
187
dxil_dump_indention_dec(d);
188
}
189
190
static void dump_type_name(struct dxil_dumper *d, const struct dxil_type *type)
191
{
192
if (!type) {
193
_mesa_string_buffer_append(d->buf, "(type error)");
194
return;
195
}
196
197
switch (type->type) {
198
case TYPE_VOID:
199
_mesa_string_buffer_append(d->buf, "void");
200
break;
201
case TYPE_INTEGER:
202
_mesa_string_buffer_printf(d->buf, "int%d", type->int_bits);
203
break;
204
case TYPE_FLOAT:
205
_mesa_string_buffer_printf(d->buf, "float%d", type->float_bits);
206
break;
207
case TYPE_POINTER:
208
dump_type_name(d, type->ptr_target_type);
209
_mesa_string_buffer_append(d->buf, "*");
210
break;
211
case TYPE_STRUCT:
212
_mesa_string_buffer_printf(d->buf, "struct %s", type->struct_def.name);
213
break;
214
case TYPE_ARRAY:
215
dump_type_name(d, type->array_or_vector_def.elem_type);
216
_mesa_string_buffer_printf(d->buf, "[%d]", type->array_or_vector_def.num_elems);
217
break;
218
case TYPE_FUNCTION:
219
_mesa_string_buffer_append(d->buf, "(");
220
dump_type_name(d, type->function_def.ret_type);
221
_mesa_string_buffer_append(d->buf, ")(");
222
for (size_t i = 0; i < type->function_def.args.num_types; ++i) {
223
if (i > 0)
224
_mesa_string_buffer_append(d->buf, ", ");
225
dump_type_name(d, type->function_def.args.types[i]);
226
}
227
_mesa_string_buffer_append(d->buf, ")");
228
break;
229
case TYPE_VECTOR:
230
_mesa_string_buffer_append(d->buf, "vector<");
231
dump_type_name(d, type->array_or_vector_def.elem_type);
232
_mesa_string_buffer_printf(d->buf, ", %d>", type->array_or_vector_def.num_elems);
233
break;
234
default:
235
_mesa_string_buffer_printf(d->buf, "unknown type %d", type->type);
236
}
237
}
238
239
static void
240
dump_type(struct dxil_dumper *d, const struct dxil_type *type)
241
{
242
switch (type->type) {
243
case TYPE_STRUCT:
244
_mesa_string_buffer_printf(d->buf, "struct %s {\n", type->struct_def.name);
245
dxil_dump_indention_inc(d);
246
247
for (size_t i = 0; i < type->struct_def.elem.num_types; ++i) {
248
dxil_dump_indent(d);
249
dump_type(d, type->struct_def.elem.types[i]);
250
_mesa_string_buffer_append(d->buf, "\n");
251
}
252
dxil_dump_indention_dec(d);
253
dxil_dump_indent(d);
254
_mesa_string_buffer_append(d->buf, "}\n");
255
break;
256
default:
257
dump_type_name(d, type);
258
break;
259
}
260
}
261
262
static void
263
dump_gvars(struct dxil_dumper *d, struct list_head *list)
264
{
265
if (!list_length(list))
266
return;
267
268
_mesa_string_buffer_append(d->buf, "Global variables:\n");
269
dxil_dump_indention_inc(d);
270
list_for_each_entry(struct dxil_gvar, gvar, list, head) {
271
dxil_dump_indent(d);
272
_mesa_string_buffer_printf(d->buf, "address_space(%d) ", gvar->as);
273
if (gvar->constant)
274
_mesa_string_buffer_append(d->buf, "const ");
275
if (gvar->align)
276
_mesa_string_buffer_append(d->buf, "align ");
277
if (gvar->initializer)
278
_mesa_string_buffer_printf(d->buf, "init_id:%d\n", gvar->initializer->id);
279
dump_type_name(d, gvar->type);
280
_mesa_string_buffer_printf(d->buf, " val_id:%d\n", gvar->value.id);
281
}
282
dxil_dump_indention_dec(d);
283
}
284
285
static void
286
dump_funcs(struct dxil_dumper *d, struct list_head *list)
287
{
288
if (!list_length(list))
289
return;
290
291
_mesa_string_buffer_append(d->buf, "Functions:\n");
292
dxil_dump_indention_inc(d);
293
list_for_each_entry(struct dxil_func, func, list, head) {
294
dxil_dump_indent(d);
295
if (func->decl)
296
_mesa_string_buffer_append(d->buf, "declare ");
297
_mesa_string_buffer_append(d->buf, func->name);
298
_mesa_string_buffer_append_char(d->buf, ' ');
299
dump_type_name(d, func->type);
300
if (func->attr_set)
301
_mesa_string_buffer_printf(d->buf, " #%d", func->attr_set);
302
_mesa_string_buffer_append_char(d->buf, '\n');
303
}
304
dxil_dump_indention_dec(d);
305
}
306
307
static void
308
dump_attr_set_list(struct dxil_dumper *d, struct list_head *list)
309
{
310
if (!list_length(list))
311
return;
312
313
_mesa_string_buffer_append(d->buf, "Attribute set:\n");
314
dxil_dump_indention_inc(d);
315
int attr_id = 1;
316
list_for_each_entry(struct attrib_set, attr, list, head) {
317
_mesa_string_buffer_printf(d->buf, " #%d: {", attr_id++);
318
for (unsigned i = 0; i < attr->num_attrs; ++i) {
319
if (i > 0)
320
_mesa_string_buffer_append_char(d->buf, ' ');
321
322
assert(attr->attrs[i].type == DXIL_ATTR_ENUM);
323
const char *value = "";
324
switch (attr->attrs[i].kind) {
325
case DXIL_ATTR_KIND_NONE: value = "none"; break;
326
case DXIL_ATTR_KIND_NO_UNWIND: value = "nounwind"; break;
327
case DXIL_ATTR_KIND_READ_NONE: value = "readnone"; break;
328
case DXIL_ATTR_KIND_READ_ONLY: value = "readonly"; break;
329
case DXIL_ATTR_KIND_NO_DUPLICATE: value = "noduplicate"; break;
330
}
331
_mesa_string_buffer_append(d->buf, value);
332
}
333
_mesa_string_buffer_append(d->buf, "}\n");
334
}
335
dxil_dump_indention_dec(d);
336
}
337
338
static void
339
dump_constants(struct dxil_dumper *d, struct list_head *list)
340
{
341
if (!list_length(list))
342
return;
343
344
_mesa_string_buffer_append(d->buf, "Constants:\n");
345
dxil_dump_indention_inc(d);
346
list_for_each_entry(struct dxil_const, cnst, list, head) {
347
_mesa_string_buffer_append_char(d->buf, ' ');
348
dump_value(d, &cnst->value);
349
_mesa_string_buffer_append(d->buf, " = ");
350
dump_type_name(d, cnst->value.type);
351
if (!cnst->undef) {
352
switch (cnst->value.type->type) {
353
case TYPE_FLOAT:
354
_mesa_string_buffer_printf(d->buf, " %10.5f\n", cnst->float_value);
355
break;
356
case TYPE_INTEGER:
357
_mesa_string_buffer_printf(d->buf, " %d\n", cnst->int_value);
358
break;
359
case TYPE_ARRAY:
360
_mesa_string_buffer_append(d->buf, "{");
361
for (unsigned i = 0;
362
i < cnst->value.type->array_or_vector_def.num_elems; i++) {
363
_mesa_string_buffer_printf(d->buf, " %%%d",
364
cnst->array_values[i]->id);
365
dump_type_name(d, cnst->value.type);
366
if (i != cnst->value.type->array_or_vector_def.num_elems - 1)
367
_mesa_string_buffer_append(d->buf, ",");
368
_mesa_string_buffer_append(d->buf, " ");
369
}
370
_mesa_string_buffer_append(d->buf, "}\n");
371
break;
372
default:
373
unreachable("Unsupported const type");
374
}
375
} else
376
_mesa_string_buffer_append(d->buf, " undef\n");
377
}
378
dxil_dump_indention_dec(d);
379
}
380
381
static void
382
dump_instrs(struct dxil_dumper *d, struct list_head *list)
383
{
384
_mesa_string_buffer_append(d->buf, "Shader body:\n");
385
dxil_dump_indention_inc(d);
386
387
list_for_each_entry(struct dxil_instr, instr, list, head) {
388
389
dxil_dump_indent(d);
390
if (instr->has_value) {
391
dump_value(d, &instr->value);
392
_mesa_string_buffer_append(d->buf, " = ");
393
} else {
394
_mesa_string_buffer_append_char(d->buf, ' ');
395
}
396
397
switch (instr->type) {
398
case INSTR_BINOP: dump_instr_binop(d, &instr->binop); break;
399
case INSTR_CMP: dump_instr_cmp(d, &instr->cmp);break;
400
case INSTR_SELECT:dump_instr_select(d, &instr->select); break;
401
case INSTR_CAST: dump_instr_cast(d, &instr->cast); break;
402
case INSTR_CALL: dump_instr_call(d, &instr->call); break;
403
case INSTR_RET: dump_instr_ret(d, &instr->ret); break;
404
case INSTR_EXTRACTVAL: dump_instr_extractval(d, &instr->extractval); break;
405
case INSTR_BR: dump_instr_branch(d, &instr->br); break;
406
case INSTR_PHI: dump_instr_phi(d, &instr->phi); break;
407
case INSTR_ALLOCA: dump_instr_alloca(d, &instr->alloca); break;
408
case INSTR_GEP: dump_instr_gep(d, &instr->gep); break;
409
case INSTR_LOAD: dump_instr_load(d, &instr->load); break;
410
case INSTR_STORE: dump_instr_store(d, &instr->store); break;
411
case INSTR_ATOMICRMW: dump_instr_atomicrmw(d, &instr->atomicrmw); break;
412
default:
413
_mesa_string_buffer_printf(d->buf, "unknown instruction type %d", instr->type);
414
}
415
416
_mesa_string_buffer_append(d->buf, "\n");
417
}
418
dxil_dump_indention_dec(d);
419
}
420
421
static void
422
dump_instr_binop(struct dxil_dumper *d, struct dxil_instr_binop *binop)
423
{
424
const char *str = binop->opcode < DXIL_BINOP_INSTR_COUNT ?
425
binop_strings[binop->opcode] : "INVALID";
426
427
_mesa_string_buffer_printf(d->buf, "%s ", str);
428
dump_instr_print_operands(d, 2, binop->operands);
429
}
430
431
static void
432
dump_instr_cmp(struct dxil_dumper *d, struct dxil_instr_cmp *cmp)
433
{
434
const char *str = cmp->pred < DXIL_CMP_INSTR_COUNT ?
435
pred_strings[cmp->pred] : "INVALID";
436
437
_mesa_string_buffer_printf(d->buf, "%s ", str);
438
dump_instr_print_operands(d, 2, cmp->operands);
439
}
440
441
static void
442
dump_instr_select(struct dxil_dumper *d, struct dxil_instr_select *select)
443
{
444
_mesa_string_buffer_append(d->buf, "sel ");
445
dump_instr_print_operands(d, 3, select->operands);
446
}
447
448
static void
449
dump_instr_cast(struct dxil_dumper *d, struct dxil_instr_cast *cast)
450
{
451
const char *str = cast->opcode < DXIL_CAST_INSTR_COUNT ?
452
cast_opcode_strings[cast->opcode] : "INVALID";
453
454
_mesa_string_buffer_printf(d->buf, "%s.", str);
455
dump_type_name(d, cast->type);
456
_mesa_string_buffer_append_char(d->buf, ' ');
457
dump_value(d, cast->value);
458
}
459
460
static void
461
dump_instr_call(struct dxil_dumper *d, struct dxil_instr_call *call)
462
{
463
assert(call->num_args == call->func->type->function_def.args.num_types);
464
struct dxil_type **func_arg_types = call->func->type->function_def.args.types;
465
466
_mesa_string_buffer_printf(d->buf, "%s(", call->func->name);
467
for (unsigned i = 0; i < call->num_args; ++i) {
468
if (i > 0)
469
_mesa_string_buffer_append(d->buf, ", ");
470
dump_type_name(d, func_arg_types[i]);
471
_mesa_string_buffer_append_char(d->buf, ' ');
472
dump_value(d, call->args[i]);
473
}
474
_mesa_string_buffer_append_char(d->buf, ')');
475
}
476
477
static void
478
dump_instr_ret(struct dxil_dumper *d, struct dxil_instr_ret *ret)
479
{
480
_mesa_string_buffer_append(d->buf, "ret ");
481
if (ret->value)
482
dump_value(d, ret->value);
483
}
484
485
static void
486
dump_instr_extractval(struct dxil_dumper *d, struct dxil_instr_extractval *extr)
487
{
488
_mesa_string_buffer_append(d->buf, "extractvalue ");
489
dump_type_name(d, extr->type);
490
dump_value(d, extr->src);
491
_mesa_string_buffer_printf(d->buf, ", %d", extr->idx);
492
}
493
494
static void
495
dump_instr_branch(struct dxil_dumper *d, struct dxil_instr_br *br)
496
{
497
_mesa_string_buffer_append(d->buf, "branch ");
498
if (br->cond)
499
dump_value(d, br->cond);
500
else
501
_mesa_string_buffer_append(d->buf, " (uncond)");
502
_mesa_string_buffer_printf(d->buf, " %d %d", br->succ[0], br->succ[1]);
503
}
504
505
static void
506
dump_instr_phi(struct dxil_dumper *d, struct dxil_instr_phi *phi)
507
{
508
_mesa_string_buffer_append(d->buf, "phi ");
509
dump_type_name(d, phi->type);
510
struct dxil_phi_src *src = phi->incoming;
511
for (unsigned i = 0; i < phi->num_incoming; ++i, ++src) {
512
if (i > 0)
513
_mesa_string_buffer_append(d->buf, ", ");
514
dump_value(d, src->value);
515
_mesa_string_buffer_printf(d->buf, "(%d)", src->block);
516
}
517
}
518
519
static void
520
dump_instr_alloca(struct dxil_dumper *d, struct dxil_instr_alloca *alloca)
521
{
522
_mesa_string_buffer_append(d->buf, "alloca ");
523
dump_type_name(d, alloca->alloc_type);
524
_mesa_string_buffer_append(d->buf, ", ");
525
dump_type_name(d, alloca->size_type);
526
_mesa_string_buffer_append(d->buf, ", ");
527
dump_value(d, alloca->size);
528
unsigned align_mask = (1 << 6 ) - 1;
529
unsigned align = alloca->align & align_mask;
530
_mesa_string_buffer_printf(d->buf, ", %d", 1 << (align - 1));
531
}
532
533
static void
534
dump_instr_gep(struct dxil_dumper *d, struct dxil_instr_gep *gep)
535
{
536
_mesa_string_buffer_append(d->buf, "getelementptr ");
537
if (gep->inbounds)
538
_mesa_string_buffer_append(d->buf, "inbounds ");
539
dump_type_name(d, gep->source_elem_type);
540
_mesa_string_buffer_append(d->buf, ", ");
541
for (unsigned i = 0; i < gep->num_operands; ++i) {
542
if (i > 0)
543
_mesa_string_buffer_append(d->buf, ", ");
544
dump_value(d, gep->operands[i]);
545
}
546
}
547
548
static void
549
dump_instr_load(struct dxil_dumper *d, struct dxil_instr_load *load)
550
{
551
_mesa_string_buffer_append(d->buf, "load ");
552
if (load->is_volatile)
553
_mesa_string_buffer_append(d->buf, " volatile");
554
dump_type_name(d, load->type);
555
_mesa_string_buffer_append(d->buf, ", ");
556
dump_value(d, load->ptr);
557
_mesa_string_buffer_printf(d->buf, ", %d", load->align);
558
}
559
560
static void
561
dump_instr_store(struct dxil_dumper *d, struct dxil_instr_store *store)
562
{
563
_mesa_string_buffer_append(d->buf, "store ");
564
if (store->is_volatile)
565
_mesa_string_buffer_append(d->buf, " volatile");
566
dump_value(d, store->value);
567
_mesa_string_buffer_append(d->buf, ", ");
568
dump_value(d, store->ptr);
569
_mesa_string_buffer_printf(d->buf, ", %d", store->align);
570
}
571
572
static const char *rmworder_str[] = {
573
[DXIL_ATOMIC_ORDERING_NOTATOMIC] = "not-atomic",
574
[DXIL_ATOMIC_ORDERING_UNORDERED] = "unordered",
575
[DXIL_ATOMIC_ORDERING_MONOTONIC] = "monotonic",
576
[DXIL_ATOMIC_ORDERING_ACQUIRE] = "acquire",
577
[DXIL_ATOMIC_ORDERING_RELEASE] = "release",
578
[DXIL_ATOMIC_ORDERING_ACQREL] = "acqrel",
579
[DXIL_ATOMIC_ORDERING_SEQCST] = "seqcst",
580
};
581
582
static const char *rmwsync_str[] = {
583
[DXIL_SYNC_SCOPE_SINGLETHREAD] = "single-thread",
584
[DXIL_SYNC_SCOPE_CROSSTHREAD] = "cross-thread",
585
};
586
587
static const char *rmwop_str[] = {
588
[DXIL_RMWOP_XCHG] = "xchg",
589
[DXIL_RMWOP_ADD] = "add",
590
[DXIL_RMWOP_SUB] = "sub",
591
[DXIL_RMWOP_AND] = "and",
592
[DXIL_RMWOP_NAND] = "nand",
593
[DXIL_RMWOP_OR] = "or",
594
[DXIL_RMWOP_XOR] = "xor",
595
[DXIL_RMWOP_MAX] = "max",
596
[DXIL_RMWOP_MIN] = "min",
597
[DXIL_RMWOP_UMAX] = "umax",
598
[DXIL_RMWOP_UMIN] = "umin",
599
};
600
601
static void
602
dump_instr_atomicrmw(struct dxil_dumper *d, struct dxil_instr_atomicrmw *rmw)
603
{
604
_mesa_string_buffer_printf(d->buf, "atomicrmw.%s ", rmwop_str[rmw->op]);
605
606
if (rmw->is_volatile)
607
_mesa_string_buffer_append(d->buf, " volatile");
608
dump_value(d, rmw->value);
609
_mesa_string_buffer_append(d->buf, ", ");
610
dump_value(d, rmw->ptr);
611
_mesa_string_buffer_printf(d->buf, ", ordering(%s)", rmworder_str[rmw->ordering]);
612
_mesa_string_buffer_printf(d->buf, ", sync_scope(%s)", rmwsync_str[rmw->syncscope]);
613
}
614
615
static void
616
dump_instr_print_operands(struct dxil_dumper *d, int num,
617
const struct dxil_value *val[])
618
{
619
for (int i = 0; i < num; ++i) {
620
if (i > 0)
621
_mesa_string_buffer_append(d->buf, ", ");
622
dump_value(d, val[i]);
623
}
624
}
625
626
static void
627
dump_value(struct dxil_dumper *d, const struct dxil_value *val)
628
{
629
if (val->id < 10)
630
_mesa_string_buffer_append(d->buf, " ");
631
if (val->id < 100)
632
_mesa_string_buffer_append(d->buf, " ");
633
_mesa_string_buffer_printf(d->buf, "%%%d", val->id);
634
dump_type_name(d, val->type);
635
}
636
637
static void
638
dump_mdnodes(struct dxil_dumper *d, struct list_head *list)
639
{
640
if (!list_length(list))
641
return;
642
643
_mesa_string_buffer_append(d->buf, "MD-Nodes:\n");
644
dxil_dump_indention_inc(d);
645
list_for_each_entry(struct dxil_mdnode, node, list, head) {
646
dump_mdnode(d, node);
647
}
648
dxil_dump_indention_dec(d);
649
}
650
651
static void
652
dump_mdnode(struct dxil_dumper *d, const struct dxil_mdnode *node)
653
{
654
dxil_dump_indent(d);
655
switch (node->type) {
656
case MD_STRING:
657
_mesa_string_buffer_printf(d->buf, "S:%s\n", node->string);
658
break;
659
case MD_VALUE:
660
_mesa_string_buffer_append(d->buf, "V:");
661
dump_type_name(d, node->value.type);
662
_mesa_string_buffer_append_char(d->buf, ' ');
663
dump_value(d, node->value.value);
664
_mesa_string_buffer_append_char(d->buf, '\n');
665
break;
666
case MD_NODE:
667
_mesa_string_buffer_append(d->buf, " \\\n");
668
dxil_dump_indention_inc(d);
669
for (size_t i = 0; i < node->node.num_subnodes; ++i) {
670
if (node->node.subnodes[i])
671
dump_mdnode(d, node->node.subnodes[i]);
672
else {
673
dxil_dump_indent(d);
674
_mesa_string_buffer_append(d->buf, "(nullptr)\n");
675
}
676
}
677
dxil_dump_indention_dec(d);
678
break;
679
}
680
}
681
682
static void
683
dump_named_nodes(struct dxil_dumper *d, struct list_head *list)
684
{
685
if (!list_length(list))
686
return;
687
688
_mesa_string_buffer_append(d->buf, "Named Nodes:\n");
689
dxil_dump_indention_inc(d);
690
list_for_each_entry(struct dxil_named_node, node, list, head) {
691
dxil_dump_indent(d);
692
_mesa_string_buffer_printf(d->buf, "%s:\n", node->name);
693
dxil_dump_indention_inc(d);
694
for (size_t i = 0; i < node->num_subnodes; ++i) {
695
if (node->subnodes[i])
696
dump_mdnode(d, node->subnodes[i]);
697
else {
698
dxil_dump_indent(d);
699
_mesa_string_buffer_append(d->buf, "(nullptr)\n");
700
}
701
}
702
dxil_dump_indention_dec(d);
703
}
704
dxil_dump_indention_dec(d);
705
}
706
707
static void
708
mask_to_string(uint32_t mask, char str[5])
709
{
710
const char *mc = "xyzw";
711
for (int i = 0; i < 4 && mask; ++i) {
712
str[i] = (mask & (1 << i)) ? mc[i] : '_';
713
}
714
str[4] = 0;
715
}
716
717
static void dump_io_signatures(struct _mesa_string_buffer *buf, struct dxil_module *m)
718
{
719
_mesa_string_buffer_append(buf, "\nInput signature:\n");
720
dump_io_signature(buf, m->num_sig_inputs, m->inputs);
721
_mesa_string_buffer_append(buf, "\nOutput signature:\n");
722
dump_io_signature(buf, m->num_sig_outputs, m->outputs);
723
}
724
725
static void dump_io_signature(struct _mesa_string_buffer *buf, unsigned num,
726
struct dxil_signature_record *io)
727
{
728
_mesa_string_buffer_append(buf, " SEMANTIC-NAME Index Mask Reg SysValue Format\n");
729
_mesa_string_buffer_append(buf, "----------------------------------------------\n");
730
for (unsigned i = 0; i < num; ++i, ++io) {
731
for (unsigned j = 0; j < io->num_elements; ++j) {
732
char mask[5] = "";
733
mask_to_string(io->elements[j].mask, mask);
734
_mesa_string_buffer_printf(buf, "%-15s %3d %4s %3d %-8s %-7s\n",
735
io->name, io->elements[j].semantic_index,
736
mask, io->elements[j].reg, io->sysvalue,
737
component_type_as_string(io->elements[j].comp_type));
738
}
739
}
740
}
741
742
static const char *component_type_as_string(uint32_t type)
743
{
744
return (type < DXIL_PROG_SIG_COMP_TYPE_COUNT) ?
745
dxil_type_strings[type] : "invalid";
746
}
747
748
static void dump_psv(struct _mesa_string_buffer *buf,
749
struct dxil_module *m)
750
{
751
_mesa_string_buffer_append(buf, "\nPipeline State Validation\nInputs:\n");
752
dump_psv_io(buf, m, m->num_sig_inputs, m->psv_inputs);
753
_mesa_string_buffer_append(buf, "\nOutputs:\n");
754
dump_psv_io(buf, m, m->num_sig_outputs, m->psv_outputs);
755
}
756
757
static void dump_psv_io(struct _mesa_string_buffer *buf, struct dxil_module *m,
758
unsigned num, struct dxil_psv_signature_element *io)
759
{
760
_mesa_string_buffer_append(buf, " SEMANTIC-NAME Rows Cols Kind Comp-Type Interp dynmask+stream Indices\n");
761
_mesa_string_buffer_append(buf, "----------------------------------------------\n");
762
for (unsigned i = 0; i < num; ++i, ++io) {
763
_mesa_string_buffer_printf(buf, "%-14s %d+%d %d+%d %4d %-7s %-4d %-9d [",
764
m->sem_string_table->buf + io->semantic_name_offset,
765
(int)io->start_row, (int)io->rows,
766
(int)((io->cols_and_start & 0xf) >> 4),
767
(int)(io->cols_and_start & 0xf),
768
(int)io->semantic_kind,
769
component_type_as_string(io->component_type),
770
(int)io->interpolation_mode,
771
(int)io->dynamic_mask_and_stream);
772
for (int k = 0; k < io->rows; ++k) {
773
if (k > 0)
774
_mesa_string_buffer_append(buf, ", ");
775
_mesa_string_buffer_printf(buf,"%d ", m->sem_index_table.data[io->start_row + k]);
776
}
777
_mesa_string_buffer_append(buf, "]\n");
778
}
779
}
780
781