mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
1585 lines
65 KiB
Diff
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
|
||
|
|