-- v4: vkd3d-shader/spirv: Handle thread group UAV barriers.
From: Conor McCarthy cmccarthy@codeweavers.com
The flags start at bit 16 in the token. --- libs/vkd3d-shader/tpf.c | 4 ++-- libs/vkd3d-shader/vkd3d_shader_private.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 7949be15..9142ed98 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -95,8 +95,8 @@ STATIC_ASSERT(SM4_MAX_SRC_COUNT <= SPIRV_MAX_SRC_COUNT); #define VKD3D_SM5_FP_ARRAY_SIZE_SHIFT 16 #define VKD3D_SM5_FP_TABLE_COUNT_MASK 0xffffu
-#define VKD3D_SM5_UAV_FLAGS_SHIFT 15 -#define VKD3D_SM5_UAV_FLAGS_MASK (0x1ffu << VKD3D_SM5_UAV_FLAGS_SHIFT) +#define VKD3D_SM5_UAV_FLAGS_SHIFT 16 +#define VKD3D_SM5_UAV_FLAGS_MASK (0xffu << VKD3D_SM5_UAV_FLAGS_SHIFT)
#define VKD3D_SM5_SYNC_FLAGS_SHIFT 11 #define VKD3D_SM5_SYNC_FLAGS_MASK (0xffu << VKD3D_SM5_SYNC_FLAGS_SHIFT) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 84614a4e..1c9b6e1e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -626,8 +626,8 @@ enum vkd3d_shader_sync_flags
enum vkd3d_shader_uav_flags { - VKD3DSUF_GLOBALLY_COHERENT = 0x2, - VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x100, + VKD3DSUF_GLOBALLY_COHERENT = 0x1, + VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x80, };
enum vkd3d_tessellator_domain
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 5 +++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index d72402eb..df09445f 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -477,6 +477,11 @@ static void shader_dump_uav_flags(struct vkd3d_d3d_asm_compiler *compiler, uint3 vkd3d_string_buffer_printf(&compiler->buffer, "_opc"); uav_flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; } + if (uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW) + { + vkd3d_string_buffer_printf(&compiler->buffer, "_rov"); + uav_flags &= ~VKD3DSUF_RASTERISER_ORDERED_VIEW; + }
if (uav_flags) vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", uav_flags); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1c9b6e1e..a5fc5f56 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -627,6 +627,7 @@ enum vkd3d_shader_sync_flags enum vkd3d_shader_uav_flags { VKD3DSUF_GLOBALLY_COHERENT = 0x1, + VKD3DSUF_RASTERISER_ORDERED_VIEW = 0x2, VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x80, };
From: Conor McCarthy cmccarthy@codeweavers.com
--- include/vkd3d_shader.h | 3 +++ libs/vkd3d-shader/vkd3d_shader_main.c | 26 ++++++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index cfe54dbf..ece22f2a 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -1341,6 +1341,9 @@ enum vkd3d_shader_descriptor_info_flag VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS = 0x00000008, /** The descriptor is a raw (byte-addressed) buffer. \since 1.9 */ VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER = 0x00000010, + /** The descriptor is a UAV resource, which is globally coherent. + * \since 1.9 */ + VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_GLOBALLY_COHERENT = 0x00000020,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_INFO_FLAG), }; diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 38f90966..46a414a4 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -819,25 +819,39 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, - unsigned int sample_count, unsigned int structure_stride, bool raw) + unsigned int sample_count, unsigned int structure_stride, bool raw, unsigned int flags) { struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_descriptor_type type; + unsigned int info_flags;
if (!context->scan_descriptor_info) return;
+ info_flags = raw ? VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER : 0; + if (resource->reg.reg.type == VKD3DSPR_UAV) + { + if (flags & VKD3DSUF_GLOBALLY_COHERENT) + info_flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_GLOBALLY_COHERENT; + /* We don't distinguish between APPEND and COUNTER UAVs. */ + flags &= ~(VKD3DSUF_ORDER_PRESERVING_COUNTER | VKD3DSUF_GLOBALLY_COHERENT); + if (flags) + FIXME("Unhandled UAV flags %#x.\n", flags); type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; + } else + { + if (flags) + FIXME("Unhandled SRV flags %#x.\n", flags); type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; + } if (!(d = vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, &resource->range, resource_type, resource_data_type))) return; d->sample_count = sample_count; d->structure_stride = structure_stride; - if (raw) - d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; + d->flags = info_flags; }
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context, @@ -896,7 +910,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca }
vkd3d_shader_scan_resource_declaration(context, &semantic->resource, - semantic->resource_type, resource_data_type, semantic->sample_count, 0, false); + semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags); }
static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context, @@ -930,13 +944,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte case VKD3DSIH_DCL_RESOURCE_RAW: case VKD3DSIH_DCL_UAV_RAW: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true); + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags); break; case VKD3DSIH_DCL_RESOURCE_STRUCTURED: case VKD3DSIH_DCL_UAV_STRUCTURED: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, - instruction->declaration.structured_resource.byte_stride, false); + instruction->declaration.structured_resource.byte_stride, false, instruction->flags); break; case VKD3DSIH_IF: cf_info = vkd3d_shader_scan_push_cf_info(context);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 9b308453..41104012 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5936,6 +5936,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0);
+ if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_GLOBALLY_COHERENT) + vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); + if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER) { assert(structure_stride); /* counters are valid only for structured buffers */
From: Conor McCarthy cmccarthy@codeweavers.com
The UniformMemory semantic applies the constraints to Uniform storage class memory, which matches how UAV variables are declared. --- libs/vkd3d-shader/spirv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 41104012..6edcfb2b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9074,7 +9074,7 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, if (flags & VKD3DSSF_GLOBAL_UAV) { memory_scope = SpvScopeDevice; - memory_semantics |= SpvMemorySemanticsImageMemoryMask; + memory_semantics |= SpvMemorySemanticsUniformMemoryMask | SpvMemorySemanticsImageMemoryMask; flags &= ~VKD3DSSF_GLOBAL_UAV; }
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 5 +++++ libs/vkd3d-shader/spirv.c | 13 ++++++++++--- libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index df09445f..c5eeaa41 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -433,6 +433,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal"); sync_flags &= ~VKD3DSSF_GLOBAL_UAV; } + if (sync_flags & VKD3DSSF_THREAD_GROUP_UAV) + { + vkd3d_string_buffer_printf(&compiler->buffer, "_ugroup"); + sync_flags &= ~VKD3DSSF_THREAD_GROUP_UAV; + } if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY) { vkd3d_string_buffer_printf(&compiler->buffer, "_g"); diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 6edcfb2b..3f96e292 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9053,6 +9053,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { + const enum vkd3d_shader_sync_flags uav_flags = VKD3DSSF_THREAD_GROUP_UAV | VKD3DSSF_GLOBAL_UAV; unsigned int memory_semantics = SpvMemorySemanticsAcquireReleaseMask; unsigned int flags = instruction->flags; SpvScope execution_scope = SpvScopeMax; @@ -9071,11 +9072,17 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, flags &= ~VKD3DSSF_THREAD_GROUP; }
- if (flags & VKD3DSSF_GLOBAL_UAV) + if (flags & uav_flags) { - memory_scope = SpvScopeDevice; + if ((flags & uav_flags) == uav_flags) + { + WARN("Invalid UAV sync flag combination; assuming global.\n"); + spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS, + "The flags for a UAV sync instruction are contradictory; assuming global sync."); + } + memory_scope = (flags & VKD3DSSF_GLOBAL_UAV) ? SpvScopeDevice : SpvScopeWorkgroup; memory_semantics |= SpvMemorySemanticsUniformMemoryMask | SpvMemorySemanticsImageMemoryMask; - flags &= ~VKD3DSSF_GLOBAL_UAV; + flags &= ~uav_flags; }
if (flags) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index a5fc5f56..ea3db026 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -94,6 +94,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300, + VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS = 2301,
VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000, VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001, @@ -621,6 +622,7 @@ enum vkd3d_shader_sync_flags { VKD3DSSF_THREAD_GROUP = 0x1, VKD3DSSF_GROUP_SHARED_MEMORY = 0x2, + VKD3DSSF_THREAD_GROUP_UAV = 0x4, VKD3DSSF_GLOBAL_UAV = 0x8, };
On Wed Aug 30 13:46:31 2023 +0000, Conor McCarthy wrote:
changed this line in [version 4 of the diff](/wine/vkd3d/-/merge_requests/306/diffs?diff_id=65720&start_sha=5195271e79db6cd7867bc23a1c17b1f1dcb9bd46#282778267e3fda4be8fe588f5d16e9ec352745de_9074_9075)
It is just a nitpick but I find `(flags & uav_flags) == uav_flags` harder to read than `(flags & VKD3DSSF_THREAD_GROUP_UAV) && (flags & VKD3DSSF_GLOBAL_UAV)`.
I don't have enough knowledge of SPIR-V to approve the whole series but 1/5 and 2/5 seem correct to me.