[PATCH vkd3d 4/6] vkd3d-shader: Decorate SPIR-V for nonuniform access where flagged in dxbc.
Conor McCarthy
cmccarthy at codeweavers.com
Wed May 26 03:10:53 CDT 2021
From: Philip Rebohle <philip.rebohle at tu-dortmund.de>
From: Hans-Kristian Arntzen <post at arntzen-software.no>
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
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
More information about the wine-devel
mailing list