DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[SPIR-V] DXC rejects indirectly constant Texture Load offset

Open shobomaru opened this issue 1 year ago • 1 comments

Description The HLSL code that compiles successfully in DXIL output mode results in a compilation error in SPIRV output mode.

Maybe related to #6389 ?

Steps to Reproduce dxc -T cs_6_0 -spirv path/to/file.hlsl

HLSL code:

Texture2D Tex;
float4 LoadTex(int3 pos, int2 offset)
{
        return Tex.Load(pos, offset);
}

RWStructuredBuffer<float4> Out;
[numthreads(1, 1, 1)]
void main()
{
        float4 t = LoadTex((int3)0, (int2)0);
        Out[0] = t;
}

Actual Behavior

error: Offsets to texture access operations must be immediate values. return Tex.Load(pos, offset); ^

Environment

  • DXC version: libdxcompiler.dylib: 1.8(dev;4640-45018c75)
  • Host Operating System: Windows 11 23H2 and macOS 14.5

shobomaru avatar Jun 21 '24 19:06 shobomaru

Texture2D Tex; float4 LoadTex(int3 pos, int2 offset) { // Ensure offset is a constant expression int2 fixedOffset = (int2)0; // Replace (int2)0 with a constant expression if needed return Tex.Load(pos, fixedOffset); }

RWStructuredBuffer Out; [numthreads(1, 1, 1)] void main() { float4 t = LoadTex((int3)0, (int2)0); // Ensure offset is a constant expression Out[0] = t; }

gorrila007 avatar Jun 22 '24 00:06 gorrila007

Thanks for the issue! For this one, it will be a won't fix!

In this code yes, the offset argument is not variable but fixed. But because we do constant propagation at the SPIR-V level, very late, we cannot generate a valid function to begin with. Supporting that would mean:

  • generating bad code
  • legalizing it, hoping we can const-propagate to fixup the code.

In this case, it would work fine. But if the user does something illegal, we would have a hard time reporting a useful message:

  • at this level, we only have SPIR-V, and no easy way to track back to the LoadTex call we failed to constant-propagate.

It's not optimal, but I believe the error message we show is the most user-friendly option.

An alternative to the suggested work-around would be to use templates:

Texture2D Tex;

template<int x, int y>
float4 LoadTex(int3 pos)
{
        return Tex.Load(pos, (int2)(x, y));
}

[numthreads(1, 1, 1)]
void main()
{
        float4 t = LoadTex<0, 0>((int3)0);
}

Keenuts avatar Jul 09 '24 14:07 Keenuts