Постоянный буфер не является обязательным, хотя другие буферы являются обязательными?(DirectX12) - PullRequest
0 голосов
/ 23 февраля 2019

Итак, у меня есть следующая функция, которая визуализирует анимированные объекты

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++;
    }
}

Буферы в регистрах b0 (RootSigCBVertex0) и b1 (RootSigCBAll1) связываются, но b2 не (обнаруживается при отладке в отладчике NSight)

Мои постоянные буферы в AnimationVS.hlsl выглядят так:

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;
 }

Моя корневая подпись, кажется, соответствует передаваемым параметрам, и даже графический отладчик Visual Studio говорит, что Root параметрпривязан, но не сам объект ресурса

Моя корневая подпись выглядит следующим образом

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);

Есть идеи, почему это может произойти?

РЕДАКТИРОВАТЬ: добавлен дополнительный контекст.

1 Ответ

0 голосов
/ 14 марта 2019

Итак, оказывается, это была довольно глупая ошибка с моей стороны.

Функция SkinTransfrom имеет параметр float4 bones, тогда как матрица постоянной буферной костной матрицы также называется bones.Это привело к тому, что функция использовала float4 bones в своей области, полностью игнорируя постоянный буфер.

Это также означает, что шейдер оптимизирует постоянный буфер, то есть никогда не связывает постоянный буфер в первую очередь.Это в значительной степени привело меня в круги, когда ответ был прямо передо мной!

Следующее изменение исправило его для меня:

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;
}
...