wine-staging/patches/vkd3d-latest/0007-Updated-vkd3d-to-03ad04c89004c7f800c5b1a0ea7ba286229.patch
2024-10-18 07:32:33 +11:00

1585 lines
65 KiB
Diff

From 1060207c8e59871433ade5578fd0a215ebebc6e3 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 18 Oct 2024 07:31:22 +1100
Subject: [PATCH] Updated vkd3d to 03ad04c89004c7f800c5b1a0ea7ba28622916328.
---
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 21 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 3 +-
libs/vkd3d/libs/vkd3d-shader/fx.c | 220 ++++++----
libs/vkd3d/libs/vkd3d-shader/glsl.c | 3 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 68 ++--
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/ir.c | 185 ++++++++-
libs/vkd3d/libs/vkd3d-shader/msl.c | 3 +
libs/vkd3d/libs/vkd3d-shader/spirv.c | 3 +
libs/vkd3d/libs/vkd3d-shader/tpf.c | 3 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 6 +-
libs/vkd3d/libs/vkd3d/command.c | 41 +-
libs/vkd3d/libs/vkd3d/state.c | 376 +++++++++---------
13 files changed, 607 insertions(+), 329 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 8f7e5cb666b..ae8e864c179 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -561,6 +561,21 @@ static struct signature_element *find_signature_element_by_register_index(
return NULL;
}
+/* Add missing bits to a mask to make it contiguous. */
+static unsigned int make_mask_contiguous(unsigned int mask)
+{
+ static const unsigned int table[] =
+ {
+ 0x0, 0x1, 0x2, 0x3,
+ 0x4, 0x7, 0x6, 0x7,
+ 0x8, 0xf, 0xe, 0xf,
+ 0xc, 0xf, 0xe, 0xf,
+ };
+
+ VKD3D_ASSERT(mask < ARRAY_SIZE(table));
+ return table[mask];
+}
+
static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output,
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
unsigned int register_index, bool is_dcl, unsigned int mask)
@@ -576,7 +591,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
if ((element = find_signature_element(signature, name, index)))
{
- element->mask |= mask;
+ element->mask = make_mask_contiguous(element->mask | mask);
if (!is_dcl)
element->used_mask |= mask;
return true;
@@ -596,7 +611,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
element->register_index = register_index;
element->target_location = register_index;
element->register_count = 1;
- element->mask = mask;
+ element->mask = make_mask_contiguous(mask);
element->used_mask = is_dcl ? 0 : mask;
if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
element->interpolation_mode = VKD3DSIM_LINEAR;
@@ -1305,7 +1320,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
/* Estimate instruction count to avoid reallocation in most shaders. */
if (!vsir_program_init(program, compile_info, &version,
- code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED))
+ code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, false))
return VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 59494d2500d..f9f44f34bcf 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -10311,7 +10311,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
/* Estimate instruction count to avoid reallocation in most shaders. */
count = max(token_count, 400) - 400;
- if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS))
+ if (!vsir_program_init(program, compile_info, &version,
+ (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, true))
return VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name);
sm6->ptr = &sm6->start[1];
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index e98dfcf4f32..f3f7a2c765c 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -25,6 +25,17 @@ static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uin
return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value));
}
+struct fx_4_binary_type
+{
+ uint32_t name;
+ uint32_t class;
+ uint32_t element_count;
+ uint32_t unpacked_size;
+ uint32_t stride;
+ uint32_t packed_size;
+ uint32_t typeinfo;
+};
+
struct string_entry
{
struct rb_entry entry;
@@ -2842,6 +2853,7 @@ struct fx_parser
const uint8_t *ptr, *start, *end;
struct vkd3d_shader_message_context *message_context;
struct vkd3d_string_buffer buffer;
+ unsigned int indent;
struct
{
const uint8_t *ptr;
@@ -2949,6 +2961,131 @@ static const char *fx_4_get_string(struct fx_parser *parser, uint32_t offset)
return (const char *)(parser->unstructured.ptr + offset);
}
+static void parse_fx_start_indent(struct fx_parser *parser)
+{
+ ++parser->indent;
+}
+
+static void parse_fx_end_indent(struct fx_parser *parser)
+{
+ --parser->indent;
+}
+
+static void parse_fx_print_indent(struct fx_parser *parser)
+{
+ vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, "");
+}
+
+static void parse_fx_4_numeric_value(struct fx_parser *parser, uint32_t offset,
+ const struct fx_4_binary_type *type)
+{
+ unsigned int base_type, comp_count;
+ size_t i;
+
+ base_type = (type->typeinfo >> FX_4_NUMERIC_BASE_TYPE_SHIFT) & 0xf;
+
+ comp_count = type->packed_size / sizeof(uint32_t);
+ for (i = 0; i < comp_count; ++i)
+ {
+ union hlsl_constant_value_component value;
+
+ fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t));
+
+ if (base_type == FX_4_NUMERIC_TYPE_FLOAT)
+ vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f);
+ else if (base_type == FX_4_NUMERIC_TYPE_INT)
+ vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i);
+ else if (base_type == FX_4_NUMERIC_TYPE_UINT)
+ vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u);
+ else if (base_type == FX_4_NUMERIC_TYPE_BOOL)
+ vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false" );
+ else
+ vkd3d_string_buffer_printf(&parser->buffer, "%#x", value.u);
+
+ if (i < comp_count - 1)
+ vkd3d_string_buffer_printf(&parser->buffer, ", ");
+
+ offset += sizeof(uint32_t);
+ }
+}
+
+static void fx_4_parse_string_initializer(struct fx_parser *parser, uint32_t offset)
+{
+ const char *str = fx_4_get_string(parser, offset);
+ vkd3d_string_buffer_printf(&parser->buffer, "\"%s\"", str);
+}
+
+static void fx_parse_fx_4_annotations(struct fx_parser *parser)
+{
+ struct fx_4_annotation
+ {
+ uint32_t name;
+ uint32_t type;
+ } var;
+ struct fx_4_binary_type type;
+ const char *name, *type_name;
+ uint32_t count, i, value;
+
+ count = fx_parser_read_u32(parser);
+
+ if (!count)
+ return;
+
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "<\n");
+ parse_fx_start_indent(parser);
+
+ for (i = 0; i < count; ++i)
+ {
+ fx_parser_read_u32s(parser, &var, sizeof(var));
+ fx_parser_read_unstructured(parser, &type, var.type, sizeof(type));
+
+ name = fx_4_get_string(parser, var.name);
+ type_name = fx_4_get_string(parser, type.name);
+
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "%s %s", type_name, name);
+ if (type.element_count)
+ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", type.element_count);
+ vkd3d_string_buffer_printf(&parser->buffer, " = ");
+ if (type.element_count)
+ vkd3d_string_buffer_printf(&parser->buffer, "{ ");
+
+ if (type.class == FX_4_TYPE_CLASS_NUMERIC)
+ {
+ value = fx_parser_read_u32(parser);
+ parse_fx_4_numeric_value(parser, value, &type);
+ }
+ else if (type.class == FX_4_TYPE_CLASS_OBJECT && type.typeinfo == FX_4_OBJECT_TYPE_STRING)
+ {
+ uint32_t element_count = max(type.element_count, 1);
+
+ for (uint32_t j = 0; j < element_count; ++j)
+ {
+ value = fx_parser_read_u32(parser);
+ fx_4_parse_string_initializer(parser, value);
+ if (j < element_count - 1)
+ vkd3d_string_buffer_printf(&parser->buffer, ", ");
+ }
+ }
+ else
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Only numeric and string types are supported in annotations.\n");
+ }
+
+ if (type.element_count)
+ vkd3d_string_buffer_printf(&parser->buffer, " }");
+ vkd3d_string_buffer_printf(&parser->buffer, ";\n");
+ }
+ parse_fx_end_indent(parser);
+
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, ">");
+}
+
+
static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t count)
{
struct fx_4_numeric_variable
@@ -2960,17 +3097,8 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c
uint32_t value;
uint32_t flags;
} var;
- struct fx_4_type
- {
- uint32_t name;
- uint32_t class;
- uint32_t element_count;
- uint32_t unpacked_size;
- uint32_t stride;
- uint32_t packed_size;
- uint32_t typeinfo;
- } type;
const char *name, *semantic, *type_name;
+ struct fx_4_binary_type type;
uint32_t i;
for (i = 0; i < count; ++i)
@@ -2984,54 +3112,21 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c
vkd3d_string_buffer_printf(&parser->buffer, " %s %s", type_name, name);
if (type.element_count)
vkd3d_string_buffer_printf(&parser->buffer, "[%u]", type.element_count);
+
if (var.semantic)
{
semantic = fx_4_get_string(parser, var.semantic);
vkd3d_string_buffer_printf(&parser->buffer, " : %s", semantic);
}
+ fx_parse_fx_4_annotations(parser);
+
if (var.value)
{
- unsigned int base_type, comp_count;
- size_t j;
-
- if (type.class == FX_4_TYPE_CLASS_NUMERIC)
- base_type = (type.typeinfo >> FX_4_NUMERIC_BASE_TYPE_SHIFT) & 0xf;
- else
- base_type = 0;
-
vkd3d_string_buffer_printf(&parser->buffer, " = { ");
-
- comp_count = type.unpacked_size / sizeof(uint32_t);
- for (j = 0; j < comp_count; ++j)
- {
- union hlsl_constant_value_component value;
-
- fx_parser_read_unstructured(parser, &value, var.value + j * sizeof(uint32_t), sizeof(uint32_t));
-
- if (base_type == FX_4_NUMERIC_TYPE_FLOAT)
- vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f);
- else if (base_type == FX_4_NUMERIC_TYPE_INT)
- vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i);
- else if (base_type == FX_4_NUMERIC_TYPE_UINT)
- vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u);
- else if (base_type == FX_4_NUMERIC_TYPE_BOOL)
- vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false" );
- else
- vkd3d_string_buffer_printf(&parser->buffer, "%#x", value.u);
-
- if (j < comp_count - 1)
- vkd3d_string_buffer_printf(&parser->buffer, ", ");
- }
-
+ parse_fx_4_numeric_value(parser, var.value, &type);
vkd3d_string_buffer_printf(&parser->buffer, " }");
}
vkd3d_string_buffer_printf(&parser->buffer, "; // Offset: %u, size %u.\n", var.offset, type.unpacked_size);
-
- if (fx_parser_read_u32(parser))
- {
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED, "Parsing annotations is not implemented.\n");
- return;
- }
}
}
@@ -3057,27 +3152,17 @@ static void fx_parse_buffers(struct fx_parser *parser)
name = fx_4_get_string(parser, buffer.name);
- vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s\n", name);
- vkd3d_string_buffer_printf(&parser->buffer, "{\n");
-
- if (fx_parser_read_u32(parser))
- {
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED, "Parsing annotations is not implemented.\n");
- return;
- }
+ vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s", name);
+ fx_parse_fx_4_annotations(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "\n{\n");
+ parse_fx_start_indent(parser);
fx_parse_fx_4_numeric_variables(parser, buffer.count);
-
+ parse_fx_end_indent(parser);
vkd3d_string_buffer_printf(&parser->buffer, "}\n\n");
}
}
-static void fx_4_parse_string_initializer(struct fx_parser *parser, uint32_t offset)
-{
- const char *str = fx_4_get_string(parser, offset);
- vkd3d_string_buffer_printf(&parser->buffer, "\"%s\"", str);
-}
-
static void fx_4_parse_objects(struct fx_parser *parser)
{
struct fx_4_object_variable
@@ -3087,17 +3172,8 @@ static void fx_4_parse_objects(struct fx_parser *parser)
uint32_t semantic;
uint32_t bind_point;
} var;
- struct fx_4_type
- {
- uint32_t name;
- uint32_t class;
- uint32_t element_count;
- uint32_t unpacked_size;
- uint32_t stride;
- uint32_t packed_size;
- uint32_t typeinfo;
- } type;
uint32_t i, j, value, element_count;
+ struct fx_4_binary_type type;
const char *name, *type_name;
if (parser->failed)
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index 1e17de54ede..46515818d07 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -2213,6 +2213,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags,
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
+ VKD3D_ASSERT(program->normalised_io);
+ VKD3D_ASSERT(program->normalised_hull_cp_io);
+
vkd3d_glsl_generator_init(&generator, program, compile_info,
descriptor_info, combined_sampler_info, message_context);
ret = vkd3d_glsl_generator_generate(&generator, out);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index ee13e193d49..213cec79c3d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -40,6 +40,7 @@ struct parse_initializer
unsigned int args_count;
struct hlsl_block *instrs;
bool braces;
+ struct vkd3d_shader_location loc;
};
struct parse_parameter
@@ -2506,6 +2507,32 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
}
}
+static void initialize_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *dst,
+ const struct parse_initializer *initializer, bool is_default_values_initializer)
+{
+ unsigned int store_index = 0;
+
+ /* If any of the elements has an error type, then initializer_size() is not
+ * meaningful. */
+ for (unsigned int i = 0; i < initializer->args_count; ++i)
+ {
+ if (initializer->args[i]->data_type->class == HLSL_CLASS_ERROR)
+ return;
+ }
+
+ if (initializer_size(initializer) != hlsl_type_component_count(dst->data_type))
+ {
+ hlsl_error(ctx, &initializer->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Expected %u components in initializer, but got %u.",
+ hlsl_type_component_count(dst->data_type), initializer_size(initializer));
+ return;
+ }
+
+ for (unsigned int i = 0; i < initializer->args_count; ++i)
+ initialize_var_components(ctx, initializer->instrs, dst, &store_index,
+ initializer->args[i], is_default_values_initializer);
+}
+
static bool type_has_object_components(const struct hlsl_type *type)
{
if (type->class == HLSL_CLASS_ARRAY)
@@ -2832,8 +2859,6 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
if (v->initializer.args_count)
{
bool is_default_values_initializer;
- unsigned int store_index = 0;
- unsigned int size, k;
is_default_values_initializer = (ctx->cur_buffer != ctx->globals_buffer)
|| (var->storage_modifiers & HLSL_STORAGE_UNIFORM)
@@ -2871,20 +2896,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
v->initializer.args[0] = node_from_block(v->initializer.instrs);
}
- size = initializer_size(&v->initializer);
- if (component_count != size)
- {
- hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
- "Expected %u components in initializer, but got %u.", component_count, size);
- free_parse_variable_def(v);
- continue;
- }
-
- for (k = 0; k < v->initializer.args_count; ++k)
- {
- initialize_var_components(ctx, v->initializer.instrs, var,
- &store_index, v->initializer.args[k], is_default_values_initializer);
- }
+ initialize_var(ctx, var, &v->initializer, is_default_values_initializer);
if (is_default_values_initializer)
{
@@ -5402,13 +5414,11 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type
{
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
- unsigned int i, idx = 0;
if (!(var = hlsl_new_synthetic_var(ctx, "constructor", type, loc)))
return NULL;
- for (i = 0; i < params->args_count; ++i)
- initialize_var_components(ctx, params->instrs, var, &idx, params->args[i], false);
+ initialize_var(ctx, var, params, false);
if (!(load = hlsl_new_var_load(ctx, var, loc)))
return NULL;
@@ -5425,6 +5435,14 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_type *cond_type = cond->data_type;
struct hlsl_type *common_type;
+ if (cond->data_type->class == HLSL_CLASS_ERROR
+ || first->data_type->class == HLSL_CLASS_ERROR
+ || second->data_type->class == HLSL_CLASS_ERROR)
+ {
+ block->value = ctx->error_instr;
+ return true;
+ }
+
if (cond_type->class > HLSL_CLASS_LAST_NUMERIC)
{
struct vkd3d_string_buffer *string;
@@ -8321,6 +8339,7 @@ complex_initializer:
$$.args[0] = node_from_block($1);
$$.instrs = $1;
$$.braces = false;
+ $$.loc = @$;
}
| '{' complex_initializer_list '}'
{
@@ -8352,6 +8371,7 @@ complex_initializer_list:
$$.args[$$.args_count++] = $3.args[i];
hlsl_block_add_block($$.instrs, $3.instrs);
free_parse_initializer(&$3);
+ $$.loc = @$;
}
initializer_expr:
@@ -8369,6 +8389,7 @@ initializer_expr_list:
$$.args[0] = node_from_block($1);
$$.instrs = $1;
$$.braces = false;
+ $$.loc = @$;
}
| initializer_expr_list ',' initializer_expr
{
@@ -8687,6 +8708,7 @@ func_arguments:
if (!($$.instrs = make_empty_block(ctx)))
YYABORT;
$$.braces = false;
+ $$.loc = @$;
}
| initializer_expr_list
@@ -8950,14 +8972,6 @@ postfix_expr:
free_parse_initializer(&$4);
YYABORT;
}
- if ($2->dimx * $2->dimy != initializer_size(&$4))
- {
- hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
- "Expected %u components in constructor, but got %u.",
- $2->dimx * $2->dimy, initializer_size(&$4));
- free_parse_initializer(&$4);
- YYABORT;
- }
if (!($$ = add_constructor(ctx, $2, &$4, &@2)))
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 4cf9d5eb84a..88bec8610cb 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -7366,7 +7366,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
version.major = ctx->profile->major_version;
version.minor = ctx->profile->minor_version;
version.type = ctx->profile->type;
- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED))
+ if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, false))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
@@ -7404,7 +7404,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
version.minor = ctx->profile->minor_version;
version.type = ctx->profile->type;
- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED))
+ if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, false))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index c475bf92279..b47f12d2188 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -74,7 +74,8 @@ static int convert_parameter_info(const struct vkd3d_shader_compile_info *compil
}
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 vsir_control_flow_type cf_type)
+ const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type,
+ bool normalised_io)
{
memset(program, 0, sizeof(*program));
@@ -97,6 +98,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c
program->shader_version = *version;
program->cf_type = cf_type;
+ program->normalised_io = normalised_io;
+ program->normalised_hull_cp_io = normalised_io;
return shader_instruction_array_init(&program->instructions, reserve);
}
@@ -1132,6 +1135,14 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
enum vkd3d_result ret;
unsigned int i, j;
+ VKD3D_ASSERT(!program->normalised_hull_cp_io);
+
+ if (program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
+ {
+ program->normalised_hull_cp_io = true;
+ return VKD3D_OK;
+ }
+
if (!(normaliser.outpointid_param = vsir_program_create_outpointid_param(program)))
{
ERR("Failed to allocate src param.\n");
@@ -1175,6 +1186,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
break;
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
program->instructions = normaliser.instructions;
+ program->normalised_hull_cp_io = true;
return VKD3D_OK;
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
@@ -1183,6 +1195,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature,
input_control_point_count, i, &location);
program->instructions = normaliser.instructions;
+ program->normalised_hull_cp_io = true;
return ret;
default:
break;
@@ -1190,6 +1203,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
}
program->instructions = normaliser.instructions;
+ program->normalised_hull_cp_io = true;
return VKD3D_OK;
}
@@ -1903,6 +1917,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program
struct vkd3d_shader_instruction *ins;
unsigned int i;
+ VKD3D_ASSERT(!program->normalised_io);
+
normaliser.phase = VKD3DSIH_INVALID;
normaliser.shader_type = program->shader_version.type;
normaliser.major = program->shader_version.major;
@@ -1959,6 +1975,7 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program
program->instructions = normaliser.instructions;
program->use_vocp = normaliser.use_vocp;
+ program->normalised_io = true;
return VKD3D_OK;
}
@@ -6189,6 +6206,143 @@ static void vsir_validate_register_without_indices(struct validation_context *ct
reg->idx_count, reg->type);
}
+static void vsir_validate_io_register(struct validation_context *ctx,
+ const struct vkd3d_shader_register *reg)
+{
+ const struct shader_signature *signature;
+ bool has_control_point = false;
+
+ switch (reg->type)
+ {
+ case VKD3DSPR_INPUT:
+ signature = &ctx->program->input_signature;
+
+ switch (ctx->program->shader_version.type)
+ {
+ case VKD3D_SHADER_TYPE_GEOMETRY:
+ case VKD3D_SHADER_TYPE_HULL:
+ case VKD3D_SHADER_TYPE_DOMAIN:
+ has_control_point = true;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case VKD3DSPR_OUTPUT:
+ switch (ctx->program->shader_version.type)
+ {
+ case VKD3D_SHADER_TYPE_HULL:
+ if (ctx->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE)
+ {
+ signature = &ctx->program->output_signature;
+ has_control_point = ctx->program->normalised_hull_cp_io;
+ }
+ else if (ctx->program->normalised_io)
+ {
+ signature = &ctx->program->output_signature;
+ has_control_point = true;
+ }
+ else
+ {
+ signature = &ctx->program->patch_constant_signature;
+ }
+ break;
+
+ default:
+ signature = &ctx->program->output_signature;
+ break;
+ }
+ break;
+
+ case VKD3DSPR_INCONTROLPOINT:
+ signature = &ctx->program->input_signature;
+ has_control_point = true;
+ break;
+
+ case VKD3DSPR_OUTCONTROLPOINT:
+ signature = &ctx->program->output_signature;
+ has_control_point = true;
+ break;
+
+ case VKD3DSPR_PATCHCONST:
+ signature = &ctx->program->patch_constant_signature;
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+
+ if (!ctx->program->normalised_io)
+ {
+ /* Indices are [register] or [control point, register]. Both are
+ * allowed to have a relative address. */
+ unsigned int expected_idx_count = 1 + !!has_control_point;
+
+ if (reg->idx_count != expected_idx_count)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid index count %u for a register of type %#x.",
+ reg->idx_count, reg->type);
+ return;
+ }
+ }
+ else
+ {
+ struct signature_element *element;
+ unsigned int expected_idx_count;
+ unsigned int signature_idx;
+ bool is_array = false;
+
+ /* If the signature element is not an array, indices are
+ * [signature] or [control point, signature]. If the signature
+ * element is an array, indices are [array, signature] or
+ * [control point, array, signature]. In any case `signature' is
+ * not allowed to have a relative address, while the others are.
+ */
+ if (reg->idx_count < 1)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid index count %u for a register of type %#x.",
+ reg->idx_count, reg->type);
+ return;
+ }
+
+ if (reg->idx[reg->idx_count - 1].rel_addr)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX,
+ "Non-NULL relative address for the signature index of a register of type %#x.",
+ reg->type);
+ return;
+ }
+
+ signature_idx = reg->idx[reg->idx_count - 1].offset;
+
+ if (signature_idx >= signature->element_count)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX,
+ "Signature index %u exceeds the signature size %u in a register of type %#x.",
+ signature_idx, signature->element_count, reg->type);
+ return;
+ }
+
+ element = &signature->elements[signature_idx];
+ if (element->register_count > 1 || vsir_sysval_semantic_is_tess_factor(element->sysval_semantic))
+ is_array = true;
+
+ expected_idx_count = 1 + !!has_control_point + !!is_array;
+
+ if (reg->idx_count != expected_idx_count)
+ {
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid index count %u for a register of type %#x.",
+ reg->idx_count, reg->type);
+ return;
+ }
+ }
+}
+
static void vsir_validate_temp_register(struct validation_context *ctx,
const struct vkd3d_shader_register *reg)
{
@@ -6502,10 +6656,18 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_temp_register(ctx, reg);
break;
+ case VKD3DSPR_INPUT:
+ vsir_validate_io_register(ctx, reg);
+ break;
+
case VKD3DSPR_RASTOUT:
vsir_validate_rastout_register(ctx, reg);
break;
+ case VKD3DSPR_OUTPUT:
+ vsir_validate_io_register(ctx, reg);
+ break;
+
case VKD3DSPR_DEPTHOUT:
vsir_validate_register_without_indices(ctx, reg);
break;
@@ -6542,6 +6704,18 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_uav_register(ctx, reg);
break;
+ case VKD3DSPR_INCONTROLPOINT:
+ vsir_validate_io_register(ctx, reg);
+ break;
+
+ case VKD3DSPR_OUTCONTROLPOINT:
+ vsir_validate_io_register(ctx, reg);
+ break;
+
+ case VKD3DSPR_PATCHCONST:
+ vsir_validate_io_register(ctx, reg);
+ break;
+
case VKD3DSPR_DEPTHOUTGE:
vsir_validate_register_without_indices(ctx, reg);
break;
@@ -6810,6 +6984,11 @@ static void vsir_validate_signature_element(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
"element %u of %s signature: Invalid mask %#x.", idx, signature_type_name, element->mask);
+ if (!vkd3d_bitmask_is_contiguous(element->mask))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "element %u of %s signature: Non-contiguous mask %#x.",
+ idx, signature_type_name, element->mask);
+
/* Here we'd likely want to validate that the usage mask is a subset of the
* signature mask. Unfortunately the D3DBC parser sometimes violates this.
* For example I've seen a shader like this:
@@ -7649,11 +7828,9 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
vsir_transform(&ctx, vsir_program_remap_output_signature);
if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
- {
vsir_transform(&ctx, vsir_program_flatten_hull_shader_phases);
- vsir_transform(&ctx, instruction_array_normalise_hull_shader_control_point_io);
- }
+ vsir_transform(&ctx, instruction_array_normalise_hull_shader_control_point_io);
vsir_transform(&ctx, vsir_program_normalise_io_registers);
vsir_transform(&ctx, vsir_program_normalise_flat_constants);
vsir_transform(&ctx, vsir_program_remove_dead_code);
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
index 36750de1fd8..5baefbc1f44 100644
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
@@ -869,6 +869,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags,
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
+ VKD3D_ASSERT(program->normalised_io);
+ VKD3D_ASSERT(program->normalised_hull_cp_io);
+
if ((ret = msl_generator_init(&generator, program, compile_info, descriptor_info, message_context)) < 0)
return ret;
msl_generator_generate(&generator);
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 1efd717e970..6a28e2cd68e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -10650,6 +10650,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct
compile_info, compiler->message_context)) < 0)
return result;
+ VKD3D_ASSERT(program->normalised_io);
+ VKD3D_ASSERT(program->normalised_hull_cp_io);
+
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;
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 54344f2afc0..848e78a34d3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -2792,7 +2792,8 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
/* Estimate instruction count to avoid reallocation in most shaders. */
- if (!vsir_program_init(program, compile_info, &version, token_count / 7u + 20, VSIR_CF_STRUCTURED))
+ if (!vsir_program_init(program, compile_info,
+ &version, token_count / 7u + 20, VSIR_CF_STRUCTURED, false))
return false;
vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name);
sm4->ptr = sm4->start;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index d63bfd96121..9df538a0da0 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -255,6 +255,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED = 11000,
VKD3D_SHADER_ERROR_FX_INVALID_VERSION = 11001,
+ VKD3D_SHADER_ERROR_FX_INVALID_DATA = 11002,
};
enum vkd3d_shader_opcode
@@ -1414,6 +1415,8 @@ struct vsir_program
bool use_vocp;
bool has_point_size;
enum vsir_control_flow_type cf_type;
+ bool normalised_io;
+ bool normalised_hull_cp_io;
const char **block_names;
size_t block_name_count;
@@ -1426,7 +1429,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
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 vsir_control_flow_type cf_type);
+ const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type,
+ bool normalised_io);
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index eab0436bebd..5495809fcb9 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -2795,39 +2795,30 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
/* We use separate bindings for buffer and texture SRVs/UAVs.
* See d3d12_root_signature_init(). For unbounded ranges the
* descriptors exist in two consecutive sets, otherwise they occur
- * in pairs in one set. */
- if (range->descriptor_count == UINT_MAX)
- {
- if (vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
- && vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
- {
- vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1];
- vk_descriptor_write->dstBinding = 0;
- }
- }
- else
- {
- if (!use_array)
- vk_descriptor_write->dstBinding = vk_binding + 2 * index;
- if (vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
- && vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
- ++vk_descriptor_write->dstBinding;
- }
-
+ * as consecutive ranges within a set. */
if (vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|| vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{
vk_descriptor_write->pTexelBufferView = &u.view->v.u.vk_buffer_view;
+ break;
+ }
+
+ if (range->descriptor_count == UINT_MAX)
+ {
+ vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1];
+ vk_descriptor_write->dstBinding = 0;
}
else
{
- vk_image_info->sampler = VK_NULL_HANDLE;
- vk_image_info->imageView = u.view->v.u.vk_image_view;
- vk_image_info->imageLayout = u.header->magic == VKD3D_DESCRIPTOR_MAGIC_SRV
- ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
-
- vk_descriptor_write->pImageInfo = vk_image_info;
+ vk_descriptor_write->dstBinding += use_array ? 1 : range->descriptor_count;
}
+
+ vk_image_info->sampler = VK_NULL_HANDLE;
+ vk_image_info->imageView = u.view->v.u.vk_image_view;
+ vk_image_info->imageLayout = u.header->magic == VKD3D_DESCRIPTOR_MAGIC_SRV
+ ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
+
+ vk_descriptor_write->pImageInfo = vk_image_info;
break;
case VKD3D_DESCRIPTOR_MAGIC_SAMPLER:
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index fb377177403..8e5ec70a577 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -219,6 +219,30 @@ static VkShaderStageFlags stage_flags_from_visibility(D3D12_SHADER_VISIBILITY vi
}
}
+static VkShaderStageFlags stage_flags_from_vkd3d_shader_visibility(enum vkd3d_shader_visibility visibility)
+{
+ switch (visibility)
+ {
+ case VKD3D_SHADER_VISIBILITY_ALL:
+ return VK_SHADER_STAGE_ALL;
+ case VKD3D_SHADER_VISIBILITY_VERTEX:
+ return VK_SHADER_STAGE_VERTEX_BIT;
+ case VKD3D_SHADER_VISIBILITY_HULL:
+ return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+ case VKD3D_SHADER_VISIBILITY_DOMAIN:
+ return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+ case VKD3D_SHADER_VISIBILITY_GEOMETRY:
+ return VK_SHADER_STAGE_GEOMETRY_BIT;
+ case VKD3D_SHADER_VISIBILITY_PIXEL:
+ return VK_SHADER_STAGE_FRAGMENT_BIT;
+ case VKD3D_SHADER_VISIBILITY_COMPUTE:
+ return VK_SHADER_STAGE_COMPUTE_BIT;
+ default:
+ FIXME("Unhandled visibility %#x.\n", visibility);
+ return VKD3D_SHADER_VISIBILITY_ALL;
+ }
+}
+
static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_d3d12(D3D12_SHADER_VISIBILITY visibility)
{
switch (visibility)
@@ -260,23 +284,6 @@ static VkDescriptorType vk_descriptor_type_from_vkd3d_descriptor_type(enum vkd3d
}
}
-static VkDescriptorType vk_descriptor_type_from_d3d12_root_parameter(D3D12_ROOT_PARAMETER_TYPE type)
-{
- switch (type)
- {
- /* SRV and UAV root parameters are buffer views. */
- case D3D12_ROOT_PARAMETER_TYPE_SRV:
- return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
- case D3D12_ROOT_PARAMETER_TYPE_UAV:
- return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
- case D3D12_ROOT_PARAMETER_TYPE_CBV:
- return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- default:
- FIXME("Unhandled descriptor root parameter type %#x.\n", type);
- return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
- }
-}
-
static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_d3d12_range_type(
D3D12_DESCRIPTOR_RANGE_TYPE type)
{
@@ -313,20 +320,6 @@ static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_d3d12_root_p
}
}
-static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutBinding *binding_desc,
- enum vkd3d_shader_descriptor_type descriptor_type, D3D12_SHADER_VISIBILITY shader_visibility,
- bool is_buffer, uint32_t vk_binding, unsigned int descriptor_count)
-{
- binding_desc->binding = vk_binding;
- binding_desc->descriptorType
- = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, is_buffer);
- binding_desc->descriptorCount = descriptor_count;
- binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility);
- binding_desc->pImmutableSamplers = NULL;
-
- return true;
-}
-
struct d3d12_root_signature_info
{
size_t binding_count;
@@ -719,18 +712,66 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
return S_OK;
}
+struct vk_binding_array
+{
+ VkDescriptorSetLayoutBinding *bindings;
+ size_t capacity, count;
+
+ unsigned int table_index;
+ unsigned int unbounded_offset;
+ VkDescriptorSetLayoutCreateFlags flags;
+};
+
+static void vk_binding_array_cleanup(struct vk_binding_array *array)
+{
+ vkd3d_free(array->bindings);
+ array->bindings = NULL;
+}
+
+static bool vk_binding_array_add_binding(struct vk_binding_array *array,
+ VkDescriptorType descriptor_type, unsigned int descriptor_count,
+ VkShaderStageFlags stage_flags, const VkSampler *immutable_sampler, unsigned int *binding_idx)
+{
+ unsigned int binding_count = array->count;
+ VkDescriptorSetLayoutBinding *binding;
+
+ if (!vkd3d_array_reserve((void **)&array->bindings, &array->capacity,
+ array->count + 1, sizeof(*array->bindings)))
+ {
+ ERR("Failed to reallocate the Vulkan binding array.\n");
+ return false;
+ }
+
+ *binding_idx = binding_count;
+ binding = &array->bindings[binding_count];
+ binding->binding = binding_count;
+ binding->descriptorType = descriptor_type;
+ binding->descriptorCount = descriptor_count;
+ binding->stageFlags = stage_flags;
+ binding->pImmutableSamplers = immutable_sampler;
+ ++array->count;
+
+ return true;
+}
+
struct vkd3d_descriptor_set_context
{
- VkDescriptorSetLayoutBinding *current_binding;
- VkDescriptorSetLayoutBinding *first_binding;
+ struct vk_binding_array vk_bindings[VKD3D_MAX_DESCRIPTOR_SETS];
unsigned int table_index;
unsigned int unbounded_offset;
unsigned int descriptor_index;
unsigned int uav_counter_index;
unsigned int push_constant_index;
- uint32_t descriptor_binding;
};
+static void descriptor_set_context_cleanup(struct vkd3d_descriptor_set_context *context)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(context->vk_bindings); ++i)
+ vk_binding_array_cleanup(&context->vk_bindings[i]);
+}
+
static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, unsigned int set_count)
{
uint32_t max_count = min(VKD3D_MAX_DESCRIPTOR_SETS, device->vk_info.device_limits.maxBoundDescriptorSets);
@@ -745,56 +786,56 @@ static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, uns
return true;
}
-static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
- VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count, bool unbounded,
- const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout);
-
-static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_root_signature *root_signature,
- struct vkd3d_descriptor_set_context *context, VkDescriptorSetLayoutCreateFlags flags)
+static struct vk_binding_array *d3d12_root_signature_current_vk_binding_array(
+ struct d3d12_root_signature *root_signature, struct vkd3d_descriptor_set_context *context)
{
- struct d3d12_descriptor_set_layout *layout;
- unsigned int index;
- HRESULT hr;
-
- if (!context->descriptor_binding)
- return S_OK;
+ if (root_signature->vk_set_count >= ARRAY_SIZE(context->vk_bindings))
+ return NULL;
- index = root_signature->vk_set_count;
- layout = &root_signature->descriptor_set_layouts[index];
+ return &context->vk_bindings[root_signature->vk_set_count];
+}
- if (!vkd3d_validate_descriptor_set_count(root_signature->device, index + 1))
- return E_INVALIDARG;
+static void d3d12_root_signature_append_vk_binding_array(struct d3d12_root_signature *root_signature,
+ VkDescriptorSetLayoutCreateFlags flags, struct vkd3d_descriptor_set_context *context)
+{
+ struct vk_binding_array *array;
- if (FAILED(hr = vkd3d_create_descriptor_set_layout(root_signature->device, flags, context->descriptor_binding,
- context->unbounded_offset != UINT_MAX, context->first_binding, &layout->vk_layout)))
- return hr;
- layout->table_index = context->table_index;
- layout->unbounded_offset = context->unbounded_offset;
- ++root_signature->vk_set_count;
+ if (!(array = d3d12_root_signature_current_vk_binding_array(root_signature, context)) || !array->count)
+ return;
- context->current_binding = context->first_binding;
- context->descriptor_binding = 0;
+ array->table_index = context->table_index;
+ array->unbounded_offset = context->unbounded_offset;
+ array->flags = flags;
- return S_OK;
+ ++root_signature->vk_set_count;
}
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)
+ 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,
+ const VkSampler *immutable_sampler, unsigned int *binding_idx)
{
struct vkd3d_shader_descriptor_offset *offset = root_signature->descriptor_offsets
? &root_signature->descriptor_offsets[context->descriptor_index] : NULL;
- struct vkd3d_shader_resource_binding *mapping
- = &root_signature->descriptor_mapping[context->descriptor_index++];
+ struct vkd3d_shader_resource_binding *mapping;
+ struct vk_binding_array *array;
+ unsigned int idx;
+
+ if (!(array = d3d12_root_signature_current_vk_binding_array(root_signature, context))
+ || !(vk_binding_array_add_binding(&context->vk_bindings[root_signature->vk_set_count],
+ vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, buffer_descriptor), descriptor_count,
+ stage_flags_from_vkd3d_shader_visibility(shader_visibility), immutable_sampler, &idx)))
+ return E_OUTOFMEMORY;
+ mapping = &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type;
mapping->register_space = register_space;
mapping->register_index = register_idx;
mapping->shader_visibility = shader_visibility;
mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
mapping->binding.set = root_signature->vk_set_count;
- mapping->binding.binding = context->descriptor_binding++;
+ mapping->binding.binding = idx;
mapping->binding.count = descriptor_count;
if (offset)
{
@@ -803,37 +844,11 @@ static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signatur
}
if (context->unbounded_offset != UINT_MAX)
- return d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
+ d3d12_root_signature_append_vk_binding_array(root_signature, 0, context);
- return S_OK;
-}
+ if (binding_idx)
+ *binding_idx = idx;
-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,
- 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;
- for (i = 0; i < binding_count; ++i)
- {
- 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;
-
- 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 S_OK;
}
@@ -895,38 +910,41 @@ static unsigned int vk_binding_count_from_descriptor_range(const struct d3d12_ro
return min(count, VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
}
-static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_root_signature *root_signature,
+static HRESULT d3d12_root_signature_init_descriptor_table_binding(struct d3d12_root_signature *root_signature,
const struct d3d12_root_descriptor_table_range *range, D3D12_SHADER_VISIBILITY visibility,
+ unsigned int vk_binding_array_count, unsigned int bindings_per_range,
struct vkd3d_descriptor_set_context *context)
{
enum vkd3d_shader_visibility shader_visibility = vkd3d_shader_visibility_from_d3d12(visibility);
- bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
+ bool is_buffer = range->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
enum vkd3d_shader_descriptor_type descriptor_type = range->type;
+ unsigned int i, register_space = range->register_space;
HRESULT hr;
if (range->descriptor_count == UINT_MAX)
context->unbounded_offset = range->offset;
- if (descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
+ for (i = 0; i < bindings_per_range; ++i)
{
- if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
- descriptor_type, visibility, true, context->descriptor_binding, range->vk_binding_count))
- return E_NOTIMPL;
- ++context->current_binding;
-
- 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)))
+ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
+ register_space, range->base_register_idx + i, is_buffer, shader_visibility,
+ vk_binding_array_count, context, NULL, NULL)))
return hr;
}
- if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
- descriptor_type, visibility, is_buffer, context->descriptor_binding, range->vk_binding_count))
- return E_NOTIMPL;
- ++context->current_binding;
+ if (descriptor_type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV && descriptor_type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
+ {
+ context->unbounded_offset = UINT_MAX;
+ return S_OK;
+ }
- 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;
+ for (i = 0; i < bindings_per_range; ++i)
+ {
+ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
+ register_space, range->base_register_idx + i, false, shader_visibility,
+ vk_binding_array_count, context, NULL, NULL)))
+ return hr;
+ }
context->unbounded_offset = UINT_MAX;
@@ -1116,11 +1134,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
const D3D12_ROOT_SIGNATURE_DESC *desc, const struct d3d12_root_signature_info *info,
struct vkd3d_descriptor_set_context *context)
{
+ unsigned int i, j, range_count, bindings_per_range, vk_binding_array_count;
const struct d3d12_device *device = root_signature->device;
bool use_vk_heaps = root_signature->device->use_vk_heaps;
struct d3d12_root_descriptor_table *table;
- unsigned int i, j, k, range_count;
- uint32_t vk_binding;
HRESULT hr;
root_signature->descriptor_table_mask = 0;
@@ -1177,7 +1194,6 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
for (j = 0; j < range_count; ++j)
{
struct d3d12_root_descriptor_table_range *range;
- VkDescriptorSetLayoutBinding *cur_binding;
range = &table->ranges[j];
@@ -1223,53 +1239,23 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
base_range = range;
}
- range->binding = context->descriptor_binding;
range->vk_binding_count = vk_binding_count_from_descriptor_range(range,
info, &device->vk_info.descriptor_limits);
-
- if (FAILED(hr = d3d12_root_signature_init_descriptor_array_binding(root_signature,
- range, p->ShaderVisibility, context)))
- return hr;
-
- continue;
+ vk_binding_array_count = range->vk_binding_count;
+ bindings_per_range = 1;
}
-
- cur_binding = context->current_binding;
-
- 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, &vk_binding)))
- return hr;
-
- /* Unroll descriptor range. */
- for (k = 0; k < range->descriptor_count; ++k)
+ else
{
- uint32_t vk_current_binding = vk_binding + k;
-
- if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
- || range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
- {
- vk_current_binding = vk_binding + 2 * k;
-
- /* Assign binding for image view. */
- if (!vk_binding_from_d3d12_descriptor_range(cur_binding,
- range->type, p->ShaderVisibility, false, vk_current_binding + 1, 1))
- return E_NOTIMPL;
-
- ++cur_binding;
- }
-
- if (!vk_binding_from_d3d12_descriptor_range(cur_binding,
- range->type, p->ShaderVisibility, true, vk_current_binding, 1))
- return E_NOTIMPL;
-
- ++cur_binding;
+ range->vk_binding_count = range->descriptor_count;
+ vk_binding_array_count = 1;
+ bindings_per_range = range->descriptor_count;
}
- table->ranges[j].vk_binding_count = table->ranges[j].descriptor_count;
- table->ranges[j].binding = vk_binding;
+ range->binding = context->vk_bindings[root_signature->vk_set_count].count;
- context->current_binding = cur_binding;
+ if (FAILED(hr = d3d12_root_signature_init_descriptor_table_binding(root_signature, range,
+ p->ShaderVisibility, vk_binding_array_count, bindings_per_range, context)))
+ return hr;
}
++context->push_constant_index;
}
@@ -1280,8 +1266,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_signature *root_signature,
const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context)
{
- VkDescriptorSetLayoutBinding *cur_binding = context->current_binding;
- unsigned int i;
+ unsigned int binding, i;
HRESULT hr;
root_signature->push_descriptor_mask = 0;
@@ -1296,23 +1281,16 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
root_signature->push_descriptor_mask |= 1u << i;
- if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature,
+ if (FAILED(hr = d3d12_root_signature_append_vk_binding(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, &cur_binding->binding)))
+ p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, true,
+ vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), 1, context, NULL, &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);
- cur_binding->pImmutableSamplers = NULL;
root_signature->parameters[i].parameter_type = p->ParameterType;
- root_signature->parameters[i].u.descriptor.binding = cur_binding->binding;
-
- ++cur_binding;
+ root_signature->parameters[i].u.descriptor.binding = binding;
}
- context->current_binding = cur_binding;
return S_OK;
}
@@ -1320,7 +1298,6 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc,
struct vkd3d_descriptor_set_context *context)
{
- VkDescriptorSetLayoutBinding *cur_binding = context->current_binding;
unsigned int i;
HRESULT hr;
@@ -1332,21 +1309,15 @@ 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;
- 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, &cur_binding->binding)))
+ if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, false,
+ vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), 1, context,
+ &root_signature->static_samplers[i], NULL)))
return hr;
- cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
- cur_binding->descriptorCount = 1;
- cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility);
- cur_binding->pImmutableSamplers = &root_signature->static_samplers[i];
-
- ++cur_binding;
}
- context->current_binding = cur_binding;
if (device->use_vk_heaps)
- return d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
+ d3d12_root_signature_append_vk_binding_array(root_signature, 0, context);
return S_OK;
}
@@ -1479,6 +1450,34 @@ static HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device,
return S_OK;
}
+static HRESULT d3d12_root_signature_create_descriptor_set_layouts(struct d3d12_root_signature *root_signature,
+ struct vkd3d_descriptor_set_context *context)
+{
+ unsigned int i;
+ HRESULT hr;
+
+ d3d12_root_signature_append_vk_binding_array(root_signature, 0, context);
+
+ if (!vkd3d_validate_descriptor_set_count(root_signature->device, root_signature->vk_set_count))
+ return E_INVALIDARG;
+
+ for (i = 0; i < root_signature->vk_set_count; ++i)
+ {
+ struct d3d12_descriptor_set_layout *layout = &root_signature->descriptor_set_layouts[i];
+ struct vk_binding_array *array = &context->vk_bindings[i];
+
+ VKD3D_ASSERT(array->count);
+
+ if (FAILED(hr = vkd3d_create_descriptor_set_layout(root_signature->device, array->flags, array->count,
+ array->unbounded_offset != UINT_MAX, array->bindings, &layout->vk_layout)))
+ return hr;
+ layout->unbounded_offset = array->unbounded_offset;
+ layout->table_index = array->table_index;
+ }
+
+ return S_OK;
+}
+
static unsigned int d3d12_root_signature_copy_descriptor_set_layouts(const struct d3d12_root_signature *root_signature,
VkDescriptorSetLayout *vk_set_layouts)
{
@@ -1510,7 +1509,6 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
VkDescriptorSetLayout vk_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
struct vkd3d_descriptor_set_context context;
- VkDescriptorSetLayoutBinding *binding_desc;
struct d3d12_root_signature_info info;
bool use_vk_heaps;
unsigned int i;
@@ -1518,7 +1516,6 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
memset(&context, 0, sizeof(context));
context.unbounded_offset = UINT_MAX;
- binding_desc = NULL;
root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl;
root_signature->refcount = 1;
@@ -1580,20 +1577,14 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
sizeof(*root_signature->static_samplers))))
goto fail;
- if (!(binding_desc = vkd3d_calloc(info.binding_count, sizeof(*binding_desc))))
- goto fail;
- context.first_binding = binding_desc;
- context.current_binding = binding_desc;
-
if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context)))
goto fail;
/* We use KHR_push_descriptor for root descriptor parameters. */
if (vk_info->KHR_push_descriptor)
{
- if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature,
- &context, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)))
- goto fail;
+ d3d12_root_signature_append_vk_binding_array(root_signature,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, &context);
}
root_signature->main_set = root_signature->vk_set_count;
@@ -1609,11 +1600,10 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
if (use_vk_heaps)
d3d12_root_signature_init_descriptor_table_push_constants(root_signature, &context);
- if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature, &context, 0)))
+ if (FAILED(hr = d3d12_root_signature_create_descriptor_set_layouts(root_signature, &context)))
goto fail;
- vkd3d_free(binding_desc);
- binding_desc = NULL;
+ descriptor_set_context_cleanup(&context);
i = d3d12_root_signature_copy_descriptor_set_layouts(root_signature, vk_layouts);
if (FAILED(hr = vkd3d_create_pipeline_layout(device, i,
@@ -1629,7 +1619,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa
return S_OK;
fail:
- vkd3d_free(binding_desc);
+ descriptor_set_context_cleanup(&context);
d3d12_root_signature_cleanup(root_signature, device);
return hr;
}
--
2.45.2