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