From 9e4a790de10cd892ca247951a63dc3fe87eb7c89 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 16 May 2024 11:41:58 +0200 Subject: [PATCH] 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 7c7c71e3..2e37549f 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 605e9753..3f65f521 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 96e73d23..a0ae457e 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 4e3bef96..704c904f 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 18456480..89434b0a 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 81bc95c2..1a1d01e7 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); }