mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
1461 lines
64 KiB
Diff
1461 lines
64 KiB
Diff
From 6a3728b4a23434276c39df90387800b72386cd3c Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Sat, 13 Jan 2024 11:46:16 +1100
|
|
Subject: [PATCH] Updated vkd3d to 3e2ace8d33a203bf0c8d6a7bf140ef9a9a08352d.
|
|
|
|
---
|
|
libs/vkd3d/Makefile.in | 1 +
|
|
libs/vkd3d/include/private/vkd3d_common.h | 1 +
|
|
libs/vkd3d/include/vkd3d_shader.h | 7 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 60 ++++++-
|
|
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 34 ++--
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 12 +-
|
|
libs/vkd3d/libs/vkd3d-shader/fx.c | 158 ++++++++++++++++++
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 77 +++++++--
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 13 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 81 ++++++++-
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 8 +-
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 40 ++---
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 11 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 36 +++-
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 6 +-
|
|
libs/vkd3d/libs/vkd3d/command.c | 3 +-
|
|
libs/vkd3d/libs/vkd3d/device.c | 42 ++++-
|
|
libs/vkd3d/libs/vkd3d/resource.c | 22 ++-
|
|
libs/vkd3d/libs/vkd3d/state.c | 23 ++-
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +-
|
|
21 files changed, 548 insertions(+), 91 deletions(-)
|
|
create mode 100644 libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
|
|
diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in
|
|
index dbc10594f62..448e9a0e61d 100644
|
|
--- a/libs/vkd3d/Makefile.in
|
|
+++ b/libs/vkd3d/Makefile.in
|
|
@@ -17,6 +17,7 @@ SOURCES = \
|
|
libs/vkd3d-shader/d3dbc.c \
|
|
libs/vkd3d-shader/dxbc.c \
|
|
libs/vkd3d-shader/dxil.c \
|
|
+ libs/vkd3d-shader/fx.c \
|
|
libs/vkd3d-shader/glsl.c \
|
|
libs/vkd3d-shader/hlsl.c \
|
|
libs/vkd3d-shader/hlsl.l \
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
index e9bff2fbba3..54fe1ca5017 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
@@ -52,6 +52,7 @@
|
|
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
|
|
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
|
|
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
|
|
+#define TAG_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0')
|
|
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
|
|
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
|
|
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index b1a1fff6451..a9c9ccc4a52 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -785,6 +785,11 @@ enum vkd3d_shader_target_type
|
|
* An 'OpenGL Shading Language' shader. \since 1.3
|
|
*/
|
|
VKD3D_SHADER_TARGET_GLSL,
|
|
+ /**
|
|
+ * Binary format used by Direct3D 9/10.x/11 effects profiles.
|
|
+ * Output is a raw FX section without container. \since 1.11
|
|
+ */
|
|
+ VKD3D_SHADER_TARGET_FX,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE),
|
|
};
|
|
@@ -1270,6 +1275,8 @@ enum vkd3d_shader_descriptor_range_flags
|
|
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
|
|
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
|
|
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
|
|
+ /** \since 1.11 */
|
|
+ VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_RANGE_FLAGS),
|
|
};
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
index 0589bc42174..4829956cecf 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -365,6 +365,7 @@ struct vkd3d_d3d_asm_compiler
|
|
struct vkd3d_shader_version shader_version;
|
|
struct vkd3d_d3d_asm_colours colours;
|
|
enum vsir_asm_dialect dialect;
|
|
+ const struct vkd3d_shader_instruction *current;
|
|
};
|
|
|
|
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
|
|
@@ -841,6 +842,27 @@ static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler,
|
|
compiler->colours.literal, b ? "true" : "false", compiler->colours.reset, suffix);
|
|
}
|
|
|
|
+static void shader_print_untyped_literal(struct vkd3d_d3d_asm_compiler *compiler,
|
|
+ const char *prefix, uint32_t u, const char *suffix)
|
|
+{
|
|
+ union
|
|
+ {
|
|
+ uint32_t u;
|
|
+ float f;
|
|
+ } value;
|
|
+ unsigned int exponent = (u >> 23) & 0xff;
|
|
+
|
|
+ value.u = u;
|
|
+
|
|
+ if (exponent != 0 && exponent != 0xff)
|
|
+ return shader_print_float_literal(compiler, prefix, value.f, suffix);
|
|
+
|
|
+ if (u <= 10000)
|
|
+ return shader_print_uint_literal(compiler, prefix, value.u, suffix);
|
|
+
|
|
+ return shader_print_hex_literal(compiler, prefix, value.u, suffix);
|
|
+}
|
|
+
|
|
static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler,
|
|
unsigned int offset, const struct vkd3d_shader_src_param *rel_addr)
|
|
{
|
|
@@ -1102,6 +1124,19 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
|
|
if (reg->type == VKD3DSPR_IMMCONST)
|
|
{
|
|
+ bool untyped = false;
|
|
+
|
|
+ switch (compiler->current->handler_idx)
|
|
+ {
|
|
+ case VKD3DSIH_MOV:
|
|
+ case VKD3DSIH_MOVC:
|
|
+ untyped = true;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
shader_addline(buffer, "%s(", compiler->colours.reset);
|
|
switch (reg->dimension)
|
|
{
|
|
@@ -1109,7 +1144,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
switch (reg->data_type)
|
|
{
|
|
case VKD3D_DATA_FLOAT:
|
|
- shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
+ if (untyped)
|
|
+ shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
+ else
|
|
+ shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
break;
|
|
case VKD3D_DATA_INT:
|
|
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
@@ -1129,10 +1167,20 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
switch (reg->data_type)
|
|
{
|
|
case VKD3D_DATA_FLOAT:
|
|
- shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
|
|
+ if (untyped)
|
|
+ {
|
|
+ shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
+ shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[1], "");
|
|
+ shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[2], "");
|
|
+ shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[3], "");
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
|
|
+ }
|
|
break;
|
|
case VKD3D_DATA_INT:
|
|
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
@@ -1678,6 +1726,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|
|
struct vkd3d_string_buffer *buffer = &compiler->buffer;
|
|
unsigned int i;
|
|
|
|
+ compiler->current = ins;
|
|
+
|
|
if (ins->predicate)
|
|
{
|
|
vkd3d_string_buffer_printf(buffer, "(");
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
index 63deaaad29a..37ebc73c099 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
@@ -130,13 +130,13 @@ static void skip_dword_unknown(const char **ptr, unsigned int count)
|
|
}
|
|
}
|
|
|
|
-static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
|
|
+static const char *shader_get_string(const char *data, size_t data_size, size_t offset)
|
|
{
|
|
size_t len, max_len;
|
|
|
|
if (offset >= data_size)
|
|
{
|
|
- WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
|
|
+ WARN("Invalid offset %#zx (data size %#zx).\n", offset, data_size);
|
|
return NULL;
|
|
}
|
|
|
|
@@ -230,7 +230,7 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
|
|
chunk_offset = read_u32(&ptr);
|
|
TRACE("chunk %u at offset %#x\n", i, chunk_offset);
|
|
|
|
- if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size))
|
|
+ if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(uint32_t), data_size))
|
|
{
|
|
WARN("Invalid chunk offset %#x (data size %zu).\n", chunk_offset, data_size);
|
|
vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET,
|
|
@@ -399,7 +399,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
|
|
|
|
for (i = 0; i < count; ++i)
|
|
{
|
|
- uint32_t name_offset, mask;
|
|
+ size_t name_offset;
|
|
+ uint32_t mask;
|
|
|
|
e[i].sort_index = i;
|
|
|
|
@@ -411,7 +412,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
|
|
name_offset = read_u32(&ptr);
|
|
if (!(e[i].semantic_name = shader_get_string(data, section->data.size, name_offset)))
|
|
{
|
|
- WARN("Invalid name offset %#x (data size %#zx).\n", name_offset, section->data.size);
|
|
+ WARN("Invalid name offset %#zx (data size %#zx).\n", name_offset, section->data.size);
|
|
vkd3d_free(e);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
@@ -592,7 +593,7 @@ static int shader_parse_descriptor_ranges(struct root_signature_parser_context *
|
|
const char *ptr;
|
|
unsigned int i;
|
|
|
|
- if (!require_space(offset, 5 * count, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 5 * count, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -623,7 +624,8 @@ static void shader_validate_descriptor_range1(const struct vkd3d_shader_descript
|
|
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE
|
|
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
|
|
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
|
|
- | VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
|
|
+ | VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC
|
|
+ | VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS);
|
|
|
|
if (unknown_flags)
|
|
FIXME("Unknown descriptor range flags %#x.\n", unknown_flags);
|
|
@@ -670,7 +672,7 @@ static int shader_parse_descriptor_table(struct root_signature_parser_context *c
|
|
unsigned int count;
|
|
const char *ptr;
|
|
|
|
- if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -697,7 +699,7 @@ static int shader_parse_descriptor_table1(struct root_signature_parser_context *
|
|
unsigned int count;
|
|
const char *ptr;
|
|
|
|
- if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -722,7 +724,7 @@ static int shader_parse_root_constants(struct root_signature_parser_context *con
|
|
{
|
|
const char *ptr;
|
|
|
|
- if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 3, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -744,7 +746,7 @@ static int shader_parse_root_descriptor(struct root_signature_parser_context *co
|
|
{
|
|
const char *ptr;
|
|
|
|
- if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -776,7 +778,7 @@ static int shader_parse_root_descriptor1(struct root_signature_parser_context *c
|
|
{
|
|
const char *ptr;
|
|
|
|
- if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 3, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -802,7 +804,7 @@ static int shader_parse_root_parameters(struct root_signature_parser_context *co
|
|
unsigned int i;
|
|
int ret;
|
|
|
|
- if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 3 * count, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -844,13 +846,13 @@ static int shader_parse_root_parameters(struct root_signature_parser_context *co
|
|
}
|
|
|
|
static int shader_parse_root_parameters1(struct root_signature_parser_context *context,
|
|
- uint32_t offset, DWORD count, struct vkd3d_shader_root_parameter1 *parameters)
|
|
+ uint32_t offset, unsigned int count, struct vkd3d_shader_root_parameter1 *parameters)
|
|
{
|
|
const char *ptr;
|
|
unsigned int i;
|
|
int ret;
|
|
|
|
- if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 3 * count, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
@@ -897,7 +899,7 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co
|
|
const char *ptr;
|
|
unsigned int i;
|
|
|
|
- if (!require_space(offset, 13 * count, sizeof(DWORD), context->data_size))
|
|
+ if (!require_space(offset, 13 * count, sizeof(uint32_t), context->data_size))
|
|
{
|
|
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index c744dfcedf0..869a709d63f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -2331,8 +2331,8 @@ static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm
|
|
|
|
static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record)
|
|
{
|
|
+ const struct sm6_type *type, *ret_type;
|
|
const unsigned int max_count = 15;
|
|
- const struct sm6_type *ret_type;
|
|
struct sm6_value *fn;
|
|
unsigned int i, j;
|
|
|
|
@@ -2347,18 +2347,18 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi
|
|
fn->u.function.name = "";
|
|
}
|
|
|
|
- if (!(fn->type = sm6_parser_get_type(sm6, record->operands[0])))
|
|
+ if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
|
|
return false;
|
|
- if (!sm6_type_is_function(fn->type))
|
|
+ if (!sm6_type_is_function(type))
|
|
{
|
|
WARN("Type is not a function.\n");
|
|
return false;
|
|
}
|
|
- ret_type = fn->type->u.function->ret_type;
|
|
+ ret_type = type->u.function->ret_type;
|
|
|
|
- if (!(fn->type = sm6_type_get_pointer_to_type(fn->type, ADDRESS_SPACE_DEFAULT, sm6)))
|
|
+ if (!(fn->type = sm6_type_get_pointer_to_type(type, ADDRESS_SPACE_DEFAULT, sm6)))
|
|
{
|
|
- WARN("Failed to get pointer type for type %u.\n", fn->type->class);
|
|
+ WARN("Failed to get pointer type for type %u.\n", type->class);
|
|
return false;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
new file mode 100644
|
|
index 00000000000..6c4c1203d48
|
|
--- /dev/null
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
@@ -0,0 +1,158 @@
|
|
+/*
|
|
+ * FX (Direct3D 9/10/11 effect) support
|
|
+ *
|
|
+ * Copyright 2023 Nikolay Sivov for CodeWeavers
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
+ */
|
|
+
|
|
+#include "hlsl.h"
|
|
+
|
|
+struct fx_write_context
|
|
+{
|
|
+ struct vkd3d_bytecode_buffer unstructured;
|
|
+ struct vkd3d_bytecode_buffer structured;
|
|
+
|
|
+ uint32_t technique_count;
|
|
+ int status;
|
|
+};
|
|
+
|
|
+static uint32_t fx_put_raw_string(struct fx_write_context *fx, const char *string)
|
|
+{
|
|
+ /* NULLs are emitted as empty strings using the same 4 bytes at the start of the section. */
|
|
+ return string ? put_string(&fx->unstructured, string) : 0;
|
|
+}
|
|
+
|
|
+static void write_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
|
|
+{
|
|
+ struct vkd3d_bytecode_buffer *buffer = &fx->structured;
|
|
+ uint32_t name_offset;
|
|
+
|
|
+ name_offset = fx_put_raw_string(fx, var->name);
|
|
+ put_u32(buffer, name_offset);
|
|
+ put_u32(buffer, 0); /* Pass count. */
|
|
+ put_u32(buffer, 0); /* Annotation count. */
|
|
+
|
|
+ /* TODO: passes */
|
|
+}
|
|
+
|
|
+static void set_status(struct fx_write_context *fx, int status)
|
|
+{
|
|
+ if (fx->status < 0)
|
|
+ return;
|
|
+ if (status < 0)
|
|
+ fx->status = status;
|
|
+}
|
|
+
|
|
+static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *fx)
|
|
+{
|
|
+ struct hlsl_ir_var *var;
|
|
+
|
|
+ LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
|
+ {
|
|
+ const struct hlsl_type *type = var->data_type;
|
|
+
|
|
+ if (type->base_type == HLSL_TYPE_TECHNIQUE && type->e.version == 10)
|
|
+ {
|
|
+ write_technique(var, fx);
|
|
+ ++fx->technique_count;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ set_status(fx, fx->unstructured.status);
|
|
+ set_status(fx, fx->structured.status);
|
|
+}
|
|
+
|
|
+static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
|
+{
|
|
+ struct vkd3d_bytecode_buffer buffer = { 0 };
|
|
+ struct fx_write_context fx;
|
|
+ uint32_t size_offset, size;
|
|
+
|
|
+ memset(&fx, 0, sizeof(fx));
|
|
+
|
|
+ put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
|
|
+
|
|
+ /* TODO: buffers */
|
|
+ /* TODO: objects */
|
|
+ /* TODO: shared buffers */
|
|
+ /* TODO: shared objects */
|
|
+
|
|
+ write_techniques(ctx->globals, &fx);
|
|
+
|
|
+ put_u32(&buffer, ctx->profile->minor_version == 0 ? 0xfeff1001 : 0xfeff1011); /* Version. */
|
|
+ put_u32(&buffer, 0); /* Buffer count. */
|
|
+ put_u32(&buffer, 0); /* Variable count. */
|
|
+ put_u32(&buffer, 0); /* Object count. */
|
|
+ put_u32(&buffer, 0); /* Pool buffer count. */
|
|
+ put_u32(&buffer, 0); /* Pool variable count. */
|
|
+ put_u32(&buffer, 0); /* Pool object count. */
|
|
+ put_u32(&buffer, fx.technique_count);
|
|
+ size_offset = put_u32(&buffer, 0); /* Unstructured size. */
|
|
+ put_u32(&buffer, 0); /* String count. */
|
|
+ put_u32(&buffer, 0); /* Texture object count. */
|
|
+ put_u32(&buffer, 0); /* Depth stencil state count. */
|
|
+ put_u32(&buffer, 0); /* Blend state count. */
|
|
+ put_u32(&buffer, 0); /* Rasterizer state count. */
|
|
+ put_u32(&buffer, 0); /* Sampler state count. */
|
|
+ put_u32(&buffer, 0); /* Rendertarget view count. */
|
|
+ put_u32(&buffer, 0); /* Depth stencil view count. */
|
|
+ put_u32(&buffer, 0); /* Shader count. */
|
|
+ put_u32(&buffer, 0); /* Inline shader count. */
|
|
+
|
|
+ size = align(fx.unstructured.size, 4);
|
|
+ set_u32(&buffer, size_offset, size);
|
|
+
|
|
+ bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
|
|
+ bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size);
|
|
+
|
|
+ vkd3d_free(fx.unstructured.data);
|
|
+ vkd3d_free(fx.structured.data);
|
|
+
|
|
+ set_status(&fx, buffer.status);
|
|
+
|
|
+ if (!fx.status)
|
|
+ {
|
|
+ out->code = buffer.data;
|
|
+ out->size = buffer.size;
|
|
+ }
|
|
+
|
|
+ if (fx.status < 0)
|
|
+ ctx->result = fx.status;
|
|
+
|
|
+ return fx.status;
|
|
+}
|
|
+
|
|
+int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
|
+{
|
|
+ if (ctx->profile->major_version == 2)
|
|
+ {
|
|
+ hlsl_fixme(ctx, &ctx->location, "Writing fx_2_0 binaries is not implemented.");
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+ else if (ctx->profile->major_version == 4)
|
|
+ {
|
|
+ return hlsl_fx_4_write(ctx, out);
|
|
+ }
|
|
+ else if (ctx->profile->major_version == 5)
|
|
+ {
|
|
+ hlsl_fixme(ctx, &ctx->location, "Writing fx_5_0 binaries is not implemented.");
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
+}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index a41967876a2..1e247445119 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -98,19 +98,22 @@ bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var
|
|
struct hlsl_scope *scope = ctx->cur_scope;
|
|
struct hlsl_ir_var *var;
|
|
|
|
- LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
|
+ if (decl->name)
|
|
{
|
|
- if (!strcmp(decl->name, var->name))
|
|
- return false;
|
|
- }
|
|
- if (local_var && scope->upper->upper == ctx->globals)
|
|
- {
|
|
- /* Check whether the variable redefines a function parameter. */
|
|
- LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
|
|
+ LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
|
{
|
|
- if (!strcmp(decl->name, var->name))
|
|
+ if (var->name && !strcmp(decl->name, var->name))
|
|
return false;
|
|
}
|
|
+ if (local_var && scope->upper->upper == ctx->globals)
|
|
+ {
|
|
+ /* Check whether the variable redefines a function parameter. */
|
|
+ LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
|
|
+ {
|
|
+ if (var->name && !strcmp(decl->name, var->name))
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
list_add_tail(&scope->vars, &decl->scope_entry);
|
|
@@ -123,7 +126,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
|
|
|
|
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
|
|
{
|
|
- if (!strcmp(name, var->name))
|
|
+ if (var->name && !strcmp(name, var->name))
|
|
return var;
|
|
}
|
|
if (!scope->upper)
|
|
@@ -915,6 +918,11 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
|
|
if (t1->class == HLSL_CLASS_ARRAY)
|
|
return t1->e.array.elements_count == t2->e.array.elements_count
|
|
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
|
|
+ if (t1->class == HLSL_CLASS_OBJECT)
|
|
+ {
|
|
+ if (t1->base_type == HLSL_TYPE_TECHNIQUE && t1->e.version != t2->e.version)
|
|
+ return false;
|
|
+ }
|
|
|
|
return true;
|
|
}
|
|
@@ -993,6 +1001,13 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
|
|
break;
|
|
}
|
|
|
|
+ case HLSL_CLASS_OBJECT:
|
|
+ {
|
|
+ if (type->base_type == HLSL_TYPE_TECHNIQUE)
|
|
+ type->e.version = old->e.version;
|
|
+ break;
|
|
+ }
|
|
+
|
|
default:
|
|
break;
|
|
}
|
|
@@ -3351,12 +3366,25 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
|
|
{"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1},
|
|
{"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1},
|
|
{"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4},
|
|
+ {"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1},
|
|
{"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1},
|
|
{"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1},
|
|
{"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1},
|
|
{"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1},
|
|
};
|
|
|
|
+ static const struct
|
|
+ {
|
|
+ char *name;
|
|
+ unsigned int version;
|
|
+ }
|
|
+ technique_types[] =
|
|
+ {
|
|
+ {"technique", 9},
|
|
+ {"technique10", 10},
|
|
+ {"technique11", 11},
|
|
+ };
|
|
+
|
|
for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
|
|
{
|
|
for (y = 1; y <= 4; ++y)
|
|
@@ -3461,6 +3489,13 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
|
|
effect_types[i].base_type, effect_types[i].dimx, effect_types[i].dimy);
|
|
hlsl_scope_add_type(ctx->globals, type);
|
|
}
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(technique_types); ++i)
|
|
+ {
|
|
+ type = hlsl_new_type(ctx, technique_types[i].name, HLSL_CLASS_OBJECT, HLSL_TYPE_TECHNIQUE, 1, 1);
|
|
+ type->e.version = technique_types[i].version;
|
|
+ hlsl_scope_add_type(ctx->globals, type);
|
|
+ }
|
|
}
|
|
|
|
static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
|
|
@@ -3596,7 +3631,13 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
|
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
- if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
|
|
+ if (compile_info->target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT)
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
+ "The '%s' target profile is only compatible with the 'fx' target type.", profile->name);
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
+ }
|
|
+ else if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
|
|
{
|
|
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
"The '%s' target profile is incompatible with the 'd3dbc' target type.", profile->name);
|
|
@@ -3608,6 +3649,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
|
"The '%s' target profile is incompatible with the 'dxbc-tpf' target type.", profile->name);
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
+ else if (compile_info->target_type == VKD3D_SHADER_TARGET_FX && profile->type != VKD3D_SHADER_TYPE_EFFECT)
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
+ "The '%s' target profile is incompatible with the 'fx' target type.", profile->name);
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
+ }
|
|
|
|
if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
@@ -3632,6 +3679,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
|
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
+ if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT)
|
|
+ {
|
|
+ ret = hlsl_emit_effect_binary(&ctx, out);
|
|
+
|
|
+ hlsl_ctx_cleanup(&ctx);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
if ((func = hlsl_get_function(&ctx, entry_point)))
|
|
{
|
|
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index b56dea10f4c..8bc98b99e8a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -95,6 +95,8 @@ enum hlsl_base_type
|
|
HLSL_TYPE_UAV,
|
|
HLSL_TYPE_PIXELSHADER,
|
|
HLSL_TYPE_VERTEXSHADER,
|
|
+ HLSL_TYPE_TECHNIQUE,
|
|
+ HLSL_TYPE_EFFECT_GROUP,
|
|
HLSL_TYPE_STRING,
|
|
HLSL_TYPE_VOID,
|
|
};
|
|
@@ -138,8 +140,10 @@ struct hlsl_type
|
|
struct rb_entry scope_entry;
|
|
|
|
enum hlsl_type_class class;
|
|
- /* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
|
|
- * If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
|
|
+ /* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
|
|
+ * If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
|
|
+ * If class is HLSL_CLASS_OBJECT and base_type is HLSL_TYPE_TECHNIQUE, additional version
|
|
+ * field is used to distinguish between technique types.
|
|
* Otherwise, base_type is not used. */
|
|
enum hlsl_base_type base_type;
|
|
|
|
@@ -191,6 +195,8 @@ struct hlsl_type
|
|
/* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or
|
|
* HLSL_TYPE_UAV. */
|
|
struct hlsl_type *resource_format;
|
|
+ /* Additional field to distinguish object types. Currently used only for technique types. */
|
|
+ unsigned int version;
|
|
} e;
|
|
|
|
/* Number of numeric register components used by one value of this type, for each regset.
|
|
@@ -400,6 +406,8 @@ struct hlsl_ir_var
|
|
struct list scope_entry;
|
|
/* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */
|
|
struct list extern_entry;
|
|
+ /* Scope that variable itself defines, used to provide a container for techniques and passes. */
|
|
+ struct hlsl_scope *scope;
|
|
|
|
/* Indexes of the IR instructions where the variable is first written and last read (liveness
|
|
* range). The IR instructions are numerated starting from 2, because 0 means unused, and 1
|
|
@@ -1160,6 +1168,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
|
|
|
|
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
|
|
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
|
|
+int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
|
|
|
|
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain);
|
|
bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
index fe838750747..6cef0e02eff 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
@@ -89,6 +89,7 @@ else {return KW_ELSE; }
|
|
extern {return KW_EXTERN; }
|
|
false {return KW_FALSE; }
|
|
for {return KW_FOR; }
|
|
+fxgroup {return KW_FXGROUP; }
|
|
GeometryShader {return KW_GEOMETRYSHADER; }
|
|
groupshared {return KW_GROUPSHARED; }
|
|
if {return KW_IF; }
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index 26f9357419b..7424e63a478 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -1096,6 +1096,55 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
|
|
return true;
|
|
}
|
|
|
|
+static bool add_technique(struct hlsl_ctx *ctx, const char *name, const char *typename,
|
|
+ const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ struct hlsl_ir_var *var;
|
|
+ struct hlsl_type *type;
|
|
+
|
|
+ type = hlsl_get_type(ctx->globals, typename, false, false);
|
|
+ if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL)))
|
|
+ return false;
|
|
+
|
|
+ if (!hlsl_add_var(ctx, var, false))
|
|
+ {
|
|
+ struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name);
|
|
+
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
|
|
+ "Identifier \"%s\" was already declared in this scope.", var->name);
|
|
+ hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
|
|
+ hlsl_free_var(var);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl_scope *scope,
|
|
+ const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ struct hlsl_ir_var *var;
|
|
+ struct hlsl_type *type;
|
|
+
|
|
+ type = hlsl_get_type(ctx->globals, "fxgroup", false, false);
|
|
+ if (!(var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL)))
|
|
+ return false;
|
|
+ var->scope = scope;
|
|
+
|
|
+ if (!hlsl_add_var(ctx, var, false))
|
|
+ {
|
|
+ struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name);
|
|
+
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED,
|
|
+ "Identifier \"%s\" was already declared in this scope.", var->name);
|
|
+ hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
|
|
+ hlsl_free_var(var);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string)
|
|
{
|
|
struct hlsl_reg_reservation reservation = {0};
|
|
@@ -4888,6 +4937,7 @@ static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hls
|
|
%token KW_EXTERN
|
|
%token KW_FALSE
|
|
%token KW_FOR
|
|
+%token KW_FXGROUP
|
|
%token KW_GEOMETRYSHADER
|
|
%token KW_GROUPSHARED
|
|
%token KW_IF
|
|
@@ -5094,7 +5144,8 @@ hlsl_prog:
|
|
destroy_block($2);
|
|
}
|
|
| hlsl_prog preproc_directive
|
|
- | hlsl_prog technique
|
|
+ | hlsl_prog global_technique
|
|
+ | hlsl_prog effect_group
|
|
| hlsl_prog ';'
|
|
|
|
technique_name:
|
|
@@ -5110,7 +5161,8 @@ pass_list:
|
|
technique9:
|
|
KW_TECHNIQUE technique_name '{' pass_list '}'
|
|
{
|
|
- hlsl_fixme(ctx, &@$, "Unsupported \'technique\' declaration.");
|
|
+ if (!add_technique(ctx, $2, "technique", &@1))
|
|
+ YYABORT;
|
|
}
|
|
|
|
technique10:
|
|
@@ -5120,7 +5172,8 @@ technique10:
|
|
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
|
"The 'technique10' keyword is invalid for this profile.");
|
|
|
|
- hlsl_fixme(ctx, &@$, "Unsupported \'technique10\' declaration.");
|
|
+ if (!add_technique(ctx, $2, "technique10", &@1))
|
|
+ YYABORT;
|
|
}
|
|
|
|
technique11:
|
|
@@ -5130,14 +5183,32 @@ technique11:
|
|
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
|
"The 'technique11' keyword is invalid for this profile.");
|
|
|
|
- hlsl_fixme(ctx, &@$, "Unsupported \'technique11\' declaration.");
|
|
+ if (!add_technique(ctx, $2, "technique11", &@1))
|
|
+ YYABORT;
|
|
}
|
|
|
|
-technique:
|
|
+global_technique:
|
|
technique9
|
|
| technique10
|
|
| technique11
|
|
|
|
+group_technique:
|
|
+ technique10
|
|
+ | technique11
|
|
+
|
|
+group_techniques:
|
|
+ group_technique
|
|
+ | group_techniques group_technique
|
|
+
|
|
+effect_group:
|
|
+ KW_FXGROUP any_identifier '{' scope_start group_techniques '}'
|
|
+ {
|
|
+ struct hlsl_scope *scope = ctx->cur_scope;
|
|
+ hlsl_pop_scope(ctx);
|
|
+ if (!(add_effect_group(ctx, $2, scope, &@2)))
|
|
+ YYABORT;
|
|
+ }
|
|
+
|
|
buffer_declaration:
|
|
buffer_type any_identifier colon_attribute
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index bac4269198b..9fd60fa76a4 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -492,7 +492,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
if (shader_instruction_is_dcl(ins))
|
|
break;
|
|
for (j = 0; j < ins->dst_count; ++j)
|
|
- shader_dst_param_normalise_outpointid((struct vkd3d_shader_dst_param *)&ins->dst[j], &normaliser);
|
|
+ shader_dst_param_normalise_outpointid(&ins->dst[j], &normaliser);
|
|
break;
|
|
}
|
|
}
|
|
@@ -1116,9 +1116,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
if (shader_instruction_is_dcl(ins))
|
|
break;
|
|
for (i = 0; i < ins->dst_count; ++i)
|
|
- shader_dst_param_io_normalise((struct vkd3d_shader_dst_param *)&ins->dst[i], false, normaliser);
|
|
+ shader_dst_param_io_normalise(&ins->dst[i], false, normaliser);
|
|
for (i = 0; i < ins->src_count; ++i)
|
|
- shader_src_param_io_normalise((struct vkd3d_shader_src_param *)&ins->src[i], normaliser);
|
|
+ shader_src_param_io_normalise(&ins->src[i], normaliser);
|
|
break;
|
|
}
|
|
}
|
|
@@ -1310,7 +1310,7 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
|
|
else
|
|
{
|
|
for (j = 0; j < ins->src_count; ++j)
|
|
- shader_register_normalise_flat_constants((struct vkd3d_shader_src_param *)&ins->src[j], &normaliser);
|
|
+ shader_register_normalise_flat_constants(&ins->src[j], &normaliser);
|
|
}
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 987197887de..a9e02d0a98e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -2198,7 +2198,7 @@ static void vkd3d_symbol_make_io(struct vkd3d_symbol *symbol,
|
|
|
|
static void vkd3d_symbol_set_register_info(struct vkd3d_symbol *symbol,
|
|
uint32_t val_id, SpvStorageClass storage_class,
|
|
- enum vkd3d_shader_component_type component_type, DWORD write_mask)
|
|
+ enum vkd3d_shader_component_type component_type, uint32_t write_mask)
|
|
{
|
|
symbol->id = val_id;
|
|
symbol->descriptor_array = NULL;
|
|
@@ -3370,7 +3370,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_src_param *src, DWORD write_mask);
|
|
+ const struct vkd3d_shader_src_param *src, uint32_t write_mask);
|
|
|
|
static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_register_index *reg_index)
|
|
@@ -3997,7 +3997,7 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id;
|
|
@@ -4011,7 +4011,7 @@ static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id;
|
|
@@ -4027,7 +4027,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask,
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask,
|
|
enum vkd3d_shader_src_modifier modifier, uint32_t val_id)
|
|
{
|
|
switch (modifier)
|
|
@@ -4050,7 +4050,7 @@ static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_src_param *src, DWORD write_mask)
|
|
+ const struct vkd3d_shader_src_param *src, uint32_t write_mask)
|
|
{
|
|
uint32_t val_id;
|
|
|
|
@@ -4059,7 +4059,7 @@ static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_src_param *src, DWORD write_mask, enum vkd3d_shader_component_type component_type)
|
|
+ const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type)
|
|
{
|
|
struct vkd3d_shader_src_param src_param = *src;
|
|
|
|
@@ -7068,7 +7068,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler,
|
|
enum vkd3d_shader_component_type component_type;
|
|
uint32_t type_id, val_id, src_ids[2];
|
|
unsigned int component_count, i;
|
|
- DWORD write_mask;
|
|
+ uint32_t write_mask;
|
|
|
|
component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
|
|
@@ -7370,7 +7370,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
enum vkd3d_shader_component_type component_type;
|
|
unsigned int i, j, k, src_count;
|
|
- DWORD write_mask;
|
|
+ uint32_t write_mask;
|
|
SpvOp op;
|
|
|
|
src_count = instruction->src_count;
|
|
@@ -7427,8 +7427,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
uint32_t components[VKD3D_VEC4_SIZE];
|
|
+ uint32_t write_mask;
|
|
unsigned int i, j;
|
|
- DWORD write_mask;
|
|
|
|
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
|
|
@@ -7460,8 +7460,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
uint32_t components[VKD3D_VEC4_SIZE];
|
|
+ uint32_t write_mask;
|
|
unsigned int i, j;
|
|
- DWORD write_mask;
|
|
|
|
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
|
|
@@ -8226,7 +8226,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler,
|
|
unsigned int image_operand_count = 0;
|
|
struct vkd3d_shader_image image;
|
|
uint32_t image_operands[2];
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
bool multisample;
|
|
|
|
multisample = instruction->handler_idx == VKD3DSIH_LD2DMS;
|
|
@@ -8300,7 +8300,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
|
|
unsigned int image_operand_count = 0;
|
|
struct vkd3d_shader_image image;
|
|
uint32_t image_operands[3];
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
SpvOp op;
|
|
|
|
resource = &src[1];
|
|
@@ -8416,7 +8416,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
|
|
struct vkd3d_shader_image image;
|
|
unsigned int component_idx;
|
|
uint32_t image_operands[1];
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
bool extended_offset;
|
|
|
|
if (instruction->handler_idx == VKD3DSIH_GATHER4_C
|
|
@@ -8476,13 +8476,13 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
|
|
|
|
static uint32_t spirv_compiler_emit_raw_structured_addressing(
|
|
struct spirv_compiler *compiler, uint32_t type_id, unsigned int stride,
|
|
- const struct vkd3d_shader_src_param *src0, DWORD src0_mask,
|
|
- const struct vkd3d_shader_src_param *src1, DWORD src1_mask)
|
|
+ const struct vkd3d_shader_src_param *src0, uint32_t src0_mask,
|
|
+ const struct vkd3d_shader_src_param *src1, uint32_t src1_mask)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
const struct vkd3d_shader_src_param *offset;
|
|
uint32_t structure_id = 0, offset_id;
|
|
- DWORD offset_write_mask;
|
|
+ uint32_t offset_write_mask;
|
|
|
|
if (stride)
|
|
{
|
|
@@ -8791,7 +8791,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
const struct vkd3d_symbol *resource_symbol;
|
|
struct vkd3d_shader_image image;
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
uint32_t indices[2];
|
|
|
|
resource_symbol = spirv_compiler_find_resource(compiler, &src[1].reg);
|
|
@@ -8834,7 +8834,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
const struct vkd3d_symbol *resource_symbol;
|
|
struct vkd3d_shader_image image;
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
uint32_t indices[2];
|
|
|
|
resource_symbol = spirv_compiler_find_resource(compiler, &dst->reg);
|
|
@@ -9000,7 +9000,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
|
|
struct vkd3d_shader_register_info reg_info;
|
|
struct vkd3d_shader_image image;
|
|
unsigned int structure_stride;
|
|
- DWORD coordinate_mask;
|
|
+ uint32_t coordinate_mask;
|
|
uint32_t operands[6];
|
|
unsigned int i = 0;
|
|
SpvScope scope;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 2cc56663efe..43b3525bb7b 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -742,8 +742,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv,
|
|
static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode,
|
|
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
|
|
{
|
|
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
|
|
- (struct vkd3d_shader_src_param *)&ins->src[0]);
|
|
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
|
|
ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ?
|
|
VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
}
|
|
@@ -751,8 +750,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins,
|
|
static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode,
|
|
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
|
|
{
|
|
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
|
|
- (struct vkd3d_shader_src_param *)&ins->src[0]);
|
|
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
|
|
if (ins->src[0].reg.type != VKD3DSPR_IMMCONST)
|
|
{
|
|
FIXME("Switch case value is not a 32-bit constant.\n");
|
|
@@ -1130,9 +1128,8 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in
|
|
static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
|
|
const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
|
|
{
|
|
- struct vkd3d_shader_src_param *src_params = (struct vkd3d_shader_src_param *)ins->src;
|
|
- src_params[0].reg.u.fp_body_idx = *tokens++;
|
|
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &src_params[0]);
|
|
+ ins->src[0].reg.u.fp_body_idx = *tokens++;
|
|
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]);
|
|
}
|
|
|
|
static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode,
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index 8fd98d2a551..61e46f5538e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -383,13 +383,42 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte
|
|
return offset;
|
|
}
|
|
|
|
-void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
|
|
+size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size)
|
|
+{
|
|
+ size_t offset = bytecode_align(buffer);
|
|
+
|
|
+ if (buffer->status)
|
|
+ return offset;
|
|
+
|
|
+ if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1))
|
|
+ {
|
|
+ buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ return offset;
|
|
+ }
|
|
+
|
|
+ memset(buffer->data + offset, 0, size);
|
|
+ buffer->size = offset + size;
|
|
+ return offset;
|
|
+}
|
|
+
|
|
+static void bytecode_set_bytes(struct vkd3d_bytecode_buffer *buffer, size_t offset,
|
|
+ const void *value, size_t size)
|
|
{
|
|
if (buffer->status)
|
|
return;
|
|
|
|
- assert(vkd3d_bound_range(offset, sizeof(value), buffer->size));
|
|
- memcpy(buffer->data + offset, &value, sizeof(value));
|
|
+ assert(vkd3d_bound_range(offset, size, buffer->size));
|
|
+ memcpy(buffer->data + offset, value, size);
|
|
+}
|
|
+
|
|
+void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
|
|
+{
|
|
+ bytecode_set_bytes(buffer, offset, &value, sizeof(value));
|
|
+}
|
|
+
|
|
+void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length)
|
|
+{
|
|
+ bytecode_set_bytes(buffer, offset, string, length);
|
|
}
|
|
|
|
static void vkd3d_shader_dump_blob(const char *path, const char *profile,
|
|
@@ -1913,6 +1942,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
|
|
{
|
|
VKD3D_SHADER_TARGET_D3D_BYTECODE,
|
|
VKD3D_SHADER_TARGET_DXBC_TPF,
|
|
+ VKD3D_SHADER_TARGET_FX,
|
|
};
|
|
|
|
static const enum vkd3d_shader_target_type d3dbc_types[] =
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index 224d27f4e1b..cc156f88074 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -1126,8 +1126,8 @@ struct vkd3d_shader_instruction
|
|
uint32_t flags;
|
|
unsigned int dst_count;
|
|
unsigned int src_count;
|
|
- const struct vkd3d_shader_dst_param *dst;
|
|
- const struct vkd3d_shader_src_param *src;
|
|
+ struct vkd3d_shader_dst_param *dst;
|
|
+ struct vkd3d_shader_src_param *src;
|
|
struct vkd3d_shader_texel_offset texel_offset;
|
|
enum vkd3d_shader_resource_type resource_type;
|
|
unsigned int resource_stride;
|
|
@@ -1357,7 +1357,9 @@ struct vkd3d_bytecode_buffer
|
|
/* Align to the next 4-byte offset, and return that offset. */
|
|
size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer);
|
|
size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size);
|
|
+size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size);
|
|
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value);
|
|
+void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length);
|
|
|
|
static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
index 013b5d0751f..4c39d00de24 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
@@ -3270,7 +3270,8 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l
|
|
{
|
|
VkDescriptorSet vk_descriptor_set = heap->vk_descriptor_sets[set].vk_set;
|
|
|
|
- if (!vk_descriptor_set)
|
|
+ /* Null vk_set_layout means set 0 uses mutable descriptors, and this set is unused. */
|
|
+ if (!vk_descriptor_set || !list->device->vk_descriptor_heap_layouts[set].vk_set_layout)
|
|
continue;
|
|
|
|
VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bindings->vk_bind_point, rs->vk_pipeline_layout,
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
index 69a46e9188a..ea243977c22 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
@@ -94,6 +94,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
|
|
VK_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker),
|
|
VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable),
|
|
VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing),
|
|
+ VK_EXTENSION(EXT_MUTABLE_DESCRIPTOR_TYPE, EXT_mutable_descriptor_type),
|
|
VK_EXTENSION(EXT_ROBUSTNESS_2, EXT_robustness2),
|
|
VK_EXTENSION(EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION, EXT_shader_demote_to_helper_invocation),
|
|
VK_EXTENSION(EXT_SHADER_STENCIL_EXPORT, EXT_shader_stencil_export),
|
|
@@ -106,13 +107,32 @@ static HRESULT vkd3d_create_vk_descriptor_heap_layout(struct d3d12_device *devic
|
|
{
|
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
VkDescriptorSetLayoutBindingFlagsCreateInfoEXT flags_info;
|
|
+ VkMutableDescriptorTypeCreateInfoEXT mutable_info;
|
|
+ VkMutableDescriptorTypeListEXT type_list;
|
|
VkDescriptorSetLayoutCreateInfo set_desc;
|
|
VkDescriptorBindingFlagsEXT set_flags;
|
|
VkDescriptorSetLayoutBinding binding;
|
|
VkResult vr;
|
|
|
|
+ static const VkDescriptorType descriptor_types[] =
|
|
+ {
|
|
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
|
+ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
|
+ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
|
+ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
|
+ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
|
+ };
|
|
+
|
|
+ if (device->vk_info.EXT_mutable_descriptor_type && index && index != VKD3D_SET_INDEX_UAV_COUNTER
|
|
+ && device->vk_descriptor_heap_layouts[index].applicable_heap_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
|
|
+ {
|
|
+ device->vk_descriptor_heap_layouts[index].vk_set_layout = VK_NULL_HANDLE;
|
|
+ return S_OK;
|
|
+ }
|
|
+
|
|
binding.binding = 0;
|
|
- binding.descriptorType = device->vk_descriptor_heap_layouts[index].type;
|
|
+ binding.descriptorType = (device->vk_info.EXT_mutable_descriptor_type && !index)
|
|
+ ? VK_DESCRIPTOR_TYPE_MUTABLE_EXT : device->vk_descriptor_heap_layouts[index].type;
|
|
binding.descriptorCount = device->vk_descriptor_heap_layouts[index].count;
|
|
binding.stageFlags = VK_SHADER_STAGE_ALL;
|
|
binding.pImmutableSamplers = NULL;
|
|
@@ -132,6 +152,17 @@ static HRESULT vkd3d_create_vk_descriptor_heap_layout(struct d3d12_device *devic
|
|
flags_info.bindingCount = 1;
|
|
flags_info.pBindingFlags = &set_flags;
|
|
|
|
+ if (binding.descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_EXT)
|
|
+ {
|
|
+ type_list.descriptorTypeCount = ARRAY_SIZE(descriptor_types);
|
|
+ type_list.pDescriptorTypes = descriptor_types;
|
|
+ mutable_info.sType = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT;
|
|
+ mutable_info.pNext = NULL;
|
|
+ mutable_info.mutableDescriptorTypeListCount = 1;
|
|
+ mutable_info.pMutableDescriptorTypeLists = &type_list;
|
|
+ flags_info.pNext = &mutable_info;
|
|
+ }
|
|
+
|
|
if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL,
|
|
&device->vk_descriptor_heap_layouts[index].vk_set_layout))) < 0)
|
|
{
|
|
@@ -763,6 +794,7 @@ struct vkd3d_physical_device_info
|
|
VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
|
|
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
|
|
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features;
|
|
+ VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_features;
|
|
|
|
VkPhysicalDeviceFeatures2 features2;
|
|
};
|
|
@@ -780,6 +812,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features;
|
|
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features;
|
|
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *timeline_semaphore_features;
|
|
+ VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *mutable_features;
|
|
VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features;
|
|
VkPhysicalDeviceMaintenance3Properties *maintenance3_properties;
|
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties;
|
|
@@ -800,6 +833,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|
vertex_divisor_features = &info->vertex_divisor_features;
|
|
vertex_divisor_properties = &info->vertex_divisor_properties;
|
|
timeline_semaphore_features = &info->timeline_semaphore_features;
|
|
+ mutable_features = &info->mutable_features;
|
|
xfb_features = &info->xfb_features;
|
|
xfb_properties = &info->xfb_properties;
|
|
|
|
@@ -823,6 +857,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|
vk_prepend_struct(&info->features2, vertex_divisor_features);
|
|
timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
|
|
vk_prepend_struct(&info->features2, timeline_semaphore_features);
|
|
+ mutable_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT;
|
|
+ vk_prepend_struct(&info->features2, mutable_features);
|
|
|
|
if (vulkan_info->KHR_get_physical_device_properties2)
|
|
VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2));
|
|
@@ -1594,6 +1630,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|
vulkan_info->EXT_shader_demote_to_helper_invocation = false;
|
|
if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment)
|
|
vulkan_info->EXT_texel_buffer_alignment = false;
|
|
+ if (!physical_device_info->mutable_features.mutableDescriptorType)
|
|
+ vulkan_info->EXT_mutable_descriptor_type = false;
|
|
if (!physical_device_info->timeline_semaphore_features.timelineSemaphore)
|
|
vulkan_info->KHR_timeline_semaphore = false;
|
|
|
|
@@ -4513,7 +4551,7 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance,
|
|
thread_data->data = data;
|
|
if (!(thread->handle = CreateThread(NULL, 0, call_thread_main, thread_data, 0, NULL)))
|
|
{
|
|
- ERR("Failed to create thread, error %d.\n", GetLastError());
|
|
+ ERR("Failed to create thread, error %lu.\n", GetLastError());
|
|
vkd3d_free(thread_data);
|
|
hr = E_FAIL;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
|
|
index f4ce1ccaffa..163dd6ce210 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/resource.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/resource.c
|
|
@@ -2470,12 +2470,14 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea
|
|
{
|
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
struct d3d12_descriptor_heap_vk_set *descriptor_set;
|
|
- enum vkd3d_vk_descriptor_set_index set;
|
|
+ enum vkd3d_vk_descriptor_set_index set, end;
|
|
unsigned int i = writes->count;
|
|
|
|
+ end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_UNIFORM_BUFFER
|
|
+ : VKD3D_SET_INDEX_STORAGE_IMAGE;
|
|
/* Binding a shader with the wrong null descriptor type works in Windows.
|
|
* To support that here we must write one to all applicable Vulkan sets. */
|
|
- for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++set)
|
|
+ for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= end; ++set)
|
|
{
|
|
descriptor_set = &descriptor_heap->vk_descriptor_sets[set];
|
|
writes->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
@@ -4220,9 +4222,11 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descrip
|
|
|
|
for (set = 0, pool_desc.poolSizeCount = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set)
|
|
{
|
|
- if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type)
|
|
+ if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type
|
|
+ && device->vk_descriptor_heap_layouts[set].vk_set_layout)
|
|
{
|
|
- pool_sizes[pool_desc.poolSizeCount].type = device->vk_descriptor_heap_layouts[set].type;
|
|
+ pool_sizes[pool_desc.poolSizeCount].type = (device->vk_info.EXT_mutable_descriptor_type && !set)
|
|
+ ? VK_DESCRIPTOR_TYPE_MUTABLE_EXT : device->vk_descriptor_heap_layouts[set].type;
|
|
pool_sizes[pool_desc.poolSizeCount++].descriptorCount = desc->NumDescriptors;
|
|
}
|
|
}
|
|
@@ -4248,6 +4252,16 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_set(struct d3d12_descript
|
|
VkDescriptorSetAllocateInfo set_desc;
|
|
VkResult vr;
|
|
|
|
+ if (!device->vk_descriptor_heap_layouts[set].vk_set_layout)
|
|
+ {
|
|
+ /* Set 0 uses mutable descriptors, and this set is unused. */
|
|
+ if (!descriptor_heap->vk_descriptor_sets[0].vk_set)
|
|
+ d3d12_descriptor_heap_create_descriptor_set(descriptor_heap, device, 0);
|
|
+ descriptor_set->vk_set = descriptor_heap->vk_descriptor_sets[0].vk_set;
|
|
+ descriptor_set->vk_type = device->vk_descriptor_heap_layouts[set].type;
|
|
+ return S_OK;
|
|
+ }
|
|
+
|
|
set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
set_desc.pNext = &set_size;
|
|
set_desc.descriptorPool = descriptor_heap->vk_descriptor_pool;
|
|
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
|
|
index 1457ddf9c7f..82782e7d5fc 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/state.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/state.c
|
|
@@ -848,7 +848,20 @@ static void vkd3d_descriptor_heap_binding_from_descriptor_range(const struct d3d
|
|
const struct vkd3d_device_descriptor_limits *descriptor_limits = &root_signature->device->vk_info.descriptor_limits;
|
|
unsigned int descriptor_set_size;
|
|
|
|
- switch (range->type)
|
|
+ if (root_signature->device->vk_info.EXT_mutable_descriptor_type)
|
|
+ {
|
|
+ if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
|
|
+ {
|
|
+ binding->set = VKD3D_SET_INDEX_SAMPLER;
|
|
+ descriptor_set_size = descriptor_limits->sampler_max_descriptors;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ binding->set = 0;
|
|
+ descriptor_set_size = descriptor_limits->sampled_image_max_descriptors;
|
|
+ }
|
|
+ }
|
|
+ else switch (range->type)
|
|
{
|
|
case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
|
|
binding->set = is_buffer ? VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER : VKD3D_SET_INDEX_SAMPLED_IMAGE;
|
|
@@ -1368,8 +1381,14 @@ static unsigned int d3d12_root_signature_copy_descriptor_set_layouts(const struc
|
|
|
|
if (device->use_vk_heaps)
|
|
{
|
|
+ VkDescriptorSetLayout mutable_layout = device->vk_descriptor_heap_layouts[0].vk_set_layout;
|
|
+
|
|
for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set)
|
|
- vk_set_layouts[i++] = device->vk_descriptor_heap_layouts[set].vk_set_layout;
|
|
+ {
|
|
+ VkDescriptorSetLayout vk_set_layout = device->vk_descriptor_heap_layouts[set].vk_set_layout;
|
|
+ /* All layouts must be valid, so if null, just set it to the mutable one. */
|
|
+ vk_set_layouts[i++] = vk_set_layout ? vk_set_layout : mutable_layout;
|
|
+ }
|
|
}
|
|
|
|
return i;
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
index bd7e7290d9e..9bf4575d46a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
@@ -133,6 +133,7 @@ struct vkd3d_vulkan_info
|
|
bool EXT_debug_marker;
|
|
bool EXT_depth_clip_enable;
|
|
bool EXT_descriptor_indexing;
|
|
+ bool EXT_mutable_descriptor_type;
|
|
bool EXT_robustness2;
|
|
bool EXT_shader_demote_to_helper_invocation;
|
|
bool EXT_shader_stencil_export;
|
|
@@ -248,7 +249,7 @@ static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
|
|
static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
|
|
{
|
|
if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
|
|
- ERR("Could not sleep on the condition variable, error %u.\n", GetLastError());
|
|
+ ERR("Could not sleep on the condition variable, error %lu.\n", GetLastError());
|
|
}
|
|
|
|
static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
|
|
--
|
|
2.43.0
|
|
|