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

820 lines
36 KiB
Diff

From aa331ed696532453589a4be7a098626756853e78 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Sat, 16 Dec 2023 09:37:22 +1100
Subject: [PATCH] Updated vkd3d to f96a791807701a4583e6c613c2f5bd47c00ea767.
---
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 8 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 10 +-
libs/vkd3d/libs/vkd3d-shader/ir.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 54 ++++-----
libs/vkd3d/libs/vkd3d-shader/tpf.c | 18 +--
.../libs/vkd3d-shader/vkd3d_shader_main.c | 29 +++--
.../libs/vkd3d-shader/vkd3d_shader_private.h | 10 +-
libs/vkd3d/libs/vkd3d/command.c | 4 +
libs/vkd3d/libs/vkd3d/device.c | 114 +++++++++++++++++-
libs/vkd3d/libs/vkd3d/resource.c | 19 ++-
libs/vkd3d/libs/vkd3d/state.c | 12 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 23 +++-
12 files changed, 220 insertions(+), 85 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index 86ddd1ffded..ac1c41f96e2 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -1381,10 +1381,10 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
&& param->reg.dimension == VSIR_DIMENSION_VEC4)
{
- unsigned int swizzle_x = vkd3d_swizzle_get_component(swizzle, 0);
- unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1);
- unsigned int swizzle_z = vkd3d_swizzle_get_component(swizzle, 2);
- unsigned int swizzle_w = vkd3d_swizzle_get_component(swizzle, 3);
+ unsigned int swizzle_x = vsir_swizzle_get_component(swizzle, 0);
+ unsigned int swizzle_y = vsir_swizzle_get_component(swizzle, 1);
+ unsigned int swizzle_z = vsir_swizzle_get_component(swizzle, 2);
+ unsigned int swizzle_w = vsir_swizzle_get_component(swizzle, 3);
static const char swizzle_chars[] = "xyzw";
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index c78ffebac69..d40ea4b5942 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1063,12 +1063,12 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1,
}
}
-static unsigned int mask_from_swizzle(unsigned int swizzle)
+static unsigned int mask_from_swizzle(uint32_t swizzle)
{
- return (1u << vkd3d_swizzle_get_component(swizzle, 0))
- | (1u << vkd3d_swizzle_get_component(swizzle, 1))
- | (1u << vkd3d_swizzle_get_component(swizzle, 2))
- | (1u << vkd3d_swizzle_get_component(swizzle, 3));
+ return (1u << vsir_swizzle_get_component(swizzle, 0))
+ | (1u << vsir_swizzle_get_component(swizzle, 1))
+ | (1u << vsir_swizzle_get_component(swizzle, 2))
+ | (1u << vsir_swizzle_get_component(swizzle, 3));
}
static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 1a569619707..a0b5ea27698 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -1002,7 +1002,7 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
id_idx = reg->idx_count - 1;
reg_idx = reg->idx[id_idx].offset;
- write_mask = VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(src_param->swizzle, 0);
+ write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0);
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
e = &signature->elements[element_idx];
@@ -1014,7 +1014,7 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
if ((component_idx = vsir_write_mask_get_component_idx(e->mask)))
{
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
- if (vkd3d_swizzle_get_component(src_param->swizzle, i))
+ if (vsir_swizzle_get_component(src_param->swizzle, i))
src_param->swizzle -= component_idx << VKD3D_SHADER_SWIZZLE_SHIFT(i);
}
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 5c537598e1e..f77bc25329d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -3595,17 +3595,17 @@ static bool vkd3d_swizzle_is_equal(unsigned int dst_write_mask,
return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask);
}
-static bool vkd3d_swizzle_is_scalar(unsigned int swizzle)
+static bool vkd3d_swizzle_is_scalar(uint32_t swizzle)
{
- unsigned int component_idx = vkd3d_swizzle_get_component(swizzle, 0);
- return vkd3d_swizzle_get_component(swizzle, 1) == component_idx
- && vkd3d_swizzle_get_component(swizzle, 2) == component_idx
- && vkd3d_swizzle_get_component(swizzle, 3) == component_idx;
+ unsigned int component_idx = vsir_swizzle_get_component(swizzle, 0);
+ return vsir_swizzle_get_component(swizzle, 1) == component_idx
+ && vsir_swizzle_get_component(swizzle, 2) == component_idx
+ && vsir_swizzle_get_component(swizzle, 3) == component_idx;
}
static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
uint32_t val_id, uint32_t val_write_mask, enum vkd3d_shader_component_type component_type,
- unsigned int swizzle, uint32_t write_mask)
+ uint32_t swizzle, uint32_t write_mask)
{
unsigned int i, component_idx, component_count, val_component_count;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -3623,7 +3623,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
if (component_count == 1)
{
component_idx = vsir_write_mask_get_component_idx(write_mask);
- component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
+ component_idx = vsir_swizzle_get_component(swizzle, component_idx);
component_idx -= vsir_write_mask_get_component_idx(val_write_mask);
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
}
@@ -3634,7 +3634,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
{
- assert(VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(swizzle, i) == val_write_mask);
+ assert(VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(swizzle, i) == val_write_mask);
components[component_idx++] = val_id;
}
}
@@ -3644,14 +3644,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- components[component_idx++] = vkd3d_swizzle_get_component(swizzle, i);
+ components[component_idx++] = vsir_swizzle_get_component(swizzle, i);
}
return vkd3d_spirv_build_op_vector_shuffle(builder,
type_id, val_id, val_id, components, component_count);
}
static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compiler,
- uint32_t vector1_id, uint32_t vector2_id, unsigned int swizzle, unsigned int write_mask,
+ uint32_t vector1_id, uint32_t vector2_id, uint32_t swizzle, uint32_t write_mask,
enum vkd3d_shader_component_type component_type, unsigned int component_count)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -3664,9 +3664,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil
for (i = 0; i < component_count; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- components[i] = vkd3d_swizzle_get_component(swizzle, i);
+ components[i] = vsir_swizzle_get_component(swizzle, i);
else
- components[i] = VKD3D_VEC4_SIZE + vkd3d_swizzle_get_component(swizzle, i);
+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i);
}
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
@@ -3675,7 +3675,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil
}
static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, DWORD swizzle, uint32_t write_mask)
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask)
{
unsigned int component_count = vsir_write_mask_component_count(write_mask);
uint32_t values[VKD3D_VEC4_SIZE] = {0};
@@ -3693,7 +3693,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- values[j++] = reg->u.immconst_uint[vkd3d_swizzle_get_component(swizzle, i)];
+ values[j++] = reg->u.immconst_uint[vsir_swizzle_get_component(swizzle, i)];
}
}
@@ -3702,7 +3702,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
}
static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, DWORD swizzle, uint32_t write_mask)
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask)
{
unsigned int component_count = vsir_write_mask_component_count(write_mask);
uint64_t values[VKD3D_DVEC2_SIZE] = {0};
@@ -3720,7 +3720,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi
for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component64(swizzle, i)];
+ values[j++] = reg->u.immconst_uint64[vsir_swizzle_get_component64(swizzle, i)];
}
}
@@ -3742,7 +3742,7 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, DWORD swizzle, uint32_t write_mask,
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask,
const struct vkd3d_shader_register_info *reg_info)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -3755,7 +3755,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
assert(vsir_write_mask_component_count(write_mask) == 1);
component_idx = vsir_write_mask_get_component_idx(write_mask);
- component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
+ component_idx = vsir_swizzle_get_component(swizzle, component_idx);
skipped_component_mask = ~reg_info->write_mask & ((VKD3DSP_WRITEMASK_0 << component_idx) - 1);
if (skipped_component_mask)
component_idx -= vsir_write_mask_component_count(skipped_component_mask);
@@ -3871,7 +3871,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co
static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, enum vkd3d_shader_component_type component_type,
- unsigned int swizzle)
+ uint32_t swizzle)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
enum vkd3d_shader_component_type reg_component_type;
@@ -3897,7 +3897,7 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler
}
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
- component_idx = vkd3d_swizzle_get_component(swizzle, 0);
+ component_idx = vsir_swizzle_get_component(swizzle, 0);
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
}
@@ -4233,7 +4233,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp
static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler,
const struct vkd3d_shader_dst_param *dst, uint32_t val_id,
- enum vkd3d_shader_component_type component_type, DWORD swizzle)
+ enum vkd3d_shader_component_type component_type, uint32_t swizzle)
{
unsigned int component_count = vsir_write_mask_component_count(dst->write_mask);
uint32_t component_ids[VKD3D_VEC4_SIZE];
@@ -4242,7 +4242,7 @@ static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler
component_idx = vsir_write_mask_get_component_idx(dst->write_mask);
for (i = 0; i < component_count; ++i)
{
- if (vkd3d_swizzle_get_component(swizzle, component_idx + i))
+ if (vsir_swizzle_get_component(swizzle, component_idx + i))
ERR("Invalid swizzle %#x for scalar value, write mask %#x.\n", swizzle, dst->write_mask);
component_ids[i] = val_id;
@@ -6940,7 +6940,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
for (i = 0; i < ARRAY_SIZE(components); ++i)
{
if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))
- components[i] = VKD3D_VEC4_SIZE + vkd3d_swizzle_get_component(src->swizzle, i);
+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(src->swizzle, i);
else
components[i] = i;
}
@@ -8414,7 +8414,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
}
else
{
- component_idx = vkd3d_swizzle_get_component(sampler->swizzle, 0);
+ component_idx = vsir_swizzle_get_component(sampler->swizzle, 0);
/* Nvidia driver requires signed integer type. */
component_id = spirv_compiler_get_constant(compiler,
VKD3D_SHADER_COMPONENT_INT, 1, &component_idx);
@@ -8492,7 +8492,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
continue;
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
coordinate_id = base_coordinate_id;
if (component_idx)
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
@@ -8524,7 +8524,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
continue;
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
coordinate_id = base_coordinate_id;
if (component_idx)
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
@@ -8568,7 +8568,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler,
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
continue;
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
coordinate_id = base_coordinate_id;
if (component_idx)
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 235e855223f..9508abfb868 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -1982,10 +1982,10 @@ static uint32_t swizzle_from_sm4(uint32_t s)
static uint32_t swizzle_to_sm4(uint32_t s)
{
uint32_t ret = 0;
- ret |= ((vkd3d_swizzle_get_component(s, 0)) & 0x3);
- ret |= ((vkd3d_swizzle_get_component(s, 1)) & 0x3) << 2;
- ret |= ((vkd3d_swizzle_get_component(s, 2)) & 0x3) << 4;
- ret |= ((vkd3d_swizzle_get_component(s, 3)) & 0x3) << 6;
+ ret |= ((vsir_swizzle_get_component(s, 0)) & 0x3);
+ ret |= ((vsir_swizzle_get_component(s, 1)) & 0x3) << 2;
+ ret |= ((vsir_swizzle_get_component(s, 2)) & 0x3) << 4;
+ ret |= ((vsir_swizzle_get_component(s, 3)) & 0x3) << 6;
return ret;
}
@@ -2014,12 +2014,12 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
|| priv->p.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
}
-static unsigned int mask_from_swizzle(unsigned int swizzle)
+static uint32_t mask_from_swizzle(uint32_t swizzle)
{
- return (1u << vkd3d_swizzle_get_component(swizzle, 0))
- | (1u << vkd3d_swizzle_get_component(swizzle, 1))
- | (1u << vkd3d_swizzle_get_component(swizzle, 2))
- | (1u << vkd3d_swizzle_get_component(swizzle, 3));
+ return (1u << vsir_swizzle_get_component(swizzle, 0))
+ | (1u << vsir_swizzle_get_component(swizzle, 1))
+ | (1u << vsir_swizzle_get_component(swizzle, 2))
+ | (1u << vsir_swizzle_get_component(swizzle, 3));
}
static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_parser *priv,
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index 4fd5c9bd034..caf8a6a4a3e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1073,6 +1073,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
vkd3d_shader_scan_sampler_declaration(context, instruction);
break;
case VKD3DSIH_DCL:
+ if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE)
+ break;
+
if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
{
vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic);
@@ -1540,9 +1543,6 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
scan_info = *compile_info;
- if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
- return ret;
-
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
@@ -1550,6 +1550,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
break;
case VKD3D_SHADER_TARGET_GLSL:
+ if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
+ return ret;
if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->shader_version,
message_context, &parser->location)))
{
@@ -1560,19 +1562,22 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
vkd3d_glsl_generator_destroy(glsl_generator);
+ vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;
case VKD3D_SHADER_TARGET_SPIRV_BINARY:
case VKD3D_SHADER_TARGET_SPIRV_TEXT:
+ if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
+ return ret;
ret = spirv_compile(parser, &scan_descriptor_info, compile_info, out, message_context);
+ vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;
default:
/* Validation should prevent us from reaching this. */
- assert(0);
+ vkd3d_unreachable();
}
- vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
return ret;
}
@@ -1621,14 +1626,10 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
return ret;
}
- if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
- {
- ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_D3D);
- vkd3d_shader_parser_destroy(parser);
- return ret;
- }
+ ret = vkd3d_shader_parser_compile(parser, compile_info, out, message_context);
- return VKD3D_ERROR;
+ vkd3d_shader_parser_destroy(parser);
+ return ret;
}
static int compile_dxbc_dxil(const struct vkd3d_shader_compile_info *compile_info,
@@ -1906,6 +1907,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
static const enum vkd3d_shader_target_type d3dbc_types[] =
{
+ VKD3D_SHADER_TARGET_SPIRV_BINARY,
+#ifdef HAVE_SPIRV_TOOLS
+ VKD3D_SHADER_TARGET_SPIRV_TEXT,
+#endif
VKD3D_SHADER_TARGET_D3D_ASM,
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 6fa57a111bb..274faf296e8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1557,19 +1557,17 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64)
return write_mask32 | (write_mask32 << 1);
}
-static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
- unsigned int idx)
+static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
{
return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
}
-static inline unsigned int vkd3d_swizzle_get_component64(DWORD swizzle,
- unsigned int idx)
+static inline unsigned int vsir_swizzle_get_component64(uint32_t swizzle, unsigned int idx)
{
return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u;
}
-static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned int write_mask)
+static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask)
{
unsigned int i, compacted_swizzle = 0;
@@ -1578,7 +1576,7 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
{
compacted_swizzle <<= VKD3D_SHADER_SWIZZLE_SHIFT(1);
- compacted_swizzle |= vkd3d_swizzle_get_component(swizzle, i);
+ compacted_swizzle |= vsir_swizzle_get_component(swizzle, i);
}
}
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index 15c8317b191..549f6a45ffb 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -2644,6 +2644,8 @@ static bool d3d12_command_list_update_compute_pipeline(struct d3d12_command_list
{
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
+ vkd3d_cond_signal(&list->device->worker_cond);
+
if (list->current_pipeline != VK_NULL_HANDLE)
return true;
@@ -2665,6 +2667,8 @@ static bool d3d12_command_list_update_graphics_pipeline(struct d3d12_command_lis
VkRenderPass vk_render_pass;
VkPipeline vk_pipeline;
+ vkd3d_cond_signal(&list->device->worker_cond);
+
if (list->current_pipeline != VK_NULL_HANDLE)
return true;
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 5c801ca4676..69a46e9188a 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -2056,7 +2056,7 @@ static HRESULT d3d12_device_init_pipeline_cache(struct d3d12_device *device)
VkPipelineCacheCreateInfo cache_info;
VkResult vr;
- vkd3d_mutex_init(&device->mutex);
+ vkd3d_mutex_init(&device->pipeline_cache_mutex);
cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
cache_info.pNext = NULL;
@@ -2080,7 +2080,7 @@ static void d3d12_device_destroy_pipeline_cache(struct d3d12_device *device)
if (device->vk_pipeline_cache)
VK_CALL(vkDestroyPipelineCache(device->vk_device, device->vk_pipeline_cache, NULL));
- vkd3d_mutex_destroy(&device->mutex);
+ vkd3d_mutex_destroy(&device->pipeline_cache_mutex);
}
#define VKD3D_VA_FALLBACK_BASE 0x8000000000000000ull
@@ -2495,6 +2495,28 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface)
return refcount;
}
+static HRESULT device_worker_stop(struct d3d12_device *device)
+{
+ HRESULT hr;
+
+ TRACE("device %p.\n", device);
+
+ vkd3d_mutex_lock(&device->worker_mutex);
+
+ device->worker_should_exit = true;
+ vkd3d_cond_signal(&device->worker_cond);
+
+ vkd3d_mutex_unlock(&device->worker_mutex);
+
+ if (FAILED(hr = vkd3d_join_thread(device->vkd3d_instance, &device->worker_thread)))
+ return hr;
+
+ vkd3d_mutex_destroy(&device->worker_mutex);
+ vkd3d_cond_destroy(&device->worker_cond);
+
+ return S_OK;
+}
+
static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
@@ -2520,6 +2542,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
d3d12_device_destroy_vkd3d_queues(device);
vkd3d_desc_object_cache_cleanup(&device->view_desc_cache);
vkd3d_desc_object_cache_cleanup(&device->cbuffer_desc_cache);
+ if (device->use_vk_heaps)
+ device_worker_stop(device);
+ vkd3d_free(device->heaps);
VK_CALL(vkDestroyDevice(device->vk_device, NULL));
if (device->parent)
IUnknown_Release(device->parent);
@@ -4251,6 +4276,40 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface)
return impl_from_ID3D12Device5(iface);
}
+static void *device_worker_main(void *arg)
+{
+ struct d3d12_descriptor_heap *heap;
+ struct d3d12_device *device = arg;
+ size_t i;
+
+ vkd3d_set_thread_name("device_worker");
+
+ vkd3d_mutex_lock(&device->worker_mutex);
+
+ while (!device->worker_should_exit)
+ {
+ for (i = 0; i < device->heap_count; ++i)
+ {
+ /* Descriptor updates are not written to Vulkan descriptor sets until a command list
+ * is submitted to a queue, while the client is free to write d3d12 descriptors earlier,
+ * from any thread. This causes a delay right before command list execution, so
+ * handling these updates in a worker thread can speed up execution significantly. */
+ heap = device->heaps[i];
+ if (heap->dirty_list_head == UINT_MAX)
+ continue;
+ vkd3d_mutex_lock(&heap->vk_sets_mutex);
+ d3d12_desc_flush_vk_heap_updates_locked(heap, device);
+ vkd3d_mutex_unlock(&heap->vk_sets_mutex);
+ }
+
+ vkd3d_cond_wait(&device->worker_cond, &device->worker_mutex);
+ }
+
+ vkd3d_mutex_unlock(&device->worker_mutex);
+
+ return NULL;
+}
+
static HRESULT d3d12_device_init(struct d3d12_device *device,
struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
{
@@ -4270,6 +4329,14 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
device->vk_device = VK_NULL_HANDLE;
+ device->heaps = NULL;
+ device->heap_capacity = 0;
+ device->heap_count = 0;
+ memset(&device->worker_thread, 0, sizeof(device->worker_thread));
+ device->worker_should_exit = false;
+ vkd3d_mutex_init(&device->worker_mutex);
+ vkd3d_cond_init(&device->worker_cond);
+
if (FAILED(hr = vkd3d_create_vk_device(device, create_info)))
goto out_free_instance;
@@ -4291,6 +4358,13 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
if (FAILED(hr = vkd3d_vk_descriptor_heap_layouts_init(device)))
goto out_cleanup_uav_clear_state;
+ if (device->use_vk_heaps && FAILED(hr = vkd3d_create_thread(device->vkd3d_instance,
+ device_worker_main, device, &device->worker_thread)))
+ {
+ WARN("Failed to create worker thread, hr %#x.\n", hr);
+ goto out_cleanup_descriptor_heap_layouts;
+ }
+
vkd3d_render_pass_cache_init(&device->render_pass_cache);
vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
vkd3d_time_domains_init(device);
@@ -4308,6 +4382,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
return S_OK;
+out_cleanup_descriptor_heap_layouts:
+ vkd3d_vk_descriptor_heap_layouts_cleanup(device);
out_cleanup_uav_clear_state:
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
out_destroy_null_resources:
@@ -4361,6 +4437,40 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
device->removed_reason = reason;
}
+HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap)
+{
+ vkd3d_mutex_lock(&device->worker_mutex);
+
+ if (!vkd3d_array_reserve((void **)&device->heaps, &device->heap_capacity, device->heap_count + 1,
+ sizeof(*device->heaps)))
+ {
+ vkd3d_mutex_unlock(&device->worker_mutex);
+ return E_OUTOFMEMORY;
+ }
+ device->heaps[device->heap_count++] = heap;
+
+ vkd3d_mutex_unlock(&device->worker_mutex);
+
+ return S_OK;
+}
+
+void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap)
+{
+ size_t i;
+
+ vkd3d_mutex_lock(&device->worker_mutex);
+
+ for (i = 0; i < device->heap_count; ++i)
+ {
+ if (device->heaps[i] == heap)
+ {
+ device->heaps[i] = device->heaps[--device->heap_count];
+ break;
+ }
+ }
+
+ vkd3d_mutex_unlock(&device->worker_mutex);
+}
#ifdef _WIN32
struct thread_data
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index abbdfbe2015..609c67102a6 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -2632,20 +2632,18 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
for (; i != UINT_MAX; i = next)
{
src = &descriptors[i];
- next = (int)src->next >> 1;
+ next = vkd3d_atomic_exchange(&src->next, 0);
+ next = (int)next >> 1;
+ /* A race exists here between updating src->next and getting the current object. The best
+ * we can do is get the object last, which may result in a harmless rewrite later. */
u.object = d3d12_desc_get_object_ref(src, device);
if (!u.object)
- {
- vkd3d_atomic_exchange(&src->next, 0);
continue;
- }
writes.held_refs[writes.held_ref_count++] = u.object;
d3d12_desc_write_vk_heap(descriptor_heap, i, &writes, u.object, device);
-
- vkd3d_atomic_exchange(&src->next, 0);
}
/* Avoid thunk calls wherever possible. */
@@ -3997,6 +3995,9 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
{
struct d3d12_desc *descriptors = (struct d3d12_desc *)heap->descriptors;
+ if (heap->use_vk_heaps)
+ d3d12_device_remove_descriptor_heap(device, heap);
+
for (i = 0; i < heap->desc.NumDescriptors; ++i)
{
d3d12_desc_destroy(&descriptors[i], device);
@@ -4320,6 +4321,12 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
dst[i].next = 0;
}
object->dirty_list_head = UINT_MAX;
+
+ if (object->use_vk_heaps && FAILED(hr = d3d12_device_add_descriptor_heap(device, object)))
+ {
+ vkd3d_free(object);
+ return hr;
+ }
}
else
{
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index 9a039452c99..626d6d62b3c 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -1691,7 +1691,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
HRESULT hr = S_OK;
unsigned int i;
- vkd3d_mutex_lock(&device->mutex);
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
for (i = 0; i < cache->render_pass_count; ++i)
{
@@ -1708,7 +1708,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
if (!found)
hr = vkd3d_render_pass_cache_create_pass_locked(cache, device, key, vk_render_pass);
- vkd3d_mutex_unlock(&device->mutex);
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return hr;
}
@@ -3615,7 +3615,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
*vk_render_pass = VK_NULL_HANDLE;
- vkd3d_mutex_lock(&device->mutex);
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
@@ -3627,7 +3627,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
}
}
- vkd3d_mutex_unlock(&device->mutex);
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return vk_pipeline;
}
@@ -3646,7 +3646,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
compiled_pipeline->vk_pipeline = vk_pipeline;
compiled_pipeline->vk_render_pass = vk_render_pass;
- vkd3d_mutex_lock(&device->mutex);
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
@@ -3661,7 +3661,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
if (compiled_pipeline)
list_add_tail(&graphics->compiled_pipelines, &compiled_pipeline->entry);
- vkd3d_mutex_unlock(&device->mutex);
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return compiled_pipeline;
}
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index f06f564d6ea..bd7e7290d9e 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -1757,9 +1757,23 @@ struct d3d12_device
struct vkd3d_gpu_va_allocator gpu_va_allocator;
- struct vkd3d_mutex mutex;
struct vkd3d_desc_object_cache view_desc_cache;
struct vkd3d_desc_object_cache cbuffer_desc_cache;
+
+ VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
+ unsigned int vk_pool_count;
+ struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
+ bool use_vk_heaps;
+
+ struct d3d12_descriptor_heap **heaps;
+ size_t heap_capacity;
+ size_t heap_count;
+ union vkd3d_thread_handle worker_thread;
+ struct vkd3d_mutex worker_mutex;
+ struct vkd3d_cond worker_cond;
+ bool worker_should_exit;
+
+ struct vkd3d_mutex pipeline_cache_mutex;
struct vkd3d_render_pass_cache render_pass_cache;
VkPipelineCache vk_pipeline_cache;
@@ -1799,11 +1813,6 @@ struct d3d12_device
const struct vkd3d_format_compatibility_list *format_compatibility_lists;
struct vkd3d_null_resources null_resources;
struct vkd3d_uav_clear_state uav_clear_state;
-
- VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
- unsigned int vk_pool_count;
- struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
- bool use_vk_heaps;
};
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
@@ -1813,6 +1822,8 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent);
void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
const char *message, ...) VKD3D_PRINTF_FUNC(3, 4);
struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface);
+HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
+void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
{
--
2.43.0