[PATCH vkd3d 4/5] vkd3d-shader: Pass compile options as an array instead of as flags.

Henri Verbeet hverbeet at codeweavers.com
Fri Jun 19 06:43:35 CDT 2020


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 include/vkd3d_shader.h                   | 20 ++++++++++-----
 libs/vkd3d-shader/spirv.c                | 24 ++++++++++++++----
 libs/vkd3d-shader/vkd3d_shader_main.c    |  8 +++---
 libs/vkd3d-shader/vkd3d_shader_private.h |  3 +--
 libs/vkd3d/state.c                       |  4 ++-
 programs/vkd3d-compiler/main.c           | 43 ++++++++++++++++++++++++++++----
 tests/vkd3d_shader_api.c                 | 13 ++++++++--
 7 files changed, 89 insertions(+), 26 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index e4c86ed..367f8a2 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 5770341..9b655e4 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 ae4a9b4..7179436 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 9945c6b..ecfd665 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 831bbde..8bc2595 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 5f7b0c2..d33dafd 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 9e5bdf3..00c6f95 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);
 
-- 
2.11.0




More information about the wine-devel mailing list