From 460abeb03ebed8f76828c67f6bdc9c2deaa9ad04 Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Wed, 5 Nov 2025 20:34:39 -0300 Subject: [PATCH] vkd3d-shader/ir: Make FOG and PSIZE write masks 0x1 on I/O normalization. The validator checks that on normalized vsir I/O destination write masks are always a subset of the element's write mask. This is currently not always happening for FOG and PSIZE outputs, because d3dbc input might use the 0xf mask instead, despite these semantics being scalar. Note that this problem is hidden when using varying mapping, because in that case the vsir_program_remap_output_signature() pass, specifically the remove_unread_output_components() function, fixes the write mask. --- libs/vkd3d-shader/ir.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 5b1d0449a..6a1c5303e 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -3846,16 +3846,19 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par break; case VKD3DSPR_RASTOUT: + /* Fog and point size are scalar, but fxc/d3dcompiler emits a full + * write mask when writing to them. */ + if (reg->idx[0].offset > 0) + { + write_mask = VKD3DSP_WRITEMASK_0; + dst_param->write_mask = write_mask; + } /* Leave point size as a system value for the backends to consume. */ if (reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) return true; reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset; signature = normaliser->output_signature; reg->type = VKD3DSPR_OUTPUT; - /* Fog and point size are scalar, but fxc/d3dcompiler emits a full - * write mask when writing to them. */ - if (reg->idx[0].offset > 0) - write_mask = VKD3DSP_WRITEMASK_0; break; default: