From e7be5aa9fd7ceb839c494a5ad3e6c36e220fe413 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 5 Aug 2025 21:17:34 +0200 Subject: [PATCH] vkd3d-shader/hlsl: Pass a vkd3d_shader_source_list pointer to hlsl_ctx_init(). Instead of storing the list inside struct hlsl_ctx. The source file names in the list are used by the location information that the HLSL frontend produces, and end up being referenced by the vsir program. If we want the vsir program to be able to outlive the hlsl_ctx, its location information can't reference data owned by the hlsl_ctx. --- libs/vkd3d-shader/hlsl.c | 39 ++++++++++++++++++++++++--------------- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 4 ++-- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index dd9573877..927eac5b6 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -4897,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) hlsl_release_string_buffer(ctx, name); } -static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, - const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) +static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files, + const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, + struct vkd3d_shader_message_context *message_context) { unsigned int i; @@ -4908,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil ctx->message_context = message_context; - vkd3d_shader_source_list_init(&ctx->source_files); - if (!vkd3d_shader_source_list_append(&ctx->source_files, + ctx->source_files = source_files; + if (!vkd3d_shader_source_list_append(source_files, compile_info->source_name ? compile_info->source_name : "")) - { - vkd3d_shader_source_list_cleanup(&ctx->source_files); return false; - } - ctx->location.source_name = ctx->source_files.sources[0]; + ctx->location.source_name = source_files->sources[0]; ctx->location.line = ctx->location.column = 1; vkd3d_string_buffer_cache_init(&ctx->string_buffers); @@ -4925,7 +4923,6 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) { vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); - vkd3d_shader_source_list_cleanup(&ctx->source_files); return false; } hlsl_push_scope(ctx); @@ -5011,7 +5008,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) unsigned int i; vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); - vkd3d_shader_source_list_cleanup(&ctx->source_files); rb_destroy(&ctx->functions, free_function_rb, NULL); @@ -5052,8 +5048,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) vkd3d_free(ctx->constant_defs.regs); } -static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context) +static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { enum vkd3d_shader_target_type target_type = compile_info->target_type; const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; @@ -5097,7 +5093,7 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil return VKD3D_ERROR_INVALID_ARGUMENT; } - if (!hlsl_ctx_init(ctx, compile_info, profile, message_context)) + if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY; if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) @@ -5126,14 +5122,20 @@ static int hlsl_ctx_parse(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) { + struct vkd3d_shader_source_list source_list; struct hlsl_ctx ctx; int ret; - if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) + vkd3d_shader_source_list_init(&source_list); + if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, message_context)) < 0) + { + vkd3d_shader_source_list_cleanup(&source_list); return ret; + } ret = hlsl_emit_effect_binary(&ctx, out); hlsl_ctx_cleanup(&ctx); + vkd3d_shader_source_list_cleanup(&source_list); return ret; } @@ -5145,14 +5147,19 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags = vkd3d_shader_init_config_flags(); struct hlsl_ir_function_decl *decl, *entry_func = NULL; struct vkd3d_shader_code reflection_data = {0}; + struct vkd3d_shader_source_list source_list; struct hlsl_ir_function *func; struct vsir_program program; const char *entry_point; struct hlsl_ctx ctx; int ret; - if ((ret = hlsl_ctx_parse(&ctx, compile_info, message_context)) < 0) + vkd3d_shader_source_list_init(&source_list); + if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, message_context)) < 0) + { + vkd3d_shader_source_list_cleanup(&source_list); return ret; + } hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO); entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; @@ -5179,6 +5186,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Entry point \"%s\" is not defined.", entry_point); hlsl_ctx_cleanup(&ctx); + vkd3d_shader_source_list_cleanup(&source_list); return VKD3D_ERROR_INVALID_SHADER; } @@ -5190,6 +5198,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_compile_info *compile_info, vsir_program_cleanup(&program); } hlsl_ctx_cleanup(&ctx); + vkd3d_shader_source_list_cleanup(&source_list); return ret; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 49cf2b8a9..d86594a5e 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1093,7 +1093,7 @@ struct hlsl_ctx { const struct hlsl_profile_info *profile; - struct vkd3d_shader_source_list source_files; + struct vkd3d_shader_source_list *source_files; /* Current location being read in the HLSL source, updated while parsing. */ struct vkd3d_shader_location location; /* Stores the logging messages and logging configuration. */ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b37214911..024d96c56 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -7192,14 +7192,14 @@ preproc_directive: { if (strcmp($2, ctx->location.source_name)) { - if (!vkd3d_shader_source_list_append(&ctx->source_files, $2)) + if (!vkd3d_shader_source_list_append(ctx->source_files, $2)) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; } else { ctx->location.line = $1; - ctx->location.source_name = ctx->source_files.sources[ctx->source_files.count - 1]; + ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1]; } } vkd3d_free($2);