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

Need access to `boolN`'s `?:` operator #735

Closed rickbrew closed 8 months ago

rickbrew commented 8 months ago

According to https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-operators#boolean-math-operators , boolN and boolMxN should support the ?: operator as a per-component selector.

AFAIK, you can't overload the ?: operator in C#/.NET, at least not in the way we'd need for this, and I'd be surprised if that changes.

So I'm proposing to surface this as a method, Hlsl.Select():

public static class Hlsl
{
    public static float Select(bool selector, float value1, float value2);
    public static float2 Select(bool2 selector, float2 value1, float2 value2);
    public static float3 Select(bool3 selector, float3 value1, float3 value2);
    public static float4 Select(bool4 selector, float4 value1, float4 value2);
    ...
    public static float1x4 Select(bool1x4 selector, float1x4 value1, float1x4 value2);
    public static float2x4 Select(bool2x4 selector, float2x4 value1, float2x4 value2);
    public static float3x4 Select(bool3x4 selector, float3x4 value1, float3x4 value2);
    public static float4x4 Select(bool4x4 selector, float4x4 value1, float4x4 value2);
    ...
    // All other valid combinations of types and vector/matrix sizes
}

Access to this would allow me to change this:

float4 value1 = ...;
float4 value2 = ...;
bool4 selector = ...;
uint4 mask = ~(Hlsl.BoolToUInt(selector) - 1);
float4 result = Hlsl.AsFloat((mask & Hlsl.AsUInt(value1)) | (~mask & Hlsl.AsUInt(value2)));

to just:

float4 value1 = ...;
float4 value2 = ...;
bool4 selector = ...;
float4 result = Hlsl.Select(selector, value1, value2);

This would be a good win for legibility, and maybe performance.