vkd3d-shader: Emit typed format for UAVs which use atomics.

Mesa will assert if not, and the format must be known here.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2020-12-04 11:13:36 +01:00
parent c4fbe47106
commit e6961afca6
3 changed files with 34 additions and 2 deletions

View File

@ -556,6 +556,7 @@ enum vkd3d_shader_uav_flag
{
VKD3D_SHADER_UAV_FLAG_READ_ACCESS = 0x00000001,
VKD3D_SHADER_UAV_FLAG_ATOMIC_COUNTER = 0x00000002,
VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS = 0x00000004,
};
struct vkd3d_shader_scan_info

View File

@ -6096,6 +6096,7 @@ static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler
uint32_t sampled_type_id;
unsigned int uav_flags;
SpvImageFormat format;
bool uav_atomic;
bool uav_read;
bool is_uav;
@ -6104,7 +6105,8 @@ static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler
{
uav_flags = vkd3d_shader_scan_get_register_flags(scan_info, VKD3DSPR_UAV, reg->idx[0].offset);
uav_read = (uav_flags & VKD3D_SHADER_UAV_FLAG_READ_ACCESS) != 0;
if (raw_structured || (uav_read && !vkd3d_dxbc_compiler_supports_typed_uav_load_without_format(compiler)))
uav_atomic = (uav_flags & VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS) != 0;
if (raw_structured || uav_atomic || (uav_read && !vkd3d_dxbc_compiler_supports_typed_uav_load_without_format(compiler)))
format = image_format_for_image_read(data_type);
}
@ -6173,14 +6175,17 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
{
SpvImageFormat format = SpvImageFormatUnknown;
unsigned int flags = 0;
bool uav_atomic;
bool uav_read;
if (is_uav)
{
uav_read = (uav_flags & VKD3D_SHADER_UAV_FLAG_READ_ACCESS) != 0;
uav_atomic = (uav_flags & VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS) != 0;
if (structure_stride || raw || uav_read)
{
if ((uav_read && !structure_stride && !raw) &&
if ((uav_read && !structure_stride && !raw && !uav_atomic) &&
vkd3d_dxbc_compiler_supports_typed_uav_load_without_format(compiler))
{
format = SpvImageFormatUnknown;

View File

@ -366,6 +366,14 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr
|| ((handler_idx == VKD3DSIH_LD_STRUCTURED || handler_idx == VKD3DSIH_LD_STRUCTURED_FEEDBACK) && instruction->src[2].reg.type == VKD3DSPR_UAV);
}
static bool vkd3d_shader_instruction_is_uav_atomic(const struct vkd3d_shader_instruction *instruction)
{
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
return ((VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR) ||
(VKD3DSIH_IMM_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR)) &&
handler_idx != VKD3DSIH_IMM_ATOMIC_CONSUME;
}
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *scan_info,
const struct vkd3d_shader_register *reg)
{
@ -373,6 +381,13 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *sca
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_READ_ACCESS);
}
static void vkd3d_shader_scan_record_uav_atomic(struct vkd3d_shader_scan_info *scan_info,
const struct vkd3d_shader_register *reg)
{
vkd3d_shader_scan_set_register_flags(scan_info, VKD3DSPR_UAV,
reg->idx[0].offset, VKD3D_SHADER_UAV_FLAG_ATOMIC_ACCESS);
}
static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction)
{
enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
@ -400,6 +415,7 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in
const struct vkd3d_shader_instruction *instruction)
{
unsigned int i;
bool is_atomic;
switch (instruction->handler_idx)
{
@ -412,15 +428,25 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in
if (vkd3d_shader_instruction_is_uav_read(instruction))
{
is_atomic = vkd3d_shader_instruction_is_uav_atomic(instruction);
for (i = 0; i < instruction->dst_count; ++i)
{
if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
{
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->dst[i].reg);
if (is_atomic)
vkd3d_shader_scan_record_uav_atomic(scan_info, &instruction->dst[i].reg);
}
}
for (i = 0; i < instruction->src_count; ++i)
{
if (instruction->src[i].reg.type == VKD3DSPR_UAV)
{
vkd3d_shader_scan_record_uav_read(scan_info, &instruction->src[i].reg);
if (is_atomic)
vkd3d_shader_scan_record_uav_atomic(scan_info, &instruction->src[i].reg);
}
}
}