Falcor icon indicating copy to clipboard operation
Falcor copied to clipboard

Cannot use ParameterBlock<> in shader.

Open Alekssasho opened this issue 6 years ago • 6 comments

If you add new ParameterBlock<> inside a shader, the root descriptor in dx12 fails to compile and issues warning.

The easiest way to reproduce is to change Shadow texture in ForwardRenderer sample to be in ParameterBlock. ForwardRenderer.slang: Texture2D gVisibilityBuffer; becomes struct ShadowTextureData { Texture2D gVisibilityBuffer; }; ParameterBlock<ShadowTextureData> Shadow;

This fails on runtime when trying to compile the root descriptor for this program with Shader register range of type CBV (root parameter [3], visibility ALL, descriptor table slot [7]) overlaps with another shader register range (root parameter[0], visibility ALL, descriptor table slot [0]). It looks like some constant buffer has the same index as the ParameterBlock created in ShaderCommon.slang for material data.

Am I doing something wrong, or there is a bug inside Falcor, which prevents from adding multiple ParameterBlocks ?

Alekssasho avatar Oct 29 '18 18:10 Alekssasho

You should be able to add multiple ParameterBlocks. I'm looking into it.

nbentyNV avatar Oct 29 '18 18:10 nbentyNV

I found the issue. The problem is that Falcor reflection always create an entry for a CB named as the ParameterBlock. In this case, there's no real CB, so the indices are incorrect. I have a fix, will test it and release it with Falcor 3.1.1 later this week.

@tfoleyNV somewhat related, I was under the assumption that each ParameterBlock resides in its own register-space. Is that not true?

nbentyNV avatar Oct 29 '18 18:10 nbentyNV

Awesome. Thanks for the quick reaction.

Alekssasho avatar Oct 29 '18 19:10 Alekssasho

I have a fix in my fork. If you don't want to wait for the release, replace ParameterBlockReflection::addResource() in ProgramReflection.cpp with the following:

void ParameterBlockReflection::addResource(const ReflectionVar::SharedConstPtr& pVar)
    {
        const ReflectionResourceType* pResourceType = pVar->getType()->unwrapArray()->asResourceType();
        assert(pResourceType);
        uint32_t elementCount = max(1u, pVar->getType()->getTotalArraySize());

        const ReflectionType* pType = pResourceType->getStructType().get();
        const ReflectionStructType* pStruct = (pType != nullptr) ? pType->asStructType() : nullptr;

        // pVar might be a CB for a ParameterBlock. If it's empty, don't add it
        if(pStruct == nullptr || pStruct->getSize())
        {
            mResources.push_back(getResourceDesc(pVar, elementCount, pVar->getName()));
            mpResourceVars->addMember(pVar);
        }

        // If this is a constant-buffer, it might contain resources. Extract them.
        if (pStruct)
        {
            for (const auto& pMember : *pStruct)
            {
                if (doesTypeContainsResources(pMember->getType().get()))
                {
                    mpResourceVars->addMember(pMember);
                }
            }
            flattenResources(pStruct, mResources);
        }
    }

nbentyNV avatar Oct 29 '18 19:10 nbentyNV

I was just about to come here and comment that a ParameterBlock<X> where X contains only resources won't generate a constant buffer, and Falcor probably doesn't account for that. Putting an int dummy; field into the ShadowTextureData field above should serve as a workaround for the issue.

I was under the assumption that each ParameterBlock resides in its own register-space. Is that not true?

For Vulkan, each (non-empty) ParameterBlock will end up getting a distinct set. For D3D, there is the problem that users might not want distinct spaces, especially when outputting for Shader Model 5.0 or earlier. There is an option to make Slang use a strategy like what it does for Vulkan, but it isn't on by default because D3D never actually requires that you give things distinct spaces - you can still assign them to different descriptor tables even when they are in the same space.

tangent-vector avatar Oct 29 '18 20:10 tangent-vector

Thanks the fix worked.

Alekssasho avatar Oct 29 '18 20:10 Alekssasho