From 1007ba40b53009aacea808160b072d299641bbe0 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sun, 23 Nov 2025 00:16:01 +0100 Subject: [PATCH] vkd3d-shader: Introduce vkd3d_shader_string_from_message_context(). It's main advantage over vkd3d_shader_message_context_copy_messages() is that it can't fail. The original issue this addresses is that vkd3d_shader_compile() should free its output when vkd3d_shader_message_context_copy_messages() fails, as spotted by Giovanni; that likely would have applied to a number of the other uses of vkd3d_shader_message_context_copy_messages() as well. --- libs/vkd3d-shader/dxbc.c | 13 ++----- libs/vkd3d-shader/vkd3d_shader_main.c | 46 +++++++++++------------- libs/vkd3d-shader/vkd3d_shader_private.h | 3 +- 3 files changed, 25 insertions(+), 37 deletions(-) diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 45a45c3ad..f1533fbcd 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -340,11 +340,7 @@ int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxbc, ret = parse_dxbc(dxbc, &message_context, NULL, flags, desc); vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages) && ret >= 0) - { - vkd3d_shader_free_dxbc(desc); - ret = VKD3D_ERROR_OUT_OF_MEMORY; - } + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); if (ret < 0) @@ -1106,9 +1102,7 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, ret = for_each_dxbc_section(dxbc, &message_context, NULL, rts0_handler, root_signature); vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; - + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); if (ret < 0) vkd3d_shader_free_root_signature(root_signature); @@ -1558,8 +1552,7 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro done: vkd3d_shader_message_context_trace_messages(&context.message_context); - if (!vkd3d_shader_message_context_copy_messages(&context.message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_shader_string_from_message_context(messages, &context.message_context); vkd3d_shader_message_context_cleanup(&context.message_context); return ret; } diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 92a3dbb4c..68285be0a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -319,14 +319,21 @@ void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *cache, struct cache->buffers[cache->count++] = buffer; } -void vkd3d_shader_code_from_string_buffer(struct vkd3d_shader_code *code, struct vkd3d_string_buffer *buffer) +static char *vkd3d_shader_string_from_string_buffer(struct vkd3d_string_buffer *buffer) { - code->code = buffer->buffer; - code->size = buffer->content_size; + char *s = buffer->buffer; buffer->buffer = NULL; buffer->buffer_size = 0; buffer->content_size = 0; + + return s; +} + +void vkd3d_shader_code_from_string_buffer(struct vkd3d_shader_code *code, struct vkd3d_string_buffer *buffer) +{ + code->size = buffer->content_size; + code->code = vkd3d_shader_string_from_string_buffer(buffer); } void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context, @@ -347,23 +354,15 @@ void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_mess vkd3d_string_buffer_trace_(&context->messages, function); } -bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context, char **out) +void vkd3d_shader_string_from_message_context(char **out, struct vkd3d_shader_message_context *context) { - char *messages; - if (!out) - return true; + return; - *out = NULL; - - if (!context->messages.content_size) - return true; - - if (!(messages = vkd3d_malloc(context->messages.content_size + 1))) - return false; - memcpy(messages, context->messages.buffer, context->messages.content_size + 1); - *out = messages; - return true; + if (context->messages.content_size) + *out = vkd3d_shader_string_from_string_buffer(&context->messages); + else + *out = NULL; } void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, @@ -1772,8 +1771,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char } vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); return ret; } @@ -1920,8 +1918,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_TARGET); vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); return ret; } @@ -2039,9 +2036,7 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, ret = shader_parse_input_signature(dxbc, &message_context, &shader_signature); vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; - + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); if (!vkd3d_shader_signature_from_shader_signature(signature, &shader_signature)) @@ -2246,8 +2241,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_PREPROC); vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) - ret = VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_shader_string_from_message_context(messages, &message_context); vkd3d_shader_message_context_cleanup(&message_context); return ret; } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index dece8e2ea..2ca0e2c5c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1833,7 +1833,6 @@ struct vkd3d_shader_message_context }; void vkd3d_shader_message_context_cleanup(struct vkd3d_shader_message_context *context); -bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context, char **out); void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context, enum vkd3d_shader_log_level log_level); void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_message_context *context, @@ -1851,6 +1850,8 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args); +void vkd3d_shader_string_from_message_context(char **out, struct vkd3d_shader_message_context *context); + 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) \