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