[PATCH vkd3d 4/6] vkd3d-shader: Introduce struct vkd3d_shader_parser_ops.

Henri Verbeet hverbeet at codeweavers.com
Wed Oct 6 10:11:47 CDT 2021


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 | 182 ++++++++++++-----------
 libs/vkd3d-shader/glsl.c                 |   4 +-
 libs/vkd3d-shader/trace.c                |   6 +-
 libs/vkd3d-shader/vkd3d_shader_main.c    |  18 +--
 libs/vkd3d-shader/vkd3d_shader_private.h |  39 ++++-
 5 files changed, 138 insertions(+), 111 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 656c982c..44e842d3 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -960,90 +960,7 @@ static enum vkd3d_data_type map_data_type(char t)
     }
 }
 
-static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code,
-        size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature,
-        struct vkd3d_shader_message_context *message_context)
-{
-    struct vkd3d_shader_version version;
-    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 false;
-    }
-
-    version_token = byte_code[0];
-    TRACE("Version: 0x%08x.\n", version_token);
-    token_count = byte_code[1];
-    TRACE("Token count: %u.\n", token_count);
-
-    if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
-    {
-        WARN("Invalid token count %u.\n", token_count);
-        return false;
-    }
-
-    sm4->start = &byte_code[2];
-    sm4->end = &byte_code[token_count];
-
-    switch (version_token >> 16)
-    {
-        case VKD3D_SM4_PS:
-            version.type = VKD3D_SHADER_TYPE_PIXEL;
-            break;
-
-        case VKD3D_SM4_VS:
-            version.type = VKD3D_SHADER_TYPE_VERTEX;
-            break;
-
-        case VKD3D_SM4_GS:
-            version.type = VKD3D_SHADER_TYPE_GEOMETRY;
-            break;
-
-        case VKD3D_SM5_HS:
-            version.type = VKD3D_SHADER_TYPE_HULL;
-            break;
-
-        case VKD3D_SM5_DS:
-            version.type = VKD3D_SHADER_TYPE_DOMAIN;
-            break;
-
-        case VKD3D_SM5_CS:
-            version.type = VKD3D_SHADER_TYPE_COMPUTE;
-            break;
-
-        default:
-            FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
-    }
-    version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
-    version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
-
-    vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version);
-    sm4->p.ptr = sm4->start;
-
-    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(sm4->output_map))
-        {
-            WARN("Invalid output index %u.\n", e->register_index);
-            continue;
-        }
-
-        sm4->output_map[e->register_index] = e->semantic_index;
-    }
-
-    list_init(&sm4->src_free);
-    list_init(&sm4->src);
-
-    return true;
-}
-
-void shader_sm4_free(struct vkd3d_shader_parser *parser)
+static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
 {
     struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
     struct vkd3d_shader_src_param_entry *e1, *e2;
@@ -1521,7 +1438,7 @@ 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)
+static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins)
 {
     struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
     const struct vkd3d_sm4_opcode_info *opcode_info;
@@ -1643,14 +1560,14 @@ fail:
     return;
 }
 
-bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
+static bool shader_sm4_is_end(struct vkd3d_shader_parser *parser)
 {
     struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
 
     return parser->ptr == sm4->end;
 }
 
-void shader_sm4_reset(struct vkd3d_shader_parser *parser)
+static void shader_sm4_reset(struct vkd3d_shader_parser *parser)
 {
     struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
 
@@ -1658,6 +1575,97 @@ void shader_sm4_reset(struct vkd3d_shader_parser *parser)
     parser->failed = false;
 }
 
+static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
+{
+    .parser_reset = shader_sm4_reset,
+    .parser_destroy = shader_sm4_destroy,
+    .parser_read_instruction = shader_sm4_read_instruction,
+    .parser_is_end = shader_sm4_is_end,
+};
+
+static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code,
+        size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature,
+        struct vkd3d_shader_message_context *message_context)
+{
+    struct vkd3d_shader_version version;
+    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 false;
+    }
+
+    version_token = byte_code[0];
+    TRACE("Version: 0x%08x.\n", version_token);
+    token_count = byte_code[1];
+    TRACE("Token count: %u.\n", token_count);
+
+    if (token_count < 2 || byte_code_size / sizeof(*byte_code) < token_count)
+    {
+        WARN("Invalid token count %u.\n", token_count);
+        return false;
+    }
+
+    sm4->start = &byte_code[2];
+    sm4->end = &byte_code[token_count];
+
+    switch (version_token >> 16)
+    {
+        case VKD3D_SM4_PS:
+            version.type = VKD3D_SHADER_TYPE_PIXEL;
+            break;
+
+        case VKD3D_SM4_VS:
+            version.type = VKD3D_SHADER_TYPE_VERTEX;
+            break;
+
+        case VKD3D_SM4_GS:
+            version.type = VKD3D_SHADER_TYPE_GEOMETRY;
+            break;
+
+        case VKD3D_SM5_HS:
+            version.type = VKD3D_SHADER_TYPE_HULL;
+            break;
+
+        case VKD3D_SM5_DS:
+            version.type = VKD3D_SHADER_TYPE_DOMAIN;
+            break;
+
+        case VKD3D_SM5_CS:
+            version.type = VKD3D_SHADER_TYPE_COMPUTE;
+            break;
+
+        default:
+            FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
+    }
+    version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
+    version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
+
+    vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops);
+    sm4->p.ptr = sm4->start;
+
+    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(sm4->output_map))
+        {
+            WARN("Invalid output index %u.\n", e->register_index);
+            continue;
+        }
+
+        sm4->output_map[e->register_index] = e->semantic_index;
+    }
+
+    list_init(&sm4->src_free);
+    list_init(&sm4->src);
+
+    return true;
+}
+
 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)
 {
diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c
index b90a5d91..56fa7043 100644
--- a/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d-shader/glsl.c
@@ -99,9 +99,9 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
     vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n");
     vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
 
-    while (!shader_sm4_is_end(parser))
+    while (!vkd3d_shader_parser_is_end(parser))
     {
-        shader_sm4_read_instruction(parser, &ins);
+        vkd3d_shader_parser_read_instruction(parser, &ins);
 
         if (ins.handler_idx == VKD3DSIH_INVALID)
         {
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index 57104246..edba0b42 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -1889,12 +1889,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
             shader_version->minor, compiler.colours.reset);
 
     indent = 0;
-    shader_sm4_reset(parser);
-    while (!shader_sm4_is_end(parser))
+    vkd3d_shader_parser_reset(parser);
+    while (!vkd3d_shader_parser_is_end(parser))
     {
         struct vkd3d_shader_instruction ins;
 
-        shader_sm4_read_instruction(parser, &ins);
+        vkd3d_shader_parser_read_instruction(parser, &ins);
         if (ins.handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Skipping unrecognized instruction.\n");
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index c30a3757..98607154 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -364,18 +364,14 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
 
 void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
         struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_version *version)
+        const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops)
 {
     parser->message_context = message_context;
     parser->location.source_name = source_name;
     parser->location.line = 1;
     parser->location.column = 0;
     parser->shader_version = *version;
-}
-
-static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
-{
-    shader_sm4_free(parser);
+    parser->ops = ops;
 }
 
 void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
@@ -946,12 +942,12 @@ 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_parser_reset(parser);
     }
 
-    while (!shader_sm4_is_end(parser))
+    while (!vkd3d_shader_parser_is_end(parser))
     {
-        shader_sm4_read_instruction(parser, &instruction);
+        vkd3d_shader_parser_read_instruction(parser, &instruction);
 
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
@@ -1081,9 +1077,9 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
         return VKD3D_ERROR;
     }
 
-    while (!shader_sm4_is_end(parser))
+    while (!vkd3d_shader_parser_is_end(parser))
     {
-        shader_sm4_read_instruction(parser, &instruction);
+        vkd3d_shader_parser_read_instruction(parser, &instruction);
 
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 97048ea6..da12247a 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -902,24 +902,47 @@ struct vkd3d_shader_parser
     struct vkd3d_shader_desc shader_desc;
     struct vkd3d_shader_version shader_version;
     const uint32_t *ptr;
+    const struct vkd3d_shader_parser_ops *ops;
+};
+
+struct vkd3d_shader_parser_ops
+{
+    void (*parser_reset)(struct vkd3d_shader_parser *parser);
+    void (*parser_destroy)(struct vkd3d_shader_parser *parser);
+    void (*parser_read_instruction)(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *instruction);
+    bool (*parser_is_end)(struct vkd3d_shader_parser *parser);
 };
 
 void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
         enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
 void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
         struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_version *version);
+        const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops);
 
-void vkd3d_shader_trace(struct vkd3d_shader_parser *parser);
+static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
+{
+    parser->ops->parser_destroy(parser);
+}
 
-const char *shader_get_type_prefix(enum vkd3d_shader_type type);
+static inline bool vkd3d_shader_parser_is_end(struct vkd3d_shader_parser *parser)
+{
+    return parser->ops->parser_is_end(parser);
+}
 
-struct vkd3d_shader_message_context;
+static inline void vkd3d_shader_parser_read_instruction(struct vkd3d_shader_parser *parser,
+        struct vkd3d_shader_instruction *instruction)
+{
+    parser->ops->parser_read_instruction(parser, instruction);
+}
+
+static inline void vkd3d_shader_parser_reset(struct vkd3d_shader_parser *parser)
+{
+    parser->ops->parser_reset(parser);
+}
+
+void vkd3d_shader_trace(struct vkd3d_shader_parser *parser);
 
-void shader_sm4_free(struct vkd3d_shader_parser *parser);
-void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins);
-bool shader_sm4_is_end(struct vkd3d_shader_parser *parser);
-void shader_sm4_reset(struct vkd3d_shader_parser *parser);
+const char *shader_get_type_prefix(enum vkd3d_shader_type type);
 
 struct vkd3d_string_buffer
 {
-- 
2.20.1




More information about the wine-devel mailing list