mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/spirv: Parse the SPIR-V magic number.
This commit is contained in:
parent
49fba97b0a
commit
6cac18e395
Notes:
Henri Verbeet
2024-12-09 16:17:46 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1239
@ -38,6 +38,8 @@
|
||||
# define VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER 0
|
||||
#endif
|
||||
|
||||
#define VKD3D_SPIRV_HEADER_SIZE 5
|
||||
|
||||
#ifdef HAVE_SPIRV_TOOLS
|
||||
# include "spirv-tools/libspirv.h"
|
||||
|
||||
@ -185,10 +187,25 @@ static bool vkd3d_spirv_validate(struct vkd3d_string_buffer *buffer, const struc
|
||||
|
||||
#endif /* HAVE_SPIRV_TOOLS */
|
||||
|
||||
struct spirv_colours
|
||||
{
|
||||
const char *reset;
|
||||
const char *comment;
|
||||
};
|
||||
|
||||
struct spirv_parser
|
||||
{
|
||||
struct vkd3d_shader_location location;
|
||||
struct vkd3d_shader_message_context *message_context;
|
||||
enum vkd3d_shader_compile_option_formatting_flags formatting;
|
||||
struct spirv_colours colours;
|
||||
bool failed;
|
||||
|
||||
const uint32_t *code;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
|
||||
struct vkd3d_string_buffer *text;
|
||||
};
|
||||
|
||||
static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_error(struct spirv_parser *parser,
|
||||
@ -199,6 +216,90 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_error(struct spirv_parser *pars
|
||||
va_start(args, format);
|
||||
vkd3d_shader_verror(parser->message_context, &parser->location, error, format, args);
|
||||
va_end(args);
|
||||
parser->failed = true;
|
||||
}
|
||||
|
||||
static uint32_t spirv_parser_read_u32(struct spirv_parser *parser)
|
||||
{
|
||||
if (parser->pos >= parser->size)
|
||||
{
|
||||
parser->failed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parser->code[parser->pos++];
|
||||
}
|
||||
|
||||
static void VKD3D_PRINTF_FUNC(2, 3) spirv_parser_print_comment(struct spirv_parser *parser, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!parser->text)
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
vkd3d_string_buffer_printf(parser->text, "%s; ", parser->colours.comment);
|
||||
vkd3d_string_buffer_vprintf(parser->text, format, args);
|
||||
vkd3d_string_buffer_printf(parser->text, "%s\n", parser->colours.reset);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
|
||||
{
|
||||
uint32_t magic;
|
||||
|
||||
if (parser->pos > parser->size || parser->size - parser->pos < VKD3D_SPIRV_HEADER_SIZE)
|
||||
{
|
||||
spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_INVALID_SHADER,
|
||||
"Unexpected end while reading the SPIR-V header.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
magic = spirv_parser_read_u32(parser);
|
||||
|
||||
if (magic != SpvMagicNumber)
|
||||
{
|
||||
spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_INVALID_SHADER,
|
||||
"Invalid magic number %#08x.", magic);
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER)
|
||||
spirv_parser_print_comment(parser, "SPIR-V");
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static enum vkd3d_result spirv_parser_parse(struct spirv_parser *parser, struct vkd3d_shader_code *text)
|
||||
{
|
||||
struct vkd3d_string_buffer buffer;
|
||||
enum vkd3d_result ret;
|
||||
|
||||
if (text)
|
||||
{
|
||||
vkd3d_string_buffer_init(&buffer);
|
||||
parser->text = &buffer;
|
||||
}
|
||||
|
||||
if ((ret = spirv_parser_read_header(parser)) < 0)
|
||||
goto fail;
|
||||
|
||||
if (parser->failed)
|
||||
{
|
||||
ret = VKD3D_ERROR_INVALID_SHADER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
fail:
|
||||
if (text)
|
||||
{
|
||||
if (TRACE_ON())
|
||||
vkd3d_string_buffer_trace(&buffer);
|
||||
vkd3d_string_buffer_cleanup(&buffer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void spirv_parser_cleanup(struct spirv_parser *parser)
|
||||
@ -207,8 +308,20 @@ static void spirv_parser_cleanup(struct spirv_parser *parser)
|
||||
}
|
||||
|
||||
static enum vkd3d_result spirv_parser_init(struct spirv_parser *parser, const struct vkd3d_shader_code *source,
|
||||
const char *source_name, struct vkd3d_shader_message_context *message_context)
|
||||
const char *source_name, enum vkd3d_shader_compile_option_formatting_flags formatting,
|
||||
struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
static const struct spirv_colours no_colours =
|
||||
{
|
||||
.reset = "",
|
||||
.comment = "",
|
||||
};
|
||||
static const struct spirv_colours colours =
|
||||
{
|
||||
.reset = "\x1b[m",
|
||||
.comment = "\x1b[36m",
|
||||
};
|
||||
|
||||
memset(parser, 0, sizeof(*parser));
|
||||
parser->location.source_name = source_name;
|
||||
parser->message_context = message_context;
|
||||
@ -220,6 +333,14 @@ static enum vkd3d_result spirv_parser_init(struct spirv_parser *parser, const st
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
parser->formatting = formatting;
|
||||
if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR)
|
||||
parser->colours = colours;
|
||||
else
|
||||
parser->colours = no_colours;
|
||||
parser->code = source->code;
|
||||
parser->size = source->size / 4;
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
@ -236,11 +357,14 @@ static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_co
|
||||
|
||||
MESSAGE("Creating a SPIR-V parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
|
||||
|
||||
if ((ret = spirv_parser_init(&parser, spirv, source_name, message_context)) < 0)
|
||||
if ((ret = spirv_parser_init(&parser, spirv, source_name, formatting, message_context)) < 0)
|
||||
return ret;
|
||||
|
||||
ret = spirv_parser_parse(&parser, out);
|
||||
|
||||
spirv_parser_cleanup(&parser);
|
||||
|
||||
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, enum vkd3d_shader_spirv_environment environment)
|
||||
|
Loading…
x
Reference in New Issue
Block a user