diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index e4c86ed5..367f8a20 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -40,11 +40,17 @@ enum vkd3d_shader_structure_type VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; -enum vkd3d_shader_compiler_option +enum vkd3d_shader_compile_option_name { - VKD3D_SHADER_STRIP_DEBUG = 0x00000001, + VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG = 0x00000001, - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILER_OPTION), + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), +}; + +struct vkd3d_shader_compile_option +{ + enum vkd3d_shader_compile_option_name name; + unsigned int value; }; enum vkd3d_shader_visibility @@ -226,6 +232,9 @@ struct vkd3d_shader_compile_info const void *next; struct vkd3d_shader_code source; + + const struct vkd3d_shader_compile_option *options; + unsigned int option_count; }; enum vkd3d_shader_spirv_environment @@ -644,8 +653,7 @@ struct vkd3d_shader_signature #ifndef VKD3D_SHADER_NO_PROTOTYPES -int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *spirv, unsigned int compiler_options); +int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv); void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code); int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, @@ -675,7 +683,7 @@ void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature * Function pointer typedefs for vkd3d-shader functions. */ typedef int (*PFN_vkd3d_shader_compile_dxbc)(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *spirv, unsigned int compiler_options); + struct vkd3d_shader_code *spirv); typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code); typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 5770341e..9b655e40 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2062,7 +2062,7 @@ struct vkd3d_dxbc_compiler { struct vkd3d_spirv_builder spirv_builder; - uint32_t options; + bool strip_debug; struct rb_tree symbol_table; uint32_t temp_id; @@ -2123,8 +2123,7 @@ static bool is_control_point_phase(const struct vkd3d_shader_phase *phase) static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler); struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options, - const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_info *scan_info) { const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature; @@ -2164,7 +2163,22 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader } vkd3d_spirv_builder_init(&compiler->spirv_builder); - compiler->options = compiler_options; + + for (i = 0; i < compile_info->option_count; ++i) + { + const struct vkd3d_shader_compile_option *option = &compile_info->options[i]; + + switch (option->name) + { + case VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG: + compiler->strip_debug = !!option->value; + break; + + default: + WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value); + break; + } + } rb_init(&compiler->symbol_table, vkd3d_symbol_compare); @@ -8723,7 +8737,7 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler); } - if (compiler->options & VKD3D_SHADER_STRIP_DEBUG) + if (compiler->strip_debug) vkd3d_spirv_stream_clear(&builder->debug_stream); if (!vkd3d_spirv_compile_module(builder, spirv)) diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index ae4a9b40..71794368 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -103,8 +103,7 @@ static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) free_shader_desc(&parser->shader_desc); } -int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *spirv, unsigned int compiler_options) +int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv) { struct vkd3d_shader_instruction instruction; struct vkd3d_dxbc_compiler *spirv_compiler; @@ -112,8 +111,7 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_in struct vkd3d_shader_parser parser; int ret; - TRACE("compile_info %p, spirv %p, compiler_options %#x.\n", - compile_info, spirv, compiler_options); + TRACE("compile_info %p, spirv %p.\n", compile_info, spirv); if (compile_info->type != VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO) { @@ -135,7 +133,7 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_compile_info *compile_in vkd3d_shader_trace(parser.data); if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version, - &parser.shader_desc, compiler_options, compile_info, &scan_info))) + &parser.shader_desc, compile_info, &scan_info))) { ERR("Failed to create DXBC compiler.\n"); vkd3d_shader_parser_destroy(&parser); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 9945c6b4..ecfd6658 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -820,8 +820,7 @@ int shader_parse_input_signature(const void *dxbc, size_t dxbc_length, struct vkd3d_dxbc_compiler; struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options, - const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_info *scan_info) DECLSPEC_HIDDEN; int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 831bbde5..8bc2595c 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1350,8 +1350,10 @@ static HRESULT create_shader_stage(struct d3d12_device *device, compile_info.next = shader_interface; compile_info.source.code = code->pShaderBytecode; compile_info.source.size = code->BytecodeLength; + compile_info.options = NULL; + compile_info.option_count = 0; - if ((ret = vkd3d_shader_compile_dxbc(&compile_info, &spirv, 0)) < 0) + if ((ret = vkd3d_shader_compile_dxbc(&compile_info, &spirv)) < 0) { WARN("Failed to compile shader, vkd3d result %d.\n", ret); return hresult_from_vkd3d_result(ret); diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index 5f7b0c2f..d33dafda 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -26,6 +26,8 @@ #include "vkd3d_common.h" #include "vkd3d_shader.h" +#define MAX_COMPILE_OPTIONS 1 + static bool read_shader(struct vkd3d_shader_code *shader, const char *filename) { struct stat st; @@ -87,11 +89,11 @@ static bool write_shader(const struct vkd3d_shader_code *shader, const char *fil static const struct { const char *name; - enum vkd3d_shader_compiler_option compiler_option; + enum vkd3d_shader_compile_option_name compile_option; } compiler_options[] = { - {"--strip-debug", VKD3D_SHADER_STRIP_DEBUG}, + {"--strip-debug", VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG}, }; static void print_usage(const char *program_name) @@ -108,9 +110,38 @@ struct options { const char *filename; const char *output_filename; - unsigned int compiler_options; + struct vkd3d_shader_compile_option compile_options[MAX_COMPILE_OPTIONS]; + unsigned int compile_option_count; }; +static void add_compile_option(struct options *options, + enum vkd3d_shader_compile_option_name name, unsigned int value) +{ + struct vkd3d_shader_compile_option *o; + unsigned int i; + + for (i = 0; i < options->compile_option_count; ++i) + { + o = &options->compile_options[i]; + + if (o->name == name) + { + o->value = value; + return; + } + } + + if (options->compile_option_count >= ARRAY_SIZE(options->compile_options)) + { + fprintf(stderr, "Ignoring option.\n"); + return; + } + + o = &options->compile_options[options->compile_option_count++]; + o->name = name; + o->value = value; +} + static bool parse_command_line(int argc, char **argv, struct options *options) { unsigned int i, j; @@ -134,7 +165,7 @@ static bool parse_command_line(int argc, char **argv, struct options *options) { if (!strcmp(argv[i], compiler_options[j].name)) { - options->compiler_options |= compiler_options[j].compiler_option; + add_compile_option(options, compiler_options[j].compile_option, 1); break; } } @@ -161,6 +192,8 @@ int main(int argc, char **argv) info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; info.next = NULL; + info.options = options.compile_options; + info.option_count = options.compile_option_count; if (!read_shader(&info.source, options.filename)) { @@ -168,7 +201,7 @@ int main(int argc, char **argv) return 1; } - ret = vkd3d_shader_compile_dxbc(&info, &spirv, options.compiler_options); + ret = vkd3d_shader_compile_dxbc(&info, &spirv); vkd3d_shader_free_shader_code(&info.source); if (ret < 0) { diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c index 9e5bdf31..00c6f957 100644 --- a/tests/vkd3d_shader_api.c +++ b/tests/vkd3d_shader_api.c @@ -49,13 +49,20 @@ static void test_invalid_shaders(void) 0x3f800000, 0x3f800000, 0x3f800000, 0x01000002, 0x01000015, 0x08000036, 0x001020f2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0100003e, }; + static const struct vkd3d_shader_compile_option option = + { + .name = VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG, + .value = 1, + }; info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; info.next = NULL; info.source.code = ps_break_code; info.source.size = sizeof(ps_break_code); + info.options = &option; + info.option_count = 1; - rc = vkd3d_shader_compile_dxbc(&info, &spirv, VKD3D_SHADER_STRIP_DEBUG); + rc = vkd3d_shader_compile_dxbc(&info, &spirv); ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc); } @@ -127,8 +134,10 @@ static void test_vkd3d_shader_pfns(void) compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; compile_info.next = NULL; compile_info.source = vs; + compile_info.options = NULL; + compile_info.option_count = 0; - rc = pfn_vkd3d_shader_compile_dxbc(&compile_info, &spirv, 0); + rc = pfn_vkd3d_shader_compile_dxbc(&compile_info, &spirv); ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc); pfn_vkd3d_shader_free_shader_code(&spirv);