diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c792114a6a58c7c97abf827d154d7ecd22d.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c792114a6a58c7c97abf827d154d7ecd22d.patch index a076cc21..398141fe 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-c792114a6a58c7c97abf827d154d7ecd22d.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-c792114a6a58c7c97abf827d154d7ecd22d.patch @@ -1,4 +1,4 @@ -From a2fa979feeaa5fd254ad1cdb97674f08af22866d Mon Sep 17 00:00:00 2001 +From bdf5b5c756c711423757ec2173f1fefc8e26b6fb Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 7 Mar 2024 10:40:41 +1100 Subject: [PATCH] Updated vkd3d to c792114a6a58c7c97abf827d154d7ecd22d81536. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-5a53b739959db74e8dcce023a7d49356b90.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-5a53b739959db74e8dcce023a7d49356b90.patch index e3451523..6f658127 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-5a53b739959db74e8dcce023a7d49356b90.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-5a53b739959db74e8dcce023a7d49356b90.patch @@ -1,4 +1,4 @@ -From c260bdc81c8b805b4ad1772f80c56a2dd9847e55 Mon Sep 17 00:00:00 2001 +From 3370da0785c88923acf2b8a46a54f0093bb82e2c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 15 Jul 2024 10:03:30 +1000 Subject: [PATCH] Updated vkd3d to 5a53b739959db74e8dcce023a7d49356b9008e92. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-0202393d41f00d8c9f20f59ec080b833b54.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-0202393d41f00d8c9f20f59ec080b833b54.patch index e87e5c83..d77f3828 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-0202393d41f00d8c9f20f59ec080b833b54.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-0202393d41f00d8c9f20f59ec080b833b54.patch @@ -1,4 +1,4 @@ -From 017785c8b77bd331c1b0ed650654e254d906451a Mon Sep 17 00:00:00 2001 +From 54c3fbb3eb8bab6743a681fb284dedcb4f73e53f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 Jul 2024 08:43:16 +1000 Subject: [PATCH] Updated vkd3d to 0202393d41f00d8c9f20f59ec080b833b5436f5a. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-7eb63a7c0d23a83bbdfcfa5ed83b9434370.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-7eb63a7c0d23a83bbdfcfa5ed83b9434370.patch index caa73eba..a97a8b05 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-7eb63a7c0d23a83bbdfcfa5ed83b9434370.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-7eb63a7c0d23a83bbdfcfa5ed83b9434370.patch @@ -1,4 +1,4 @@ -From 45adbbc810744d699a90f672f84115239ad48169 Mon Sep 17 00:00:00 2001 +From 384371550b180a434f9464957aba5fe2a5f84423 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 18 Jul 2024 10:01:10 +1000 Subject: [PATCH] Updated vkd3d to 7eb63a7c0d23a83bbdfcfa5ed83b943437051138. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-947b937a1afc0f1d57b11883dad9ffb3fbd.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-947b937a1afc0f1d57b11883dad9ffb3fbd.patch new file mode 100644 index 00000000..79721802 --- /dev/null +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-947b937a1afc0f1d57b11883dad9ffb3fbd.patch @@ -0,0 +1,1116 @@ +From 00a356111955d1f510fe914fe7289c918d76cfec Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Fri, 26 Jul 2024 09:32:27 +1000 +Subject: [PATCH] Updated vkd3d to 947b937a1afc0f1d57b11883dad9ffb3fbdf6380. + +--- + libs/vkd3d/include/vkd3d_shader.h | 24 +++ + libs/vkd3d/libs/vkd3d-shader/fx.c | 16 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 163 ++++++++++++++++-- + libs/vkd3d/libs/vkd3d-shader/ir.c | 73 ++++++-- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 77 ++++----- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 + + libs/vkd3d/libs/vkd3d/device.c | 146 +++++++--------- + libs/vkd3d/libs/vkd3d/state.c | 56 +++--- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 1 - + 9 files changed, 367 insertions(+), 191 deletions(-) + +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 4acb622468a..d4756810065 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -553,6 +553,30 @@ enum vkd3d_shader_parameter_name + * \since 1.13 + */ + VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, ++ /** ++ * Whether to use flat interpolation for fragment shader colour inputs. ++ * If the value is nonzero, inputs whose semantic usage is COLOR will use ++ * flat interpolation instead of linear. ++ * This parameter is ignored if the shader model is 4 or greater, since only ++ * shader model 3 and below do not specify the interpolation mode in the ++ * shader bytecode. ++ * ++ * This parameter can be used to implement fixed function shade mode, as ++ * present in Direct3D versions up to 9, if the target environment does not ++ * support shade mode as part of its own fixed-function API (as Vulkan and ++ * core OpenGL). ++ * ++ * The data type for this parameter must be ++ * VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32. ++ * ++ * The default value is zero, i.e. use linear interpolation. ++ * ++ * Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this ++ * version of vkd3d-shader. ++ * ++ * \since 1.13 ++ */ ++ VKD3D_SHADER_PARAMETER_NAME_FLAT_INTERPOLATION, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), + }; +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index bd2ad1290cd..15a518c07db 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -189,8 +189,8 @@ static uint32_t write_string(const char *string, struct fx_write_context *fx) + + static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) + { +- if (var->state_block_count) +- hlsl_fixme(fx->ctx, &var->loc, "Write state block assignments."); ++ if (var->state_block_count && var->state_blocks[0]->count) ++ hlsl_fixme(fx->ctx, &var->loc, "Write pass assignments."); + + fx->ops->write_pass(var, fx); + } +@@ -397,6 +397,9 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx + + /* TODO: annotations */ + /* TODO: assignments */ ++ ++ /* For some reason every pass adds to the total shader object count. */ ++ fx->shader_count++; + } + + static uint32_t get_fx_4_type_size(const struct hlsl_type *type) +@@ -852,6 +855,10 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n + case HLSL_CLASS_STRUCT: + put_u32(buffer, type->e.record.field_count); + break; ++ case HLSL_CLASS_VERTEX_SHADER: ++ case HLSL_CLASS_PIXEL_SHADER: ++ fx->shader_count += elements_count; ++ break; + default: + ; + } +@@ -1063,7 +1070,7 @@ static const struct fx_write_context_ops fx_2_ops = + + static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + { +- uint32_t offset, size, technique_count, parameter_count, object_count; ++ uint32_t offset, size, technique_count, shader_count, parameter_count, object_count; + struct vkd3d_bytecode_buffer buffer = { 0 }; + struct vkd3d_bytecode_buffer *structured; + struct fx_write_context fx; +@@ -1080,7 +1087,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + + parameter_count = put_u32(structured, 0); /* Parameter count */ + technique_count = put_u32(structured, 0); +- put_u32(structured, 0); /* Unknown */ ++ shader_count = put_u32(structured, 0); + object_count = put_u32(structured, 0); + + write_fx_2_parameters(&fx); +@@ -1089,6 +1096,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + + write_techniques(ctx->globals, &fx); + set_u32(structured, technique_count, fx.technique_count); ++ set_u32(structured, shader_count, fx.shader_count); + + put_u32(structured, 0); /* String count */ + put_u32(structured, 0); /* Resource count */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 56736a65306..312eaec8a73 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -34,6 +34,14 @@ struct parse_fields + size_t count, capacity; + }; + ++struct parse_initializer ++{ ++ struct hlsl_ir_node **args; ++ unsigned int args_count; ++ struct hlsl_block *instrs; ++ bool braces; ++}; ++ + struct parse_parameter + { + struct hlsl_type *type; +@@ -41,6 +49,7 @@ struct parse_parameter + struct hlsl_semantic semantic; + struct hlsl_reg_reservation reg_reservation; + uint32_t modifiers; ++ struct parse_initializer initializer; + }; + + struct parse_colon_attribute +@@ -49,14 +58,6 @@ struct parse_colon_attribute + struct hlsl_reg_reservation reg_reservation; + }; + +-struct parse_initializer +-{ +- struct hlsl_ir_node **args; +- unsigned int args_count; +- struct hlsl_block *instrs; +- bool braces; +-}; +- + struct parse_array_sizes + { + uint32_t *sizes; /* innermost first */ +@@ -73,6 +74,7 @@ struct parse_variable_def + struct hlsl_semantic semantic; + struct hlsl_reg_reservation reg_reservation; + struct parse_initializer initializer; ++ struct hlsl_scope *annotations; + + struct hlsl_type *basic_type; + uint32_t modifiers; +@@ -1188,6 +1190,9 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, + return true; + } + ++static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs, ++ struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src); ++ + static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters, + struct parse_parameter *param, const struct vkd3d_shader_location *loc) + { +@@ -1204,11 +1209,52 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "packoffset() is not allowed on function parameters."); + ++ if (parameters->count && parameters->vars[parameters->count - 1]->default_values ++ && !param->initializer.args_count) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, ++ "Missing default value for parameter '%s'.", param->name); ++ ++ if (param->initializer.args_count && (param->modifiers & HLSL_STORAGE_OUT)) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, ++ "Output parameter '%s' has a default value.", param->name); ++ + if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, + ¶m->reg_reservation))) + return false; + var->is_param = 1; + ++ if (param->initializer.args_count) ++ { ++ unsigned int component_count = hlsl_type_component_count(param->type); ++ unsigned int store_index = 0; ++ unsigned int size, i; ++ ++ if (!(var->default_values = hlsl_calloc(ctx, component_count, sizeof(*var->default_values)))) ++ return false; ++ ++ if (!param->initializer.braces) ++ { ++ if (!(add_implicit_conversion(ctx, param->initializer.instrs, param->initializer.args[0], param->type, loc))) ++ return false; ++ ++ param->initializer.args[0] = node_from_block(param->initializer.instrs); ++ } ++ ++ size = initializer_size(¶m->initializer); ++ if (component_count != size) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Expected %u components in initializer, but got %u.", component_count, size); ++ } ++ ++ for (i = 0; i < param->initializer.args_count; ++i) ++ { ++ initialize_var_components(ctx, param->initializer.instrs, var, &store_index, param->initializer.args[i]); ++ } ++ ++ free_parse_initializer(¶m->initializer); ++ } ++ + if (!hlsl_add_var(ctx, var, false)) + { + hlsl_free_var(var); +@@ -2226,7 +2272,9 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d + /* 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 +- * (top-to-bottom left-to-right), so they have to be adjusted. */ ++ * (top-to-bottom left-to-right), so they have to be adjusted. ++ * An exception is that the order of matrix initializers for function parameters are row-major ++ * (top-to-bottom left-to-right). */ + static unsigned int get_component_index_from_default_initializer_index(struct hlsl_ctx *ctx, + struct hlsl_type *type, unsigned int index) + { +@@ -2299,7 +2347,11 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i + return; + default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); + +- dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index); ++ if (dst->is_param) ++ dst_index = *store_index; ++ else ++ dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index); ++ + dst->default_values[dst_index] = default_value; + + hlsl_block_cleanup(&block); +@@ -2498,6 +2550,8 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + return; + } + ++ var->annotations = v->annotations; ++ + if (constant_buffer && ctx->cur_scope == ctx->globals) + { + if (!(var_name = vkd3d_strdup(v->name))) +@@ -2567,6 +2621,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, + "Const variable \"%s\" is missing an initializer.", var->name); + } ++ ++ if (var->annotations) ++ { ++ hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "Annotations are only allowed for objects in the global scope."); ++ } + } + + if ((var->storage_modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) +@@ -2742,14 +2802,18 @@ static bool func_is_compatible_match(struct hlsl_ctx *ctx, + { + unsigned int i; + +- if (decl->parameters.count != args->args_count) ++ if (decl->parameters.count < args->args_count) + return false; + +- for (i = 0; i < decl->parameters.count; ++i) ++ for (i = 0; i < args->args_count; ++i) + { + if (!implicit_compatible_data_types(ctx, args->args[i]->data_type, decl->parameters.vars[i]->data_type)) + return false; + } ++ ++ if (args->args_count < decl->parameters.count && !decl->parameters.vars[args->args_count]->default_values) ++ return false; ++ + return true; + } + +@@ -2792,11 +2856,11 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu + const struct parse_initializer *args, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_node *call; +- unsigned int i; ++ unsigned int i, j; + +- assert(args->args_count == func->parameters.count); ++ assert(args->args_count <= func->parameters.count); + +- for (i = 0; i < func->parameters.count; ++i) ++ for (i = 0; i < args->args_count; ++i) + { + struct hlsl_ir_var *param = func->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i]; +@@ -2821,11 +2885,40 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu + } + } + ++ /* Add default values for the remaining parameters. */ ++ for (i = args->args_count; i < func->parameters.count; ++i) ++ { ++ struct hlsl_ir_var *param = func->parameters.vars[i]; ++ unsigned int comp_count = hlsl_type_component_count(param->data_type); ++ struct hlsl_deref param_deref; ++ ++ assert(param->default_values); ++ ++ hlsl_init_simple_deref_from_var(¶m_deref, param); ++ ++ for (j = 0; j < comp_count; ++j) ++ { ++ struct hlsl_type *type = hlsl_type_get_component_type(ctx, param->data_type, j); ++ struct hlsl_constant_value value; ++ struct hlsl_ir_node *comp; ++ struct hlsl_block store_block; ++ ++ value.u[0] = param->default_values[j].value; ++ if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, comp); ++ ++ if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) ++ return false; ++ hlsl_block_add_block(args->instrs, &store_block); ++ } ++ } ++ + if (!(call = hlsl_new_call(ctx, func, loc))) + return false; + hlsl_block_add_instr(args->instrs, call); + +- for (i = 0; i < func->parameters.count; ++i) ++ for (i = 0; i < args->args_count; ++i) + { + struct hlsl_ir_var *param = func->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i]; +@@ -3206,6 +3299,29 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); + } + ++static bool intrinsic_asint(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; ++ struct hlsl_type *data_type; ++ ++ data_type = params->args[0]->data_type; ++ if (data_type->e.numeric.type == HLSL_TYPE_BOOL || data_type->e.numeric.type == HLSL_TYPE_DOUBLE) ++ { ++ struct vkd3d_string_buffer *string; ++ ++ if ((string = hlsl_type_to_string(ctx, data_type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Wrong argument type of asint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", ++ string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ } ++ data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_INT); ++ ++ operands[0] = params->args[0]; ++ return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); ++} ++ + static bool intrinsic_asuint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -4732,6 +4848,7 @@ intrinsic_functions[] = + {"any", 1, true, intrinsic_any}, + {"asfloat", 1, true, intrinsic_asfloat}, + {"asin", 1, true, intrinsic_asin}, ++ {"asint", 1, true, intrinsic_asint}, + {"asuint", -1, true, intrinsic_asuint}, + {"atan", 1, true, intrinsic_atan}, + {"atan2", 2, true, intrinsic_atan2}, +@@ -6067,6 +6184,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h + %type name_opt + + %type parameter ++%type parameter_decl + + %type param_list + %type parameters +@@ -6902,6 +7020,14 @@ param_list: + } + + parameter: ++ parameter_decl ++ | parameter_decl '=' complex_initializer ++ { ++ $$ = $1; ++ $$.initializer = $3; ++ } ++ ++parameter_decl: + var_modifiers type_no_void any_identifier arrays colon_attribute + { + uint32_t modifiers = $1; +@@ -6934,6 +7060,8 @@ parameter: + $$.name = $3; + $$.semantic = $5.semantic; + $$.reg_reservation = $5.reg_reservation; ++ ++ memset(&$$.initializer, 0, sizeof($$.initializer)); + } + + texture_type: +@@ -7370,7 +7498,7 @@ variables_def_typed: + } + + variable_decl: +- any_identifier arrays colon_attribute ++ any_identifier arrays colon_attribute annotations_opt + { + $$ = hlsl_alloc(ctx, sizeof(*$$)); + $$->loc = @1; +@@ -7378,6 +7506,7 @@ variable_decl: + $$->arrays = $2; + $$->semantic = $3.semantic; + $$->reg_reservation = $3.reg_reservation; ++ $$->annotations = $4; + } + + state_block_start: +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 9202c77cadb..e0ac6322c71 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -105,6 +105,18 @@ void vsir_program_cleanup(struct vsir_program *program) + shader_signature_cleanup(&program->patch_constant_signature); + } + ++const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( ++ const struct vsir_program *program, enum vkd3d_shader_parameter_name name) ++{ ++ for (unsigned int i = 0; i < program->parameter_count; ++i) ++ { ++ if (program->parameters[i].name == name) ++ return &program->parameters[i]; ++ } ++ ++ return NULL; ++} ++ + static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shader_register *reg) + { + return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID; +@@ -1711,7 +1723,33 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi + } + } + +-static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program) ++static bool use_flat_interpolation(const struct vsir_program *program, ++ struct vkd3d_shader_message_context *message_context) ++{ ++ static const struct vkd3d_shader_location no_loc; ++ const struct vkd3d_shader_parameter1 *parameter; ++ ++ if (!(parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FLAT_INTERPOLATION))) ++ return false; ++ ++ if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) ++ { ++ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Unsupported flat interpolation parameter type %#x.\n", parameter->type); ++ return false; ++ } ++ if (parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) ++ { ++ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Invalid flat interpolation parameter data type %#x.\n", parameter->data_type); ++ return false; ++ } ++ ++ return parameter->u.immediate_constant.u.u32; ++} ++ ++static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, ++ struct vkd3d_shader_message_context *message_context) + { + struct io_normaliser normaliser = {program->instructions}; + struct vkd3d_shader_instruction *ins; +@@ -1774,6 +1812,18 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ++ if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ++ && program->shader_version.major < 4 && use_flat_interpolation(program, message_context)) ++ { ++ for (i = 0; i < program->input_signature.element_count; ++i) ++ { ++ struct signature_element *element = &program->input_signature.elements[i]; ++ ++ if (!ascii_strcasecmp(element->semantic_name, "COLOR")) ++ element->interpolation_mode = VKD3DSIM_CONSTANT; ++ } ++ } ++ + normaliser.phase = VKD3DSIH_INVALID; + for (i = 0; i < normaliser.instructions.count; ++i) + shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); +@@ -5497,10 +5547,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + } + + dst_param_init_ssa_bool(&ins->dst[0], program->ssa_count); +- ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; +- ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); +- ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; +- ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); ++ ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); + + ++ins; + vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DISCARD, 0, 1); +@@ -5541,17 +5589,8 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + || !(program->output_signature.elements[colour_signature_idx].mask & VKD3DSP_WRITEMASK_3)) + return VKD3D_OK; + +- for (unsigned int i = 0; i < program->parameter_count; ++i) +- { +- const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i]; +- +- if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC) +- func = parameter; +- else if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF) +- ref = parameter; +- } +- +- if (!func || !ref) ++ if (!(func = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC)) ++ || !(ref = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF))) + return VKD3D_OK; + + if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) +@@ -6590,7 +6629,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t + return result; + } + +- if ((result = vsir_program_normalise_io_registers(program)) < 0) ++ if ((result = vsir_program_normalise_io_registers(program, message_context)) < 0) + return result; + + if ((result = instruction_array_normalise_flat_constants(program)) < 0) +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 72a6f1e60dc..d66446be0b0 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -2393,6 +2393,7 @@ struct ssa_register_info + struct spirv_compiler + { + struct vkd3d_spirv_builder spirv_builder; ++ const struct vsir_program *program; + + struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location location; +@@ -2418,8 +2419,6 @@ struct spirv_compiler + uint32_t *descriptor_offset_ids; + struct vkd3d_push_constant_buffer_binding *push_constants; + const struct vkd3d_shader_spirv_target_info *spirv_target_info; +- const struct vkd3d_shader_parameter1 *parameters; +- unsigned int parameter_count; + + struct + { +@@ -2536,13 +2535,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p + const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, + struct vkd3d_shader_message_context *message_context, uint64_t config_flags) + { +- const struct shader_signature *patch_constant_signature = &program->patch_constant_signature; +- const struct shader_signature *output_signature = &program->output_signature; + const struct vkd3d_shader_interface_info *shader_interface; + const struct vkd3d_shader_descriptor_offset_info *offset_info; + const struct vkd3d_shader_spirv_target_info *target_info; + struct spirv_compiler *compiler; +- unsigned int max_element_count; + unsigned int i; + + if (!(compiler = vkd3d_malloc(sizeof(*compiler)))) +@@ -2570,13 +2566,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p + compiler->spirv_target_info = target_info; + } + +- max_element_count = max(output_signature->element_count, patch_constant_signature->element_count); +- if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) +- { +- vkd3d_free(compiler); +- return NULL; +- } +- + vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler)); + + compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT +@@ -3297,20 +3286,6 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil + return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); + } + +-static const struct vkd3d_shader_parameter1 *spirv_compiler_get_shader_parameter( +- struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name) +-{ +- unsigned int i; +- +- for (i = 0; i < compiler->parameter_count; ++i) +- { +- if (compiler->parameters[i].name == name) +- return &compiler->parameters[i]; +- } +- +- return NULL; +-} +- + static const struct vkd3d_spec_constant_info + { + enum vkd3d_shader_parameter_name name; +@@ -3341,12 +3316,11 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com + { + if (!compiler->current_spec_constant_id) + { +- const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; + unsigned int i, id = 0; + +- for (i = 0; info && i < info->parameter_count; ++i) ++ for (i = 0; i < compiler->program->parameter_count; ++i) + { +- const struct vkd3d_shader_parameter *current = &info->parameters[i]; ++ const struct vkd3d_shader_parameter1 *current = &compiler->program->parameters[i]; + + if (current->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT) + id = max(current->u.specialization_constant.id + 1, id); +@@ -3404,7 +3378,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi + const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- unsigned int index = parameter - compiler->parameters; ++ unsigned int index = parameter - compiler->program->parameters; + uint32_t type_id, ptr_id, ptr_type_id; + + type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); +@@ -3416,17 +3390,29 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi + } + + static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler, +- enum vkd3d_shader_parameter_name name) ++ enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type) + { + const struct vkd3d_shader_parameter1 *parameter; +- enum vkd3d_data_type type = VKD3D_DATA_UINT; + +- if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name))) ++ static const struct ++ { ++ enum vkd3d_data_type type; ++ } ++ type_map[] = ++ { ++ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VKD3D_DATA_FLOAT}, ++ [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT}, ++ }; ++ ++ if (!(parameter = vsir_program_get_parameter(compiler->program, name))) + { + WARN("Unresolved shader parameter %#x.\n", name); + goto default_parameter; + } + ++ if (type_map[parameter->data_type].type != type) ++ ERR("Expected data type %#x for parameter %#x, got %#x.\n", type, name, parameter->data_type); ++ + if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { + if (parameter->data_type == VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) +@@ -3435,11 +3421,6 @@ static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *comp + return spirv_compiler_get_constant_uint(compiler, parameter->u.immediate_constant.u.u32); + } + +- if (parameter->data_type == VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) +- type = VKD3D_DATA_FLOAT; +- else +- type = VKD3D_DATA_UINT; +- + if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT) + return spirv_compiler_get_spec_constant(compiler, name, parameter->u.specialization_constant.id, type); + if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_BUFFER) +@@ -4225,7 +4206,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + else if (reg->type == VKD3DSPR_UNDEF) + return spirv_compiler_emit_load_undef(compiler, reg, write_mask); + else if (reg->type == VKD3DSPR_PARAMETER) +- return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset); ++ return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset, reg->data_type); + + component_count = vsir_write_mask_component_count(write_mask); + component_type = vkd3d_component_type_from_data_type(reg->data_type); +@@ -9566,7 +9547,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co + if (src->reg.type == VKD3DSPR_RASTERIZER) + { + val_id = spirv_compiler_emit_shader_parameter(compiler, +- VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT); ++ VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VKD3D_DATA_UINT); + } + else + { +@@ -10597,12 +10578,16 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct + struct vkd3d_shader_instruction_array instructions; + enum vkd3d_shader_spirv_environment environment; + enum vkd3d_result result = VKD3D_OK; +- unsigned int i; ++ unsigned int i, max_element_count; + + if ((result = vsir_program_normalise(program, compiler->config_flags, + compile_info, compiler->message_context)) < 0) + return result; + ++ max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count); ++ if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ + if (program->temp_count) + spirv_compiler_emit_temps(compiler, program->temp_count); + if (program->ssa_count) +@@ -10610,12 +10595,10 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct + + spirv_compiler_emit_descriptor_declarations(compiler); + +- compiler->parameter_count = program->parameter_count; +- compiler->parameters = program->parameters; +- compiler->spirv_parameter_info = vkd3d_calloc(compiler->parameter_count, sizeof(*compiler->spirv_parameter_info)); +- for (i = 0; i < compiler->parameter_count; ++i) ++ compiler->spirv_parameter_info = vkd3d_calloc(program->parameter_count, sizeof(*compiler->spirv_parameter_info)); ++ for (i = 0; i < program->parameter_count; ++i) + { +- const struct vkd3d_shader_parameter1 *parameter = &compiler->parameters[i]; ++ const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i]; + + if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_BUFFER) + { +@@ -10642,6 +10625,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct + if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + ++ compiler->program = program; ++ + instructions = program->instructions; + memset(&program->instructions, 0, sizeof(program->instructions)); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index bf9759ebbbf..7aff22e3420 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -1382,6 +1382,8 @@ void vsir_program_cleanup(struct vsir_program *program); + int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, + struct vkd3d_shader_message_context *message_context); ++const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( ++ const struct vsir_program *program, enum vkd3d_shader_parameter_name name); + bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_version *version, unsigned int reserve); + enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags, +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index ff3e41e6b70..5fe381af90c 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -831,114 +831,90 @@ struct vkd3d_physical_device_info + VkPhysicalDeviceFeatures2 features2; + }; + +-static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *info, struct d3d12_device *device) ++static void vkd3d_chain_physical_device_info_structures(struct vkd3d_physical_device_info *info, ++ struct d3d12_device *device) + { +- const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; +- VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering_features; +- VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties; +- VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties; +- VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties; +- VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features; +- VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *fragment_shader_interlock_features; +- VkPhysicalDeviceRobustness2FeaturesEXT *robustness2_features; +- VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features; +- VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features; +- VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features; +- VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *timeline_semaphore_features; +- VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *mutable_features; +- VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features; +- VkPhysicalDeviceMaintenance3Properties *maintenance3_properties; +- VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties; +- VkPhysicalDevice physical_device = device->vk_physical_device; +- VkPhysicalDevice4444FormatsFeaturesEXT *formats4444_features; +- VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features; + struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; +- VkPhysicalDeviceSubgroupProperties *subgroup_properties; + +- memset(info, 0, sizeof(*info)); +- conditional_rendering_features = &info->conditional_rendering_features; +- depth_clip_features = &info->depth_clip_features; +- descriptor_indexing_features = &info->descriptor_indexing_features; +- fragment_shader_interlock_features = &info->fragment_shader_interlock_features; +- robustness2_features = &info->robustness2_features; +- descriptor_indexing_properties = &info->descriptor_indexing_properties; +- maintenance3_properties = &info->maintenance3_properties; +- demote_features = &info->demote_features; +- buffer_alignment_features = &info->texel_buffer_alignment_features; +- buffer_alignment_properties = &info->texel_buffer_alignment_properties; +- vertex_divisor_features = &info->vertex_divisor_features; +- vertex_divisor_properties = &info->vertex_divisor_properties; +- timeline_semaphore_features = &info->timeline_semaphore_features; +- mutable_features = &info->mutable_features; +- formats4444_features = &info->formats4444_features; +- xfb_features = &info->xfb_features; +- xfb_properties = &info->xfb_properties; +- subgroup_properties = &info->subgroup_properties; ++ info->features2.pNext = NULL; + +- info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; +- +- conditional_rendering_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; + if (vulkan_info->EXT_conditional_rendering) +- vk_prepend_struct(&info->features2, conditional_rendering_features); +- depth_clip_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->conditional_rendering_features); + if (vulkan_info->EXT_depth_clip_enable) +- vk_prepend_struct(&info->features2, depth_clip_features); +- descriptor_indexing_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->depth_clip_features); + if (vulkan_info->EXT_descriptor_indexing) +- vk_prepend_struct(&info->features2, descriptor_indexing_features); +- fragment_shader_interlock_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->descriptor_indexing_features); + if (vulkan_info->EXT_fragment_shader_interlock) +- vk_prepend_struct(&info->features2, fragment_shader_interlock_features); +- robustness2_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->fragment_shader_interlock_features); + if (vulkan_info->EXT_robustness2) +- vk_prepend_struct(&info->features2, robustness2_features); +- demote_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->robustness2_features); + if (vulkan_info->EXT_shader_demote_to_helper_invocation) +- vk_prepend_struct(&info->features2, demote_features); +- buffer_alignment_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->demote_features); + if (vulkan_info->EXT_texel_buffer_alignment) +- vk_prepend_struct(&info->features2, buffer_alignment_features); +- xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->texel_buffer_alignment_features); + if (vulkan_info->EXT_transform_feedback) +- vk_prepend_struct(&info->features2, xfb_features); +- vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->xfb_features); + if (vulkan_info->EXT_vertex_attribute_divisor) +- vk_prepend_struct(&info->features2, vertex_divisor_features); +- timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; ++ vk_prepend_struct(&info->features2, &info->vertex_divisor_features); + if (vulkan_info->KHR_timeline_semaphore) +- vk_prepend_struct(&info->features2, timeline_semaphore_features); +- mutable_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->timeline_semaphore_features); + if (vulkan_info->EXT_mutable_descriptor_type) +- vk_prepend_struct(&info->features2, mutable_features); +- formats4444_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; ++ vk_prepend_struct(&info->features2, &info->mutable_features); + if (vulkan_info->EXT_4444_formats) +- vk_prepend_struct(&info->features2, formats4444_features); ++ vk_prepend_struct(&info->features2, &info->formats4444_features); + +- if (vulkan_info->KHR_get_physical_device_properties2) +- VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2)); +- else +- VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &info->features2.features)); ++ info->properties2.pNext = NULL; + +- info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; +- +- maintenance3_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; + if (vulkan_info->KHR_maintenance3) +- vk_prepend_struct(&info->properties2, maintenance3_properties); +- descriptor_indexing_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT; ++ vk_prepend_struct(&info->properties2, &info->maintenance3_properties); + if (vulkan_info->EXT_descriptor_indexing) +- vk_prepend_struct(&info->properties2, descriptor_indexing_properties); +- buffer_alignment_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT; ++ vk_prepend_struct(&info->properties2, &info->descriptor_indexing_properties); + if (vulkan_info->EXT_texel_buffer_alignment) +- vk_prepend_struct(&info->properties2, buffer_alignment_properties); +- xfb_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; ++ vk_prepend_struct(&info->properties2, &info->texel_buffer_alignment_properties); + if (vulkan_info->EXT_transform_feedback) +- vk_prepend_struct(&info->properties2, xfb_properties); +- vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT; ++ vk_prepend_struct(&info->properties2, &info->xfb_properties); + if (vulkan_info->EXT_vertex_attribute_divisor) +- vk_prepend_struct(&info->properties2, vertex_divisor_properties); +- subgroup_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; ++ vk_prepend_struct(&info->properties2, &info->vertex_divisor_properties); + if (d3d12_device_environment_is_vulkan_min_1_1(device)) +- vk_prepend_struct(&info->properties2, subgroup_properties); ++ vk_prepend_struct(&info->properties2, &info->subgroup_properties); ++} ++ ++static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *info, struct d3d12_device *device) ++{ ++ const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; ++ VkPhysicalDevice physical_device = device->vk_physical_device; ++ struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; ++ ++ memset(info, 0, sizeof(*info)); ++ ++ info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; ++ info->conditional_rendering_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; ++ info->depth_clip_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT; ++ info->descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; ++ info->fragment_shader_interlock_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; ++ info->robustness2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; ++ info->demote_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; ++ info->texel_buffer_alignment_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT; ++ info->xfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; ++ info->vertex_divisor_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; ++ info->timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; ++ info->mutable_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; ++ info->formats4444_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; ++ ++ info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; ++ info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; ++ info->descriptor_indexing_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT; ++ info->texel_buffer_alignment_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT; ++ info->xfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; ++ info->vertex_divisor_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT; ++ info->subgroup_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; ++ ++ vkd3d_chain_physical_device_info_structures(info, device); ++ ++ if (vulkan_info->KHR_get_physical_device_properties2) ++ VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2)); ++ else ++ VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &info->features2.features)); + + if (vulkan_info->KHR_get_physical_device_properties2) + VK_CALL(vkGetPhysicalDeviceProperties2KHR(physical_device, &info->properties2)); +@@ -1840,6 +1816,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, + vkd3d_device_descriptor_limits_init(&vulkan_info->descriptor_limits, + &physical_device_info->properties2.properties.limits); + ++ vkd3d_chain_physical_device_info_structures(physical_device_info, device); ++ + return S_OK; + } + +diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c +index 7197193523d..bbfaaad47dd 100644 +--- a/libs/vkd3d/libs/vkd3d/state.c ++++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -645,7 +645,7 @@ static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_ro + return S_OK; + } + +-static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, ++static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, + enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx, + bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility, + unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context) +@@ -670,33 +670,38 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * + } + + if (context->unbounded_offset != UINT_MAX) +- d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0); ++ return d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0); ++ ++ return S_OK; + } + +-static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, ++static HRESULT d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, + enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx, + unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors, +- enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context) ++ enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context, ++ uint32_t *first_binding) + { +- uint32_t first_binding; + unsigned int i; ++ HRESULT hr; + + is_buffer_descriptor |= descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV; + duplicate_descriptors = (descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV + || descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + && duplicate_descriptors; + +- first_binding = context->descriptor_binding; ++ *first_binding = context->descriptor_binding; + for (i = 0; i < binding_count; ++i) + { +- if (duplicate_descriptors) +- d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, +- base_register_idx + i, true, shader_visibility, 1, context); ++ if (duplicate_descriptors ++ && FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, ++ register_space, base_register_idx + i, true, shader_visibility, 1, context))) ++ return hr; + +- d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, +- base_register_idx + i, is_buffer_descriptor, shader_visibility, 1, context); ++ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, ++ base_register_idx + i, is_buffer_descriptor, shader_visibility, 1, context))) ++ return hr; + } +- return first_binding; ++ return S_OK; + } + + static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE type) +@@ -764,6 +769,7 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r + enum vkd3d_shader_visibility shader_visibility = vkd3d_shader_visibility_from_d3d12(visibility); + bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV; + enum vkd3d_shader_descriptor_type descriptor_type = range->type; ++ HRESULT hr; + + if (range->descriptor_count == UINT_MAX) + context->unbounded_offset = range->offset; +@@ -775,8 +781,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r + return E_NOTIMPL; + ++context->current_binding; + +- d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space, +- range->base_register_idx, true, shader_visibility, range->vk_binding_count, context); ++ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space, ++ range->base_register_idx, true, shader_visibility, range->vk_binding_count, context))) ++ return hr; + } + + if (!vk_binding_from_d3d12_descriptor_range(context->current_binding, +@@ -784,8 +791,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r + return E_NOTIMPL; + ++context->current_binding; + +- d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space, +- range->base_register_idx, is_buffer, shader_visibility, range->vk_binding_count, context); ++ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space, ++ range->base_register_idx, is_buffer, shader_visibility, range->vk_binding_count, context))) ++ return hr; + + context->unbounded_offset = UINT_MAX; + +@@ -1130,9 +1138,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo + + cur_binding = context->current_binding; + +- vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature, ++ if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature, + range->type, range->register_space, range->base_register_idx, range->descriptor_count, false, true, +- shader_visibility, context); ++ shader_visibility, context, &vk_binding))) ++ return hr; + + /* Unroll descriptor range. */ + for (k = 0; k < range->descriptor_count; ++k) +@@ -1175,6 +1184,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign + { + VkDescriptorSetLayoutBinding *cur_binding = context->current_binding; + unsigned int i; ++ HRESULT hr; + + root_signature->push_descriptor_mask = 0; + +@@ -1188,10 +1198,11 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign + + root_signature->push_descriptor_mask |= 1u << i; + +- cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, ++ if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature, + vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType), + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false, +- vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context); ++ vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context, &cur_binding->binding))) ++ return hr; + cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType); + cur_binding->descriptorCount = 1; + cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility); +@@ -1223,9 +1234,10 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa + if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i]))) + return hr; + +- cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, ++ if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false, +- vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context); ++ vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context, &cur_binding->binding))) ++ return hr; + cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + cur_binding->descriptorCount = 1; + cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility); +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 7acd39d65be..cae8aa69c8b 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -1756,7 +1756,6 @@ static inline void vk_prepend_struct(void *header, void *structure) + { + VkBaseOutStructure *vk_header = header, *vk_structure = structure; + +- assert(!vk_structure->pNext); + vk_structure->pNext = vk_header->pNext; + vk_header->pNext = vk_structure; + } +-- +2.43.0 +