shader-slang / slang

Making it easier to work with shaders
MIT License
1.78k stars 159 forks source link

Unable to use vectors in initialization list of other vectors #4460

Closed chaoticbob closed 16 hours ago

chaoticbob commented 5 days ago

Using float2 vars in initialization list for float3 and float4 fails to compile. Using float3 in initialization list for float4 fails to compile. Error msg:

shader.hlsl(14): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float3 h0 = {v2, 1};
                 ^~
shader.hlsl(15): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float3 i0 = {1, float2(0, 1)};
                          ^
shader.hlsl(23): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float4 r0 = {input.foo[0], input.bar[1].yz};
                          ^
shader.hlsl(24): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float4 r1 = {v2, v2};
                 ^~
shader.hlsl(25): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float4 r2 = {v2, 0, 1};
                 ^~
shader.hlsl(26): error 30019: expected an expression of type 'float', got 'vector<float,3>'
    float4 r3 = {h0, 1};
                 ^~
shader.hlsl(27): error 30019: expected an expression of type 'float', got 'vector<float,3>'
    float4 r4 = {0, float3(g0.x, h0.x, i0.x)};

Was expecting that whatever I can pass into a vector's constructor, I should be able to pass into an initialization list.

CMD

slangc.exe -target spirv -lang slang -D__spirv__ -emit-spirv-directly -profile ps_6_0 -entry main shader.hlsl

Shader

struct PSInput
{
    float2 foo[4] : A;
    float3 bar[2] : B;
};

float4 main(PSInput input) : SV_TARGET
{
    float2 v2  = input.foo[0];

    float3 g0 = float3(v2, 1);
    float3 h0 = {v2, 1};
    float3 i0 = {1, float2(0, 1)};

    float4 s0 = float4(input.foo[0], input.bar[1].yz);
    float4 s1 = float4(v2, v2);
    float4 s2 = float4(v2, 0, 1);
    float4 s3 = float4(h0, 1);
    float4 s4 = float4(0, float3(g0.x, h0.x, i0.x));

    float4 r0 = {input.foo[0], input.bar[1].yz};
    float4 r1 = {v2, v2};
    float4 r2 = {v2, 0, 1};
    float4 r3 = {h0, 1};
    float4 r4 = {0, float3(g0.x, h0.x, i0.x)};

    return s0 + s1 + s2 + s3 + s4 +
           r0 + r1 + r2 + r3 + r4;
}
ArielG-NV commented 4 days ago

Implementation note: If implementing by adding constructors to struct vector the permutation count will be quite large. This is likely not the approach which should be taken.

edit: no longer applies

jkwak-work commented 16 hours ago

It appears that this is a duplicate issue to #4461. I am closing this as a duplicate and it will be followed up by #4461.

All lines in the given shader works except ones that uses the list-initializer. The following two lines are supposed to call the same constructor but the second one fails to call the constructor,

    float3 g0 = float3(v2, 1); // WORKS
    float3 h0 = {v2, 1}; // FAILS

The error message is following,

a.slang(12): error 30019: expected an expression of type 'float', got 'vector<float,2>'
    float3 h0 = {v2, 1};
                 ^~

It looks like that the list-initializer is trying to assign the values to the member variables directly rather than calling the constructor.

ArielG-NV commented 16 hours ago

It looks like that the list-initializer is trying to assign the values to the member variables directly rather than calling the constructor.

This is a correct analysis on how initializer-lists in Slang work, they (unlike C++) do not call a constructor:

  1. if empty ({}), they set all member variables to their respective initExpr, all other variables are zeroed (does not always zero values due to a bug?)
  2. if non empty initializer list, the initializer list tries to map values 1:1 with member variables for initialization (with some functional caveats and exceptions).
ArielG-NV commented 16 hours ago

Looking at the problem again, I think this is actually a bug in _readAggregateValueFromInitializerList.

Specifically the else if (auto toVecType = as<VectorExpressionType>(toType)) part of code which should allow vector initialization using {...}.