From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_sm4.c | 79 +++++++++++++++++------------------- 1 file changed, 37 insertions(+), 42 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index c61d5d78..bcab9deb 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -480,53 +480,59 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ } }
-static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) +static int sm4_compare_extern_resources(const void *a, const void *b) { - if (a->data_type->base_type != b->data_type->base_type) - return a->data_type->base_type - b->data_type->base_type; - if (a->reg.allocated && b->reg.allocated) - return a->reg.id - b->reg.id; - return strcmp(a->name, b->name); + const struct hlsl_ir_var *aa = *(const struct hlsl_ir_var **)a; + const struct hlsl_ir_var *bb = *(const struct hlsl_ir_var **)b; + + if (aa->data_type->base_type != bb->data_type->base_type) + return aa->data_type->base_type - bb->data_type->base_type; + return aa->reg.id - bb->reg.id; }
-static void sm4_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) +static const struct hlsl_ir_var **sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) { - struct hlsl_ir_var *var; + const struct hlsl_ir_var **extern_resources; + const struct hlsl_ir_var *var;
- list_remove(&to_sort->extern_entry); + *count = 0;
- LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry) + if(!(extern_resources = vkd3d_malloc(list_count(&ctx->extern_vars) * sizeof(*extern_resources) + 1))) + return NULL; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (sm4_compare_externs(to_sort, var) < 0) + if (var->reg.allocated && var->data_type->type == HLSL_CLASS_OBJECT) { - list_add_before(&var->extern_entry, &to_sort->extern_entry); - return; + extern_resources[*count] = var; + ++*count; } }
- list_add_tail(sorted, &to_sort->extern_entry); -} - -static void sm4_sort_externs(struct hlsl_ctx *ctx) -{ - struct list sorted = LIST_INIT(sorted); - struct hlsl_ir_var *var, *next; + if (*count == 0) + { + vkd3d_free(extern_resources); + return NULL; + }
- LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + if(!(extern_resources = vkd3d_realloc(extern_resources, (*count) * sizeof(*extern_resources)))) { - if (var->data_type->type == HLSL_CLASS_OBJECT) - sm4_sort_extern(&sorted, var); + *count = 0; + return NULL; } - list_move_tail(&ctx->extern_vars, &sorted); + + qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); + return extern_resources; }
static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { size_t cbuffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; - unsigned int cbuffer_count = 0, resource_count = 0, i, j; + unsigned int cbuffer_count = 0, resource_count = 0, extern_resources_count, i, j; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; + const struct hlsl_ir_var **extern_resources; const struct hlsl_buffer *cbuffer; const struct hlsl_ir_var *var;
@@ -540,14 +546,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) 0x4353, /* COMPUTE */ };
- sm4_sort_externs(ctx); - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->reg.allocated && var->data_type->type == HLSL_CLASS_OBJECT) - ++resource_count; - } + extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
+ resource_count += extern_resources_count; LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) @@ -583,12 +584,11 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) resources_offset = bytecode_get_size(&buffer); set_u32(&buffer, resource_position, resources_offset);
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + for (i = 0; i < extern_resources_count; ++i) { uint32_t flags = 0;
- if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) - continue; + var = extern_resources[i];
if (var->reg_reservation.type) flags |= D3D_SIF_USERPACKED; @@ -633,12 +633,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, flags); /* flags */ }
- i = 0; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + for (i = 0; i < extern_resources_count; ++i) { - if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) - continue; + var = extern_resources[i];
string_offset = put_string(&buffer, var->name); set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); @@ -653,8 +650,6 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); }
- assert(i == resource_count); - /* Buffers. */
cbuffers_offset = bytecode_get_size(&buffer);