Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
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 | 54 +++++++++++++++++++++
libs/vkd3d-shader/vkd3d_shader_private.h | 11 +++++
5 files changed, 114 insertions(+), 37 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 52b3dd10..78eacf28 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_list *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("<anonymous struct>");
+ vkd3d_string_buffer_printf(string, "<anonymous struct>");
+ return string;
default:
- return vkd3d_strdup("<unexpected type>");
+ vkd3d_string_buffer_printf(string, "<unexpected type>");
+ return string;
}
}
const char *debug_hlsl_type(const struct hlsl_type *type)
{
+ struct vkd3d_string_buffer_list string_buffers;
+ struct vkd3d_string_buffer *string;
const char *ret;
- char *string;
- if (!(string = hlsl_type_to_string(type)))
+ vkd3d_string_buffer_list_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_list_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_list_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_list_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..62f7d88b 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_list 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_list *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..681dd4f2 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,54 @@ void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const
}
}
+void vkd3d_string_buffer_list_init(struct vkd3d_string_buffer_list *list)
+{
+ list_init(&list->list);
+}
+
+void vkd3d_string_buffer_list_cleanup(struct vkd3d_string_buffer_list *list)
+{
+ struct vkd3d_string_buffer *buffer, *buffer_next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(buffer, buffer_next, &list->list, struct vkd3d_string_buffer, entry)
+ {
+ vkd3d_string_buffer_cleanup(buffer);
+ vkd3d_free(buffer);
+ }
+ list_init(&list->list);
+}
+
+struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_list *list)
+{
+ struct vkd3d_string_buffer *buffer;
+
+ if (list_empty(&list->list))
+ {
+ 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 = LIST_ENTRY(list_head(&list->list), struct vkd3d_string_buffer, entry);
+ list_remove(&buffer->entry);
+ }
+ vkd3d_string_buffer_clear(buffer);
+ return buffer;
+}
+
+void vkd3d_string_buffer_release(struct vkd3d_string_buffer_list *list, struct vkd3d_string_buffer *buffer)
+{
+ if (!buffer)
+ return;
+ list_add_head(&list->list, &buffer->entry);
+}
+
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..2ef3d5da 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -865,17 +865,28 @@ bool shader_sm4_is_end(void *data, const DWORD **ptr) DECLSPEC_HIDDEN;
struct vkd3d_string_buffer
{
+ struct list entry;
char *buffer;
unsigned int buffer_size;
unsigned int content_size;
};
+struct vkd3d_string_buffer_list
+{
+ struct list list;
+};
+
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_list *list) DECLSPEC_HIDDEN;
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
+void vkd3d_string_buffer_list_cleanup(struct vkd3d_string_buffer_list *list) DECLSPEC_HIDDEN;
+void vkd3d_string_buffer_list_init(struct vkd3d_string_buffer_list *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_list *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