vkd3d-shader: Introduce DESCRIPTOR_INFO_FLAG_UAV_ATOMICS and always declare UAV images with known type for atomic ops.

Atomic ops on images with Unknown type will cause SPIR-V validation failure,
and assertion failure in Mesa debug builds. D3D12 allows atomics on typed
buffers, and this requires a distinction to be made between UAV reads and
atomic ops.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53874
This commit is contained in:
Conor McCarthy 2022-11-18 13:44:05 +10:00 committed by Alexandre Julliard
parent fc652d2b27
commit 1b11b57652
Notes: Alexandre Julliard 2022-11-21 22:45:52 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/49
3 changed files with 34 additions and 2 deletions

View File

@ -1263,6 +1263,9 @@ enum vkd3d_shader_descriptor_info_flag
VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ = 0x00000002,
/** The descriptor is a comparison sampler. */
VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE = 0x00000004,
/** The descriptor is a UAV resource, on which the shader performs
* atomic ops. \since 1.6 */
VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS = 0x00000008,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_INFO_FLAG),
};

View File

@ -5864,9 +5864,9 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_descriptor_info *d;
bool uav_read, uav_atomics;
uint32_t sampled_type_id;
SpvImageFormat format;
bool uav_read;
format = SpvImageFormatUnknown;
if (reg->type == VKD3DSPR_UAV)
@ -5874,7 +5874,8 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler
d = spirv_compiler_get_descriptor_info(compiler,
VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range);
uav_read = !!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ);
if (raw_structured || (uav_read && !compiler->uav_read_without_format))
uav_atomics = !!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS);
if (raw_structured || uav_atomics || (uav_read && !compiler->uav_read_without_format))
format = image_format_for_image_read(data_type);
else if (uav_read)
vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat);

View File

@ -692,6 +692,25 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER;
}
static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_instruction *instruction)
{
enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
return (VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR)
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR);
}
static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_register *reg)
{
struct vkd3d_shader_descriptor_info *d;
if (!context->scan_descriptor_info)
return;
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS;
}
static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range,
enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type,
@ -1019,6 +1038,15 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
if (vkd3d_shader_instruction_is_uav_counter(instruction))
vkd3d_shader_scan_record_uav_counter(context, &instruction->src[0].reg);
if (vkd3d_shader_instruction_is_uav_atomic_op(instruction))
{
for (i = 0; i < instruction->dst_count; ++i)
{
if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
vkd3d_shader_scan_record_uav_atomic_op(context, &instruction->dst[i].reg);
}
}
++context->location.line;
return VKD3D_OK;
}