From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 264 +++++++++++++++++++------------------- 1 file changed, 133 insertions(+), 131 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index dc3d96313..03ed9f2c8 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -36,137 +36,7 @@
#ifdef HAVE_SPIRV_TOOLS # include "spirv-tools/libspirv.h" - -static spv_target_env spv_target_env_from_vkd3d(enum vkd3d_shader_spirv_environment environment) -{ - switch (environment) - { - case VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5: - return SPV_ENV_OPENGL_4_5; - case VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0: - return SPV_ENV_VULKAN_1_0; - default: - ERR("Invalid environment %#x.\n", environment); - return SPV_ENV_VULKAN_1_0; - } -} - -static uint32_t get_binary_to_text_options(enum vkd3d_shader_compile_option_formatting_flags formatting) -{ - uint32_t out = 0; - unsigned int i; - - static const struct - { - enum vkd3d_shader_compile_option_formatting_flags vkd3d; - uint32_t spv; - bool invert; - } - valuemap[] = - { - {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR, SPV_BINARY_TO_TEXT_OPTION_COLOR }, - {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT, SPV_BINARY_TO_TEXT_OPTION_INDENT }, - {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS, SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET}, - {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, true}, - {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_RAW_IDS, SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES, true}, - }; - - for (i = 0; i < ARRAY_SIZE(valuemap); ++i) - { - if (valuemap[i].invert == !(formatting & valuemap[i].vkd3d)) - out |= valuemap[i].spv; - } - - return out; -} - -static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment, - enum vkd3d_shader_compile_option_formatting_flags formatting, struct vkd3d_shader_code *out) -{ - spv_diagnostic diagnostic = NULL; - spv_text text = NULL; - spv_context context; - spv_result_t spvret; - enum vkd3d_result result = VKD3D_OK; - - context = spvContextCreate(spv_target_env_from_vkd3d(environment)); - - if (!(spvret = spvBinaryToText(context, spirv->code, spirv->size / sizeof(uint32_t), - get_binary_to_text_options(formatting), &text, &diagnostic))) - { - void *code = vkd3d_malloc(text->length); - if (code) - { - memcpy(code, text->str, text->length); - out->size = text->length; - out->code = code; - } - else - result = VKD3D_ERROR_OUT_OF_MEMORY; - } - else - { - FIXME("Failed to convert SPIR-V binary to text, ret %d.\n", spvret); - FIXME("Diagnostic message: %s.\n", debugstr_a(diagnostic->error)); - result = VKD3D_ERROR; - } - - spvTextDestroy(text); - spvDiagnosticDestroy(diagnostic); - spvContextDestroy(context); - - return result; -} - -static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment) -{ - static const enum vkd3d_shader_compile_option_formatting_flags formatting - = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; - struct vkd3d_shader_code text; - - if (!vkd3d_spirv_binary_to_text(spirv, environment, formatting, &text)) - { - vkd3d_shader_trace_text(text.code, text.size); - vkd3d_shader_free_shader_code(&text); - } -} - -static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment) -{ - spv_diagnostic diagnostic = NULL; - spv_context context; - spv_result_t ret; - - context = spvContextCreate(spv_target_env_from_vkd3d(environment)); - - if ((ret = spvValidateBinary(context, spirv->code, spirv->size / sizeof(uint32_t), - &diagnostic))) - { - FIXME("Failed to validate SPIR-V binary, ret %d.\n", ret); - FIXME("Diagnostic message: %s.\n", debugstr_a(diagnostic->error)); - } - - spvDiagnosticDestroy(diagnostic); - spvContextDestroy(context); -} - -#else - -static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment, - enum vkd3d_shader_compile_option_formatting_flags formatting, struct vkd3d_shader_code *out) -{ - return VKD3D_ERROR; -} -static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment) {} -static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv, - enum vkd3d_shader_spirv_environment environment) {} - -#endif /* HAVE_SPIRV_TOOLS */ +#endif
enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, unsigned int index) @@ -2754,6 +2624,138 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_warning(struct spirv_compiler va_end(args); }
+#ifdef HAVE_SPIRV_TOOLS +static spv_target_env spv_target_env_from_vkd3d(enum vkd3d_shader_spirv_environment environment) +{ + switch (environment) + { + case VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5: + return SPV_ENV_OPENGL_4_5; + case VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0: + return SPV_ENV_VULKAN_1_0; + default: + ERR("Invalid environment %#x.\n", environment); + return SPV_ENV_VULKAN_1_0; + } +} + +static uint32_t get_binary_to_text_options(enum vkd3d_shader_compile_option_formatting_flags formatting) +{ + uint32_t out = 0; + unsigned int i; + + static const struct + { + enum vkd3d_shader_compile_option_formatting_flags vkd3d; + uint32_t spv; + bool invert; + } + valuemap[] = + { + {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR, SPV_BINARY_TO_TEXT_OPTION_COLOR }, + {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT, SPV_BINARY_TO_TEXT_OPTION_INDENT }, + {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS, SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET}, + {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, true}, + {VKD3D_SHADER_COMPILE_OPTION_FORMATTING_RAW_IDS, SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES, true}, + }; + + for (i = 0; i < ARRAY_SIZE(valuemap); ++i) + { + if (valuemap[i].invert == !(formatting & valuemap[i].vkd3d)) + out |= valuemap[i].spv; + } + + return out; +} + +static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment, + enum vkd3d_shader_compile_option_formatting_flags formatting, struct vkd3d_shader_code *out) +{ + spv_diagnostic diagnostic = NULL; + spv_text text = NULL; + spv_context context; + spv_result_t spvret; + enum vkd3d_result result = VKD3D_OK; + + context = spvContextCreate(spv_target_env_from_vkd3d(environment)); + + if (!(spvret = spvBinaryToText(context, spirv->code, spirv->size / sizeof(uint32_t), + get_binary_to_text_options(formatting), &text, &diagnostic))) + { + void *code = vkd3d_malloc(text->length); + if (code) + { + memcpy(code, text->str, text->length); + out->size = text->length; + out->code = code; + } + else + result = VKD3D_ERROR_OUT_OF_MEMORY; + } + else + { + FIXME("Failed to convert SPIR-V binary to text, ret %d.\n", spvret); + FIXME("Diagnostic message: %s.\n", debugstr_a(diagnostic->error)); + result = VKD3D_ERROR; + } + + spvTextDestroy(text); + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); + + return result; +} + +static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment) +{ + static const enum vkd3d_shader_compile_option_formatting_flags formatting + = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; + struct vkd3d_shader_code text; + + if (!vkd3d_spirv_binary_to_text(spirv, environment, formatting, &text)) + { + vkd3d_shader_trace_text(text.code, text.size); + vkd3d_shader_free_shader_code(&text); + } +} + +static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment) +{ + spv_diagnostic diagnostic = NULL; + spv_context context; + spv_result_t ret; + + context = spvContextCreate(spv_target_env_from_vkd3d(environment)); + + if ((ret = spvValidateBinary(context, spirv->code, spirv->size / sizeof(uint32_t), + &diagnostic))) + { + FIXME("Failed to validate SPIR-V binary, ret %d.\n", ret); + FIXME("Diagnostic message: %s.\n", debugstr_a(diagnostic->error)); + } + + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); +} + +#else + +static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment, + enum vkd3d_shader_compile_option_formatting_flags formatting, struct vkd3d_shader_code *out) +{ + return VKD3D_ERROR; +} +static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment) {} +static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv, + enum vkd3d_shader_spirv_environment environment) {} + +#endif /* HAVE_SPIRV_TOOLS */ + static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spirv_compiler *compiler, const struct vkd3d_shader_register_range *range) {