From: Zebediah Figura Subject: [PATCH vkd3d v3 1/6] vkd3d-shader: Return a vkd3d_string_buffer from hlsl_type_to_string(). Message-Id: <20210228000314.848782-1-zfigura@codeweavers.com> Date: Sat, 27 Feb 2021 18:03:09 -0600 Signed-off-by: Zebediah Figura --- libs/vkd3d-shader/hlsl.c | 62 +++++++++++++----------- libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d-shader/hlsl.y | 20 +++++--- libs/vkd3d-shader/vkd3d_shader_main.c | 60 +++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 11 +++++ 5 files changed, 120 insertions(+), 37 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 52b3dd10..e2a77707 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -648,10 +648,10 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr return 0; } -char *hlsl_type_to_string(const struct hlsl_type *type) +struct vkd3d_string_buffer *hlsl_type_to_string(struct vkd3d_string_buffer_cache *string_buffers, + const struct hlsl_type *type) { - const char *name; - char *string; + struct vkd3d_string_buffer *string; static const char base_types[HLSL_TYPE_LAST_SCALAR + 1][7] = { @@ -663,66 +663,70 @@ char *hlsl_type_to_string(const struct hlsl_type *type) "bool", }; + if (!(string = vkd3d_string_buffer_get(string_buffers))) + return NULL; + if (type->name) - return vkd3d_strdup(type->name); + { + vkd3d_string_buffer_printf(string, "%s", type->name); + return string; + } switch (type->type) { case HLSL_CLASS_SCALAR: - return vkd3d_strdup(base_types[type->base_type]); + vkd3d_string_buffer_printf(string, "%s", base_types[type->base_type]); + return string; case HLSL_CLASS_VECTOR: - name = base_types[type->base_type]; - if ((string = malloc(strlen(name) + 2))) - sprintf(string, "%s%u", name, type->dimx); + vkd3d_string_buffer_printf(string, "%s%u", base_types[type->base_type], type->dimx); return string; case HLSL_CLASS_MATRIX: - name = base_types[type->base_type]; - if ((string = malloc(strlen(name) + 4))) - sprintf(string, "%s%ux%u", name, type->dimx, type->dimy); + vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->base_type], type->dimx, type->dimy); return string; case HLSL_CLASS_ARRAY: { + struct vkd3d_string_buffer *inner_string; const struct hlsl_type *t; - char *inner_string; - size_t len = 1; for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type) - len += 14; - if (!(inner_string = hlsl_type_to_string(t))) - return NULL; - len += strlen(inner_string); + ; - if ((string = malloc(len))) + if ((inner_string = hlsl_type_to_string(string_buffers, t))) { - strcpy(string, inner_string); - for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type) - sprintf(string + strlen(string), "[%u]", t->e.array.elements_count); + vkd3d_string_buffer_printf(string, "%s", inner_string->buffer); + vkd3d_string_buffer_release(string_buffers, inner_string); } - vkd3d_free(inner_string); + for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type) + vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); return string; } case HLSL_CLASS_STRUCT: - return vkd3d_strdup(""); + vkd3d_string_buffer_printf(string, ""); + return string; default: - return vkd3d_strdup(""); + vkd3d_string_buffer_printf(string, ""); + return string; } } const char *debug_hlsl_type(const struct hlsl_type *type) { + struct vkd3d_string_buffer_cache string_buffers; + struct vkd3d_string_buffer *string; const char *ret; - char *string; - if (!(string = hlsl_type_to_string(type))) + vkd3d_string_buffer_cache_init(&string_buffers); + if (!(string = hlsl_type_to_string(&string_buffers, type))) return NULL; - ret = vkd3d_dbg_sprintf("%s", string); - vkd3d_free(string); + ret = vkd3d_dbg_sprintf("%s", string->buffer); + vkd3d_string_buffer_release(&string_buffers, string); + vkd3d_string_buffer_cache_cleanup(&string_buffers); return ret; } @@ -1526,6 +1530,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_message_cont ctx->source_files_count = 1; ctx->location.source_name = ctx->source_files[0]; ctx->location.line = ctx->location.column = 1; + vkd3d_string_buffer_cache_init(&ctx->string_buffers); ctx->matrix_majority = HLSL_COLUMN_MAJOR; @@ -1553,6 +1558,7 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) for (i = 0; i < ctx->source_files_count; ++i) vkd3d_free((void *)ctx->source_files[i]); vkd3d_free(ctx->source_files); + vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); rb_destroy(&ctx->functions, free_function_rb, NULL); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a374f54a..5a0470b9 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -390,6 +390,7 @@ struct hlsl_ctx unsigned int source_files_count; struct vkd3d_shader_location location; struct vkd3d_shader_message_context *message_context; + struct vkd3d_string_buffer_cache string_buffers; bool failed; void *scanner; @@ -496,7 +497,8 @@ static inline void hlsl_src_remove(struct hlsl_src *src) const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN; -char *hlsl_type_to_string(const struct hlsl_type *type) DECLSPEC_HIDDEN; +struct vkd3d_string_buffer *hlsl_type_to_string(struct vkd3d_string_buffer_cache *string_buffers, + const struct hlsl_type *type) DECLSPEC_HIDDEN; char *hlsl_modifiers_to_string(unsigned int modifiers) DECLSPEC_HIDDEN; const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) DECLSPEC_HIDDEN; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ea640b94..1fb1b7f3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -255,13 +255,15 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct if (!implicit_compatible_data_types(src_type, dst_type)) { - char *src_string = hlsl_type_to_string(src_type), *dst_string = hlsl_type_to_string(dst_type); + struct vkd3d_string_buffer *src_string, *dst_string; + src_string = hlsl_type_to_string(&ctx->string_buffers, src_type); + dst_string = hlsl_type_to_string(&ctx->string_buffers, dst_type); if (src_string && dst_string) hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Can't implicitly convert from %s to %s.", src_string, dst_string); - vkd3d_free(src_string); - vkd3d_free(dst_string); + "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); + vkd3d_string_buffer_release(&ctx->string_buffers, src_string); + vkd3d_string_buffer_release(&ctx->string_buffers, dst_string); return NULL; } @@ -2744,13 +2746,15 @@ unary_expr: if (!compatible_data_types(src_type, dst_type)) { - char *src_string = hlsl_type_to_string(src_type), *dst_string = hlsl_type_to_string(dst_type); + struct vkd3d_string_buffer *src_string, *dst_string; + src_string = hlsl_type_to_string(&ctx->string_buffers, src_type); + dst_string = hlsl_type_to_string(&ctx->string_buffers, dst_type); if (src_string && dst_string) hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.", - src_string, dst_string); - vkd3d_free(src_string); - vkd3d_free(dst_string); + src_string->buffer, dst_string->buffer); + vkd3d_string_buffer_release(&ctx->string_buffers, src_string); + vkd3d_string_buffer_release(&ctx->string_buffers, dst_string); YYABORT; } diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index bae2852a..51136243 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -33,6 +33,12 @@ void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer) vkd3d_free(buffer->buffer); } +static void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer) +{ + buffer->buffer[0] = '\0'; + buffer->content_size = 0; +} + static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc) { unsigned int new_buffer_size = buffer->buffer_size * 2; @@ -107,6 +113,60 @@ void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const } } +void vkd3d_string_buffer_cache_init(struct vkd3d_string_buffer_cache *cache) +{ + memset(cache, 0, sizeof(*cache)); +} + +void vkd3d_string_buffer_cache_cleanup(struct vkd3d_string_buffer_cache *cache) +{ + unsigned int i; + + for (i = 0; i < cache->count; ++i) + { + vkd3d_string_buffer_cleanup(cache->buffers[i]); + vkd3d_free(cache->buffers[i]); + } + vkd3d_free(cache->buffers); + vkd3d_string_buffer_cache_init(cache); +} + +struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *cache) +{ + struct vkd3d_string_buffer *buffer; + + if (!cache->count) + { + if (!vkd3d_array_reserve((void **)&cache->buffers, &cache->capacity, + cache->max_count + 1, sizeof(*cache->buffers))) + return NULL; + ++cache->max_count; + + if (!(buffer = vkd3d_malloc(sizeof(*buffer)))) + return NULL; + vkd3d_string_buffer_init(buffer); + if (!vkd3d_string_buffer_resize(buffer, 1)) + { + vkd3d_free(buffer); + return NULL; + } + } + else + { + buffer = cache->buffers[--cache->count]; + } + vkd3d_string_buffer_clear(buffer); + return buffer; +} + +void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *cache, struct vkd3d_string_buffer *buffer) +{ + if (!buffer) + return; + assert(cache->count + 1 <= cache->max_count); + cache->buffers[cache->count++] = buffer; +} + void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context, enum vkd3d_shader_log_level log_level) { diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e837dbcd..cf66c67a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -870,12 +870,23 @@ struct vkd3d_string_buffer unsigned int content_size; }; +struct vkd3d_string_buffer_cache +{ + struct vkd3d_string_buffer **buffers; + size_t count, max_count, capacity; +}; + enum vkd3d_result vkd3d_dxbc_binary_to_text(void *data, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out) DECLSPEC_HIDDEN; void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN; +struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list) DECLSPEC_HIDDEN; void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN; +void vkd3d_string_buffer_cache_cleanup(struct vkd3d_string_buffer_cache *list) DECLSPEC_HIDDEN; +void vkd3d_string_buffer_cache_init(struct vkd3d_string_buffer_cache *list) DECLSPEC_HIDDEN; int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3) DECLSPEC_HIDDEN; +void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, + struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN; #define vkd3d_string_buffer_trace(buffer) \ vkd3d_string_buffer_trace_(buffer, __FUNCTION__) void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN; -- 2.30.1