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.65k stars 122 forks source link

'GeneratedComputeShaderDescriptorAttribute' did not add IComputeShaderDescriptor #790

Closed 3DartBlade closed 2 months ago

3DartBlade commented 2 months ago

Description

I've been trying to get the sample 'MultiplyByTwo' code running from the wiki. I finally figured out after a lot of searching that I need the 3.0.0 preview version of the package, and my project is now using .NET 8.0 thanks to primary constructors.

However, calling GraphicsDevice.Run exactly as it is on the wiki, with a struck exactly as on the wiki (see code below), causes this compilation error: CS0315 The type 'MultiplyByTwo' cannot be used as type parameter 'T' in the generic type or method 'GraphicsDeviceExtensions.For<T>(GraphicsDevice, int, in T)'. There is no boxing conversion from 'MultiplyByTwo' to 'ComputeSharp.Descriptors.IComputeShaderDescriptor<MultiplyByTwo>'.

Through the internet and the description of the GeneratedComputeShaderDescriptorAttribute I found out that this is probably due to the GraphicsDevice.Run method expecting a T where T has an IComputeShaderDescriptor which apparently my struct doesn't have despite the GeneratedComputeShaderDescriptorAttribute specified above it.

Reproduction Steps

  1. Start a new project in Microsoft Visual Studio Community 2022 Version 17.9.6
    • Console App, Place solution and project in the same directory, Framework: .NET 8.0 (Long Term Support), Do not use top-level statements
  2. Install ComputeSharp 3.0.0 through VS's NuGet manager GUI
  3. Use the code specified on the wiki:
    
    using System;
    using System.Linq;
    using ComputeSharp;

public class Program { public static void Main(string[] args) { int[] array = [.. Enumerable.Range(1, 100)];

    // Allocate a GPU buffer and copy the data to it.
    // We want the shader to modify the items in-place, so we
    // can allocate a single read-write buffer to work on.
    using ReadWriteBuffer<int> buffer = GraphicsDevice.GetDefault().AllocateReadWriteBuffer(array);

    GraphicsDevice.GetDefault().For(buffer.Length, new MultiplyByTwo(buffer));

    // Get the data back
    buffer.CopyTo(array);
}

}

[ThreadGroupSize(DefaultThreadGroupSizes.X)] [GeneratedComputeShaderDescriptor] public readonly partial struct MultiplyByTwo(ReadWriteBuffer buffer) : IComputeShader { public void Execute() { buffer[ThreadIds.X] *= 2; } }



### Expected Behavior

The script compiles with no error.

### Actual Behavior

Doesn't compile and spits out the above mentioned error code.

### System info

- Windows 11
- Microsoft Visual Studio Community 2022 Version 17.9.6
- ComputeSharp 3.0.0-preview2

If you need any additional information or testing, don't hesitate to reach out!
3DartBlade commented 2 months ago

Project files: ComputeSharpTest3.zip (Ignore the typo, I've been trying to get this to work for a long time now)

Sergio0694 commented 2 months ago

You're missing AllowUnsafeBlocks, the analyzers are telling you that as well 🙂

image

Just set that in your .csproj and it'll work as expected. The generators are disabled otherwise.

3DartBlade commented 2 months ago

Thank you, that solved it!

For some reason it did not show me those errors, but that's probably my Visual Studio's fault. At least if someone has the same issue they'll find the answer here. I'm just glad it works now!