Sergio0694 / ComputeSharp

A .NET library to run C# code in parallel on the GPU through DX12, D2D1, and dynamically generated HLSL compute and pixel shaders, with the goal of making GPU computing easy to use for all .NET developers! 🚀
MIT License
2.74k stars 122 forks source link

ConstantBuffer.Length gives shader compilation error #794

Closed BobSammers closed 4 months ago

BobSammers commented 5 months ago

Description (optional)

ConstantBuffer<T> has a .Length property, but I get a shader compile error when I try to access it for a buffer of uints.

Reproduction Steps

Attempt to compile a shader with the following code

[ThreadGroupSize(DefaultThreadGroupSizes.XY)]
[GeneratedComputeShaderDescriptor]
internal readonly partial struct Trial(
        ReadWriteTexture2D<uint> pixelBuffer,
        ConstantBuffer<uint> colourMap,
        int xMax
    ) : IComputeShader
{
    public void Execute()
    {
        var index = (int)(ThreadIds.X / (float)xMax * colourMap.Length);
        pixelBuffer[ThreadIds.XY] = colourMap[index];
    }
}

Expected Behavior

Shader is correctly compiled.

Actual Behavior

Compilation fails:

Message: "The DXC compiler encountered one or more errors while trying to compile the shader: "

error: invalid format for vector swizzle 'GetDimensions' resource.GetDimensions(_0, _1);

[error]: no matching function for call to '__get_Dimension0'

int index = (int)(ThreadIds.x / (float)xMax * __get_Dimension0(colourMap));
~~~~~~~~~~~~~~~ static int __get_Dimension0(uint resource) .

Using the current stable version (2.1.0), this occurs at run time; using 3.0.0-preview2 results in errors as soon as the code is typed.

System info

This section should contain useful info such as:

Additional context (optional)

It may be that ConstantBuffer<T> is not the best type to use in this scenario (I have no experience in shader programming), but as the Length property is provided in a C# class specifically intended for creating shaders, I'm assuming it is a bug if it cannot be translated into valid HLSL. Using a ReadOnlyBuffer<T> instead in otherwise identical code works as expected, and the example compiles and runs with expected results.

Sergio0694 commented 4 months ago

Thank you for the report! Yes, ConstantBuffer<T> is not the right type for this, you should be using ReadOnlyBuffer<T>. I plan on eventually rewriting ConstantBuffer<T> entirely, as it shouldn't really be structured this way. For now I'll try to just avoid this error and provide some useful diagnostics instead. I recommend just using ReadOnlyBuffer<T> in your shader 🙂

BobSammers commented 4 months ago

I'll leave the ReadOnlyBuffer<T> in place then! Thanks.

Apologies for going off-topic, but if it's possible to answer briefly, what are the respective use-cases for these two types? If my colour map is compile-time constant - when do I use a ConstantBuffer if not here?