[PATCH vkd3d 1/5] vkd3d-shader/sm4: Store a vkd3d_shader_parser structure in the vkd3d_sm4_data structure.

Henri Verbeet hverbeet at codeweavers.com
Fri Oct 1 10:51:11 CDT 2021


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 | 103 +++++++++++++++--------
 libs/vkd3d-shader/vkd3d_shader_main.c    |  70 +++++----------
 libs/vkd3d-shader/vkd3d_shader_private.h |   6 +-
 3 files changed, 95 insertions(+), 84 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 23814a35..da919b1d 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -99,6 +99,7 @@ struct vkd3d_sm4_data
     struct vkd3d_shader_immediate_constant_buffer icb;
 
     struct vkd3d_shader_message_context *message_context;
+    struct vkd3d_shader_parser p;
 };
 
 struct vkd3d_sm4_opcode_info
@@ -165,6 +166,11 @@ static const enum vkd3d_data_type data_type_table[] =
     /* VKD3D_SM4_DATA_UNUSED */     VKD3D_DATA_UNUSED,
 };
 
+static struct vkd3d_sm4_data *vkd3d_sm4_data(struct vkd3d_shader_parser *parser)
+{
+    return CONTAINING_RECORD(parser, struct vkd3d_sm4_data, p);
+}
+
 static bool shader_is_sm_5_1(const struct vkd3d_sm4_data *priv)
 {
     const struct vkd3d_shader_version *version = &priv->shader_version;
@@ -998,17 +1004,16 @@ static enum vkd3d_data_type map_data_type(char t)
     }
 }
 
-void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
+static bool shader_sm4_init(struct vkd3d_sm4_data *sm4, const uint32_t *byte_code, size_t byte_code_size,
         const struct vkd3d_shader_signature *output_signature, struct vkd3d_shader_message_context *message_context)
 {
-    DWORD version_token, token_count;
-    struct vkd3d_sm4_data *priv;
+    uint32_t version_token, token_count;
     unsigned int i;
 
     if (byte_code_size / sizeof(*byte_code) < 2)
     {
         WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
-        return NULL;
+        return false;
     }
 
     version_token = byte_code[0];
@@ -1019,82 +1024,77 @@ void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
     if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
     {
         WARN("Invalid token count %u.\n", token_count);
-        return NULL;
-    }
-
-    if (!(priv = vkd3d_malloc(sizeof(*priv))))
-    {
-        ERR("Failed to allocate private data\n");
-        return NULL;
+        return false;
     }
 
-    priv->start = &byte_code[2];
-    priv->end = &byte_code[token_count];
+    sm4->start = &byte_code[2];
+    sm4->end = &byte_code[token_count];
 
     switch (version_token >> 16)
     {
         case VKD3D_SM4_PS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_PIXEL;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_PIXEL;
             break;
 
         case VKD3D_SM4_VS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_VERTEX;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_VERTEX;
             break;
 
         case VKD3D_SM4_GS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_GEOMETRY;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_GEOMETRY;
             break;
 
         case VKD3D_SM5_HS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_HULL;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_HULL;
             break;
 
         case VKD3D_SM5_DS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_DOMAIN;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_DOMAIN;
             break;
 
         case VKD3D_SM5_CS:
-            priv->shader_version.type = VKD3D_SHADER_TYPE_COMPUTE;
+            sm4->shader_version.type = VKD3D_SHADER_TYPE_COMPUTE;
             break;
 
         default:
             FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
     }
-    priv->shader_version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
-    priv->shader_version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
+    sm4->shader_version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
+    sm4->shader_version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
 
-    memset(priv->output_map, 0xff, sizeof(priv->output_map));
+    memset(sm4->output_map, 0xff, sizeof(sm4->output_map));
     for (i = 0; i < output_signature->element_count; ++i)
     {
         struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
 
-        if (e->register_index >= ARRAY_SIZE(priv->output_map))
+        if (e->register_index >= ARRAY_SIZE(sm4->output_map))
         {
             WARN("Invalid output index %u.\n", e->register_index);
             continue;
         }
 
-        priv->output_map[e->register_index] = e->semantic_index;
+        sm4->output_map[e->register_index] = e->semantic_index;
     }
 
-    list_init(&priv->src_free);
-    list_init(&priv->src);
+    list_init(&sm4->src_free);
+    list_init(&sm4->src);
 
-    priv->message_context = message_context;
+    sm4->message_context = message_context;
 
-    return priv;
+    return true;
 }
 
 void shader_sm4_free(struct vkd3d_shader_parser *parser)
 {
+    struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
     struct vkd3d_shader_src_param_entry *e1, *e2;
-    struct vkd3d_sm4_data *sm4 = parser->data;
 
     list_move_head(&sm4->src_free, &sm4->src);
     LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &sm4->src_free, struct vkd3d_shader_src_param_entry, entry)
     {
         vkd3d_free(e1);
     }
+    free_shader_desc(&parser->shader_desc);
     vkd3d_free(sm4);
 }
 
@@ -1122,7 +1122,7 @@ static struct vkd3d_shader_src_param *get_src_param(struct vkd3d_sm4_data *priv)
 
 void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version)
 {
-    struct vkd3d_sm4_data *sm4 = parser->data;
+    struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
 
     parser->ptr = sm4->start;
     *shader_version = sm4->shader_version;
@@ -1573,9 +1573,9 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
 
 void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
 {
+    struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
     const struct vkd3d_sm4_opcode_info *opcode_info;
     uint32_t opcode_token, opcode, previous_token;
-    struct vkd3d_sm4_data *sm4 = parser->data;
     const uint32_t **ptr = &parser->ptr;
     unsigned int i, len;
     size_t remaining;
@@ -1693,18 +1693,55 @@ fail:
 
 bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
 {
-    struct vkd3d_sm4_data *sm4 = parser->data;
+    struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
 
     return parser->ptr == sm4->end;
 }
 
 void shader_sm4_reset(struct vkd3d_shader_parser *parser)
 {
-    struct vkd3d_sm4_data *sm4 = parser->data;
+    struct vkd3d_sm4_data *sm4 = vkd3d_sm4_data(parser);
 
     parser->ptr = sm4->start;
 }
 
+int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
+{
+    struct vkd3d_shader_desc *shader_desc;
+    struct vkd3d_sm4_data *sm4;
+    int ret;
+
+    if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4))))
+    {
+        ERR("Failed to allocate parser.\n");
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+    }
+
+    shader_desc = &sm4->p.shader_desc;
+    if ((ret = shader_extract_from_dxbc(compile_info->source.code, compile_info->source.size,
+            message_context, compile_info->source_name, shader_desc)) < 0)
+    {
+        WARN("Failed to extract shader, vkd3d result %d.\n", ret);
+        vkd3d_free(sm4);
+        return ret;
+    }
+
+    if (!shader_sm4_init(sm4, shader_desc->byte_code, shader_desc->byte_code_size,
+            &shader_desc->output_signature, message_context))
+    {
+        WARN("Failed to initialise shader parser.\n");
+        free_shader_desc(shader_desc);
+        vkd3d_free(sm4);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    shader_sm4_read_header(&sm4->p, &sm4->p.shader_version);
+    *parser = &sm4->p;
+
+    return VKD3D_OK;
+}
+
 static bool require_space(size_t offset, size_t count, size_t size, size_t data_size)
 {
     return !count || (data_size - offset) / count >= size;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index e38261b4..f253e479 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -372,35 +372,9 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
             shader_get_source_type_suffix(source_type), shader->code, shader->size);
 }
 
-static int vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
-        const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
-{
-    struct vkd3d_shader_desc *shader_desc = &parser->shader_desc;
-    int ret;
-
-    if ((ret = shader_extract_from_dxbc(compile_info->source.code, compile_info->source.size,
-            message_context, compile_info->source_name, shader_desc)) < 0)
-    {
-        WARN("Failed to extract shader, vkd3d result %d.\n", ret);
-        return ret;
-    }
-
-    if (!(parser->data = shader_sm4_init(shader_desc->byte_code,
-            shader_desc->byte_code_size, &shader_desc->output_signature, message_context)))
-    {
-        WARN("Failed to initialize shader parser.\n");
-        free_shader_desc(shader_desc);
-        return VKD3D_ERROR_INVALID_ARGUMENT;
-    }
-
-    shader_sm4_read_header(parser, &parser->shader_version);
-    return VKD3D_OK;
-}
-
 static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
 {
     shader_sm4_free(parser);
-    free_shader_desc(&parser->shader_desc);
 }
 
 static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_info *compile_info,
@@ -939,7 +913,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
     struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
     struct vkd3d_shader_instruction instruction;
     struct vkd3d_shader_scan_context context;
-    struct vkd3d_shader_parser parser;
+    struct vkd3d_shader_parser *parser;
     int ret;
 
     if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
@@ -950,7 +924,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
 
     vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
 
-    if ((ret = vkd3d_shader_parser_init(&parser, compile_info, message_context)) < 0)
+    if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
     {
         vkd3d_shader_scan_context_cleanup(&context);
         return ret;
@@ -958,13 +932,13 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
 
     if (TRACE_ON())
     {
-        vkd3d_shader_trace(&parser);
-        shader_sm4_reset(&parser);
+        vkd3d_shader_trace(parser);
+        shader_sm4_reset(parser);
     }
 
-    while (!shader_sm4_is_end(&parser))
+    while (!shader_sm4_is_end(parser))
     {
-        shader_sm4_read_instruction(&parser, &instruction);
+        shader_sm4_read_instruction(parser, &instruction);
 
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
@@ -987,7 +961,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
 
 done:
     vkd3d_shader_scan_context_cleanup(&context);
-    vkd3d_shader_parser_destroy(&parser);
+    vkd3d_shader_parser_destroy(parser);
     return ret;
 }
 
@@ -1037,7 +1011,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
     struct vkd3d_shader_instruction instruction;
     struct vkd3d_shader_compile_info scan_info;
     struct vkd3d_dxbc_compiler *spirv_compiler;
-    struct vkd3d_shader_parser parser;
+    struct vkd3d_shader_parser *parser;
     int ret;
 
     scan_info = *compile_info;
@@ -1048,19 +1022,19 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
     if ((ret = scan_dxbc(&scan_info, message_context)) < 0)
         return ret;
 
-    if ((ret = vkd3d_shader_parser_init(&parser, compile_info, message_context)) < 0)
+    if ((ret = vkd3d_shader_sm4_parser_create(compile_info, message_context, &parser)) < 0)
     {
         vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
         return ret;
     }
 
-    vkd3d_shader_dump_shader(compile_info->source_type, parser.shader_version.type, &compile_info->source);
+    vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
 
     if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
     {
         vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
-        ret = vkd3d_dxbc_binary_to_text(&parser, compile_info, out);
-        vkd3d_shader_parser_destroy(&parser);
+        ret = vkd3d_dxbc_binary_to_text(parser, compile_info, out);
+        vkd3d_shader_parser_destroy(parser);
         return ret;
     }
 
@@ -1068,34 +1042,34 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
     {
         struct vkd3d_glsl_generator *glsl_generator;
 
-        if (!(glsl_generator = vkd3d_glsl_generator_create(&parser.shader_version, compile_info, message_context)))
+        if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->shader_version, compile_info, message_context)))
         {
             ERR("Failed to create GLSL generator.\n");
-            vkd3d_shader_parser_destroy(&parser);
+            vkd3d_shader_parser_destroy(parser);
             vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
             return VKD3D_ERROR;
         }
 
-        ret = vkd3d_glsl_generator_generate(glsl_generator, &parser, out);
+        ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
 
         vkd3d_glsl_generator_destroy(glsl_generator);
-        vkd3d_shader_parser_destroy(&parser);
+        vkd3d_shader_parser_destroy(parser);
         vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
         return ret;
     }
 
-    if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
-            &parser.shader_desc, compile_info, &scan_descriptor_info, message_context)))
+    if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser->shader_version,
+            &parser->shader_desc, compile_info, &scan_descriptor_info, message_context)))
     {
         ERR("Failed to create DXBC compiler.\n");
-        vkd3d_shader_parser_destroy(&parser);
+        vkd3d_shader_parser_destroy(parser);
         vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
         return VKD3D_ERROR;
     }
 
-    while (!shader_sm4_is_end(&parser))
+    while (!shader_sm4_is_end(parser))
     {
-        shader_sm4_read_instruction(&parser, &instruction);
+        shader_sm4_read_instruction(parser, &instruction);
 
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
@@ -1112,7 +1086,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
         ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, compile_info, out);
 
     vkd3d_dxbc_compiler_destroy(spirv_compiler);
-    vkd3d_shader_parser_destroy(&parser);
+    vkd3d_shader_parser_destroy(parser);
     vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
     return ret;
 }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 8b3e7624..0ac5ecef 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -891,7 +891,6 @@ struct vkd3d_shader_parser
 {
     struct vkd3d_shader_desc shader_desc;
     struct vkd3d_shader_version shader_version;
-    void *data;
     const uint32_t *ptr;
 };
 
@@ -901,8 +900,6 @@ const char *shader_get_type_prefix(enum vkd3d_shader_type type);
 
 struct vkd3d_shader_message_context;
 
-void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
-        const struct vkd3d_shader_signature *output_signature, struct vkd3d_shader_message_context *message_context);
 void shader_sm4_free(struct vkd3d_shader_parser *parser);
 void shader_sm4_read_header(struct vkd3d_shader_parser *parser, struct vkd3d_shader_version *shader_version);
 void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins);
@@ -1001,6 +998,9 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
 #define vkd3d_shader_trace_text(text, size) \
         vkd3d_shader_trace_text_(text, size, __FUNCTION__)
 
+int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
+
 int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
         struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_desc *desc);
 void free_shader_desc(struct vkd3d_shader_desc *desc);
-- 
2.20.1




More information about the wine-devel mailing list