From: Francisco Casas franciscojacb@gmail.com
Some dxbc instructions require swizzle types that differ from what is usual for the register type.
e.g. gather4 requires a register with register type VKD3D_SM4_RT_SAMPLER but a swizzle type VKD3D_SM4_SWIZZLE_VEC4 instead of the usual VKD3D_SM4_SWIZZLE_NONE.
The new fields of sm4_instruction can be used to handle these exceptions.
Also, they shouldn't change the current behaviour of the rest of the code since they are currently initalized with zeroes everywhere a sm4_instruction is initialized.
Signed-off-by: Francisco Casas franciscojacb@gmail.com --- libs/vkd3d-shader/hlsl_sm4.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9d45e163..29d728db 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -747,6 +747,11 @@ struct sm4_instruction { struct sm4_register reg; unsigned int swizzle; + /* If use_custom_swizzle_type is true, then custom_swizzle_type will be used in the + * instruction, instead of the result of the default swizzle type obtained from the register + * type. */ + bool use_custom_swizzle_type; + enum vkd3d_sm4_swizzle_type custom_swizzle_type; } srcs[2]; unsigned int src_count;
@@ -754,7 +759,7 @@ struct sm4_instruction unsigned int idx_count; };
-static unsigned int sm4_swizzle_type(enum vkd3d_sm4_register_type type) +static unsigned int sm4_default_swizzle_type(enum vkd3d_sm4_register_type type) { switch (type) { @@ -913,8 +918,10 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st
for (i = 0; i < instr->src_count; ++i) { + unsigned int swizzle_type = instr->srcs[i].use_custom_swizzle_type ? + instr->srcs[i].custom_swizzle_type : sm4_default_swizzle_type(instr->srcs[i].reg.type); token = sm4_encode_register(&instr->srcs[i].reg); - token |= sm4_swizzle_type(instr->srcs[i].reg.type) << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; + token |= swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; token |= instr->srcs[i].swizzle << VKD3D_SM4_SWIZZLE_SHIFT; if (instr->srcs[i].reg.mod) token |= VKD3D_SM4_EXTENDED_OPERAND;