wine-staging/patches/vkd3d-latest/0010-Updated-vkd3d-to-3e2ace8d33a203bf0c8d6a7bf140ef9a9a0.patch
2024-01-13 12:21:42 +11:00

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