Skip to content

vkd3d-shader/spirv: Fixes for NonReadable decorators

The existing code reuses the same SPIR-V variable for all descriptors mapped to the same Vulkan binding, and applies the NonReadable decoration based on the VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ only. This potentially causes the decoration to be applied twice, should two non-read descriptors be mapped to the same variable, which isn't allowed in SPIR-V, and the validator complains.

And in the case two uav descriptors are mapped to the same variable, and one is read from while the other is not, the variable would get the NonReadable decorator, while being read from later.

The first case can be hit with the following minimal test, with VKD3D_SHADER_CONFIG=force_validation: (extracted and simplified from sm6-uav-rwtexture.shader_test)

[require]
shader model >= 6.0

[uav 0]
size (2d, 1, 1)

[uav 1]
size (2d, 1, 1)

[pixel shader]
RWTexture2D<float> u;
RWTexture2D<float> v;

float4 main() : sv_target
{
    u[uint2(0, 0)] = 0.5;
    v[uint2(0, 0)] = 0.5;
    return 0;
}

[test]
draw quad

The second case can be hit with the same test, just modifying it to do v[uint2(0, 0)] = u[uint2(0, 0)];, and although it doesn't explicit error, i believe it is incorrect to set the NonReadable decoration while still reading from the variable, which can be seen on the SPIR-V dump when tracing.

This fixes two test failures i hit on my machine with both radv and llvmpipe. (Those tests do not fail on CI due to debian's older version of spirv-tools.)

I am not sure if this fix is the best possible fix for this, so feedback is welcome.

Edited by navi

Merge request reports

Loading