[PATCH vkd3d 2/5] vkd3d-shader: Pass a vkd3d_shader_compile_info structure to vkd3d_shader_scan_dxbc().

Henri Verbeet hverbeet at codeweavers.com
Thu Jul 30 05:29:55 CDT 2020


In order to allow it to handle different source types.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 include/vkd3d_shader.h                   | 18 +++---
 libs/vkd3d-shader/spirv.c                | 33 ++---------
 libs/vkd3d-shader/vkd3d_shader.map       |  4 +-
 libs/vkd3d-shader/vkd3d_shader_main.c    | 97 +++++++++++++++++++-------------
 libs/vkd3d-shader/vkd3d_shader_private.h | 23 +++++++-
 libs/vkd3d/state.c                       | 41 ++++++++++----
 tests/vkd3d_shader_api.c                 | 20 +++++--
 7 files changed, 141 insertions(+), 95 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 69a98e0..96d0545 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -32,7 +32,7 @@ enum vkd3d_shader_structure_type
     /* 1.2 */
     VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
     VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO,
-    VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
+    VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
     VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO,
     VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO,
     VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
@@ -653,10 +653,11 @@ struct vkd3d_shader_descriptor_info
     unsigned int count;
 };
 
-struct vkd3d_shader_scan_info
+/* Extends vkd3d_shader_compile_info. */
+struct vkd3d_shader_scan_descriptor_info
 {
     enum vkd3d_shader_structure_type type;
-    void *next;
+    const void *next;
 
     struct vkd3d_shader_descriptor_info *descriptors;
     unsigned int descriptor_count;
@@ -762,9 +763,8 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
 int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst,
         enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
 
-int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
-        struct vkd3d_shader_scan_info *scan_info, char **messages);
-void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info);
+int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages);
+void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
 
 int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_signature *signature);
@@ -793,9 +793,9 @@ typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
 typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst,
         enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
 
-typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
-        struct vkd3d_shader_scan_info *scan_info, char **messages);
-typedef void (*PFN_vkd3d_shader_free_scan_info)(struct vkd3d_shader_scan_info *scan_info);
+typedef int (*PFN_vkd3d_shader_scan)(const struct vkd3d_shader_compile_info *compile_info, char **messages);
+typedef void (*PFN_vkd3d_shader_free_scan_descriptor_info)(
+        struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
 
 typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_signature *signature);
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 3ece044..86ee263 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -111,27 +111,6 @@ static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
 
 #endif  /* HAVE_SPIRV_TOOLS */
 
-struct vkd3d_struct
-{
-    enum vkd3d_shader_structure_type type;
-    const void *next;
-};
-
-#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
-static const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
-        enum vkd3d_shader_structure_type type)
-{
-    while (chain)
-    {
-        if (chain->type == type)
-            return chain;
-
-        chain = chain->next;
-    }
-
-    return NULL;
-}
-
 static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
         unsigned int index)
 {
@@ -2103,7 +2082,7 @@ struct vkd3d_dxbc_compiler
 
     uint32_t binding_idx;
 
-    const struct vkd3d_shader_scan_info *scan_info;
+    const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
     unsigned int input_control_point_count;
     unsigned int output_control_point_count;
     bool use_vocp;
@@ -2134,7 +2113,7 @@ static const char *vkd3d_dxbc_compiler_get_entry_point_name(const struct vkd3d_d
 
 struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
         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_scan_descriptor_info *scan_descriptor_info)
 {
     const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
     const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature;
@@ -2216,7 +2195,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
         }
     }
 
-    compiler->scan_info = scan_info;
+    compiler->scan_descriptor_info = scan_descriptor_info;
 
     vkd3d_dxbc_compiler_emit_initial_declarations(compiler);
 
@@ -5177,13 +5156,13 @@ static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descri
         struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_descriptor_type type,
         unsigned int register_space, unsigned int register_index)
 {
-    const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info;
+    const struct vkd3d_shader_scan_descriptor_info *descriptor_info = compiler->scan_descriptor_info;
     const struct vkd3d_shader_descriptor_info *d;
     unsigned int i;
 
-    for (i = 0; i < scan_info->descriptor_count; ++i)
+    for (i = 0; i < descriptor_info->descriptor_count; ++i)
     {
-        d = &scan_info->descriptors[i];
+        d = &descriptor_info->descriptors[i];
         if (d->type == type && d->register_space == register_space && d->register_index == register_index)
             return d;
     }
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index 55b50ad..9c9f0a5 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -6,12 +6,12 @@ global:
     vkd3d_shader_find_signature_element;
     vkd3d_shader_free_messages;
     vkd3d_shader_free_root_signature;
-    vkd3d_shader_free_scan_info;
+    vkd3d_shader_free_scan_descriptor_info;
     vkd3d_shader_free_shader_code;
     vkd3d_shader_free_shader_signature;
     vkd3d_shader_parse_input_signature;
     vkd3d_shader_parse_root_signature;
-    vkd3d_shader_scan_dxbc;
+    vkd3d_shader_scan;
     vkd3d_shader_serialize_root_signature;
 
 local: *;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index cf8b289..5d50487 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -285,10 +285,11 @@ void vkd3d_shader_free_messages(char *messages)
 int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
         struct vkd3d_shader_code *out, char **messages)
 {
+    struct vkd3d_shader_scan_descriptor_info scan_descriptor_info;
     struct vkd3d_shader_message_context message_context;
     struct vkd3d_shader_instruction instruction;
+    struct vkd3d_shader_compile_info scan_info;
     struct vkd3d_dxbc_compiler *spirv_compiler;
-    struct vkd3d_shader_scan_info scan_info;
     struct vkd3d_shader_parser parser;
     int ret;
 
@@ -300,9 +301,12 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
     if ((ret = vkd3d_shader_validate_compile_info(compile_info)) < 0)
         return ret;
 
-    scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
-    scan_info.next = NULL;
-    if ((ret = vkd3d_shader_scan_dxbc(&compile_info->source, &scan_info, messages)) < 0)
+    scan_info = *compile_info;
+    scan_descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
+    scan_descriptor_info.next = scan_info.next;
+    scan_info.next = &scan_descriptor_info;
+
+    if ((ret = vkd3d_shader_scan(&scan_info, messages)) < 0)
         return ret;
 
     if (!vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name))
@@ -317,15 +321,19 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
     }
     vkd3d_shader_message_context_cleanup(&message_context);
     if (ret < 0)
+    {
+        vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
         return ret;
+    }
 
     vkd3d_shader_dump_shader(parser.shader_version.type, &compile_info->source);
 
     if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
-            &parser.shader_desc, compile_info, &scan_info)))
+            &parser.shader_desc, compile_info, &scan_descriptor_info)))
     {
         ERR("Failed to create DXBC compiler.\n");
         vkd3d_shader_parser_destroy(&parser);
+        vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
         return VKD3D_ERROR;
     }
 
@@ -336,9 +344,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Encountered unrecognized or invalid instruction.\n");
-            vkd3d_dxbc_compiler_destroy(spirv_compiler);
-            vkd3d_shader_parser_destroy(&parser);
-            return VKD3D_ERROR_INVALID_ARGUMENT;
+            ret = VKD3D_ERROR_INVALID_SHADER;
+            break;
         }
 
         if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0)
@@ -350,13 +357,13 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
 
     vkd3d_dxbc_compiler_destroy(spirv_compiler);
     vkd3d_shader_parser_destroy(&parser);
-    vkd3d_shader_free_scan_info(&scan_info);
+    vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
     return ret;
 }
 
 struct vkd3d_shader_scan_context
 {
-    struct vkd3d_shader_scan_info *scan_info;
+    struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
     size_t descriptors_size;
 
     struct vkd3d_shader_message_context message_context;
@@ -385,11 +392,12 @@ struct vkd3d_shader_scan_context
 };
 
 static bool vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
-        struct vkd3d_shader_scan_info *scan_info)
+        struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
+        enum vkd3d_shader_log_level log_level, const char *source_name)
 {
     memset(context, 0, sizeof(*context));
-    context->scan_info = scan_info;
-    return vkd3d_shader_message_context_init(&context->message_context, VKD3D_SHADER_LOG_INFO, NULL);
+    context->scan_descriptor_info = scan_descriptor_info;
+    return vkd3d_shader_message_context_init(&context->message_context, log_level, source_name);
 }
 
 static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context)
@@ -471,7 +479,7 @@ static struct vkd3d_shader_descriptor_info *vkd3d_shader_scan_get_uav_descriptor
     for (i = 0; i < context->uav_range_count; ++i)
     {
         if (context->uav_ranges[i].id == range_id)
-            return &context->scan_info->descriptors[context->uav_ranges[i].descriptor_idx];
+            return &context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx];
     }
 
     return NULL;
@@ -492,7 +500,7 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *
 {
     struct vkd3d_shader_descriptor_info *d;
 
-    if (!context->scan_info)
+    if (!context->scan_descriptor_info)
         return;
 
     d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@@ -511,7 +519,7 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
 {
     struct vkd3d_shader_descriptor_info *d;
 
-    if (!context->scan_info)
+    if (!context->scan_descriptor_info)
         return;
 
     d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@@ -523,17 +531,17 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
         enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type,
         unsigned int flags)
 {
-    struct vkd3d_shader_scan_info *scan_info = context->scan_info;
+    struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info;
     struct vkd3d_shader_descriptor_info *d;
 
-    if (!vkd3d_array_reserve((void **)&scan_info->descriptors, &context->descriptors_size,
-            scan_info->descriptor_count + 1, sizeof(*scan_info->descriptors)))
+    if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size,
+            info->descriptor_count + 1, sizeof(*info->descriptors)))
     {
         ERR("Failed to allocate descriptor info.\n");
         return false;
     }
 
-    d = &scan_info->descriptors[scan_info->descriptor_count];
+    d = &info->descriptors[info->descriptor_count];
     d->type = type;
     d->register_space = register_space;
     d->register_index = register_index;
@@ -541,7 +549,7 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
     d->resource_data_type = resource_data_type;
     d->flags = flags;
     d->count = 1;
-    ++scan_info->descriptor_count;
+    ++info->descriptor_count;
 
     return true;
 }
@@ -568,7 +576,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
 {
     const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
 
-    if (!context->scan_info)
+    if (!context->scan_descriptor_info)
         return;
 
     vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space,
@@ -581,7 +589,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
     const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
     unsigned int flags;
 
-    if (!context->scan_info)
+    if (!context->scan_descriptor_info)
         return;
 
     if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
@@ -598,7 +606,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
 {
     enum vkd3d_shader_descriptor_type type;
 
-    if (!context->scan_info)
+    if (!context->scan_descriptor_info)
         return;
 
     if (resource->reg.reg.type == VKD3DSPR_UAV)
@@ -609,7 +617,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
             resource->register_index, resource_type, resource_data_type, 0);
     if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
         vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset,
-                context->scan_info->descriptor_count - 1);
+                context->scan_descriptor_info->descriptor_count - 1);
 }
 
 static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
@@ -811,31 +819,44 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
     return VKD3D_OK;
 }
 
-int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
-        struct vkd3d_shader_scan_info *scan_info, char **messages)
+int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
 {
+    struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
     struct vkd3d_shader_message_context *message_context;
     struct vkd3d_shader_instruction instruction;
     struct vkd3d_shader_scan_context context;
     struct vkd3d_shader_parser parser;
     int ret;
 
-    TRACE("dxbc {%p, %zu}, scan_info %p, messages %p.\n", dxbc->code, dxbc->size, scan_info, messages);
+    TRACE("compile_info %p, messages %p.\n", compile_info, messages);
 
     if (messages)
         *messages = NULL;
 
-    if (scan_info->type != VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO)
+    if (compile_info->type != VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO)
     {
-        WARN("Invalid structure type %#x.\n", scan_info->type);
+        WARN("Invalid structure type %#x.\n", compile_info->type);
         return VKD3D_ERROR_INVALID_ARGUMENT;
     }
 
-    if (!vkd3d_shader_scan_context_init(&context, scan_info))
+    if (compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF)
+    {
+        WARN("Unsupported source type %#x.\n", compile_info->source_type);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
+    {
+        scan_descriptor_info->descriptors = NULL;
+        scan_descriptor_info->descriptor_count = 0;
+    }
+
+    if (!vkd3d_shader_scan_context_init(&context, scan_descriptor_info,
+            compile_info->log_level, compile_info->source_name))
         return VKD3D_ERROR;
     message_context = &context.message_context;
 
-    if ((ret = vkd3d_shader_parser_init(&parser, dxbc, message_context)) < 0)
+    if ((ret = vkd3d_shader_parser_init(&parser, &compile_info->source, message_context)) < 0)
     {
         vkd3d_shader_message_context_trace_messages(message_context);
         if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context)))
@@ -847,8 +868,6 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
     if (TRACE_ON())
         vkd3d_shader_trace(parser.data);
 
-    memset(scan_info, 0, sizeof(*scan_info));
-
     message_context->line = 2; /* Line 1 is the version token. */
     message_context->column = 1;
     while (!shader_sm4_is_end(parser.data, &parser.ptr))
@@ -858,14 +877,14 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Encountered unrecognized or invalid instruction.\n");
-            vkd3d_shader_free_scan_info(scan_info);
+            vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
             ret = VKD3D_ERROR_INVALID_SHADER;
             goto done;
         }
 
         if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0)
         {
-            vkd3d_shader_free_scan_info(scan_info);
+            vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
             goto done;
         }
         ++message_context->line;
@@ -882,12 +901,12 @@ done:
     return ret;
 }
 
-void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info)
+void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
 {
-    if (!scan_info)
+    if (!scan_descriptor_info)
         return;
 
-    vkd3d_free(scan_info->descriptors);
+    vkd3d_free(scan_descriptor_info->descriptors);
 }
 
 void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 4fa17d6..ae2f6c2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -846,7 +846,7 @@ 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, const struct vkd3d_shader_compile_info *compile_info,
-        const struct vkd3d_shader_scan_info *scan_info) DECLSPEC_HIDDEN;
+        const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info) DECLSPEC_HIDDEN;
 int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN;
 int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
@@ -941,6 +941,27 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
     return compacted_swizzle;
 }
 
+struct vkd3d_struct
+{
+    enum vkd3d_shader_structure_type type;
+    const void *next;
+};
+
+#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
+static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
+        enum vkd3d_shader_structure_type type)
+{
+    while (chain)
+    {
+        if (chain->type == type)
+            return (void *)chain;
+
+        chain = chain->next;
+    }
+
+    return NULL;
+}
+
 #define VKD3D_DXBC_MAX_SOURCE_COUNT 6
 #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
 
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 316132b..93f22ce 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1376,6 +1376,25 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
     return S_OK;
 }
 
+static int vkd3d_scan_dxbc(const D3D12_SHADER_BYTECODE *code,
+        struct vkd3d_shader_scan_descriptor_info *descriptor_info)
+{
+    struct vkd3d_shader_compile_info compile_info;
+
+    compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
+    compile_info.next = descriptor_info;
+    compile_info.source.code = code->pShaderBytecode;
+    compile_info.source.size = code->BytecodeLength;
+    compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
+    compile_info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
+    compile_info.options = NULL;
+    compile_info.option_count = 0;
+    compile_info.log_level = VKD3D_SHADER_LOG_NONE;
+    compile_info.source_name = NULL;
+
+    return vkd3d_shader_scan(&compile_info, NULL);
+}
+
 static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
         const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface,
         VkPipelineLayout vk_pipeline_layout, VkPipeline *vk_pipeline)
@@ -1409,7 +1428,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
 
 static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipeline_state *state,
         struct d3d12_device *device, const struct d3d12_root_signature *root_signature,
-        const struct vkd3d_shader_scan_info *shader_info)
+        const struct vkd3d_shader_scan_descriptor_info *shader_info)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     struct vkd3d_descriptor_set_context context;
@@ -1503,11 +1522,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
         struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    struct vkd3d_shader_scan_descriptor_info shader_info;
     struct vkd3d_shader_interface_info shader_interface;
     const struct d3d12_root_signature *root_signature;
-    struct vkd3d_shader_scan_info shader_info;
     VkPipelineLayout vk_pipeline_layout;
-    struct vkd3d_shader_code dxbc;
     HRESULT hr;
     int ret;
 
@@ -1525,11 +1543,9 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
         return E_INVALIDARG;
     }
 
-    dxbc.code = desc->CS.pShaderBytecode;
-    dxbc.size = desc->CS.BytecodeLength;
-    shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
+    shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
     shader_info.next = NULL;
-    if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0)
+    if ((ret = vkd3d_scan_dxbc(&desc->CS, &shader_info)) < 0)
     {
         WARN("Failed to scan shader bytecode, vkd3d result %d.\n", ret);
         return hresult_from_vkd3d_result(ret);
@@ -1541,7 +1557,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
         WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
         return hr;
     }
-    vkd3d_shader_free_scan_info(&shader_info);
+    vkd3d_shader_free_scan_descriptor_info(&shader_info);
 
     shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
     shader_interface.next = NULL;
@@ -2266,14 +2282,17 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
 
     for (i = 0; i < ARRAY_SIZE(shader_stages); ++i)
     {
+        struct vkd3d_shader_scan_descriptor_info shader_info =
+        {
+            .type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
+        };
         const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset);
-        struct vkd3d_shader_scan_info shader_info = {VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO};
         const struct vkd3d_shader_code dxbc = {b->pShaderBytecode, b->BytecodeLength};
 
         if (!b->pShaderBytecode)
             continue;
 
-        if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0)
+        if ((ret = vkd3d_scan_dxbc(b, &shader_info)) < 0)
         {
             WARN("Failed to scan shader bytecode, stage %#x, vkd3d result %d.\n",
                     shader_stages[i].stage, ret);
@@ -2291,7 +2310,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
                 break;
             }
         }
-        vkd3d_shader_free_scan_info(&shader_info);
+        vkd3d_shader_free_scan_descriptor_info(&shader_info);
 
         target_info = NULL;
         switch (shader_stages[i].stage)
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index 079559a..be63b39 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -68,10 +68,14 @@ static void test_invalid_shaders(void)
 
     rc = vkd3d_shader_compile(&info, &spirv, NULL);
     ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+    rc = vkd3d_shader_scan(&info, NULL);
+    ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
 }
 
 static void test_vkd3d_shader_pfns(void)
 {
+    PFN_vkd3d_shader_free_scan_descriptor_info pfn_vkd3d_shader_free_scan_descriptor_info;
     PFN_vkd3d_shader_serialize_root_signature pfn_vkd3d_shader_serialize_root_signature;
     PFN_vkd3d_shader_find_signature_element pfn_vkd3d_shader_find_signature_element;
     PFN_vkd3d_shader_free_shader_signature pfn_vkd3d_shader_free_shader_signature;
@@ -79,13 +83,13 @@ static void test_vkd3d_shader_pfns(void)
     PFN_vkd3d_shader_parse_root_signature pfn_vkd3d_shader_parse_root_signature;
     PFN_vkd3d_shader_free_root_signature pfn_vkd3d_shader_free_root_signature;
     PFN_vkd3d_shader_free_shader_code pfn_vkd3d_shader_free_shader_code;
-    PFN_vkd3d_shader_scan_dxbc pfn_vkd3d_shader_scan_dxbc;
     PFN_vkd3d_shader_compile pfn_vkd3d_shader_compile;
+    PFN_vkd3d_shader_scan pfn_vkd3d_shader_scan;
 
     struct vkd3d_shader_versioned_root_signature_desc root_signature_desc;
+    struct vkd3d_shader_scan_descriptor_info descriptor_info;
     struct vkd3d_shader_signature_element *element;
     struct vkd3d_shader_compile_info compile_info;
-    struct vkd3d_shader_scan_info scan_info;
     struct vkd3d_shader_signature signature;
     struct vkd3d_shader_code dxbc, spirv;
     int rc;
@@ -112,6 +116,7 @@ static void test_vkd3d_shader_pfns(void)
     };
     static const struct vkd3d_shader_code vs = {vs_code, sizeof(vs_code)};
 
+    pfn_vkd3d_shader_free_scan_descriptor_info = vkd3d_shader_free_scan_descriptor_info;
     pfn_vkd3d_shader_serialize_root_signature = vkd3d_shader_serialize_root_signature;
     pfn_vkd3d_shader_find_signature_element = vkd3d_shader_find_signature_element;
     pfn_vkd3d_shader_free_shader_signature = vkd3d_shader_free_shader_signature;
@@ -119,8 +124,8 @@ static void test_vkd3d_shader_pfns(void)
     pfn_vkd3d_shader_parse_root_signature = vkd3d_shader_parse_root_signature;
     pfn_vkd3d_shader_free_root_signature = vkd3d_shader_free_root_signature;
     pfn_vkd3d_shader_free_shader_code = vkd3d_shader_free_shader_code;
-    pfn_vkd3d_shader_scan_dxbc = vkd3d_shader_scan_dxbc;
     pfn_vkd3d_shader_compile = vkd3d_shader_compile;
+    pfn_vkd3d_shader_scan = vkd3d_shader_scan;
 
     rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc);
     ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
@@ -149,10 +154,13 @@ static void test_vkd3d_shader_pfns(void)
     ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
     pfn_vkd3d_shader_free_shader_code(&spirv);
 
-    memset(&scan_info, 0, sizeof(scan_info));
-    scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
-    rc = pfn_vkd3d_shader_scan_dxbc(&vs, &scan_info, NULL);
+    memset(&descriptor_info, 0, sizeof(descriptor_info));
+    descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
+    compile_info.next = &descriptor_info;
+
+    rc = pfn_vkd3d_shader_scan(&compile_info, NULL);
     ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+    pfn_vkd3d_shader_free_scan_descriptor_info(&descriptor_info);
 }
 
 START_TEST(vkd3d_shader_api)
-- 
2.11.0




More information about the wine-devel mailing list