Path: blob/21.2-virgl/src/microsoft/compiler/dxil_dump.c
4564 views
/*1* Copyright © Microsoft Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "dxil_dump.h"24#include "dxil_internal.h"2526#define DIXL_DUMP_DECL27#include "dxil_dump_decls.h"2829#include "dxil_module.h"303132#include "util/string_buffer.h"33#include "util/list.h"3435#include <stdio.h>3637struct dxil_dumper {38struct _mesa_string_buffer *buf;39int current_indent;40};4142struct dxil_dumper *dxil_dump_create(void)43{44struct dxil_dumper *d = calloc(1, sizeof(struct dxil_dumper));45d->buf = _mesa_string_buffer_create(NULL, 1024);46d->current_indent = 0;47return d;48}4950void dxil_dump_free(struct dxil_dumper *d)51{52_mesa_string_buffer_destroy(d->buf);53d->buf = 0;54free(d);55}5657void dxil_dump_buf_to_file(struct dxil_dumper *d, FILE *f)58{59assert(f);60assert(d);61assert(d->buf);62fprintf(f, "%s", d->buf->buf);63}6465static66void dxil_dump_indention_inc(struct dxil_dumper *d)67{68++d->current_indent;69}7071static72void dxil_dump_indention_dec(struct dxil_dumper *d)73{74--d->current_indent;75assert(d->current_indent >= 0);76}7778static79void dxil_dump_indent(struct dxil_dumper *d)80{81for (int i = 0; i < 2 * d->current_indent; ++i)82_mesa_string_buffer_append_char(d->buf, ' ');83}8485void86dxil_dump_module(struct dxil_dumper *d, struct dxil_module *m)87{88assert(m);89assert(d);9091_mesa_string_buffer_printf(d->buf, "DXIL MODULE:\n");92dump_metadata(d, m);93dump_shader_info(d, &m->info);94dump_types(d, &m->type_list);95dump_gvars(d, &m->gvar_list);96dump_funcs(d, &m->func_list);97dump_attr_set_list(d, &m->attr_set_list);98dump_constants(d, &m->const_list);99dump_instrs(d, &m->instr_list);100dump_mdnodes(d, &m->mdnode_list);101dump_named_nodes(d, &m->md_named_node_list);102dump_io_signatures(d->buf, m);103dump_psv(d->buf, m);104_mesa_string_buffer_printf(d->buf, "END DXIL MODULE\n");105}106107static void108dump_metadata(struct dxil_dumper *d, struct dxil_module *m)109{110_mesa_string_buffer_printf(d->buf, "Shader: %s\n",111dump_shader_string(m->shader_kind));112113_mesa_string_buffer_printf(d->buf, "Version: %d.%d\n",114m->major_version, m->minor_version);115116dump_features(d->buf, &m->feats);117}118119static void120dump_shader_info(struct dxil_dumper *d, struct dxil_shader_info *info)121{122_mesa_string_buffer_append(d->buf, "Shader Info:\n");123if (info->has_out_position)124_mesa_string_buffer_append(d->buf, " has_out_position\n");125}126127static const char *128dump_shader_string(enum dxil_shader_kind kind)129{130#define SHADER_STR(X) case DXIL_ ## X ## _SHADER: return #X131132switch (kind) {133SHADER_STR(VERTEX);134SHADER_STR(PIXEL);135SHADER_STR(GEOMETRY);136SHADER_STR(COMPUTE);137default:138return "UNSUPPORTED";139}140#undef SHADER_STR141}142143static void144dump_features(struct _mesa_string_buffer *buf, struct dxil_features *feat)145{146_mesa_string_buffer_printf(buf, "Features:\n");147#define PRINT_FEAT(F) if (feat->F) _mesa_string_buffer_printf(buf, " %s\n", #F)148PRINT_FEAT(doubles);149PRINT_FEAT(cs_4x_raw_sb);150PRINT_FEAT(uavs_at_every_stage);151PRINT_FEAT(use_64uavs);152PRINT_FEAT(min_precision);153PRINT_FEAT(dx11_1_double_extensions);154PRINT_FEAT(dx11_1_shader_extensions);155PRINT_FEAT(dx9_comparison_filtering);156PRINT_FEAT(tiled_resources);157PRINT_FEAT(stencil_ref);158PRINT_FEAT(inner_coverage);159PRINT_FEAT(typed_uav_load_additional_formats);160PRINT_FEAT(rovs);161PRINT_FEAT(array_layer_from_vs_or_ds);162PRINT_FEAT(wave_ops);163PRINT_FEAT(int64_ops);164PRINT_FEAT(view_id);165PRINT_FEAT(barycentrics);166PRINT_FEAT(native_low_precision);167PRINT_FEAT(shading_rate);168PRINT_FEAT(raytracing_tier_1_1);169PRINT_FEAT(sampler_feedback);170#undef PRINT_FEAT171}172173static void174dump_types(struct dxil_dumper *d, struct list_head *list)175{176if (!list_length(list))177return;178179_mesa_string_buffer_append(d->buf, "Types:\n");180dxil_dump_indention_inc(d);181list_for_each_entry(struct dxil_type, type, list, head) {182dxil_dump_indent(d);183dump_type(d, type);184_mesa_string_buffer_append(d->buf, "\n");185}186dxil_dump_indention_dec(d);187}188189static void dump_type_name(struct dxil_dumper *d, const struct dxil_type *type)190{191if (!type) {192_mesa_string_buffer_append(d->buf, "(type error)");193return;194}195196switch (type->type) {197case TYPE_VOID:198_mesa_string_buffer_append(d->buf, "void");199break;200case TYPE_INTEGER:201_mesa_string_buffer_printf(d->buf, "int%d", type->int_bits);202break;203case TYPE_FLOAT:204_mesa_string_buffer_printf(d->buf, "float%d", type->float_bits);205break;206case TYPE_POINTER:207dump_type_name(d, type->ptr_target_type);208_mesa_string_buffer_append(d->buf, "*");209break;210case TYPE_STRUCT:211_mesa_string_buffer_printf(d->buf, "struct %s", type->struct_def.name);212break;213case TYPE_ARRAY:214dump_type_name(d, type->array_or_vector_def.elem_type);215_mesa_string_buffer_printf(d->buf, "[%d]", type->array_or_vector_def.num_elems);216break;217case TYPE_FUNCTION:218_mesa_string_buffer_append(d->buf, "(");219dump_type_name(d, type->function_def.ret_type);220_mesa_string_buffer_append(d->buf, ")(");221for (size_t i = 0; i < type->function_def.args.num_types; ++i) {222if (i > 0)223_mesa_string_buffer_append(d->buf, ", ");224dump_type_name(d, type->function_def.args.types[i]);225}226_mesa_string_buffer_append(d->buf, ")");227break;228case TYPE_VECTOR:229_mesa_string_buffer_append(d->buf, "vector<");230dump_type_name(d, type->array_or_vector_def.elem_type);231_mesa_string_buffer_printf(d->buf, ", %d>", type->array_or_vector_def.num_elems);232break;233default:234_mesa_string_buffer_printf(d->buf, "unknown type %d", type->type);235}236}237238static void239dump_type(struct dxil_dumper *d, const struct dxil_type *type)240{241switch (type->type) {242case TYPE_STRUCT:243_mesa_string_buffer_printf(d->buf, "struct %s {\n", type->struct_def.name);244dxil_dump_indention_inc(d);245246for (size_t i = 0; i < type->struct_def.elem.num_types; ++i) {247dxil_dump_indent(d);248dump_type(d, type->struct_def.elem.types[i]);249_mesa_string_buffer_append(d->buf, "\n");250}251dxil_dump_indention_dec(d);252dxil_dump_indent(d);253_mesa_string_buffer_append(d->buf, "}\n");254break;255default:256dump_type_name(d, type);257break;258}259}260261static void262dump_gvars(struct dxil_dumper *d, struct list_head *list)263{264if (!list_length(list))265return;266267_mesa_string_buffer_append(d->buf, "Global variables:\n");268dxil_dump_indention_inc(d);269list_for_each_entry(struct dxil_gvar, gvar, list, head) {270dxil_dump_indent(d);271_mesa_string_buffer_printf(d->buf, "address_space(%d) ", gvar->as);272if (gvar->constant)273_mesa_string_buffer_append(d->buf, "const ");274if (gvar->align)275_mesa_string_buffer_append(d->buf, "align ");276if (gvar->initializer)277_mesa_string_buffer_printf(d->buf, "init_id:%d\n", gvar->initializer->id);278dump_type_name(d, gvar->type);279_mesa_string_buffer_printf(d->buf, " val_id:%d\n", gvar->value.id);280}281dxil_dump_indention_dec(d);282}283284static void285dump_funcs(struct dxil_dumper *d, struct list_head *list)286{287if (!list_length(list))288return;289290_mesa_string_buffer_append(d->buf, "Functions:\n");291dxil_dump_indention_inc(d);292list_for_each_entry(struct dxil_func, func, list, head) {293dxil_dump_indent(d);294if (func->decl)295_mesa_string_buffer_append(d->buf, "declare ");296_mesa_string_buffer_append(d->buf, func->name);297_mesa_string_buffer_append_char(d->buf, ' ');298dump_type_name(d, func->type);299if (func->attr_set)300_mesa_string_buffer_printf(d->buf, " #%d", func->attr_set);301_mesa_string_buffer_append_char(d->buf, '\n');302}303dxil_dump_indention_dec(d);304}305306static void307dump_attr_set_list(struct dxil_dumper *d, struct list_head *list)308{309if (!list_length(list))310return;311312_mesa_string_buffer_append(d->buf, "Attribute set:\n");313dxil_dump_indention_inc(d);314int attr_id = 1;315list_for_each_entry(struct attrib_set, attr, list, head) {316_mesa_string_buffer_printf(d->buf, " #%d: {", attr_id++);317for (unsigned i = 0; i < attr->num_attrs; ++i) {318if (i > 0)319_mesa_string_buffer_append_char(d->buf, ' ');320321assert(attr->attrs[i].type == DXIL_ATTR_ENUM);322const char *value = "";323switch (attr->attrs[i].kind) {324case DXIL_ATTR_KIND_NONE: value = "none"; break;325case DXIL_ATTR_KIND_NO_UNWIND: value = "nounwind"; break;326case DXIL_ATTR_KIND_READ_NONE: value = "readnone"; break;327case DXIL_ATTR_KIND_READ_ONLY: value = "readonly"; break;328case DXIL_ATTR_KIND_NO_DUPLICATE: value = "noduplicate"; break;329}330_mesa_string_buffer_append(d->buf, value);331}332_mesa_string_buffer_append(d->buf, "}\n");333}334dxil_dump_indention_dec(d);335}336337static void338dump_constants(struct dxil_dumper *d, struct list_head *list)339{340if (!list_length(list))341return;342343_mesa_string_buffer_append(d->buf, "Constants:\n");344dxil_dump_indention_inc(d);345list_for_each_entry(struct dxil_const, cnst, list, head) {346_mesa_string_buffer_append_char(d->buf, ' ');347dump_value(d, &cnst->value);348_mesa_string_buffer_append(d->buf, " = ");349dump_type_name(d, cnst->value.type);350if (!cnst->undef) {351switch (cnst->value.type->type) {352case TYPE_FLOAT:353_mesa_string_buffer_printf(d->buf, " %10.5f\n", cnst->float_value);354break;355case TYPE_INTEGER:356_mesa_string_buffer_printf(d->buf, " %d\n", cnst->int_value);357break;358case TYPE_ARRAY:359_mesa_string_buffer_append(d->buf, "{");360for (unsigned i = 0;361i < cnst->value.type->array_or_vector_def.num_elems; i++) {362_mesa_string_buffer_printf(d->buf, " %%%d",363cnst->array_values[i]->id);364dump_type_name(d, cnst->value.type);365if (i != cnst->value.type->array_or_vector_def.num_elems - 1)366_mesa_string_buffer_append(d->buf, ",");367_mesa_string_buffer_append(d->buf, " ");368}369_mesa_string_buffer_append(d->buf, "}\n");370break;371default:372unreachable("Unsupported const type");373}374} else375_mesa_string_buffer_append(d->buf, " undef\n");376}377dxil_dump_indention_dec(d);378}379380static void381dump_instrs(struct dxil_dumper *d, struct list_head *list)382{383_mesa_string_buffer_append(d->buf, "Shader body:\n");384dxil_dump_indention_inc(d);385386list_for_each_entry(struct dxil_instr, instr, list, head) {387388dxil_dump_indent(d);389if (instr->has_value) {390dump_value(d, &instr->value);391_mesa_string_buffer_append(d->buf, " = ");392} else {393_mesa_string_buffer_append_char(d->buf, ' ');394}395396switch (instr->type) {397case INSTR_BINOP: dump_instr_binop(d, &instr->binop); break;398case INSTR_CMP: dump_instr_cmp(d, &instr->cmp);break;399case INSTR_SELECT:dump_instr_select(d, &instr->select); break;400case INSTR_CAST: dump_instr_cast(d, &instr->cast); break;401case INSTR_CALL: dump_instr_call(d, &instr->call); break;402case INSTR_RET: dump_instr_ret(d, &instr->ret); break;403case INSTR_EXTRACTVAL: dump_instr_extractval(d, &instr->extractval); break;404case INSTR_BR: dump_instr_branch(d, &instr->br); break;405case INSTR_PHI: dump_instr_phi(d, &instr->phi); break;406case INSTR_ALLOCA: dump_instr_alloca(d, &instr->alloca); break;407case INSTR_GEP: dump_instr_gep(d, &instr->gep); break;408case INSTR_LOAD: dump_instr_load(d, &instr->load); break;409case INSTR_STORE: dump_instr_store(d, &instr->store); break;410case INSTR_ATOMICRMW: dump_instr_atomicrmw(d, &instr->atomicrmw); break;411default:412_mesa_string_buffer_printf(d->buf, "unknown instruction type %d", instr->type);413}414415_mesa_string_buffer_append(d->buf, "\n");416}417dxil_dump_indention_dec(d);418}419420static void421dump_instr_binop(struct dxil_dumper *d, struct dxil_instr_binop *binop)422{423const char *str = binop->opcode < DXIL_BINOP_INSTR_COUNT ?424binop_strings[binop->opcode] : "INVALID";425426_mesa_string_buffer_printf(d->buf, "%s ", str);427dump_instr_print_operands(d, 2, binop->operands);428}429430static void431dump_instr_cmp(struct dxil_dumper *d, struct dxil_instr_cmp *cmp)432{433const char *str = cmp->pred < DXIL_CMP_INSTR_COUNT ?434pred_strings[cmp->pred] : "INVALID";435436_mesa_string_buffer_printf(d->buf, "%s ", str);437dump_instr_print_operands(d, 2, cmp->operands);438}439440static void441dump_instr_select(struct dxil_dumper *d, struct dxil_instr_select *select)442{443_mesa_string_buffer_append(d->buf, "sel ");444dump_instr_print_operands(d, 3, select->operands);445}446447static void448dump_instr_cast(struct dxil_dumper *d, struct dxil_instr_cast *cast)449{450const char *str = cast->opcode < DXIL_CAST_INSTR_COUNT ?451cast_opcode_strings[cast->opcode] : "INVALID";452453_mesa_string_buffer_printf(d->buf, "%s.", str);454dump_type_name(d, cast->type);455_mesa_string_buffer_append_char(d->buf, ' ');456dump_value(d, cast->value);457}458459static void460dump_instr_call(struct dxil_dumper *d, struct dxil_instr_call *call)461{462assert(call->num_args == call->func->type->function_def.args.num_types);463struct dxil_type **func_arg_types = call->func->type->function_def.args.types;464465_mesa_string_buffer_printf(d->buf, "%s(", call->func->name);466for (unsigned i = 0; i < call->num_args; ++i) {467if (i > 0)468_mesa_string_buffer_append(d->buf, ", ");469dump_type_name(d, func_arg_types[i]);470_mesa_string_buffer_append_char(d->buf, ' ');471dump_value(d, call->args[i]);472}473_mesa_string_buffer_append_char(d->buf, ')');474}475476static void477dump_instr_ret(struct dxil_dumper *d, struct dxil_instr_ret *ret)478{479_mesa_string_buffer_append(d->buf, "ret ");480if (ret->value)481dump_value(d, ret->value);482}483484static void485dump_instr_extractval(struct dxil_dumper *d, struct dxil_instr_extractval *extr)486{487_mesa_string_buffer_append(d->buf, "extractvalue ");488dump_type_name(d, extr->type);489dump_value(d, extr->src);490_mesa_string_buffer_printf(d->buf, ", %d", extr->idx);491}492493static void494dump_instr_branch(struct dxil_dumper *d, struct dxil_instr_br *br)495{496_mesa_string_buffer_append(d->buf, "branch ");497if (br->cond)498dump_value(d, br->cond);499else500_mesa_string_buffer_append(d->buf, " (uncond)");501_mesa_string_buffer_printf(d->buf, " %d %d", br->succ[0], br->succ[1]);502}503504static void505dump_instr_phi(struct dxil_dumper *d, struct dxil_instr_phi *phi)506{507_mesa_string_buffer_append(d->buf, "phi ");508dump_type_name(d, phi->type);509struct dxil_phi_src *src = phi->incoming;510for (unsigned i = 0; i < phi->num_incoming; ++i, ++src) {511if (i > 0)512_mesa_string_buffer_append(d->buf, ", ");513dump_value(d, src->value);514_mesa_string_buffer_printf(d->buf, "(%d)", src->block);515}516}517518static void519dump_instr_alloca(struct dxil_dumper *d, struct dxil_instr_alloca *alloca)520{521_mesa_string_buffer_append(d->buf, "alloca ");522dump_type_name(d, alloca->alloc_type);523_mesa_string_buffer_append(d->buf, ", ");524dump_type_name(d, alloca->size_type);525_mesa_string_buffer_append(d->buf, ", ");526dump_value(d, alloca->size);527unsigned align_mask = (1 << 6 ) - 1;528unsigned align = alloca->align & align_mask;529_mesa_string_buffer_printf(d->buf, ", %d", 1 << (align - 1));530}531532static void533dump_instr_gep(struct dxil_dumper *d, struct dxil_instr_gep *gep)534{535_mesa_string_buffer_append(d->buf, "getelementptr ");536if (gep->inbounds)537_mesa_string_buffer_append(d->buf, "inbounds ");538dump_type_name(d, gep->source_elem_type);539_mesa_string_buffer_append(d->buf, ", ");540for (unsigned i = 0; i < gep->num_operands; ++i) {541if (i > 0)542_mesa_string_buffer_append(d->buf, ", ");543dump_value(d, gep->operands[i]);544}545}546547static void548dump_instr_load(struct dxil_dumper *d, struct dxil_instr_load *load)549{550_mesa_string_buffer_append(d->buf, "load ");551if (load->is_volatile)552_mesa_string_buffer_append(d->buf, " volatile");553dump_type_name(d, load->type);554_mesa_string_buffer_append(d->buf, ", ");555dump_value(d, load->ptr);556_mesa_string_buffer_printf(d->buf, ", %d", load->align);557}558559static void560dump_instr_store(struct dxil_dumper *d, struct dxil_instr_store *store)561{562_mesa_string_buffer_append(d->buf, "store ");563if (store->is_volatile)564_mesa_string_buffer_append(d->buf, " volatile");565dump_value(d, store->value);566_mesa_string_buffer_append(d->buf, ", ");567dump_value(d, store->ptr);568_mesa_string_buffer_printf(d->buf, ", %d", store->align);569}570571static const char *rmworder_str[] = {572[DXIL_ATOMIC_ORDERING_NOTATOMIC] = "not-atomic",573[DXIL_ATOMIC_ORDERING_UNORDERED] = "unordered",574[DXIL_ATOMIC_ORDERING_MONOTONIC] = "monotonic",575[DXIL_ATOMIC_ORDERING_ACQUIRE] = "acquire",576[DXIL_ATOMIC_ORDERING_RELEASE] = "release",577[DXIL_ATOMIC_ORDERING_ACQREL] = "acqrel",578[DXIL_ATOMIC_ORDERING_SEQCST] = "seqcst",579};580581static const char *rmwsync_str[] = {582[DXIL_SYNC_SCOPE_SINGLETHREAD] = "single-thread",583[DXIL_SYNC_SCOPE_CROSSTHREAD] = "cross-thread",584};585586static const char *rmwop_str[] = {587[DXIL_RMWOP_XCHG] = "xchg",588[DXIL_RMWOP_ADD] = "add",589[DXIL_RMWOP_SUB] = "sub",590[DXIL_RMWOP_AND] = "and",591[DXIL_RMWOP_NAND] = "nand",592[DXIL_RMWOP_OR] = "or",593[DXIL_RMWOP_XOR] = "xor",594[DXIL_RMWOP_MAX] = "max",595[DXIL_RMWOP_MIN] = "min",596[DXIL_RMWOP_UMAX] = "umax",597[DXIL_RMWOP_UMIN] = "umin",598};599600static void601dump_instr_atomicrmw(struct dxil_dumper *d, struct dxil_instr_atomicrmw *rmw)602{603_mesa_string_buffer_printf(d->buf, "atomicrmw.%s ", rmwop_str[rmw->op]);604605if (rmw->is_volatile)606_mesa_string_buffer_append(d->buf, " volatile");607dump_value(d, rmw->value);608_mesa_string_buffer_append(d->buf, ", ");609dump_value(d, rmw->ptr);610_mesa_string_buffer_printf(d->buf, ", ordering(%s)", rmworder_str[rmw->ordering]);611_mesa_string_buffer_printf(d->buf, ", sync_scope(%s)", rmwsync_str[rmw->syncscope]);612}613614static void615dump_instr_print_operands(struct dxil_dumper *d, int num,616const struct dxil_value *val[])617{618for (int i = 0; i < num; ++i) {619if (i > 0)620_mesa_string_buffer_append(d->buf, ", ");621dump_value(d, val[i]);622}623}624625static void626dump_value(struct dxil_dumper *d, const struct dxil_value *val)627{628if (val->id < 10)629_mesa_string_buffer_append(d->buf, " ");630if (val->id < 100)631_mesa_string_buffer_append(d->buf, " ");632_mesa_string_buffer_printf(d->buf, "%%%d", val->id);633dump_type_name(d, val->type);634}635636static void637dump_mdnodes(struct dxil_dumper *d, struct list_head *list)638{639if (!list_length(list))640return;641642_mesa_string_buffer_append(d->buf, "MD-Nodes:\n");643dxil_dump_indention_inc(d);644list_for_each_entry(struct dxil_mdnode, node, list, head) {645dump_mdnode(d, node);646}647dxil_dump_indention_dec(d);648}649650static void651dump_mdnode(struct dxil_dumper *d, const struct dxil_mdnode *node)652{653dxil_dump_indent(d);654switch (node->type) {655case MD_STRING:656_mesa_string_buffer_printf(d->buf, "S:%s\n", node->string);657break;658case MD_VALUE:659_mesa_string_buffer_append(d->buf, "V:");660dump_type_name(d, node->value.type);661_mesa_string_buffer_append_char(d->buf, ' ');662dump_value(d, node->value.value);663_mesa_string_buffer_append_char(d->buf, '\n');664break;665case MD_NODE:666_mesa_string_buffer_append(d->buf, " \\\n");667dxil_dump_indention_inc(d);668for (size_t i = 0; i < node->node.num_subnodes; ++i) {669if (node->node.subnodes[i])670dump_mdnode(d, node->node.subnodes[i]);671else {672dxil_dump_indent(d);673_mesa_string_buffer_append(d->buf, "(nullptr)\n");674}675}676dxil_dump_indention_dec(d);677break;678}679}680681static void682dump_named_nodes(struct dxil_dumper *d, struct list_head *list)683{684if (!list_length(list))685return;686687_mesa_string_buffer_append(d->buf, "Named Nodes:\n");688dxil_dump_indention_inc(d);689list_for_each_entry(struct dxil_named_node, node, list, head) {690dxil_dump_indent(d);691_mesa_string_buffer_printf(d->buf, "%s:\n", node->name);692dxil_dump_indention_inc(d);693for (size_t i = 0; i < node->num_subnodes; ++i) {694if (node->subnodes[i])695dump_mdnode(d, node->subnodes[i]);696else {697dxil_dump_indent(d);698_mesa_string_buffer_append(d->buf, "(nullptr)\n");699}700}701dxil_dump_indention_dec(d);702}703dxil_dump_indention_dec(d);704}705706static void707mask_to_string(uint32_t mask, char str[5])708{709const char *mc = "xyzw";710for (int i = 0; i < 4 && mask; ++i) {711str[i] = (mask & (1 << i)) ? mc[i] : '_';712}713str[4] = 0;714}715716static void dump_io_signatures(struct _mesa_string_buffer *buf, struct dxil_module *m)717{718_mesa_string_buffer_append(buf, "\nInput signature:\n");719dump_io_signature(buf, m->num_sig_inputs, m->inputs);720_mesa_string_buffer_append(buf, "\nOutput signature:\n");721dump_io_signature(buf, m->num_sig_outputs, m->outputs);722}723724static void dump_io_signature(struct _mesa_string_buffer *buf, unsigned num,725struct dxil_signature_record *io)726{727_mesa_string_buffer_append(buf, " SEMANTIC-NAME Index Mask Reg SysValue Format\n");728_mesa_string_buffer_append(buf, "----------------------------------------------\n");729for (unsigned i = 0; i < num; ++i, ++io) {730for (unsigned j = 0; j < io->num_elements; ++j) {731char mask[5] = "";732mask_to_string(io->elements[j].mask, mask);733_mesa_string_buffer_printf(buf, "%-15s %3d %4s %3d %-8s %-7s\n",734io->name, io->elements[j].semantic_index,735mask, io->elements[j].reg, io->sysvalue,736component_type_as_string(io->elements[j].comp_type));737}738}739}740741static const char *component_type_as_string(uint32_t type)742{743return (type < DXIL_PROG_SIG_COMP_TYPE_COUNT) ?744dxil_type_strings[type] : "invalid";745}746747static void dump_psv(struct _mesa_string_buffer *buf,748struct dxil_module *m)749{750_mesa_string_buffer_append(buf, "\nPipeline State Validation\nInputs:\n");751dump_psv_io(buf, m, m->num_sig_inputs, m->psv_inputs);752_mesa_string_buffer_append(buf, "\nOutputs:\n");753dump_psv_io(buf, m, m->num_sig_outputs, m->psv_outputs);754}755756static void dump_psv_io(struct _mesa_string_buffer *buf, struct dxil_module *m,757unsigned num, struct dxil_psv_signature_element *io)758{759_mesa_string_buffer_append(buf, " SEMANTIC-NAME Rows Cols Kind Comp-Type Interp dynmask+stream Indices\n");760_mesa_string_buffer_append(buf, "----------------------------------------------\n");761for (unsigned i = 0; i < num; ++i, ++io) {762_mesa_string_buffer_printf(buf, "%-14s %d+%d %d+%d %4d %-7s %-4d %-9d [",763m->sem_string_table->buf + io->semantic_name_offset,764(int)io->start_row, (int)io->rows,765(int)((io->cols_and_start & 0xf) >> 4),766(int)(io->cols_and_start & 0xf),767(int)io->semantic_kind,768component_type_as_string(io->component_type),769(int)io->interpolation_mode,770(int)io->dynamic_mask_and_stream);771for (int k = 0; k < io->rows; ++k) {772if (k > 0)773_mesa_string_buffer_append(buf, ", ");774_mesa_string_buffer_printf(buf,"%d ", m->sem_index_table.data[io->start_row + k]);775}776_mesa_string_buffer_append(buf, "]\n");777}778}779780781