From: Conor McCarthy Subject: [PATCH vkd3d 4/6] vkd3d-shader: Decorate SPIR-V for nonuniform access where flagged in dxbc. Message-Id: <20210526081055.19432-4-cmccarthy@codeweavers.com> Date: Wed, 26 May 2021 18:10:53 +1000 In-Reply-To: <20210526081055.19432-1-cmccarthy@codeweavers.com> References: <20210526081055.19432-1-cmccarthy@codeweavers.com> From: Philip Rebohle From: Hans-Kristian Arntzen Signed-off-by: Conor McCarthy --- libs/vkd3d-shader/dxbc.c | 6 ++++ libs/vkd3d-shader/spirv.c | 39 ++++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 7 +++++ 3 files changed, 52 insertions(+) diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 60610f44..644ee0d6 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -366,6 +366,7 @@ enum vkd3d_sm4_register_modifier VKD3D_SM4_REGISTER_MODIFIER_NEGATE = 0x40, VKD3D_SM4_REGISTER_MODIFIER_ABS = 0x80, VKD3D_SM4_REGISTER_MODIFIER_ABS_NEGATE = 0xc0, + VKD3D_SM4_REGISTER_MODIFIER_NONUNIFORM = 0x20000, }; enum vkd3d_sm4_output_primitive_type @@ -1567,6 +1568,7 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr { param->type = register_type_table[register_type]; } + param->modifier = VKD3DSPRM_NONE; param->data_type = data_type; if (token & VKD3D_SM4_REGISTER_MODIFIER) @@ -1601,6 +1603,10 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr *modifier = VKD3DSPSM_NONE; break; } + + if (m & VKD3D_SM4_REGISTER_MODIFIER_NONUNIFORM) + param->modifier = VKD3DSPRM_NONUNIFORM; + } else { diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index b99615f4..f8c93a34 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -337,6 +337,7 @@ struct vkd3d_spirv_builder uint64_t capability_draw_parameters : 1; uint64_t capability_demote_to_helper_invocation : 1; uint64_t capability_descriptor_indexing : 1; + uint64_t capability_non_uniform : 1; uint32_t ext_instr_set_glsl_450; uint32_t invocation_count; SpvExecutionModel execution_model; @@ -387,6 +388,10 @@ static void vkd3d_spirv_enable_capability(struct vkd3d_spirv_builder *builder, { builder->capability_demote_to_helper_invocation = 1; } + else if (cap == SpvCapabilityShaderNonUniformEXT) + { + builder->capability_non_uniform = 1; + } else { FIXME("Unhandled capability %#x.\n", cap); @@ -1809,6 +1814,8 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder, vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDrawParameters); if (builder->capability_demote_to_helper_invocation) vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDemoteToHelperInvocationEXT); + if (builder->capability_non_uniform) + vkd3d_spirv_build_op_capability(&stream, SpvCapabilityShaderNonUniformEXT); /* extensions */ if (builder->capability_draw_parameters) @@ -2670,6 +2677,15 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxb vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding); } +static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler *compiler, + uint32_t expression_id) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + + vkd3d_spirv_enable_capability(builder, SpvCapabilityShaderNonUniformEXT); + vkd3d_spirv_build_op_decorate(builder, expression_id, SpvDecorationNonUniformEXT, NULL, 0); +} + static void vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_symbol *symbol) { @@ -3253,6 +3269,10 @@ static uint32_t vkd3d_dxbc_compiler_get_resource_index(struct vkd3d_dxbc_compile index_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, reg->idx[0].offset + binding_offset); } + /* AMD drivers rely on the index being marked as nonuniform */ + if (reg->modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, index_id); + return index_id; } @@ -3327,6 +3347,8 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, register_info->id, indexes, index_count); + if (reg->modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, register_info->id); } } @@ -7908,6 +7930,8 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil { image->image_id = vkd3d_spirv_build_op_load(builder, image->image_type_id, image->id, SpvMemoryAccessMaskNone); + if (resource_reg->modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->image_id); } else { @@ -7939,9 +7963,14 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil sampler_id = vkd3d_spirv_build_op_load(builder, vkd3d_spirv_get_op_type_sampler(builder), sampler_var_id, SpvMemoryAccessMaskNone); + if (sampler_reg->modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, sampler_id); + sampled_image_type_id = vkd3d_spirv_get_op_type_sampled_image(builder, image->image_type_id); image->sampled_image_id = vkd3d_spirv_build_op_sampled_image(builder, sampled_image_type_id, image->image_id, sampler_id); + if (resource_reg->modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->sampled_image_id); } else { @@ -8293,6 +8322,9 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); constituents[j++] = vkd3d_spirv_build_op_load(builder, texel_type_id, ptr_id, SpvMemoryAccessMaskNone); + + if (resource->reg.modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, ptr_id); } } else @@ -8435,6 +8467,9 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_ ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); vkd3d_spirv_build_op_store(builder, ptr_id, data_id, SpvMemoryAccessMaskNone); + + if (dst->reg.modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, ptr_id); } } else @@ -8811,6 +8846,8 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, ptr_type_id, image.id, coordinate_id, sample_id); } + if (resource->reg.modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, pointer_id); } val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); @@ -8859,6 +8896,8 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); + if (src->reg.modifier == VKD3DSPRM_NONUNIFORM) + vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image.id); write_mask = VKD3DSP_WRITEMASK_0; } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 54930fa2..453d3fb7 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -436,6 +436,12 @@ enum vkd3d_immconst_type VKD3D_IMMCONST_VEC4, }; +enum vkd3d_shader_register_modifier +{ + VKD3DSPRM_NONE = 0, + VKD3DSPRM_NONUNIFORM = 1, +}; + enum vkd3d_shader_src_modifier { VKD3DSPSM_NONE = 0, @@ -604,6 +610,7 @@ struct vkd3d_shader_register_index struct vkd3d_shader_register { enum vkd3d_shader_register_type type; + enum vkd3d_shader_register_modifier modifier; enum vkd3d_data_type data_type; struct vkd3d_shader_register_index idx[3]; enum vkd3d_immconst_type immconst_type; -- 2.31.1