From 688a47c5490ad3b2459b4823ed8ce98fb3b2ddd6 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes 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