From ff21b70993b350e7f71a17e682a449f406a804cd Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 21 Dec 2024 12:28:11 +1100 Subject: [PATCH] Updated vkd3d to b60995b106724581ed33d3ea327e7dd662f1f4d9. --- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 204 +++++++++++++++++++- libs/vkd3d/libs/vkd3d-shader/ir.c | 37 +++- libs/vkd3d/libs/vkd3d-shader/tpf.c | 199 ------------------- 4 files changed, 232 insertions(+), 211 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 2acc003c9a1..b0e2b54c348 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -1688,9 +1688,6 @@ struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count); void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef); -enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, - unsigned int storage_modifiers); - struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 08f139f5e8f..4ccbed78f38 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -5489,7 +5489,8 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun return allocator.reg_count; } -enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, unsigned int storage_modifiers) +static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, + unsigned int storage_modifiers) { unsigned int i; @@ -10083,6 +10084,207 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0); } +static int sm4_compare_extern_resources(const void *a, const void *b) +{ + const struct extern_resource *aa = a; + const struct extern_resource *bb = b; + int r; + + if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) + return r; + + if ((r = vkd3d_u32_compare(aa->space, bb->space))) + return r; + + return vkd3d_u32_compare(aa->index, bb->index); +} + +static const char *string_skip_tag(const char *string) +{ + if (!strncmp(string, "", strlen(""))) + return string + strlen(""); + return string; +} + +void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; ++i) + { + vkd3d_free(extern_resources[i].name); + } + vkd3d_free(extern_resources); +} + +struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) +{ + bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0; + struct extern_resource *extern_resources = NULL; + const struct hlsl_ir_var *var; + struct hlsl_buffer *buffer; + enum hlsl_regset regset; + size_t capacity = 0; + char *name; + + *count = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (separate_components) + { + unsigned int component_count = hlsl_type_component_count(var->data_type); + unsigned int k, regset_offset; + + for (k = 0; k < component_count; ++k) + { + struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); + struct vkd3d_string_buffer *name_buffer; + + if (!hlsl_type_is_resource(component_type)) + continue; + + regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); + if (regset_offset > var->regs[regset].allocation_size) + continue; + + if (!var->objects_usage[regset][regset_offset].used) + continue; + + if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, + &capacity, *count + 1, sizeof(*extern_resources)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + if (!(name_buffer = hlsl_component_to_string(ctx, var, k))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + hlsl_release_string_buffer(ctx, name_buffer); + return NULL; + } + hlsl_release_string_buffer(ctx, name_buffer); + + extern_resources[*count].var = NULL; + extern_resources[*count].buffer = NULL; + + extern_resources[*count].name = name; + extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; + + extern_resources[*count].component_type = component_type; + + extern_resources[*count].regset = regset; + extern_resources[*count].id = var->regs[regset].id; + extern_resources[*count].space = var->regs[regset].space; + extern_resources[*count].index = var->regs[regset].index + regset_offset; + extern_resources[*count].bind_count = 1; + extern_resources[*count].loc = var->loc; + + ++*count; + } + } + else + { + unsigned int r; + + if (!hlsl_type_is_resource(var->data_type)) + continue; + + for (r = 0; r <= HLSL_REGSET_LAST; ++r) + { + if (!var->regs[r].allocated) + continue; + + if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, + &capacity, *count + 1, sizeof(*extern_resources)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + extern_resources[*count].var = var; + extern_resources[*count].buffer = NULL; + + extern_resources[*count].name = name; + /* For some reason 5.1 resources aren't marked as + * user-packed, but cbuffers still are. */ + extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1) + && !!var->reg_reservation.reg_type; + + extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0); + + extern_resources[*count].regset = r; + extern_resources[*count].id = var->regs[r].id; + extern_resources[*count].space = var->regs[r].space; + extern_resources[*count].index = var->regs[r].index; + extern_resources[*count].bind_count = var->bind_count[r]; + extern_resources[*count].loc = var->loc; + + ++*count; + } + } + } + + LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) + { + if (!buffer->reg.allocated) + continue; + + if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, + &capacity, *count + 1, sizeof(*extern_resources)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + if (!(name = hlsl_strdup(ctx, buffer->name))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + extern_resources[*count].var = NULL; + extern_resources[*count].buffer = buffer; + + extern_resources[*count].name = name; + extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type; + + extern_resources[*count].component_type = NULL; + + extern_resources[*count].regset = HLSL_REGSET_NUMERIC; + extern_resources[*count].id = buffer->reg.id; + extern_resources[*count].space = buffer->reg.space; + extern_resources[*count].index = buffer->reg.index; + extern_resources[*count].bind_count = 1; + extern_resources[*count].loc = buffer->loc; + + ++*count; + } + + qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); + + return extern_resources; +} + static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vsir_program *program) { struct extern_resource *extern_resources; diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index ec7e2d036c8..c2e4b5a4947 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -8141,6 +8141,16 @@ static void vsir_validate_dst_param(struct validation_context *ctx, } } +static void vsir_validate_io_src_param(struct validation_context *ctx, + const struct vkd3d_shader_src_param *src) +{ + struct vsir_io_register_data io_reg_data; + + if (!vsir_get_io_register_data(ctx, src->reg.type, &io_reg_data) || !(io_reg_data.flags & INPUT_BIT)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, + "Invalid register type %#x used as source parameter.", src->reg.type); +} + static void vsir_validate_src_param(struct validation_context *ctx, const struct vkd3d_shader_src_param *src) { @@ -8176,18 +8186,24 @@ static void vsir_validate_src_param(struct validation_context *ctx, "Invalid NULL register used as source parameter."); break; + case VKD3DSPR_INPUT: + vsir_validate_io_src_param(ctx, src); + break; + case VKD3DSPR_OUTPUT: - if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL - || (ctx->phase != VKD3DSIH_HS_FORK_PHASE && ctx->phase != VKD3DSIH_HS_JOIN_PHASE)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, - "Invalid OUTPUT register used as source parameter."); + vsir_validate_io_src_param(ctx, src); + break; + + case VKD3DSPR_INCONTROLPOINT: + vsir_validate_io_src_param(ctx, src); + break; + + case VKD3DSPR_OUTCONTROLPOINT: + vsir_validate_io_src_param(ctx, src); break; case VKD3DSPR_PATCHCONST: - if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN - && ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, - "PATCHCONST register used as source parameters are only allowed in Hull and Domain Shaders."); + vsir_validate_io_src_param(ctx, src); break; default: @@ -8293,6 +8309,11 @@ static void vsir_validate_signature_element(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, "element %u of %s signature: Invalid zero register count.", idx, signature_type_name); + if (ctx->program->normalisation_level < VSIR_NORMALISED_SM6 && element->register_count != 1) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, + "element %u of %s signature: Invalid register count %u.", idx, signature_type_name, + element->register_count); + if (element->register_index != UINT_MAX && (element->register_index >= MAX_REG_OUTPUT || MAX_REG_OUTPUT - element->register_index < element->register_count)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 7f115057622..bdc1c738a32 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -3483,205 +3483,6 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ } } -static int sm4_compare_extern_resources(const void *a, const void *b) -{ - const struct extern_resource *aa = (const struct extern_resource *)a; - const struct extern_resource *bb = (const struct extern_resource *)b; - int r; - - if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) - return r; - - if ((r = vkd3d_u32_compare(aa->space, bb->space))) - return r; - - return vkd3d_u32_compare(aa->index, bb->index); -} - -void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) -{ - unsigned int i; - - for (i = 0; i < count; ++i) - vkd3d_free(extern_resources[i].name); - vkd3d_free(extern_resources); -} - -static const char *string_skip_tag(const char *string) -{ - if (!strncmp(string, "", strlen(""))) - return string + strlen(""); - return string; -} - -struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) -{ - bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0; - struct extern_resource *extern_resources = NULL; - const struct hlsl_ir_var *var; - struct hlsl_buffer *buffer; - enum hlsl_regset regset; - size_t capacity = 0; - char *name; - - *count = 0; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (separate_components) - { - unsigned int component_count = hlsl_type_component_count(var->data_type); - unsigned int k, regset_offset; - - for (k = 0; k < component_count; ++k) - { - struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); - struct vkd3d_string_buffer *name_buffer; - - if (!hlsl_type_is_resource(component_type)) - continue; - - regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); - - if (regset_offset > var->regs[regset].allocation_size) - continue; - - if (var->objects_usage[regset][regset_offset].used) - { - if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, - sizeof(*extern_resources)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - - if (!(name_buffer = hlsl_component_to_string(ctx, var, k))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - hlsl_release_string_buffer(ctx, name_buffer); - return NULL; - } - hlsl_release_string_buffer(ctx, name_buffer); - - extern_resources[*count].var = NULL; - extern_resources[*count].buffer = NULL; - - extern_resources[*count].name = name; - extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; - - extern_resources[*count].component_type = component_type; - - extern_resources[*count].regset = regset; - extern_resources[*count].id = var->regs[regset].id; - extern_resources[*count].space = var->regs[regset].space; - extern_resources[*count].index = var->regs[regset].index + regset_offset; - extern_resources[*count].bind_count = 1; - extern_resources[*count].loc = var->loc; - - ++*count; - } - } - } - else - { - unsigned int r; - - if (!hlsl_type_is_resource(var->data_type)) - continue; - - for (r = 0; r <= HLSL_REGSET_LAST; ++r) - { - if (!var->regs[r].allocated) - continue; - - if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, - sizeof(*extern_resources)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - - if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - - extern_resources[*count].var = var; - extern_resources[*count].buffer = NULL; - - extern_resources[*count].name = name; - /* For some reason 5.1 resources aren't marked as - * user-packed, but cbuffers still are. */ - extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1) - && !!var->reg_reservation.reg_type; - - extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0); - - extern_resources[*count].regset = r; - extern_resources[*count].id = var->regs[r].id; - extern_resources[*count].space = var->regs[r].space; - extern_resources[*count].index = var->regs[r].index; - extern_resources[*count].bind_count = var->bind_count[r]; - extern_resources[*count].loc = var->loc; - - ++*count; - } - } - } - - LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) - { - if (!buffer->reg.allocated) - continue; - - if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, - sizeof(*extern_resources)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - - if (!(name = hlsl_strdup(ctx, buffer->name))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } - - extern_resources[*count].var = NULL; - extern_resources[*count].buffer = buffer; - - extern_resources[*count].name = name; - extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type; - - extern_resources[*count].component_type = NULL; - - extern_resources[*count].regset = HLSL_REGSET_NUMERIC; - extern_resources[*count].id = buffer->reg.id; - extern_resources[*count].space = buffer->reg.space; - extern_resources[*count].index = buffer->reg.index; - extern_resources[*count].bind_count = 1; - extern_resources[*count].loc = buffer->loc; - - ++*count; - } - - qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); - return extern_resources; -} - /* For some reason, for matrices, values from default value initializers end up in different * components than from regular initializers. Default value initializers fill the matrix in * vertical reading order (left-to-right top-to-bottom) instead of regular reading order -- 2.45.2