Skip to content

Commit

Permalink
Issue #16: Add Descriptor heap logic for textures
Browse files Browse the repository at this point in the history
Changes:
add: more logic to D3D12DrawablePool for textures & samplers

Modules:
D3D12RenderSystem
  • Loading branch information
vasumahesh1 committed Oct 18, 2018
1 parent 9a2d52f commit a7091ce
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 50 deletions.
24 changes: 19 additions & 5 deletions Source/Azura/RenderSystem/Inc/D3D12/D3D12Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
namespace Azura {
namespace D3D12 {

class D3D12Drawable : public Drawable
{
struct D3D12DescriptorEntry {
int m_count{1};
int m_cumulativeCount{0};
};

class D3D12Drawable : public Drawable {

public:
D3D12Drawable(const DrawableCreateInfo& info,
Expand All @@ -17,9 +21,19 @@ class D3D12Drawable : public Drawable
U32 numUniformSlots,
Memory::Allocator& allocator);

void CreateResourceViews(const Microsoft::WRL::ComPtr<ID3D12Device>& device, ID3D12Resource* parentBuffer, const Containers::Vector<VertexSlot>& vertexSlots, CD3DX12_CPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Log& log_D3D12RenderSystem);
void CreateResourceViews(const Microsoft::WRL::ComPtr<ID3D12Device>& device,
ID3D12Resource* parentBuffer,
const Containers::Vector<VertexSlot>& vertexSlots,
CD3DX12_CPU_DESCRIPTOR_HANDLE drawableHeapHandle,
UINT heapElementSize,
const Containers::Vector<D3D12DescriptorEntry>& descriptorEntry,
const Log& log_D3D12RenderSystem);

void RecordCommands(ID3D12GraphicsCommandList* commandList, CD3DX12_GPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Log& log_D3D12RenderSystem);
void RecordCommands(ID3D12GraphicsCommandList* commandList,
CD3DX12_GPU_DESCRIPTOR_HANDLE drawableHeapHandle,
UINT heapElementSize,
const Containers::Vector<D3D12DescriptorEntry>& descriptorEntry,
const Log& log_D3D12RenderSystem);

private:

Expand All @@ -31,4 +45,4 @@ class D3D12Drawable : public Drawable
};

} // namespace D3D12
} // namespace Azura
} // namespace Azura
19 changes: 15 additions & 4 deletions Source/Azura/RenderSystem/Inc/D3D12/D3D12DrawablePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "Generic/Drawable.h"
#include "Log/Log.h"

#include <array>

#include "D3D12/D3D12Core.h"
#include "D3D12/D3D12ScopedPipeline.h"
#include "D3D12/D3D12Drawable.h"
Expand Down Expand Up @@ -33,9 +35,10 @@ class D3D12DrawablePool : public DrawablePool {
void AddShader(U32 shaderId) override;
void BindTextureData(SlotID slot, const TextureDesc& desc, const U8* buffer) override;
void BindSampler(SlotID slot, const SamplerDesc& desc) override;
void SetTextureData(ID3D12GraphicsCommandList* bundleCommandList);
void Submit() override;

ID3D12DescriptorHeap* GetDescriptorHeap() const;
const Containers::Vector<ID3D12DescriptorHeap*>& GetAllDescriptorHeaps() const;
ID3D12RootSignature* GetRootSignature() const;
ID3D12PipelineState * GetPipelineState() const;
ID3D12GraphicsCommandList* GetSecondaryCommandList() const;
Expand All @@ -57,12 +60,20 @@ class D3D12DrawablePool : public DrawablePool {
D3D12PipelineFactory m_pipelineFactory;
D3D12ScopedBuffer m_stagingBuffer;

D3D12ScopedCommandBuffer m_secondaryCommandBuffer;
U32 m_descriptorsPerDrawable;
U32 m_offsetForCommonDescriptors{};

U32 m_descriptorsPerDrawable{0};
U32 m_cbvSrvDescriptorElementSize{0};

Containers::Vector<D3D12DescriptorEntry> m_descriptorTableSizes;
D3D12ScopedCommandBuffer m_secondaryCommandBuffer;

Microsoft::WRL::ComPtr<ID3D12RootSignature> m_rootSignature;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_descriptorHeap;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_descriptorDrawableHeap;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_descriptorTextureHeap;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> m_descriptorSamplerHeap;

Containers::Vector<ID3D12DescriptorHeap*> m_allHeaps;
};

} // namespace D3D12
Expand Down
41 changes: 34 additions & 7 deletions Source/Azura/RenderSystem/Src/D3D12/D3D12Drawable.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "D3D12/D3D12Drawable.h"
#include "D3D12/D3D12TypeMapping.h"
#include <algorithm>

namespace Azura {
namespace D3D12 {
Expand All @@ -16,15 +17,30 @@ D3D12Drawable::D3D12Drawable(const DrawableCreateInfo& info,
m_indexBufferView() {
}

void D3D12Drawable::CreateResourceViews(const Microsoft::WRL::ComPtr<ID3D12Device>& device, ID3D12Resource* parentBuffer, const Containers::Vector<VertexSlot>& vertexSlots, CD3DX12_CPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Log& log_D3D12RenderSystem) {
void D3D12Drawable::CreateResourceViews(const Microsoft::WRL::ComPtr<ID3D12Device>& device, ID3D12Resource* parentBuffer, const Containers::Vector<VertexSlot>& vertexSlots, CD3DX12_CPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Containers::Vector<D3D12DescriptorEntry>& descriptorEntry, const Log& log_D3D12RenderSystem) {
const auto gpuAddress = parentBuffer->GetGPUVirtualAddress();

std::sort(m_uniformBufferInfos.Begin(), m_uniformBufferInfos.End(), [](const UniformBufferInfo& a, const UniformBufferInfo& b) -> bool
{
if (a.m_set == b.m_set)
{
return a.m_binding < b.m_binding;
}

return a.m_set < b.m_set;
});

for (const auto& ubInfo : m_uniformBufferInfos) {
const U32 offsetInHeap = descriptorEntry[ubInfo.m_set].m_cumulativeCount + ubInfo.m_binding;

CD3DX12_CPU_DESCRIPTOR_HANDLE handle;
CD3DX12_CPU_DESCRIPTOR_HANDLE::InitOffsetted(handle, drawableHeapHandle, heapElementSize * offsetInHeap);

D3D12_CONSTANT_BUFFER_VIEW_DESC constantBufferViewDesc = {
gpuAddress + ubInfo.m_offset, ubInfo.m_byteSize
};

device->CreateConstantBufferView(&constantBufferViewDesc, drawableHeapHandle);
drawableHeapHandle.Offset(heapElementSize);
device->CreateConstantBufferView(&constantBufferViewDesc, handle);
}

for (const auto& vbInfos : m_vertexBufferInfos) {
Expand Down Expand Up @@ -57,7 +73,7 @@ void D3D12Drawable::CreateResourceViews(const Microsoft::WRL::ComPtr<ID3D12Devic
};
}

void D3D12Drawable::RecordCommands(ID3D12GraphicsCommandList* commandList, CD3DX12_GPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Log& log_D3D12RenderSystem) {
void D3D12Drawable::RecordCommands(ID3D12GraphicsCommandList* commandList, CD3DX12_GPU_DESCRIPTOR_HANDLE drawableHeapHandle, UINT heapElementSize, const Containers::Vector<D3D12DescriptorEntry>& descriptorEntry, const Log& log_D3D12RenderSystem) {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12Drawable: Recording Commands for Drawable");

commandList->IASetIndexBuffer(&m_indexBufferView);
Expand All @@ -74,10 +90,21 @@ void D3D12Drawable::RecordCommands(ID3D12GraphicsCommandList* commandList, CD3DX
++idx;
}

idx = 0;
int lastSet = -1;
for (const auto& ubInfo : m_uniformBufferInfos) {
drawableHeapHandle.Offset(idx * heapElementSize);
commandList->SetGraphicsRootDescriptorTable(ubInfo.m_set, drawableHeapHandle);

if (int(ubInfo.m_set) == lastSet)
{
continue;
}

lastSet = ubInfo.m_set;

const U32 offsetInHeap = descriptorEntry[ubInfo.m_set].m_cumulativeCount;

CD3DX12_GPU_DESCRIPTOR_HANDLE handle;
CD3DX12_GPU_DESCRIPTOR_HANDLE::InitOffsetted(handle, drawableHeapHandle, heapElementSize * offsetInHeap);
commandList->SetGraphicsRootDescriptorTable(ubInfo.m_set, handle);
++idx;
}

Expand Down
156 changes: 127 additions & 29 deletions Source/Azura/RenderSystem/Src/D3D12/D3D12DrawablePool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

#include "D3D12/d3dx12.h"
#include "D3D12/D3D12Macros.h"
#include "Memory/MemoryFactory.h"
#include "Memory/MonotonicAllocator.h"

using namespace Microsoft::WRL; // NOLINT
using namespace Azura::Containers; // NOLINT

namespace Azura {
namespace D3D12 {
Expand All @@ -24,7 +27,10 @@ D3D12DrawablePool::D3D12DrawablePool(const ComPtr<ID3D12Device>& device,
m_pipelines(mainAllocator),
m_drawables(createInfo.m_numDrawables , mainAllocator),
m_pipelineFactory(initAllocator, log_D3D12RenderSystem),
m_secondaryCommandBuffer(device, D3D12_COMMAND_LIST_TYPE_BUNDLE, log_D3D12RenderSystem) {
m_descriptorsPerDrawable(descriptorCount.m_numUniformSlots),
m_descriptorTableSizes(mainAllocator),
m_secondaryCommandBuffer(device, D3D12_COMMAND_LIST_TYPE_BUNDLE, log_D3D12RenderSystem),
m_allHeaps(mainAllocator) {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Creating D3D12 Drawable Pool");
CreateRootSignature(device);
CreateInputAttributes(createInfo);
Expand Down Expand Up @@ -141,57 +147,69 @@ void D3D12DrawablePool::BindSampler(SlotID slot, const SamplerDesc& desc) {
UNUSED(desc);
}

void D3D12DrawablePool::SetTextureData(ID3D12GraphicsCommandList* bundleCommandList)
{
if (m_textureBufferInfos.GetSize() == 0)
{
return;
}

LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Texture Data Found");

const CD3DX12_GPU_DESCRIPTOR_HANDLE textureGPUHandle(m_descriptorTextureHeap->GetGPUDescriptorHandleForHeapStart());
for (const auto& textBufInfo : m_textureBufferInfos) {
const U32 offsetInHeap = m_descriptorTableSizes[textBufInfo.m_set].m_cumulativeCount;

CD3DX12_GPU_DESCRIPTOR_HANDLE handle;
CD3DX12_GPU_DESCRIPTOR_HANDLE::InitOffsetted(handle, textureGPUHandle, m_cbvSrvDescriptorElementSize * offsetInHeap);

bundleCommandList->SetGraphicsRootDescriptorTable(textBufInfo.m_set, handle);
}
}

void D3D12DrawablePool::Submit() {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Submitting");

m_pipelineFactory.Submit(m_device, m_rootSignature, m_pipelines);

LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Created Pipelines");

m_secondaryCommandBuffer.CreateGraphicsCommandList(m_device, m_pipelines[0].GetState(), log_D3D12RenderSystem);
auto bundleCommandList = m_secondaryCommandBuffer.GetGraphicsCommandList();

const auto heapElementSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
m_cbvSrvDescriptorElementSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
const U32 heapStepOffset = m_descriptorsPerDrawable * m_cbvSrvDescriptorElementSize;

CD3DX12_CPU_DESCRIPTOR_HANDLE heapHandle(m_descriptorHeap->GetCPUDescriptorHandleForHeapStart());
CD3DX12_CPU_DESCRIPTOR_HANDLE heapHandle(m_descriptorDrawableHeap->GetCPUDescriptorHandleForHeapStart());

LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Creating Resource Views");

U32 idx = 0;
for (auto& drawable : m_drawables) {
const U32 heapOffset = idx * m_descriptorsPerDrawable * heapElementSize;
heapHandle.Offset(heapOffset);

drawable.CreateResourceViews(m_device, m_stagingBuffer.Real(), m_vertexDataSlots, heapHandle, heapElementSize, log_D3D12RenderSystem);
++idx;
drawable.CreateResourceViews(m_device, m_stagingBuffer.Real(), m_vertexDataSlots, heapHandle, m_cbvSrvDescriptorElementSize, m_descriptorTableSizes, log_D3D12RenderSystem);
heapHandle.Offset(heapStepOffset);
}

LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Created Resource Views");

ID3D12DescriptorHeap* ppHeaps[] = { m_descriptorHeap.Get() };
bundleCommandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); // NOLINT
bundleCommandList->SetDescriptorHeaps(UINT(m_allHeaps.GetSize()), m_allHeaps.Data());
bundleCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
bundleCommandList->SetGraphicsRootSignature(m_rootSignature.Get());

CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHeapHandle(m_descriptorHeap->GetGPUDescriptorHandleForHeapStart());
SetTextureData(bundleCommandList);

CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHeapHandle(m_descriptorDrawableHeap->GetGPUDescriptorHandleForHeapStart());
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Recording Commands");

idx = 0;
for (auto& drawable : m_drawables) {
const U32 heapOffset = idx * m_descriptorsPerDrawable * heapElementSize;
gpuHeapHandle.Offset(heapOffset);

drawable.RecordCommands(bundleCommandList, gpuHeapHandle, heapElementSize, log_D3D12RenderSystem);
++idx;
drawable.RecordCommands(bundleCommandList, gpuHeapHandle, m_cbvSrvDescriptorElementSize, m_descriptorTableSizes, log_D3D12RenderSystem);
gpuHeapHandle.Offset(heapStepOffset);
}

LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Closing Bundle Command Buffer");
VERIFY_D3D_OP(log_D3D12RenderSystem, bundleCommandList->Close(), "Failed to close bundle Command Buffer");
}

ID3D12DescriptorHeap* D3D12DrawablePool::GetDescriptorHeap() const {
return m_descriptorHeap.Get();
const Containers::Vector<ID3D12DescriptorHeap*>& D3D12DrawablePool::GetAllDescriptorHeaps() const {
return m_allHeaps;
}

ID3D12RootSignature* D3D12DrawablePool::GetRootSignature() const {
Expand All @@ -208,15 +226,74 @@ ID3D12GraphicsCommandList* D3D12DrawablePool::GetSecondaryCommandList() const {

void D3D12DrawablePool::CreateRootSignature(const ComPtr<ID3D12Device>& device) {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Creating Root Signature");
STACK_ALLOCATOR(Temporary, Memory::MonotonicAllocator, 2048);

CD3DX12_DESCRIPTOR_RANGE range;
CD3DX12_ROOT_PARAMETER parameter;
m_descriptorTableSizes.Reserve(m_descriptorSlots.GetSize());

range.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
parameter.InitAsDescriptorTable(1, &range, D3D12_SHADER_VISIBILITY_VERTEX);
int totalCount = 0;
for (const auto& slot : m_descriptorSlots) {
if (slot.m_binding == DescriptorBinding::Same) {
m_descriptorTableSizes.Last().m_count += 1;

++totalCount;
continue;
}

m_descriptorTableSizes.PushBack({1, totalCount});
++totalCount;
}

Vector<CD3DX12_ROOT_PARAMETER> descriptorTables(m_descriptorTableSizes.GetSize(), allocatorTemporary);

int offset = 0;
for (const auto& bindingSize : m_descriptorTableSizes) {
Vector<CD3DX12_DESCRIPTOR_RANGE> currentRanges(bindingSize.m_count, allocatorTemporary);

U32 cbvOffset = 0;
U32 srvOffset = 0;
U32 samplerOffset = 0;

for (int idx = offset; idx < offset + bindingSize.m_count; ++idx) {
CD3DX12_DESCRIPTOR_RANGE rangeData;

const auto& slot = m_descriptorSlots[idx];

switch (slot.m_type) {
case DescriptorType::UniformBuffer:
rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, cbvOffset);
currentRanges.PushBack(rangeData);
++cbvOffset;
break;

case DescriptorType::Sampler:
rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, samplerOffset);
currentRanges.PushBack(rangeData);
++samplerOffset;
break;

case DescriptorType::SampledImage:
rangeData.Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, srvOffset);
currentRanges.PushBack(rangeData);
++srvOffset;
break;

case DescriptorType::PushConstant:
case DescriptorType::CombinedImageSampler:
default:
LOG_ERR(log_D3D12RenderSystem, LOG_LEVEL, "Unsupported Descriptor Type");
break;
}

CD3DX12_ROOT_PARAMETER rootParameter;
rootParameter.InitAsDescriptorTable(currentRanges.GetSize(), currentRanges.Data(), D3D12_SHADER_VISIBILITY_ALL);
descriptorTables.PushBack(rootParameter);
}

offset += bindingSize.m_count;
}

CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(1, &parameter, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
rootSignatureDesc.Init(descriptorTables.GetSize(), descriptorTables.Data(), 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
Expand All @@ -235,13 +312,34 @@ void D3D12DrawablePool::CreateInputAttributes(const DrawablePoolCreateInfo& crea
}

void D3D12DrawablePool::CreateDescriptorHeap(const DrawablePoolCreateInfo& createInfo) {
m_descriptorsPerDrawable = m_descriptorCount.m_numUniformSlots + m_descriptorCount.m_numSampledImageSlots;

m_allHeaps.Reserve(3);
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.NumDescriptors = createInfo.m_numDrawables * m_descriptorsPerDrawable;
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
VERIFY_D3D_OP(log_D3D12RenderSystem, m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_descriptorHeap)), "Failed to create CBV SRV UAV Descriptor Heap");
VERIFY_D3D_OP(log_D3D12RenderSystem, m_device->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_descriptorDrawableHeap)), "Failed to create Drawable Descriptor Heap");
m_allHeaps.PushBack(m_descriptorDrawableHeap.Get());

if (m_descriptorCount.m_numSampledImageSlots > 0) {
D3D12_DESCRIPTOR_HEAP_DESC textureDesc = {};
textureDesc.NumDescriptors = m_descriptorCount.m_numSampledImageSlots;
textureDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
textureDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
VERIFY_D3D_OP(log_D3D12RenderSystem, m_device->CreateDescriptorHeap(&textureDesc, IID_PPV_ARGS(&m_descriptorTextureHeap)), "Failed to create Texture Descriptor Heap");

m_allHeaps.PushBack(m_descriptorTextureHeap.Get());
}

if (m_descriptorCount.m_numSamplerSlots > 0) {
D3D12_DESCRIPTOR_HEAP_DESC samplerDesc = {};
samplerDesc.NumDescriptors = m_descriptorCount.m_numSamplerSlots;
samplerDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
samplerDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
VERIFY_D3D_OP(log_D3D12RenderSystem, m_device->CreateDescriptorHeap(&samplerDesc, IID_PPV_ARGS(&m_descriptorSamplerHeap)), "Failed to create Sampler Descriptor Heap");

m_allHeaps.PushBack(m_descriptorSamplerHeap.Get());
}
}
} // namespace D3D12
} // namespace Azura
Loading

0 comments on commit a7091ce

Please sign in to comment.