vkd3d-shader/spirv: Emit immediate words for unhandled instructions.

The assembler can parse these to reconstruct the original bytecode.
This commit is contained in:
Giovanni Mascellani
2025-02-19 19:08:27 +01:00
committed by Henri Verbeet
parent 1417af2eab
commit 8c785f1dc9
Notes: Henri Verbeet 2025-03-10 15:22:45 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1382

View File

@@ -60,6 +60,8 @@
#define VKD3D_SPIRV_INSTRUCTION_OP_SHIFT 0u #define VKD3D_SPIRV_INSTRUCTION_OP_SHIFT 0u
#define VKD3D_SPIRV_INSTRUCTION_OP_MASK (0xffffu << VKD3D_SPIRV_INSTRUCTION_OP_SHIFT) #define VKD3D_SPIRV_INSTRUCTION_OP_MASK (0xffffu << VKD3D_SPIRV_INSTRUCTION_OP_SHIFT)
#define VKD3D_SPIRV_INDENT 15
#ifdef HAVE_SPIRV_TOOLS #ifdef HAVE_SPIRV_TOOLS
# include "spirv-tools/libspirv.h" # include "spirv-tools/libspirv.h"
@@ -211,6 +213,7 @@ struct spirv_colours
{ {
const char *reset; const char *reset;
const char *comment; const char *comment;
const char *literal;
}; };
struct spirv_parser struct spirv_parser
@@ -240,6 +243,16 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_error(struct spirv_parser *pars
parser->failed = true; parser->failed = true;
} }
static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_warning(struct spirv_parser *parser,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
vkd3d_shader_vwarning(parser->message_context, &parser->location, error, format, args);
va_end(args);
}
static uint32_t spirv_parser_read_u32(struct spirv_parser *parser) static uint32_t spirv_parser_read_u32(struct spirv_parser *parser)
{ {
if (parser->pos >= parser->size) if (parser->pos >= parser->size)
@@ -290,6 +303,13 @@ static void spirv_parser_print_generator(struct spirv_parser *parser, uint32_t m
spirv_parser_print_comment(parser, "Generator: Unknown (%#x); %u", id, version); spirv_parser_print_comment(parser, "Generator: Unknown (%#x); %u", id, version);
} }
static void spirv_parser_print_immediate_word(struct spirv_parser *parser,
struct vkd3d_string_buffer *buffer, const char *prefix, uint32_t w, const char *suffix)
{
vkd3d_string_buffer_printf(buffer, "%s!%s0x%08x%s%s",
prefix, parser->colours.literal, w, parser->colours.reset, suffix);
}
static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
{ {
uint32_t magic, version, generator, bound, schema; uint32_t magic, version, generator, bound, schema;
@@ -359,7 +379,6 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *parser) static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *parser)
{ {
struct vkd3d_string_buffer *buffer;
uint16_t op, count; uint16_t op, count;
unsigned int i; unsigned int i;
uint32_t word; uint32_t word;
@@ -375,17 +394,18 @@ static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *par
return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_INVALID_SHADER;
} }
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT)
vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, "");
spirv_parser_print_immediate_word(parser, parser->text, "", word, "");
--count; --count;
buffer = vkd3d_string_buffer_get(&parser->string_buffers);
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
{ {
word = spirv_parser_read_u32(parser); spirv_parser_print_immediate_word(parser, parser->text, " ", spirv_parser_read_u32(parser), "");
vkd3d_string_buffer_printf(buffer, " 0x%08x", word);
} }
spirv_parser_print_comment(parser, "<unrecognised instruction %#x>%s", op, buffer->buffer); vkd3d_string_buffer_printf(parser->text, "\n");
vkd3d_string_buffer_release(&parser->string_buffers, buffer);
spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
"Unrecognised instruction %#x.", op); "Unrecognised instruction %#x.", op);
return VKD3D_OK; return VKD3D_OK;
@@ -441,11 +461,13 @@ static enum vkd3d_result spirv_parser_init(struct spirv_parser *parser, const st
{ {
.reset = "", .reset = "",
.comment = "", .comment = "",
.literal = "",
}; };
static const struct spirv_colours colours = static const struct spirv_colours colours =
{ {
.reset = "\x1b[m", .reset = "\x1b[m",
.comment = "\x1b[36m", .comment = "\x1b[36m",
.literal = "\x1b[95m",
}; };
memset(parser, 0, sizeof(*parser)); memset(parser, 0, sizeof(*parser));