shader-slang / slang

Making it easier to work with shaders
MIT License
1.81k stars 161 forks source link

Allow swizzle on n-dimension vectors #4277

Open sriramm-nv opened 1 month ago

sriramm-nv commented 1 month ago

Fixes bug #3180

Adds a test case to repro the failure Fails when using either subscript operator or swizzle operator.

sriramm-nv commented 1 month ago

After adding the check for vector<vector<...>...> in checkUnsupportedInst, I am able to get past the error that breaks the test, but then ran into an assertion error, in the outRes.standardOutput as

assert failure: basicType

I am not sure where this error gets generated. So, it would be great if you can suggest if this is the right place to fix this, or if it needs fixing early on during IR generation.

This is the generated IR before it goes into the checker:

func %computeMain       : Func(Void, ConstantBuffer(%EntryPointParams), Vec(UInt, 3 : Int))
{
block %30(
                [nameHint("entryPointParams")]
                [layout(%16)]
                param %entryPointParams : ConstantBuffer(%EntryPointParams),
                [layout(%25)]
                [nameHint("dispatchThreadID")]
                [semantic("SV_DispatchThreadID", 0 : Int)]
                param %dispatchThreadID : Vec(UInt, 3 : Int)):
        [nameHint("dispatchThreadID")]
        let  %dispatchThreadID1 : Vec(UInt, 3 : Int)    = DebugVar(%29, 9 : UInt, 6 : UInt, 0 : UInt)
        DebugValue(%dispatchThreadID1, %dispatchThreadID)
        DebugLine(%29, 11 : UInt, 11 : UInt, 5 : UInt, 6 : UInt)
        DebugLine(%29, 11 : UInt, 11 : UInt, 5 : UInt, 6 : UInt)
        DebugLine(%29, 11 : UInt, 11 : UInt, 5 : UInt, 6 : UInt)
        [DebugLocation(%29, 11 : UInt, 31 : UInt)]
        [nameHint("v")]
        let  %v : Vec(Vec(Int, 2 : Int), 2 : Int)       = DebugVar(%29, 11 : UInt, 31 : UInt)
        [DebugLocation(%29, 11 : UInt, 31 : UInt)]
        [nameHint("v")]
        let  %v1        : Ptr(Vec(Vec(Int, 2 : Int), 2 : Int))  = var
        DebugLine(%29, 12 : UInt, 12 : UInt, 5 : UInt, 6 : UInt)
        let  %31        : Ptr(Vec(Int, 2 : Int))        = getElementPtr(%v1, 0 : Int)
        let  %32        : Ptr(Int)      = getElementPtr(%31, 0 : Int)
        store(%32, 1 : Int)
        DebugValue(%v, 1 : Int, 0 : Int, 0 : Int)
        DebugLine(%29, 13 : UInt, 13 : UInt, 5 : UInt, 6 : UInt)
        let  %33        : UInt  = swizzle(%dispatchThreadID, 0 : Int)
        let  %34        : Ptr(RWStructuredBuffer(Float, DefaultLayout, %14))    = get_field_addr(%globalParams, %outputBuffer)
        let  %35        : RWStructuredBuffer(Float, DefaultLayout, %14) = load(%34)
        let  %36        : Ptr(Float)    = rwstructuredBufferGetElementPtr(%35, %33)
        let  %37        : Vec(Vec(Int, 2 : Int), 2 : Int)       = load(%v1)
        let  %38        : Vec(Int, 2 : Int)     = swizzle(%37, 0 : Int)
        let  %39        : Int   = getElement(%38, 0 : Int)
        let  %40        : Float = castIntToFloat(%39)
        store(%36, %40)
        return_val(void_constant)

side note: how do I get rid of the Debug stuff so that the IR looks cleaner?

ArielG-NV commented 1 month ago

side note: how do I get rid of the Debug stuff so that the IR looks cleaner?

-g0 is no debug information DebugInfoLevel has the meaning of each value

the whole syntax: { OptionKind::DebugInformation, "-g...", "-g, -g<debug-info-format>, -g<debug-level>"}

ArielG-NV commented 1 month ago

I am not sure where this error gets generated. So, it would be great if you can suggest if this is the right place to fix this, or if it needs fixing early on during IR generation.

//slang-emit-cpp.cpp
const UnownedStringSlice* CPPSourceEmitter::getVectorElementNames(IRVectorType* vectorType)
{
    Index elemCount = Index(getIntVal(vectorType->getElementCount()));

    IRType* type = vectorType->getElementType()->getCanonicalType();
    IRBasicType* basicType = as<IRBasicType>(type);
    SLANG_ASSERT(basicType); // ASSERTS HERE
    return getVectorElementNames(basicType->getBaseType(), elemCount);
}

The code asserts because IRType* type has the value of a vector<int, 2>, which is not a IRBasicType.

The code works with glsl/hlsl. The code fails with cpp & spirv, this is likely a bug in slang-emit-* of each respective target.

jkwak-work commented 1 month ago
assert failure: basicType

When you have an error message like that, it means an assertion is failing. You should be able to immediately translate it to a following line when you see an error like that without running a debugger at all.

SLANG_ASSERT(basicType);

It will take a lot of time to figure out what it means if you try to manually narrow it down to where the message comes from.

jkwak-work commented 1 month ago

I don't think it is the same thing, but recently Yong submitted a similar fix. https://github.com/shader-slang/slang/pull/4310/files It may help you for this task. If not, it will still be a good thing to check out.

csyonghe commented 1 month ago

vector<vector<float, 2>, 3> isn't something we support today.

Systematically support general vector types will take a lot more effort. We should just diagnose an error when the element type of a vector is not a basic type.

sriramm-nv commented 1 month ago

side note: how do I get rid of the Debug stuff so that the IR looks cleaner?

-g0 is no debug information DebugInfoLevel has the meaning of each value

the whole syntax: { OptionKind::DebugInformation, "-g...", "-g, -g<debug-info-format>, -g<debug-level>"}

This works great in slangc. But to reproduce the assertion failure, I am using slang-test, where this option doesn't work. Will look into how this option is passed in slang-test

sriramm-nv commented 1 month ago

So, based on what I can infer from the advise, I will update the test to explicitly call out the error scenario, and not permit vector of non basic types.