From 6474e8cc7bc371d7b412b4e1622c6c2cdff0a1f8 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 16 May 2024 11:42:26 +0200 Subject: [PATCH] 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 c3e188e0..99214fba 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 633e9f89..94aedc8c 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 58eac144..ee974183 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 89d05917..4f734987 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);