2

So I have the following function which renders animated entities

void DeferredRenderer::DrawAnimated(ID3D12GraphicsCommandList * clist, std::vector<Entity*> entities)
{
    clist->SetPipelineState(sysRM->GetPSO(StringID("animDeferredPSO")));
    clist->SetGraphicsRootDescriptorTable(RootSigCBAll1, frame->GetGPUHandle(frameHeapParams.PerFrameCB));
    auto boneCBIndex = 0;
    for (auto e : entities)
    {
        //Set start of material texture in root descriptor, binds successfully
        clist->SetGraphicsRootDescriptorTable(RootSigSRVPixel1, frame->GetGPUHandle(frameHeapParams.Textures, e->GetMaterial()->GetStartIndex())); 
        //Binds successfully 
        clist->SetGraphicsRootDescriptorTable(RootSigCBVertex0, frame->GetGPUHandle(frameHeapParams.Entities, e->GetID())); 
        // Not binding!
        clist->SetGraphicsRootDescriptorTable(RootSigCBAll2, frame->GetGPUHandle(frameHeapParams.BoneCB, boneCBIndex)); 
        DrawAnimated(e->GetMesh(), clist);
        boneCBIndex++;
    }
}

The buffers at registers b0(RootSigCBVertex0) and b1 (RootSigCBAll1) bind but b2 does not (found out while debugging in NSight debugger)

My constant buffers in AnimationVS.hlsl look like this:

cbuffer ConstantBuffer : register(b0)
{
    float4x4 worldViewProjection;
    float4x4 world;
    float4x4 view;
    float4x4 projection;
    float4x4 shadowView;
    float4x4 shadowProjection;
};

cbuffer PerFrame : register(b1)
{
    float nearZ;
    float farZ;
    float2 lightPerspectiveValues;
};

cbuffer PerArmature: register(b2)
{
    float4x4 bones[MAX_BONES];
}

float4x4 SkinTransform(float4 weights, uint4 bones)
{
   // Calculate the skin transform from up to four bones and weights
   float4x4 skinTransform = 
        bones[bones.x] * weights.x +
        bones[bones.y] * weights.y +
        bones[bones.z] * weights.z +
        bones[bones.w] * weights.w;
    return skinTransform;
 }

My root signature seems to match the parameters being passed and even the Visual Studio graphics debugger says the Root parameter is bound, but not the Resource Object itself

My root signature looks like this

CD3DX12_DESCRIPTOR_RANGE range[5];
//view dependent CBV
range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//light dependent CBV
range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//G-Buffer inputs
range[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 16, 0);
//per frame CBV
range[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
//per bone 
range[4].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 2);

CD3DX12_ROOT_PARAMETER rootParameters[5];
rootParameters[0].InitAsDescriptorTable(1, &range[0], D3D12_SHADER_VISIBILITY_VERTEX);
rootParameters[1].InitAsDescriptorTable(1, &range[1], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[2].InitAsDescriptorTable(1, &range[2], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[3].InitAsDescriptorTable(1, &range[3], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[4].InitAsDescriptorTable(1, &range[4], D3D12_SHADER_VISIBILITY_ALL);

Any idea why this could happen?

EDIT: Added more context.

Nitish Victor
  • 183
  • 12
  • Have you double-checked that the PSO has the matching root signature object? Also, where is the call to ``SetGraphicsRootSignature``? – Chuck Walbourn Feb 25 '19 at 07:07
  • BTW, for bones you can typically drop one column/row because you don't do perspective projection with bones. Shaders will often use ``float4[3]`` for each bone to get a compacted 4x4 with the last column assumed to be ``0, 0, 0, 1``. – Chuck Walbourn Feb 25 '19 at 07:09
  • Right now I'm setting the root signature outside in my main draw function. `command->SetGraphicsRootSignature(rootSignature); ` `deferredRenderer->DrawAnimated(commandList, animatedEntityList);` – Nitish Victor Feb 25 '19 at 16:52
  • @ChuckWalbourn I double checked the PSO, it has the matching root signature. I also tried swapping the registers (b1 and b2) for the bones and the per frame, the per frame resource gets bound at b2 but not the bones at b1. – Nitish Victor Feb 25 '19 at 16:54

1 Answers1

0

So, turns out it was a pretty silly mistake from my end.

The SkinTransfrom function has a float4 bones parameter whilst the constant buffer bone matrix array is also called bones. This led to the function using the float4 bones within it's scope, disregarding the constant buffer completely.

This also means that the shader optimizes the constant buffer away i.e. never binding the constant buffer in the first place. This pretty much led me around in circles when the answer was right in front of me!

The following change fixed it for me :

float4x4 SkinTransform(float4 weights, uint4 boneIndices) // <-- bone to boneIndices
{
    float4x4 skinTransform = 
            bones[boneIndices.x] * weights.x +
            bones[boneIndices.y] * weights.y +
            bones[boneIndices.z] * weights.z +
            bones[boneIndices.w] * weights.w;
    return skinTransform;
}
Nitish Victor
  • 183
  • 12