From 9e4a790de10cd892ca247951a63dc3fe87eb7c89 Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:41:58 +0200
Subject: [PATCH 1/6] vkd3d-shader/ir: Use a separate allocation for the vsir
 program in struct vkd3d_shader_parser.

---
 libs/vkd3d-shader/d3dbc.c                |  41 +++++----
 libs/vkd3d-shader/dxil.c                 | 103 +++++++++++++----------
 libs/vkd3d-shader/hlsl.c                 |   2 +-
 libs/vkd3d-shader/tpf.c                  |  73 +++++++++-------
 libs/vkd3d-shader/vkd3d_shader_main.c    |  12 ++-
 libs/vkd3d-shader/vkd3d_shader_private.h |   4 +-
 6 files changed, 134 insertions(+), 101 deletions(-)

diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index 7c7c71e3c9..2e37549f8f 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -418,7 +418,7 @@ static bool has_relative_address(uint32_t param)
 static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
         const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode)
 {
-    const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
+    const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
     const struct vkd3d_sm1_opcode_info *info;
     unsigned int i = 0;
 
@@ -541,13 +541,14 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
         const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
         unsigned int register_index, bool is_dcl, unsigned int mask)
 {
+    struct vsir_program *program = sm1->p.program;
     struct shader_signature *signature;
     struct signature_element *element;
 
     if (output)
-        signature = &sm1->p.program.output_signature;
+        signature = &program->output_signature;
     else
-        signature = &sm1->p.program.input_signature;
+        signature = &program->input_signature;
 
     if ((element = find_signature_element(signature, name, index)))
     {
@@ -572,7 +573,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
     element->register_count = 1;
     element->mask = mask;
     element->used_mask = is_dcl ? 0 : mask;
-    if (sm1->p.program.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
+    if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
         element->interpolation_mode = VKD3DSIM_LINEAR;
 
     return true;
@@ -581,13 +582,14 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
 static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
         unsigned int register_index, unsigned int mask)
 {
+    struct vsir_program *program = sm1->p.program;
     struct shader_signature *signature;
     struct signature_element *element;
 
     if (output)
-        signature = &sm1->p.program.output_signature;
+        signature = &program->output_signature;
     else
-        signature = &sm1->p.program.input_signature;
+        signature = &program->input_signature;
 
     if (!(element = find_signature_element_by_register_index(signature, register_index)))
     {
@@ -602,7 +604,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
 static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1,
         const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask)
 {
-    const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
+    const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
     unsigned int register_index = reg->idx[0].offset;
 
     switch (reg->type)
@@ -705,7 +707,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
 static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1,
         const struct vkd3d_shader_semantic *semantic)
 {
-    const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
+    const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
     const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg;
     enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
     unsigned int mask = semantic->resource.reg.write_mask;
@@ -767,7 +769,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1,
 static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
         const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def)
 {
-    struct vsir_program *program = &sm1->p.program;
+    struct vsir_program *program = sm1->p.program;
     uint32_t register_index = reg->idx[0].offset;
 
     switch (reg->type)
@@ -828,7 +830,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
      * VS >= 2.0 have relative addressing (with token)
      * VS >= 1.0 < 2.0 have relative addressing (without token)
      * The version check below should work in general. */
-    if (sm1->p.program.shader_version.major < 2)
+    if (sm1->p.program->shader_version.major < 2)
     {
         *addr_token = (1u << 31)
                 | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2)
@@ -857,7 +859,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
     /* Version 2.0+ shaders may contain address tokens, but fortunately they
      * have a useful length mask - use it here. Version 1.x shaders contain no
      * such tokens. */
-    if (sm1->p.program.shader_version.major >= 2)
+    if (sm1->p.program->shader_version.major >= 2)
     {
         length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT;
         *ptr += length;
@@ -887,7 +889,8 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
 {
     struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
 
-    vsir_program_cleanup(&parser->program);
+    vsir_program_cleanup(parser->program);
+    vkd3d_free(parser->program);
     vkd3d_free(sm1);
 }
 
@@ -900,7 +903,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const
     shader_sm1_read_param(sm1, ptr, &token, &addr_token);
     if (has_relative_address(token))
     {
-        if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
+        if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1)))
         {
             vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
                     "Out of memory.");
@@ -921,7 +924,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const
     shader_sm1_read_param(sm1, ptr, &token, &addr_token);
     if (has_relative_address(token))
     {
-        if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
+        if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1)))
         {
             vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
                     "Out of memory.");
@@ -1090,7 +1093,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
 {
     struct vkd3d_shader_src_param *src_params, *predicate;
     const struct vkd3d_sm1_opcode_info *opcode_info;
-    struct vsir_program *program = &sm1->p.program;
+    struct vsir_program *program = sm1->p.program;
     struct vkd3d_shader_dst_param *dst_param;
     const uint32_t **ptr = &sm1->ptr;
     uint32_t opcode_token;
@@ -1318,6 +1321,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
     struct vkd3d_shader_instruction_array *instructions;
     struct vkd3d_shader_instruction *ins;
     struct vkd3d_shader_sm1_parser *sm1;
+    struct vsir_program *program;
     unsigned int i;
     int ret;
 
@@ -1334,7 +1338,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
         return ret;
     }
 
-    instructions = &sm1->p.program.instructions;
+    program = sm1->p.program;
+    instructions = &program->instructions;
     while (!shader_sm1_is_end(sm1))
     {
         if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@@ -1356,8 +1361,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
         ++instructions->count;
     }
 
-    for (i = 0; i < ARRAY_SIZE(sm1->p.program.flat_constant_count); ++i)
-        sm1->p.program.flat_constant_count[i] = get_external_constant_count(sm1, i);
+    for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
+        program->flat_constant_count[i] = get_external_constant_count(sm1, i);
 
     if (!sm1->p.failed)
         ret = vkd3d_shader_parser_validate(&sm1->p);
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c
index 605e97530c..3f65f521c1 100644
--- a/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d-shader/dxil.c
@@ -2305,7 +2305,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_
 {
     struct vkd3d_shader_src_param *params;
 
-    if (!(params = vsir_program_get_src_params(&sm6->p.program, count)))
+    if (!(params = vsir_program_get_src_params(sm6->p.program, count)))
     {
         ERR("Failed to allocate src params.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@@ -2322,7 +2322,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_
 {
     struct vkd3d_shader_dst_param *params;
 
-    if (!(params = vsir_program_get_dst_params(&sm6->p.program, count)))
+    if (!(params = vsir_program_get_dst_params(sm6->p.program, count)))
     {
         ERR("Failed to allocate dst params.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@@ -2504,7 +2504,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
     }
     else
     {
-        struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&sm6->p.program, 1);
+        struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1);
         if (rel_addr)
             src_param_init_from_value(rel_addr, address);
         idx->offset = 0;
@@ -2998,7 +2998,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
                 "Out of memory allocating an immediate constant buffer of count %u.", count);
         return VKD3D_ERROR_OUT_OF_MEMORY;
     }
-    if (!shader_instruction_array_add_icb(&sm6->p.program.instructions, icb))
+    if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb))
     {
         ERR("Failed to store icb object.\n");
         vkd3d_free(icb);
@@ -3385,12 +3385,14 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al
 
 static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
 {
-    if (!shader_instruction_array_reserve(&sm6->p.program.instructions, sm6->p.program.instructions.count + extra))
+    struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions;
+
+    if (!shader_instruction_array_reserve(instructions, instructions->count + extra))
     {
         ERR("Failed to allocate instruction.\n");
         return NULL;
     }
-    return &sm6->p.program.instructions.elements[sm6->p.program.instructions.count];
+    return &instructions->elements[instructions->count];
 }
 
 /* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
@@ -3400,7 +3402,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
     struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
     assert(ins);
     vsir_instruction_init(ins, &sm6->p.location, handler_idx);
-    ++sm6->p.program.instructions.count;
+    ++sm6->p.program->instructions.count;
     return ins;
 }
 
@@ -3755,9 +3757,9 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
     }
 
     /* Resolve initialiser forward references. */
-    for (i = 0; i < sm6->p.program.instructions.count; ++i)
+    for (i = 0; i < sm6->p.program->instructions.count; ++i)
     {
-        ins = &sm6->p.program.instructions.elements[i];
+        ins = &sm6->p.program->instructions.elements[i];
         if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
         {
             ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
@@ -3837,7 +3839,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(
 static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s,
         bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
 {
-    enum vkd3d_shader_type shader_type = sm6->p.program.shader_version.type;
+    enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type;
     bool is_patch_constant, is_control_point;
     struct vkd3d_shader_dst_param *param;
     const struct signature_element *e;
@@ -3882,7 +3884,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
         if (is_control_point)
         {
             if (reg_type == VKD3DSPR_OUTPUT)
-                param->reg.idx[count].rel_addr = instruction_array_create_outpointid_param(&sm6->p.program.instructions);
+                param->reg.idx[count].rel_addr = instruction_array_create_outpointid_param(&sm6->p.program->instructions);
             param->reg.idx[count++].offset = 0;
         }
 
@@ -3908,7 +3910,7 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct
 static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6,
         const struct shader_signature *patch_constant_signature)
 {
-    bool is_input = sm6->p.program.shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
+    bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
 
     sm6_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST,
             sm6->patch_constant_params);
@@ -5279,6 +5281,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
     bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT;
     bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT;
     struct vkd3d_shader_instruction *ins = state->ins;
+    struct vsir_program *program = sm6->p.program;
     unsigned int count, row_index, column_index;
     const struct vkd3d_shader_dst_param *params;
     struct vkd3d_shader_src_param *src_param;
@@ -5300,17 +5303,17 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
 
     if (is_patch_constant)
     {
-        signature = &sm6->p.program.patch_constant_signature;
+        signature = &program->patch_constant_signature;
         params = sm6->patch_constant_params;
     }
     else if (is_control_point)
     {
-        signature = &sm6->p.program.output_signature;
+        signature = &program->output_signature;
         params = sm6->output_params;
     }
     else
     {
-        signature = &sm6->p.program.input_signature;
+        signature = &program->input_signature;
         params = sm6->input_params;
     }
     if (row_index >= signature->element_count)
@@ -5801,6 +5804,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
 {
     bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT;
     struct vkd3d_shader_instruction *ins = state->ins;
+    struct vsir_program *program = sm6->p.program;
     struct vkd3d_shader_src_param *src_param;
     struct vkd3d_shader_dst_param *dst_param;
     const struct shader_signature *signature;
@@ -5811,7 +5815,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
     row_index = sm6_value_get_constant_uint(operands[0]);
     column_index = sm6_value_get_constant_uint(operands[2]);
 
-    signature = is_patch_constant ? &sm6->p.program.patch_constant_signature : &sm6->p.program.output_signature;
+    signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature;
     if (row_index >= signature->element_count)
     {
         WARN("Invalid row index %u.\n", row_index);
@@ -7771,6 +7775,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun
 static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
         struct sm6_function *function)
 {
+    struct vsir_program *program = sm6->p.program;
     struct vkd3d_shader_instruction *ins;
     size_t i, block_idx, block_count;
     const struct dxil_record *record;
@@ -7862,7 +7867,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
             {
                 struct function_emission_state state = {code_block, ins};
                 sm6_parser_emit_atomicrmw(sm6, record, &state, dst);
-                sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx);
+                program->temp_count = max(program->temp_count, state.temp_idx);
                 break;
             }
             case FUNC_CODE_INST_BINOP:
@@ -7876,7 +7881,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
             {
                 struct function_emission_state state = {code_block, ins};
                 sm6_parser_emit_call(sm6, record, &state, dst);
-                sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx);
+                program->temp_count = max(program->temp_count, state.temp_idx);
                 break;
             }
             case FUNC_CODE_INST_CAST:
@@ -8150,9 +8155,10 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
 
 static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6)
 {
+    struct vsir_program *program = sm6->p.program;
     unsigned int i;
 
-    sm6->p.program.block_count = function->block_count;
+    program->block_count = function->block_count;
 
     for (i = 0; i < function->block_count; ++i)
     {
@@ -8168,9 +8174,9 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun
         sm6_parser_emit_label(sm6, block->id);
         sm6_block_emit_phi(block, sm6);
 
-        memcpy(&sm6->p.program.instructions.elements[sm6->p.program.instructions.count], block->instructions,
+        memcpy(&program->instructions.elements[program->instructions.count], block->instructions,
                 block->instruction_count * sizeof(*block->instructions));
-        sm6->p.program.instructions.count += block->instruction_count;
+        program->instructions.count += block->instruction_count;
 
         sm6_block_emit_terminator(block, sm6);
     }
@@ -9140,7 +9146,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
         }
 
         ++sm6->descriptor_count;
-        ++sm6->p.program.instructions.count;
+        ++sm6->p.program->instructions.count;
     }
 
     return VKD3D_OK;
@@ -9454,6 +9460,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
 static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m,
         enum vkd3d_tessellator_domain tessellator_domain)
 {
+    struct vsir_program *program = sm6->p.program;
     enum vkd3d_result ret;
 
     if (!sm6_metadata_value_is_node(m))
@@ -9465,24 +9472,24 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons
     }
 
     if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0],
-            &sm6->p.program.input_signature, tessellator_domain)) < 0)
+            &program->input_signature, tessellator_domain)) < 0)
     {
         return ret;
     }
     if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1],
-            &sm6->p.program.output_signature, tessellator_domain)) < 0)
+            &program->output_signature, tessellator_domain)) < 0)
     {
         return ret;
     }
     if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[2],
-            &sm6->p.program.patch_constant_signature, tessellator_domain)) < 0)
+            &program->patch_constant_signature, tessellator_domain)) < 0)
     {
         return ret;
     }
 
-    sm6_parser_init_input_signature(sm6, &sm6->p.program.input_signature);
-    sm6_parser_init_output_signature(sm6, &sm6->p.program.output_signature);
-    sm6_parser_init_patch_constant_signature(sm6, &sm6->p.program.patch_constant_signature);
+    sm6_parser_init_input_signature(sm6, &program->input_signature);
+    sm6_parser_init_output_signature(sm6, &program->output_signature);
+    sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature);
 
     return VKD3D_OK;
 }
@@ -9511,14 +9518,15 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm
 
 static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
 {
+    struct vkd3d_shader_version *version = &sm6->p.program->shader_version;
     const struct sm6_metadata_node *node;
     struct vkd3d_shader_instruction *ins;
     unsigned int group_sizes[3];
     unsigned int i;
 
-    if (sm6->p.program.shader_version.type != VKD3D_SHADER_TYPE_COMPUTE)
+    if (version->type != VKD3D_SHADER_TYPE_COMPUTE)
     {
-        WARN("Shader of type %#x has thread group dimensions.\n", sm6->p.program.shader_version.type);
+        WARN("Shader of type %#x has thread group dimensions.\n", version->type);
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
                 "Shader has thread group dimensions but is not a compute shader.");
         return VKD3D_ERROR_INVALID_SHADER;
@@ -9754,7 +9762,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
     }
 
     sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
-    sm6->p.program.input_control_point_count = input_control_point_count;
+    sm6->p.program->input_control_point_count = input_control_point_count;
 
     i = operands[1];
     /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */
@@ -9836,7 +9844,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa
 
     sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]);
     sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input");
-    sm6->p.program.input_control_point_count = operands[1];
+    sm6->p.program->input_control_point_count = operands[1];
 
     return operands[0];
 }
@@ -9844,6 +9852,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa
 static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6,
         const struct sm6_metadata_value *m)
 {
+    struct vsir_program *program = sm6->p.program;
     const struct sm6_metadata_node *node;
     unsigned int operands[6] = {0};
     unsigned int i;
@@ -9894,10 +9903,10 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa
     }
 
     sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input");
-    sm6->p.program.input_control_point_count = operands[1];
+    program->input_control_point_count = operands[1];
     sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output");
     sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]);
-    sm6->p.program.output_control_point_count = operands[2];
+    program->output_control_point_count = operands[2];
     sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]);
     sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]);
     sm6_parser_emit_dcl_tessellator_output_primitive(sm6, operands[5]);
@@ -10121,7 +10130,8 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
 
     dxil_block_destroy(&sm6->root_block);
     dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
-    vsir_program_cleanup(&parser->program);
+    vsir_program_cleanup(parser->program);
+    vkd3d_free(parser->program);
     sm6_type_table_cleanup(sm6->types, sm6->type_count);
     sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
     sm6_functions_cleanup(sm6->functions, sm6->function_count);
@@ -10149,15 +10159,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
 {
     size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
-    const struct shader_signature *patch_constant_signature = &sm6->p.program.patch_constant_signature;
-    const struct shader_signature *output_signature = &sm6->p.program.output_signature;
-    const struct shader_signature *input_signature = &sm6->p.program.input_signature;
+    struct shader_signature *patch_constant_signature, *output_signature, *input_signature;
     const struct vkd3d_shader_location location = {.source_name = source_name};
     uint32_t version_token, dxil_version, token_count, magic;
     const uint32_t *byte_code = dxbc_desc->byte_code;
     unsigned int chunk_offset, chunk_size;
     enum bitcode_block_abbreviation abbr;
     struct vkd3d_shader_version version;
+    struct vsir_program *program;
     struct dxil_block *block;
     struct sm6_function *fn;
     enum vkd3d_result ret;
@@ -10248,9 +10257,13 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     sm6->ptr = &sm6->start[1];
     sm6->bitpos = 2;
 
-    sm6->p.program.input_signature = dxbc_desc->input_signature;
-    sm6->p.program.output_signature = dxbc_desc->output_signature;
-    sm6->p.program.patch_constant_signature = dxbc_desc->patch_constant_signature;
+    program = sm6->p.program;
+    input_signature = &program->input_signature;
+    output_signature = &program->output_signature;
+    patch_constant_signature = &program->patch_constant_signature;
+    *input_signature = dxbc_desc->input_signature;
+    *output_signature = dxbc_desc->output_signature;
+    *patch_constant_signature = dxbc_desc->patch_constant_signature;
     memset(dxbc_desc, 0, sizeof(*dxbc_desc));
 
     block = &sm6->root_block;
@@ -10313,9 +10326,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         return ret;
     }
 
-    if (!(sm6->output_params = vsir_program_get_dst_params(&sm6->p.program, output_signature->element_count))
-            || !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count))
-            || !(sm6->patch_constant_params = vsir_program_get_dst_params(&sm6->p.program,
+    if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count))
+            || !(sm6->input_params = vsir_program_get_dst_params(program, input_signature->element_count))
+            || !(sm6->patch_constant_params = vsir_program_get_dst_params(program,
             patch_constant_signature->element_count)))
     {
         ERR("Failed to allocate input/output parameters.\n");
@@ -10405,7 +10418,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         return VKD3D_ERROR_OUT_OF_MEMORY;
     }
 
-    sm6->p.program.ssa_count = sm6->ssa_next_id;
+    program->ssa_count = sm6->ssa_next_id;
 
     if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point)))
     {
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 96e73d23d7..a0ae457e92 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -4010,7 +4010,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
         }
         if (ret >= 0)
         {
-            ret = vsir_program_compile(&parser->program, parser->config_flags, &info, out, message_context);
+            ret = vsir_program_compile(parser->program, parser->config_flags, &info, out, message_context);
             vkd3d_shader_parser_destroy(parser);
         }
         vkd3d_shader_free_shader_code(&info.source);
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index 4e3bef9640..704c904f56 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -726,7 +726,7 @@ static struct vkd3d_shader_sm4_parser *vkd3d_shader_sm4_parser(struct vkd3d_shad
 
 static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
 {
-    const struct vkd3d_shader_version *version = &sm4->p.program.shader_version;
+    const struct vkd3d_shader_version *version = &sm4->p.program->shader_version;
 
     return version->major >= 5 && version->minor >= 1;
 }
@@ -811,7 +811,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
     icb->element_count = icb_size / VKD3D_VEC4_SIZE;
     icb->is_null = false;
     memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
-    shader_instruction_array_add_icb(&priv->p.program.instructions, icb);
+    shader_instruction_array_add_icb(&priv->p.program->instructions, icb);
     ins->declaration.icb = icb;
 }
 
@@ -933,6 +933,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
         uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
 {
     struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range;
+    struct vsir_program *program = priv->p.program;
     unsigned int i, register_idx, register_count;
     const struct shader_signature *signature;
     enum vkd3d_shader_register_type type;
@@ -954,32 +955,32 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
         case VKD3DSPR_INCONTROLPOINT:
             io_masks = priv->input_register_masks;
             ranges = &priv->input_index_ranges;
-            signature = &priv->p.program.input_signature;
+            signature = &program->input_signature;
             break;
         case VKD3DSPR_OUTPUT:
             if (sm4_parser_is_in_fork_or_join_phase(priv))
             {
                 io_masks = priv->patch_constant_register_masks;
                 ranges = &priv->patch_constant_index_ranges;
-                signature = &priv->p.program.patch_constant_signature;
+                signature = &program->patch_constant_signature;
             }
             else
             {
                 io_masks = priv->output_register_masks;
                 ranges = &priv->output_index_ranges;
-                signature = &priv->p.program.output_signature;
+                signature = &program->output_signature;
             }
             break;
         case VKD3DSPR_COLOROUT:
         case VKD3DSPR_OUTCONTROLPOINT:
             io_masks = priv->output_register_masks;
             ranges = &priv->output_index_ranges;
-            signature = &priv->p.program.output_signature;
+            signature = &program->output_signature;
             break;
         case VKD3DSPR_PATCHCONST:
             io_masks = priv->patch_constant_register_masks;
             ranges = &priv->patch_constant_index_ranges;
-            signature = &priv->p.program.patch_constant_signature;
+            signature = &program->patch_constant_signature;
             break;
 
         default:
@@ -1057,16 +1058,17 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction
 }
 
 static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode,
-        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
+        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
 {
     enum vkd3d_sm4_input_primitive_type primitive_type;
+    struct vsir_program *program = sm4->p.program;
 
     primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT;
     if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32)
     {
         ins->declaration.primitive_type.type = VKD3D_PT_PATCH;
         ins->declaration.primitive_type.patch_vertex_count = primitive_type - VKD3D_SM5_INPUT_PT_PATCH1 + 1;
-        priv->p.program.input_control_point_count = ins->declaration.primitive_type.patch_vertex_count;
+        program->input_control_point_count = ins->declaration.primitive_type.patch_vertex_count;
     }
     else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table))
     {
@@ -1075,7 +1077,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
     else
     {
         ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type].vkd3d_type;
-        priv->p.program.input_control_point_count = input_primitive_type_table[primitive_type].control_point_count;
+        program->input_control_point_count = input_primitive_type_table[primitive_type].control_point_count;
     }
 
     if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED)
@@ -1083,11 +1085,13 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
 }
 
 static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode,
-        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
+        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
 {
+    struct vsir_program *program = sm4->p.program;
+
     ins->declaration.count = *tokens;
     if (opcode == VKD3D_SM4_OP_DCL_TEMPS)
-        priv->p.program.temp_count = max(priv->p.program.temp_count, *tokens);
+        program->temp_count = max(program->temp_count, *tokens);
 }
 
 static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@@ -1113,7 +1117,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u
     if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
     {
         struct signature_element *e = vsir_signature_find_element_for_reg(
-                &priv->p.program.input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
+                &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
 
         e->interpolation_mode = ins->flags;
     }
@@ -1128,7 +1132,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in
     if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
     {
         struct signature_element *e = vsir_signature_find_element_for_reg(
-                &priv->p.program.input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
+                &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
 
         e->interpolation_mode = ins->flags;
     }
@@ -1183,15 +1187,17 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins,
 }
 
 static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction *ins, uint32_t opcode,
-        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
+        uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
 {
+    struct vsir_program *program = sm4->p.program;
+
     ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK)
             >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT;
 
     if (opcode == VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT)
-        priv->p.program.input_control_point_count = ins->declaration.count;
+        program->input_control_point_count = ins->declaration.count;
     else
-        priv->p.program.output_control_point_count = ins->declaration.count;
+        program->output_control_point_count = ins->declaration.count;
 }
 
 static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@@ -1749,7 +1755,8 @@ static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
 {
     struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
 
-    vsir_program_cleanup(&parser->program);
+    vsir_program_cleanup(parser->program);
+    vkd3d_free(parser->program);
     vkd3d_free(sm4);
 }
 
@@ -1758,7 +1765,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
 {
     if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE)
     {
-        struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1);
+        struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1);
 
         if (!(reg_idx->rel_addr = rel_addr))
         {
@@ -2036,7 +2043,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
 {
     return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT
             || (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE
-            || priv->p.program.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
+            || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
 }
 
 static uint32_t mask_from_swizzle(uint32_t swizzle)
@@ -2360,7 +2367,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d
 static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins)
 {
     const struct vkd3d_sm4_opcode_info *opcode_info;
-    struct vsir_program *program = &sm4->p.program;
+    struct vsir_program *program = sm4->p.program;
     uint32_t opcode_token, opcode, previous_token;
     struct vkd3d_shader_dst_param *dst_params;
     struct vkd3d_shader_src_param *src_params;
@@ -2652,6 +2659,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
     struct vkd3d_shader_instruction *ins;
     struct vkd3d_shader_sm4_parser *sm4;
     struct dxbc_shader_desc dxbc_desc = {0};
+    struct vsir_program *program;
     int ret;
 
     if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4))))
@@ -2678,29 +2686,30 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
         return VKD3D_ERROR_INVALID_ARGUMENT;
     }
 
-    sm4->p.program.input_signature = dxbc_desc.input_signature;
-    sm4->p.program.output_signature = dxbc_desc.output_signature;
-    sm4->p.program.patch_constant_signature = dxbc_desc.patch_constant_signature;
+    program = sm4->p.program;
+    program->input_signature = dxbc_desc.input_signature;
+    program->output_signature = dxbc_desc.output_signature;
+    program->patch_constant_signature = dxbc_desc.patch_constant_signature;
     memset(&dxbc_desc, 0, sizeof(dxbc_desc));
 
     /* DXBC stores used masks inverted for output signatures, for some reason.
      * We return them un-inverted. */
-    uninvert_used_masks(&sm4->p.program.output_signature);
-    if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL)
-        uninvert_used_masks(&sm4->p.program.patch_constant_signature);
+    uninvert_used_masks(&program->output_signature);
+    if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
+        uninvert_used_masks(&program->patch_constant_signature);
 
-    if (!shader_sm4_parser_validate_signature(sm4, &sm4->p.program.input_signature,
+    if (!shader_sm4_parser_validate_signature(sm4, &program->input_signature,
             sm4->input_register_masks, "Input")
-            || !shader_sm4_parser_validate_signature(sm4, &sm4->p.program.output_signature,
+            || !shader_sm4_parser_validate_signature(sm4, &program->output_signature,
             sm4->output_register_masks, "Output")
-            || !shader_sm4_parser_validate_signature(sm4, &sm4->p.program.patch_constant_signature,
+            || !shader_sm4_parser_validate_signature(sm4, &program->patch_constant_signature,
             sm4->patch_constant_register_masks, "Patch constant"))
     {
         shader_sm4_destroy(&sm4->p);
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
-    instructions = &sm4->p.program.instructions;
+    instructions = &program->instructions;
     while (sm4->ptr != sm4->end)
     {
         if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@@ -2721,7 +2730,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
         }
         ++instructions->count;
     }
-    if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL
+    if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL
             && !sm4->has_control_point_phase && !sm4->p.failed)
         shader_sm4_validate_default_phase_index_ranges(sm4);
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 1845648072..89434b0aa6 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -559,13 +559,19 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
         const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
         unsigned int instruction_reserve)
 {
+    bool ret;
+
     parser->message_context = message_context;
     parser->location.source_name = source_name;
     parser->location.line = 1;
     parser->location.column = 0;
     parser->ops = ops;
     parser->config_flags = vkd3d_shader_init_config_flags();
-    return vsir_program_init(&parser->program, version, instruction_reserve);
+    if (!(parser->program = vkd3d_calloc(1, sizeof(*parser->program))))
+        return false;
+    if (!(ret = vsir_program_init(parser->program, version, instruction_reserve)))
+        vkd3d_free(parser->program);
+    return ret;
 }
 
 void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
@@ -1544,7 +1550,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
         }
         else
         {
-            ret = vsir_program_scan(&parser->program, compile_info, &message_context, NULL);
+            ret = vsir_program_scan(parser->program, compile_info, &message_context, NULL);
             vkd3d_shader_parser_destroy(parser);
         }
     }
@@ -1665,7 +1671,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
         }
         else
         {
-            ret = vsir_program_compile(&parser->program, parser->config_flags, compile_info, out, &message_context);
+            ret = vsir_program_compile(parser->program, parser->config_flags, compile_info, out, &message_context);
             vkd3d_shader_parser_destroy(parser);
         }
     }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 81bc95c2c4..1a1d01e7ed 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1392,10 +1392,10 @@ struct vkd3d_shader_parser
 {
     struct vkd3d_shader_message_context *message_context;
     struct vkd3d_shader_location location;
+    struct vsir_program *program;
     bool failed;
 
     const struct vkd3d_shader_parser_ops *ops;
-    struct vsir_program program;
 
     uint64_t config_flags;
 };
@@ -1421,7 +1421,7 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse
 
 static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser)
 {
-    return vsir_program_validate(&parser->program, parser->config_flags,
+    return vsir_program_validate(parser->program, parser->config_flags,
             parser->location.source_name, parser->message_context);
 }
 
-- 
GitLab


From 19b552ce1b803e95363427b40204a3ef580058c9 Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:42:12 +0200
Subject: [PATCH 2/6] vkd3d-shader/ir: Pass an initialised vsir_program
 structure to vkd3d_shader_parser_init().

---
 libs/vkd3d-shader/d3dbc.c                | 11 +++++++++--
 libs/vkd3d-shader/dxil.c                 | 11 ++++++++---
 libs/vkd3d-shader/ir.c                   |  1 +
 libs/vkd3d-shader/tpf.c                  | 10 ++++++++--
 libs/vkd3d-shader/vkd3d_shader_main.c    | 13 +++----------
 libs/vkd3d-shader/vkd3d_shader_private.h |  5 ++---
 6 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index 2e37549f8f..43d4374ad7 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -1242,6 +1242,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
     const uint32_t *code = compile_info->source.code;
     size_t code_size = compile_info->source.size;
     struct vkd3d_shader_version version;
+    struct vsir_program *program;
     uint16_t shader_type;
     size_t token_count;
 
@@ -1289,10 +1290,16 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
     sm1->start = &code[1];
     sm1->end = &code[token_count];
 
+    if (!(program = vkd3d_malloc(sizeof(*program))))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
     /* Estimate instruction count to avoid reallocation in most shaders. */
-    if (!vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops,
-            code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
+    if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
+    {
+        vkd3d_free(program);
         return VKD3D_ERROR_OUT_OF_MEMORY;
+    }
+
+    vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops);
     sm1->ptr = sm1->start;
 
     return VKD3D_OK;
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c
index 3f65f521c1..7275489fe2 100644
--- a/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d-shader/dxil.c
@@ -10250,14 +10250,19 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
+    if (!(program = vkd3d_malloc(sizeof(*program))))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
     /* Estimate instruction count to avoid reallocation in most shaders. */
     count = max(token_count, 400) - 400;
-    vkd3d_shader_parser_init(&sm6->p, message_context, source_name, &version, &sm6_parser_ops,
-            (count + (count >> 2)) / 2u + 10);
+    if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
+    {
+        vkd3d_free(program);
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+    }
+    vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name, &sm6_parser_ops);
     sm6->ptr = &sm6->start[1];
     sm6->bitpos = 2;
 
-    program = sm6->p.program;
     input_signature = &program->input_signature;
     output_signature = &program->output_signature;
     patch_constant_signature = &program->patch_constant_signature;
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c
index 2c78447e38..37818d4dfa 100644
--- a/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d-shader/ir.c
@@ -21,6 +21,7 @@
 
 bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve)
 {
+    memset(program, 0, sizeof(*program));
     program->shader_version = *version;
     return shader_instruction_array_init(&program->instructions, reserve);
 }
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index 704c904f56..e7301d726b 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -2517,6 +2517,7 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
 {
     struct vkd3d_shader_version version;
     uint32_t version_token, token_count;
+    struct vsir_program *program;
 
     if (byte_code_size / sizeof(*byte_code) < 2)
     {
@@ -2570,10 +2571,15 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
     version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
     version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
 
+    if (!(program = vkd3d_malloc(sizeof(*program))))
+        return false;
     /* Estimate instruction count to avoid reallocation in most shaders. */
-    if (!vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops,
-            token_count / 7u + 20))
+    if (!vsir_program_init(program, &version, token_count / 7u + 20))
+    {
+        vkd3d_free(program);
         return false;
+    }
+    vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name, &shader_sm4_parser_ops);
     sm4->ptr = sm4->start;
 
     init_sm4_lookup_tables(&sm4->lookup);
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 89434b0aa6..a25b5f4acd 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -554,24 +554,17 @@ static uint64_t vkd3d_shader_init_config_flags(void)
     return config_flags;
 }
 
-bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
+void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program,
         struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
-        unsigned int instruction_reserve)
+        const struct vkd3d_shader_parser_ops *ops)
 {
-    bool ret;
-
     parser->message_context = message_context;
     parser->location.source_name = source_name;
     parser->location.line = 1;
     parser->location.column = 0;
     parser->ops = ops;
     parser->config_flags = vkd3d_shader_init_config_flags();
-    if (!(parser->program = vkd3d_calloc(1, sizeof(*parser->program))))
-        return false;
-    if (!(ret = vsir_program_init(parser->program, version, instruction_reserve)))
-        vkd3d_free(parser->program);
-    return ret;
+    parser->program = program;
 }
 
 void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 1a1d01e7ed..196d92efc0 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1407,10 +1407,9 @@ struct vkd3d_shader_parser_ops
 
 void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
         enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
-bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
+void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program,
         struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
-        unsigned int instruction_reserve);
+        const struct vkd3d_shader_parser_ops *ops);
 void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
         enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
 
-- 
GitLab


From efe9dfd73aac352fbe81e4baef3c3e54592ee484 Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:42:16 +0200
Subject: [PATCH 3/6] vkd3d-shader/ir: Do not store the vkd3d-shader
 configuration flags in struct vkd3d_shader_parser.

---
 libs/vkd3d-shader/d3dbc.c                |  4 ++--
 libs/vkd3d-shader/dxil.c                 |  4 ++--
 libs/vkd3d-shader/hlsl.c                 |  7 ++++---
 libs/vkd3d-shader/tpf.c                  |  4 ++--
 libs/vkd3d-shader/vkd3d_shader_main.c    | 19 ++++++++++---------
 libs/vkd3d-shader/vkd3d_shader_private.h | 13 ++++++-------
 6 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index 43d4374ad7..4e0a290535 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -1322,7 +1322,7 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1,
     return 0;
 }
 
-int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
 {
     struct vkd3d_shader_instruction_array *instructions;
@@ -1372,7 +1372,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
         program->flat_constant_count[i] = get_external_constant_count(sm1, i);
 
     if (!sm1->p.failed)
-        ret = vkd3d_shader_parser_validate(&sm1->p);
+        ret = vkd3d_shader_parser_validate(&sm1->p, config_flags);
 
     if (sm1->p.failed && ret >= 0)
         ret = VKD3D_ERROR_INVALID_SHADER;
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c
index 7275489fe2..29b36c3561 100644
--- a/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d-shader/dxil.c
@@ -10474,7 +10474,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     return VKD3D_OK;
 }
 
-int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
 {
     struct dxbc_shader_desc dxbc_desc = {0};
@@ -10520,7 +10520,7 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
     vkd3d_free(byte_code);
 
     if (!sm6->p.failed && ret >= 0)
-        ret = vkd3d_shader_parser_validate(&sm6->p);
+        ret = vkd3d_shader_parser_validate(&sm6->p, config_flags);
 
     if (sm6->p.failed && ret >= 0)
         ret = VKD3D_ERROR_INVALID_SHADER;
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index a0ae457e92..40548d4a2e 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -3991,6 +3991,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
             || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT
             || target_type == VKD3D_SHADER_TARGET_D3D_ASM)
     {
+        uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_compile_info info = *compile_info;
         struct vkd3d_shader_parser *parser;
 
@@ -3999,18 +4000,18 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
             if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0)
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
-            ret = vkd3d_shader_sm1_parser_create(&info, message_context, &parser);
+            ret = vkd3d_shader_sm1_parser_create(&info, config_flags, message_context, &parser);
         }
         else
         {
             if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
-            ret = vkd3d_shader_sm4_parser_create(&info, message_context, &parser);
+            ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser);
         }
         if (ret >= 0)
         {
-            ret = vsir_program_compile(parser->program, parser->config_flags, &info, out, message_context);
+            ret = vsir_program_compile(parser->program, config_flags, &info, out, message_context);
             vkd3d_shader_parser_destroy(parser);
         }
         vkd3d_shader_free_shader_code(&info.source);
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index e7301d726b..633e9f89ac 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -2658,7 +2658,7 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s
     return;
 }
 
-int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
 {
     struct vkd3d_shader_instruction_array *instructions;
@@ -2741,7 +2741,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
         shader_sm4_validate_default_phase_index_ranges(sm4);
 
     if (!sm4->p.failed)
-        vkd3d_shader_parser_validate(&sm4->p);
+        vkd3d_shader_parser_validate(&sm4->p, config_flags);
 
     if (sm4->p.failed)
     {
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index a25b5f4acd..f02976667b 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -540,7 +540,7 @@ static const struct vkd3d_debug_option vkd3d_shader_config_options[] =
     {"force_validation", VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION}, /* force validation of internal shader representations */
 };
 
-static uint64_t vkd3d_shader_init_config_flags(void)
+uint64_t vkd3d_shader_init_config_flags(void)
 {
     uint64_t config_flags;
     const char *config;
@@ -563,7 +563,6 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr
     parser->location.line = 1;
     parser->location.column = 0;
     parser->ops = ops;
-    parser->config_flags = vkd3d_shader_init_config_flags();
     parser->program = program;
 }
 
@@ -1515,20 +1514,21 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
     }
     else
     {
+        uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_parser *parser;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
-                ret = vkd3d_shader_sm1_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                ret = vkd3d_shader_sm4_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                ret = vkd3d_shader_sm6_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             default:
@@ -1636,20 +1636,21 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
     }
     else
     {
+        uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_parser *parser;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
-                ret = vkd3d_shader_sm1_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                ret = vkd3d_shader_sm4_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                ret = vkd3d_shader_sm6_parser_create(compile_info, &message_context, &parser);
+                ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
                 break;
 
             default:
@@ -1664,7 +1665,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
         }
         else
         {
-            ret = vsir_program_compile(parser->program, parser->config_flags, compile_info, out, &message_context);
+            ret = vsir_program_compile(parser->program, config_flags, compile_info, out, &message_context);
             vkd3d_shader_parser_destroy(parser);
         }
     }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 196d92efc0..cd4916a383 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1396,8 +1396,6 @@ struct vkd3d_shader_parser
     bool failed;
 
     const struct vkd3d_shader_parser_ops *ops;
-
-    uint64_t config_flags;
 };
 
 struct vkd3d_shader_parser_ops
@@ -1418,9 +1416,9 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse
     parser->ops->parser_destroy(parser);
 }
 
-static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser)
+static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser, uint64_t config_flags)
 {
-    return vsir_program_validate(parser->program, parser->config_flags,
+    return vsir_program_validate(parser->program, config_flags,
             parser->location.source_name, parser->message_context);
 }
 
@@ -1551,15 +1549,16 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s
         enum vkd3d_shader_error error, const char *format, va_list args);
 
 void vkd3d_shader_dump_shader(const struct vkd3d_shader_compile_info *compile_info);
+uint64_t vkd3d_shader_init_config_flags(void);
 void vkd3d_shader_trace_text_(const char *text, size_t size, const char *function);
 #define vkd3d_shader_trace_text(text, size) \
         vkd3d_shader_trace_text_(text, size, __FUNCTION__)
 
-int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
-int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
-int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info,
+int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
 
 void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);
-- 
GitLab


From 402b96ef3bc219b060cd537f6dc9f5ff2bf59a2c Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:42:22 +0200
Subject: [PATCH 4/6] vkd3d-shader/d3dbc: Parse the shader into a vsir program
 in vkd3d_shader_sm1_parser_create().

---
 libs/vkd3d-shader/d3dbc.c                | 57 +++++++-----------------
 libs/vkd3d-shader/hlsl.c                 | 14 ++++--
 libs/vkd3d-shader/vkd3d_shader_main.c    | 34 +++++++++-----
 libs/vkd3d-shader/vkd3d_shader_private.h |  4 +-
 4 files changed, 51 insertions(+), 58 deletions(-)

diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index 4e0a290535..c62d0aaaf1 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -396,11 +396,6 @@ static const enum vkd3d_shader_resource_type resource_type_table[] =
     /* VKD3D_SM1_RESOURCE_TEXTURE_3D */   VKD3D_SHADER_RESOURCE_TEXTURE_3D,
 };
 
-static struct vkd3d_shader_sm1_parser *vkd3d_shader_sm1_parser(struct vkd3d_shader_parser *parser)
-{
-    return CONTAINING_RECORD(parser, struct vkd3d_shader_sm1_parser, p);
-}
-
 static uint32_t read_u32(const uint32_t **ptr)
 {
     return *(*ptr)++;
@@ -887,11 +882,6 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
 
 static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
 {
-    struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
-
-    vsir_program_cleanup(parser->program);
-    vkd3d_free(parser->program);
-    vkd3d_free(sm1);
 }
 
 static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
@@ -1235,14 +1225,13 @@ const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
     .parser_destroy = shader_sm1_destroy,
 };
 
-static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
+static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, struct vsir_program *program,
         const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
 {
     const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
     const uint32_t *code = compile_info->source.code;
     size_t code_size = compile_info->source.size;
     struct vkd3d_shader_version version;
-    struct vsir_program *program;
     uint16_t shader_type;
     size_t token_count;
 
@@ -1290,14 +1279,9 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
     sm1->start = &code[1];
     sm1->end = &code[token_count];
 
-    if (!(program = vkd3d_malloc(sizeof(*program))))
-        return VKD3D_ERROR_OUT_OF_MEMORY;
     /* Estimate instruction count to avoid reallocation in most shaders. */
     if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
-    {
-        vkd3d_free(program);
         return VKD3D_ERROR_OUT_OF_MEMORY;
-    }
 
     vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops);
     sm1->ptr = sm1->start;
@@ -1322,70 +1306,59 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1,
     return 0;
 }
 
-int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
+int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
 {
     struct vkd3d_shader_instruction_array *instructions;
+    struct vkd3d_shader_sm1_parser sm1 = {0};
     struct vkd3d_shader_instruction *ins;
-    struct vkd3d_shader_sm1_parser *sm1;
-    struct vsir_program *program;
     unsigned int i;
     int ret;
 
-    if (!(sm1 = vkd3d_calloc(1, sizeof(*sm1))))
-    {
-        ERR("Failed to allocate parser.\n");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
-    }
-
-    if ((ret = shader_sm1_init(sm1, compile_info, message_context)) < 0)
+    if ((ret = shader_sm1_init(&sm1, program, compile_info, message_context)) < 0)
     {
         WARN("Failed to initialise shader parser, ret %d.\n", ret);
-        vkd3d_free(sm1);
         return ret;
     }
 
-    program = sm1->p.program;
     instructions = &program->instructions;
-    while (!shader_sm1_is_end(sm1))
+    while (!shader_sm1_is_end(&sm1))
     {
         if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
         {
             ERR("Failed to allocate instructions.\n");
-            vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
-            shader_sm1_destroy(&sm1->p);
+            vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
+            vsir_program_cleanup(program);
             return VKD3D_ERROR_OUT_OF_MEMORY;
         }
         ins = &instructions->elements[instructions->count];
-        shader_sm1_read_instruction(sm1, ins);
+        shader_sm1_read_instruction(&sm1, ins);
 
         if (ins->handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Encountered unrecognized or invalid instruction.\n");
-            shader_sm1_destroy(&sm1->p);
+            vsir_program_cleanup(program);
             return VKD3D_ERROR_INVALID_SHADER;
         }
         ++instructions->count;
     }
 
     for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
-        program->flat_constant_count[i] = get_external_constant_count(sm1, i);
+        program->flat_constant_count[i] = get_external_constant_count(&sm1, i);
 
-    if (!sm1->p.failed)
-        ret = vkd3d_shader_parser_validate(&sm1->p, config_flags);
+    if (!sm1.p.failed)
+        ret = vkd3d_shader_parser_validate(&sm1.p, config_flags);
 
-    if (sm1->p.failed && ret >= 0)
+    if (sm1.p.failed && ret >= 0)
         ret = VKD3D_ERROR_INVALID_SHADER;
 
     if (ret < 0)
     {
         WARN("Failed to parse shader.\n");
-        shader_sm1_destroy(&sm1->p);
+        vsir_program_cleanup(program);
         return ret;
     }
 
-    *parser = &sm1->p;
-
     return ret;
 }
 
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 40548d4a2e..c3e188e0e2 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -3994,25 +3994,31 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
         uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_compile_info info = *compile_info;
         struct vkd3d_shader_parser *parser;
+        struct vsir_program program, *p;
 
         if (profile->major_version < 4)
         {
             if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0)
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
-            ret = vkd3d_shader_sm1_parser_create(&info, config_flags, message_context, &parser);
+            ret = d3dbc_parse(&info, config_flags, message_context, &program);
+            p = &program;
         }
         else
         {
             if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
-            ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser);
+            if ((ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser)) >= 0)
+                p = parser->program;
         }
         if (ret >= 0)
         {
-            ret = vsir_program_compile(parser->program, config_flags, &info, out, message_context);
-            vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_compile(p, config_flags, &info, out, message_context);
+            if (p == &program)
+                vsir_program_cleanup(&program);
+            else
+                vkd3d_shader_parser_destroy(parser);
         }
         vkd3d_shader_free_shader_code(&info.source);
     }
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index f02976667b..58eac14485 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1516,19 +1516,23 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
     {
         uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_parser *parser;
+        struct vsir_program program, *p;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
-                ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
+                ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
+                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
+                if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
+                    p = parser->program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
+                if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
+                    p = parser->program;
                 break;
 
             default:
@@ -1543,8 +1547,11 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
         }
         else
         {
-            ret = vsir_program_scan(parser->program, compile_info, &message_context, NULL);
-            vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_scan(p, compile_info, &message_context, NULL);
+            if (p == &program)
+                vsir_program_cleanup(&program);
+            else
+                vkd3d_shader_parser_destroy(parser);
         }
     }
 
@@ -1638,19 +1645,23 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
     {
         uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_parser *parser;
+        struct vsir_program program, *p;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
-                ret = vkd3d_shader_sm1_parser_create(compile_info, config_flags, &message_context, &parser);
+                ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
+                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser);
+                if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
+                    p = parser->program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser);
+                if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
+                    p = parser->program;
                 break;
 
             default:
@@ -1665,8 +1676,11 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
         }
         else
         {
-            ret = vsir_program_compile(parser->program, config_flags, compile_info, out, &message_context);
-            vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_compile(p, config_flags, compile_info, out, &message_context);
+            if (p == &program)
+                vsir_program_cleanup(&program);
+            else
+                vkd3d_shader_parser_destroy(parser);
         }
     }
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index cd4916a383..89d05917bf 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1554,8 +1554,8 @@ 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_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
+int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
 int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
 int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-- 
GitLab


From 6474e8cc7bc371d7b412b4e1622c6c2cdff0a1f8 Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:42:26 +0200
Subject: [PATCH 5/6] vkd3d-shader/tpf: Parse the shader into a vsir program in
 vkd3d_shader_sm4_parser_create().

---
 libs/vkd3d-shader/hlsl.c                 | 14 ++---
 libs/vkd3d-shader/tpf.c                  | 78 ++++++++----------------
 libs/vkd3d-shader/vkd3d_shader_main.c    |  8 +--
 libs/vkd3d-shader/vkd3d_shader_private.h |  4 +-
 4 files changed, 35 insertions(+), 69 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index c3e188e0e2..99214fba6d 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -3993,8 +3993,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
     {
         uint64_t config_flags = vkd3d_shader_init_config_flags();
         struct vkd3d_shader_compile_info info = *compile_info;
-        struct vkd3d_shader_parser *parser;
-        struct vsir_program program, *p;
+        struct vsir_program program;
 
         if (profile->major_version < 4)
         {
@@ -4002,23 +4001,18 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
             ret = d3dbc_parse(&info, config_flags, message_context, &program);
-            p = &program;
         }
         else
         {
             if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
                 goto done;
             info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
-            if ((ret = vkd3d_shader_sm4_parser_create(&info, config_flags, message_context, &parser)) >= 0)
-                p = parser->program;
+            ret = tpf_parse(&info, config_flags, message_context, &program);
         }
         if (ret >= 0)
         {
-            ret = vsir_program_compile(p, config_flags, &info, out, message_context);
-            if (p == &program)
-                vsir_program_cleanup(&program);
-            else
-                vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_compile(&program, config_flags, &info, out, message_context);
+            vsir_program_cleanup(&program);
         }
         vkd3d_shader_free_shader_code(&info.source);
     }
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index 633e9f89ac..94aedc8ced 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -719,11 +719,6 @@ static const enum vkd3d_data_type data_type_table[] =
     /* VKD3D_SM4_DATA_UNUSED */     VKD3D_DATA_UNUSED,
 };
 
-static struct vkd3d_shader_sm4_parser *vkd3d_shader_sm4_parser(struct vkd3d_shader_parser *parser)
-{
-    return CONTAINING_RECORD(parser, struct vkd3d_shader_sm4_parser, p);
-}
-
 static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
 {
     const struct vkd3d_shader_version *version = &sm4->p.program->shader_version;
@@ -1753,11 +1748,6 @@ static enum vkd3d_data_type map_data_type(char t)
 
 static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
 {
-    struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
-
-    vsir_program_cleanup(parser->program);
-    vkd3d_free(parser->program);
-    vkd3d_free(sm4);
 }
 
 static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
@@ -2511,13 +2501,12 @@ static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
     .parser_destroy = shader_sm4_destroy,
 };
 
-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,
+static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program,
+        const uint32_t *byte_code, size_t byte_code_size, const char *source_name,
         struct vkd3d_shader_message_context *message_context)
 {
     struct vkd3d_shader_version version;
     uint32_t version_token, token_count;
-    struct vsir_program *program;
 
     if (byte_code_size / sizeof(*byte_code) < 2)
     {
@@ -2571,14 +2560,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
     version.major = VKD3D_SM4_VERSION_MAJOR(version_token);
     version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
 
-    if (!(program = vkd3d_malloc(sizeof(*program))))
-        return false;
     /* Estimate instruction count to avoid reallocation in most shaders. */
     if (!vsir_program_init(program, &version, token_count / 7u + 20))
-    {
-        vkd3d_free(program);
         return false;
-    }
     vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name, &shader_sm4_parser_ops);
     sm4->ptr = sm4->start;
 
@@ -2658,41 +2642,31 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s
     return;
 }
 
-int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
+int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
 {
     struct vkd3d_shader_instruction_array *instructions;
-    struct vkd3d_shader_instruction *ins;
-    struct vkd3d_shader_sm4_parser *sm4;
+    struct vkd3d_shader_sm4_parser sm4 = {0};
     struct dxbc_shader_desc dxbc_desc = {0};
-    struct vsir_program *program;
+    struct vkd3d_shader_instruction *ins;
     int ret;
 
-    if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4))))
-    {
-        ERR("Failed to allocate parser.\n");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
-    }
-
     dxbc_desc.is_dxil = false;
     if ((ret = shader_extract_from_dxbc(&compile_info->source,
             message_context, compile_info->source_name, &dxbc_desc)) < 0)
     {
         WARN("Failed to extract shader, vkd3d result %d.\n", ret);
-        vkd3d_free(sm4);
         return ret;
     }
 
-    if (!shader_sm4_init(sm4, dxbc_desc.byte_code, dxbc_desc.byte_code_size,
+    if (!shader_sm4_init(&sm4, program, dxbc_desc.byte_code, dxbc_desc.byte_code_size,
             compile_info->source_name, message_context))
     {
         WARN("Failed to initialise shader parser.\n");
         free_dxbc_shader_desc(&dxbc_desc);
-        vkd3d_free(sm4);
         return VKD3D_ERROR_INVALID_ARGUMENT;
     }
 
-    program = sm4->p.program;
     program->input_signature = dxbc_desc.input_signature;
     program->output_signature = dxbc_desc.output_signature;
     program->patch_constant_signature = dxbc_desc.patch_constant_signature;
@@ -2704,54 +2678,52 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
     if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
         uninvert_used_masks(&program->patch_constant_signature);
 
-    if (!shader_sm4_parser_validate_signature(sm4, &program->input_signature,
-            sm4->input_register_masks, "Input")
-            || !shader_sm4_parser_validate_signature(sm4, &program->output_signature,
-            sm4->output_register_masks, "Output")
-            || !shader_sm4_parser_validate_signature(sm4, &program->patch_constant_signature,
-            sm4->patch_constant_register_masks, "Patch constant"))
+    if (!shader_sm4_parser_validate_signature(&sm4, &program->input_signature,
+            sm4.input_register_masks, "Input")
+            || !shader_sm4_parser_validate_signature(&sm4, &program->output_signature,
+            sm4.output_register_masks, "Output")
+            || !shader_sm4_parser_validate_signature(&sm4, &program->patch_constant_signature,
+            sm4.patch_constant_register_masks, "Patch constant"))
     {
-        shader_sm4_destroy(&sm4->p);
+        vsir_program_cleanup(program);
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
     instructions = &program->instructions;
-    while (sm4->ptr != sm4->end)
+    while (sm4.ptr != sm4.end)
     {
         if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
         {
             ERR("Failed to allocate instructions.\n");
-            vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
-            shader_sm4_destroy(&sm4->p);
+            vkd3d_shader_parser_error(&sm4.p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
+            vsir_program_cleanup(program);
             return VKD3D_ERROR_OUT_OF_MEMORY;
         }
         ins = &instructions->elements[instructions->count];
-        shader_sm4_read_instruction(sm4, ins);
+        shader_sm4_read_instruction(&sm4, ins);
 
         if (ins->handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Encountered unrecognized or invalid instruction.\n");
-            shader_sm4_destroy(&sm4->p);
+            vsir_program_cleanup(program);
             return VKD3D_ERROR_OUT_OF_MEMORY;
         }
         ++instructions->count;
     }
     if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL
-            && !sm4->has_control_point_phase && !sm4->p.failed)
-        shader_sm4_validate_default_phase_index_ranges(sm4);
+            && !sm4.has_control_point_phase && !sm4.p.failed)
+        shader_sm4_validate_default_phase_index_ranges(&sm4);
 
-    if (!sm4->p.failed)
-        vkd3d_shader_parser_validate(&sm4->p, config_flags);
+    if (!sm4.p.failed)
+        vkd3d_shader_parser_validate(&sm4.p, config_flags);
 
-    if (sm4->p.failed)
+    if (sm4.p.failed)
     {
         WARN("Failed to parse shader.\n");
-        shader_sm4_destroy(&sm4->p);
+        vsir_program_cleanup(program);
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
-    *parser = &sm4->p;
-
     return VKD3D_OK;
 }
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 58eac14485..ee974183c1 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1526,8 +1526,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
-                    p = parser->program;
+                ret = tpf_parse(compile_info, config_flags, &message_context, &program);
+                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
@@ -1655,8 +1655,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
-                if ((ret = vkd3d_shader_sm4_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
-                    p = parser->program;
+                ret = tpf_parse(compile_info, config_flags, &message_context, &program);
+                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 89d05917bf..4f73498788 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1556,8 +1556,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
 
 int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
-int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
+int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
 int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
 
-- 
GitLab


From ce6f8a6a30b6b3d03f502c8f12bd4a89b641a0c7 Mon Sep 17 00:00:00 2001
From: Henri Verbeet <hverbeet@codeweavers.com>
Date: Thu, 16 May 2024 11:42:29 +0200
Subject: [PATCH 6/6] vkd3d-shader/dxil: Parse the shader into a vsir program
 in vkd3d_shader_sm6_parser_create().

---
 libs/vkd3d-shader/d3dbc.c                |  11 +--
 libs/vkd3d-shader/dxil.c                 | 108 ++++++++++-------------
 libs/vkd3d-shader/tpf.c                  |  11 +--
 libs/vkd3d-shader/vkd3d_shader_main.c    |  38 +++-----
 libs/vkd3d-shader/vkd3d_shader_private.h |  19 +---
 5 files changed, 61 insertions(+), 126 deletions(-)

diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index c62d0aaaf1..58f830dd88 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -880,10 +880,6 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
     *ptr += (opcode_info->dst_count + opcode_info->src_count);
 }
 
-static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
-{
-}
-
 static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
         struct vkd3d_shader_src_param *src_param)
 {
@@ -1220,11 +1216,6 @@ static bool shader_sm1_is_end(struct vkd3d_shader_sm1_parser *sm1)
     return false;
 }
 
-const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
-{
-    .parser_destroy = shader_sm1_destroy,
-};
-
 static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, struct vsir_program *program,
         const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
 {
@@ -1283,7 +1274,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
     if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
-    vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops);
+    vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name);
     sm1->ptr = sm1->start;
 
     return VKD3D_OK;
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c
index 29b36c3561..4943a58668 100644
--- a/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d-shader/dxil.c
@@ -909,11 +909,6 @@ static size_t size_add_with_overflow_check(size_t a, size_t b)
     return (i < a) ? SIZE_MAX : i;
 }
 
-static struct sm6_parser *sm6_parser(struct vkd3d_shader_parser *parser)
-{
-    return CONTAINING_RECORD(parser, struct sm6_parser, p);
-}
-
 static bool sm6_parser_is_end(struct sm6_parser *sm6)
 {
     return sm6->ptr == sm6->end;
@@ -10124,28 +10119,18 @@ static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
     vkd3d_free(functions);
 }
 
-static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
+static void sm6_parser_cleanup(struct sm6_parser *sm6)
 {
-    struct sm6_parser *sm6 = sm6_parser(parser);
-
     dxil_block_destroy(&sm6->root_block);
     dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
-    vsir_program_cleanup(parser->program);
-    vkd3d_free(parser->program);
     sm6_type_table_cleanup(sm6->types, sm6->type_count);
     sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
     sm6_functions_cleanup(sm6->functions, sm6->function_count);
     sm6_parser_metadata_cleanup(sm6);
     vkd3d_free(sm6->descriptors);
     vkd3d_free(sm6->values);
-    vkd3d_free(sm6);
 }
 
-static const struct vkd3d_shader_parser_ops sm6_parser_ops =
-{
-    .parser_destroy = sm6_parser_destroy,
-};
-
 static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
 {
     size_t i;
@@ -10155,7 +10140,7 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
     return NULL;
 }
 
-static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *source_name,
+static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const char *source_name,
         struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
 {
     size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
@@ -10166,7 +10151,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     unsigned int chunk_offset, chunk_size;
     enum bitcode_block_abbreviation abbr;
     struct vkd3d_shader_version version;
-    struct vsir_program *program;
     struct dxil_block *block;
     struct sm6_function *fn;
     enum vkd3d_result ret;
@@ -10250,16 +10234,11 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
-    if (!(program = vkd3d_malloc(sizeof(*program))))
-        return VKD3D_ERROR_OUT_OF_MEMORY;
     /* Estimate instruction count to avoid reallocation in most shaders. */
     count = max(token_count, 400) - 400;
     if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
-    {
-        vkd3d_free(program);
         return VKD3D_ERROR_OUT_OF_MEMORY;
-    }
-    vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name, &sm6_parser_ops);
+    vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name);
     sm6->ptr = &sm6->start[1];
     sm6->bitpos = 2;
 
@@ -10282,7 +10261,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
                     "DXIL bitcode chunk has invalid bitcode.");
         else
             vkd3d_unreachable();
-        return ret;
+        goto fail;
     }
 
     dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
@@ -10315,7 +10294,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
                     "DXIL type table is invalid.");
         else
             vkd3d_unreachable();
-        return ret;
+        goto fail;
     }
 
     if ((ret = sm6_parser_symtab_init(sm6)) < 0)
@@ -10328,7 +10307,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
                     "DXIL value symbol table is invalid.");
         else
             vkd3d_unreachable();
-        return ret;
+        goto fail;
     }
 
     if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count))
@@ -10339,7 +10318,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         ERR("Failed to allocate input/output parameters.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
                 "Out of memory allocating input/output parameters.");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
+        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+        goto fail;
     }
 
     function_count = dxil_block_compute_function_count(&sm6->root_block);
@@ -10348,7 +10328,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         ERR("Failed to allocate function array.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
                 "Out of memory allocating DXIL function array.");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
+        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+        goto fail;
     }
 
     if (sm6_parser_compute_max_value_count(sm6, &sm6->root_block, 0) == SIZE_MAX)
@@ -10356,14 +10337,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         WARN("Value array count overflowed.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
                 "Overflow occurred in the DXIL module value count.");
-        return VKD3D_ERROR_INVALID_SHADER;
+        ret = VKD3D_ERROR_INVALID_SHADER;
+        goto fail;
     }
     if (!(sm6->values = vkd3d_calloc(sm6->value_capacity, sizeof(*sm6->values))))
     {
         ERR("Failed to allocate value array.\n");
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
                 "Out of memory allocating DXIL value array.");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
+        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+        goto fail;
     }
     sm6->function_count = 0;
     sm6->ssa_next_id = 1;
@@ -10371,13 +10354,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     if ((ret = sm6_parser_globals_init(sm6)) < 0)
     {
         WARN("Failed to load global declarations.\n");
-        return ret;
+        goto fail;
     }
 
     if (!sm6_parser_allocate_named_metadata(sm6))
     {
         ERR("Failed to allocate named metadata array.\n");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
+        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+        goto fail;
     }
 
     for (i = 0, j = 0; i < sm6->root_block.child_block_count; ++i)
@@ -10391,18 +10375,19 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
             FIXME("Too many metadata tables.\n");
             vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
                     "A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables));
-            return VKD3D_ERROR_INVALID_SHADER;
+            ret = VKD3D_ERROR_INVALID_SHADER;
+            goto fail;
         }
 
         if ((ret = sm6_parser_metadata_init(sm6, block, &sm6->metadata_tables[j++])) < 0)
-            return ret;
+            goto fail;
     }
 
     if ((ret = sm6_parser_entry_point_init(sm6)) < 0)
-        return ret;
+        goto fail;
 
     if ((ret = sm6_parser_resources_init(sm6)) < 0)
-        return ret;
+        goto fail;
 
     if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
     {
@@ -10412,7 +10397,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         else if (ret == VKD3D_ERROR_INVALID_SHADER)
             vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
                     "DXIL module is invalid.");
-        return ret;
+        goto fail;
     }
 
     if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count
@@ -10420,7 +10405,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     {
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
                 "Out of memory emitting shader signature declarations.");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
+        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+        goto fail;
     }
 
     program->ssa_count = sm6->ssa_next_id;
@@ -10430,7 +10416,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         WARN("Failed to find entry point %s.\n", sm6->entry_point);
         vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
                 "The definition of the entry point function '%s' was not found.", sm6->entry_point);
-        return VKD3D_ERROR_INVALID_SHADER;
+        ret = VKD3D_ERROR_INVALID_SHADER;
+        goto fail;
     }
 
     if (version.type == VKD3D_SHADER_TYPE_HULL)
@@ -10438,7 +10425,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
         sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE);
 
         if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
-            return ret;
+            goto fail;
 
         if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function)))
         {
@@ -10446,19 +10433,20 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
             vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
                     "Failed to find the patch constant function '%s' for a hull shader.",
                     sm6->patch_constant_function);
-            return VKD3D_ERROR_INVALID_SHADER;
+            ret = VKD3D_ERROR_INVALID_SHADER;
+            goto fail;
         }
 
         sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE);
         if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
-            return ret;
+            goto fail;
 
         expected_function_count = 2;
     }
     else
     {
         if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
-            return ret;
+            goto fail;
         expected_function_count = 1;
     }
 
@@ -10472,30 +10460,27 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
     dxil_block_destroy(&sm6->root_block);
 
     return VKD3D_OK;
+
+fail:
+    vsir_program_cleanup(program);
+    return ret;
 }
 
-int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
+int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
 {
     struct dxbc_shader_desc dxbc_desc = {0};
+    struct sm6_parser sm6 = {0};
     uint32_t *byte_code = NULL;
-    struct sm6_parser *sm6;
     int ret;
 
     ERR("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
 
-    if (!(sm6 = vkd3d_calloc(1, sizeof(*sm6))))
-    {
-        ERR("Failed to allocate parser.\n");
-        return VKD3D_ERROR_OUT_OF_MEMORY;
-    }
-
     dxbc_desc.is_dxil = true;
     if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name,
             &dxbc_desc)) < 0)
     {
         WARN("Failed to extract shader, vkd3d result %d.\n", ret);
-        vkd3d_free(sm6);
         return ret;
     }
 
@@ -10507,7 +10492,6 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
         {
             ERR("Failed to allocate aligned chunk.\n");
             free_dxbc_shader_desc(&dxbc_desc);
-            vkd3d_free(sm6);
             return VKD3D_ERROR_OUT_OF_MEMORY;
         }
 
@@ -10515,24 +10499,22 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
         dxbc_desc.byte_code = byte_code;
     }
 
-    ret = sm6_parser_init(sm6, compile_info->source_name, message_context, &dxbc_desc);
+    ret = sm6_parser_init(&sm6, program, compile_info->source_name, message_context, &dxbc_desc);
     free_dxbc_shader_desc(&dxbc_desc);
     vkd3d_free(byte_code);
 
-    if (!sm6->p.failed && ret >= 0)
-        ret = vkd3d_shader_parser_validate(&sm6->p, config_flags);
+    if (!sm6.p.failed && ret >= 0)
+        ret = vkd3d_shader_parser_validate(&sm6.p, config_flags);
 
-    if (sm6->p.failed && ret >= 0)
+    if (sm6.p.failed && ret >= 0)
         ret = VKD3D_ERROR_INVALID_SHADER;
 
+    sm6_parser_cleanup(&sm6);
     if (ret < 0)
     {
-        WARN("Failed to initialise shader parser.\n");
-        sm6_parser_destroy(&sm6->p);
+        WARN("Failed to parse shader.\n");
         return ret;
     }
 
-    *parser = &sm6->p;
-
     return ret;
 }
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index 94aedc8ced..b562e815a8 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -1746,10 +1746,6 @@ static enum vkd3d_data_type map_data_type(char t)
     }
 }
 
-static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
-{
-}
-
 static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
         const uint32_t *end, uint32_t addressing, struct vkd3d_shader_register_index *reg_idx)
 {
@@ -2496,11 +2492,6 @@ fail:
     return;
 }
 
-static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
-{
-    .parser_destroy = shader_sm4_destroy,
-};
-
 static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program,
         const uint32_t *byte_code, size_t byte_code_size, const char *source_name,
         struct vkd3d_shader_message_context *message_context)
@@ -2563,7 +2554,7 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
     /* Estimate instruction count to avoid reallocation in most shaders. */
     if (!vsir_program_init(program, &version, token_count / 7u + 20))
         return false;
-    vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name, &shader_sm4_parser_ops);
+    vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name);
     sm4->ptr = sm4->start;
 
     init_sm4_lookup_tables(&sm4->lookup);
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index ee974183c1..27a88a128b 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -555,14 +555,12 @@ uint64_t vkd3d_shader_init_config_flags(void)
 }
 
 void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program,
-        struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_parser_ops *ops)
+        struct vkd3d_shader_message_context *message_context, const char *source_name)
 {
     parser->message_context = message_context;
     parser->location.source_name = source_name;
     parser->location.line = 1;
     parser->location.column = 0;
-    parser->ops = ops;
     parser->program = program;
 }
 
@@ -1515,24 +1513,20 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
     else
     {
         uint64_t config_flags = vkd3d_shader_init_config_flags();
-        struct vkd3d_shader_parser *parser;
-        struct vsir_program program, *p;
+        struct vsir_program program;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
                 ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
-                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
                 ret = tpf_parse(compile_info, config_flags, &message_context, &program);
-                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
-                    p = parser->program;
+                ret = dxil_parse(compile_info, config_flags, &message_context, &program);
                 break;
 
             default:
@@ -1543,15 +1537,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
 
         if (ret < 0)
         {
-            WARN("Failed to create shader parser.\n");
+            WARN("Failed to parse shader.\n");
         }
         else
         {
-            ret = vsir_program_scan(p, compile_info, &message_context, NULL);
-            if (p == &program)
-                vsir_program_cleanup(&program);
-            else
-                vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_scan(&program, compile_info, &message_context, NULL);
+            vsir_program_cleanup(&program);
         }
     }
 
@@ -1644,24 +1635,20 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
     else
     {
         uint64_t config_flags = vkd3d_shader_init_config_flags();
-        struct vkd3d_shader_parser *parser;
-        struct vsir_program program, *p;
+        struct vsir_program program;
 
         switch (compile_info->source_type)
         {
             case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
                 ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
-                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_TPF:
                 ret = tpf_parse(compile_info, config_flags, &message_context, &program);
-                p = &program;
                 break;
 
             case VKD3D_SHADER_SOURCE_DXBC_DXIL:
-                if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0)
-                    p = parser->program;
+                ret = dxil_parse(compile_info, config_flags, &message_context, &program);
                 break;
 
             default:
@@ -1672,15 +1659,12 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
 
         if (ret < 0)
         {
-            WARN("Failed to create shader parser.\n");
+            WARN("Failed to parse shader.\n");
         }
         else
         {
-            ret = vsir_program_compile(p, config_flags, compile_info, out, &message_context);
-            if (p == &program)
-                vsir_program_cleanup(&program);
-            else
-                vkd3d_shader_parser_destroy(parser);
+            ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context);
+            vsir_program_cleanup(&program);
         }
     }
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 4f73498788..85ae770cee 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1394,28 +1394,15 @@ struct vkd3d_shader_parser
     struct vkd3d_shader_location location;
     struct vsir_program *program;
     bool failed;
-
-    const struct vkd3d_shader_parser_ops *ops;
-};
-
-struct vkd3d_shader_parser_ops
-{
-    void (*parser_destroy)(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 vsir_program *program,
-        struct vkd3d_shader_message_context *message_context, const char *source_name,
-        const struct vkd3d_shader_parser_ops *ops);
+        struct vkd3d_shader_message_context *message_context, const char *source_name);
 void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
         enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
 
-static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
-{
-    parser->ops->parser_destroy(parser);
-}
-
 static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser, uint64_t config_flags)
 {
     return vsir_program_validate(parser->program, config_flags,
@@ -1556,10 +1543,10 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
 
 int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
+int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
+        struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
 int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
         struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
-int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
-        struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
 
 void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);
 
-- 
GitLab