Skip to content

Commit

Permalink
Issue #16 #33 #17: Update UBO in an efficient way
Browse files Browse the repository at this point in the history
Changes:
add: Generic Update Pool APIs
add: Update APIs for Constant Buffers in D3D12

Modules:
D3D12RenderSystem
DeferredRenderer
  • Loading branch information
vasumahesh1 committed Oct 21, 2018
1 parent 0e3f33c commit 1c9f296
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 43 deletions.
8 changes: 8 additions & 0 deletions Source/Azura/RenderSystem/Inc/D3D12/D3D12DrawablePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class D3D12DrawablePool : public DrawablePool {
const Containers::Vector<DescriptorSlot>& descriptorSlots,
const Containers::Vector<D3D12ScopedShader>& shaders,
const Containers::Vector<D3D12ScopedRenderPass>& renderPasses,
Microsoft::WRL::ComPtr<ID3D12CommandQueue> commandQueue,
Memory::Allocator& mainAllocator,
Memory::Allocator& initAllocator,
Log log);
Expand All @@ -46,6 +47,10 @@ class D3D12DrawablePool : public DrawablePool {
void BindSampler(SlotID slot, const SamplerDesc& desc) override;
void Submit() override;

void BeginUpdates() override;
void UpdateUniformData(DrawableID drawableId, SlotID slot, const U8* buffer, U32 size) override;
void SubmitUpdates() override;

const Containers::Vector<ID3D12DescriptorHeap*>& GetAllDescriptorHeaps() const;
ID3D12PipelineState* GetPipelineState(U32 renderPassId) const;
ID3D12GraphicsCommandList* GetSecondaryCommandList(U32 renderPassId) const;
Expand Down Expand Up @@ -73,7 +78,10 @@ class D3D12DrawablePool : public DrawablePool {

Containers::Vector<std::reference_wrapper<D3D12ScopedRenderPass>> m_renderPasses;

Microsoft::WRL::ComPtr<ID3D12CommandQueue> m_graphicsCommandQueue;

D3D12PipelineFactory m_pipelineFactory;
D3D12ScopedBuffer m_updateBuffer;
D3D12ScopedBuffer m_stagingBuffer;
D3D12ScopedBuffer m_mainBuffer;

Expand Down
2 changes: 2 additions & 0 deletions Source/Azura/RenderSystem/Inc/D3D12/D3D12ScopedBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class D3D12ScopedBuffer {
U32 GetSize() const;
U32 GetCurrentOffset() const;

void Reset();

void Transition(ID3D12GraphicsCommandList* commandList,
D3D12_RESOURCE_STATES fromState,
D3D12_RESOURCE_STATES toState) const;
Expand Down
8 changes: 8 additions & 0 deletions Source/Azura/RenderSystem/Inc/Generic/Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Drawable {
void AddVertexBufferInfo(BufferInfo&& info);
void AddInstanceBufferInfo(BufferInfo&& info);
void AddUniformBufferInfo(UniformBufferInfo&& info);
U32 GetSingleUniformBufferInfo(const DescriptorSlot & slot);
void SetIndexBufferInfo(BufferInfo&& info);

U32 GetVertexCount() const;
Expand Down Expand Up @@ -119,7 +120,12 @@ class DrawablePool {
virtual void BindTextureData(SlotID slot, const TextureDesc& desc, const U8* buffer) = 0;
virtual void BindSampler(SlotID slot, const SamplerDesc& desc) = 0;

virtual void BeginUpdates() = 0;
void UpdateUniformData(DrawableID drawableId, SlotID slot, const Containers::Vector<U8>& buffer);
virtual void UpdateUniformData(DrawableID drawableId, SlotID slot, const U8* buffer, U32 size) = 0;

virtual void Submit() = 0;
virtual void SubmitUpdates() = 0;

U32 GetSize() const;
bool CanRenderInPass(U32 renderPassId) const;
Expand All @@ -139,6 +145,8 @@ class DrawablePool {
Containers::Vector<TextureBufferInfo> m_textureBufferInfos;
Containers::Vector<SamplerInfo> m_samplerInfos;

Containers::Vector<BufferUpdate> m_bufferUpdates;

CullMode m_cullMode;

private:
Expand Down
10 changes: 10 additions & 0 deletions Source/Azura/RenderSystem/Inc/Generic/GenericTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,16 @@ struct BufferInfo {
}
};

struct BufferUpdate
{
U32 m_idx;
U32 m_gpuOffset;
U32 m_gpuByteSize;

U32 m_updateOffset;
U32 m_updateByteSize;
};

struct TextureBufferInfo final : public BufferInfo {
TextureDesc m_desc;
U32 m_set{0};
Expand Down
4 changes: 4 additions & 0 deletions Source/Azura/RenderSystem/Inc/Vulkan/VkDrawablePool.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class VkDrawablePool final : public DrawablePool {

void AppendToMainBuffer(const U8* buffer, U32 bufferSize);

void BeginUpdates() override;
void UpdateUniformData(DrawableID drawableId, SlotID slot, const U8* buffer, U32 size) override;
void SubmitUpdates() override;

private:
void SubmitTextureData();

Expand Down
86 changes: 70 additions & 16 deletions Source/Azura/RenderSystem/Src/D3D12/D3D12DrawablePool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Memory/MonotonicAllocator.h"
#include "D3D12/D3D12ScopedImage.h"
#include <algorithm>
#include <utility>

using namespace Microsoft::WRL; // NOLINT
using namespace Azura::Containers; // NOLINT
Expand All @@ -19,6 +20,7 @@ D3D12DrawablePool::D3D12DrawablePool(const ComPtr<ID3D12Device>& device,
const Vector<DescriptorSlot>& descriptorSlots,
const Vector<D3D12ScopedShader>& shaders,
const Vector<D3D12ScopedRenderPass>& renderPasses,
ComPtr<ID3D12CommandQueue> commandQueue,
Memory::Allocator& mainAllocator,
Memory::Allocator& initAllocator,
Log log)
Expand All @@ -30,6 +32,7 @@ D3D12DrawablePool::D3D12DrawablePool(const ComPtr<ID3D12Device>& device,
m_pipelines(mainAllocator),
m_drawables(createInfo.m_numDrawables, mainAllocator),
m_renderPasses(createInfo.m_renderPasses.GetSize(), mainAllocator),
m_graphicsCommandQueue(std::move(commandQueue)),
m_pipelineFactory(initAllocator, log_D3D12RenderSystem),
m_descriptorsPerDrawable(0),
m_images(mainAllocator),
Expand All @@ -39,15 +42,20 @@ D3D12DrawablePool::D3D12DrawablePool(const ComPtr<ID3D12Device>& device,
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Creating D3D12 Drawable Pool");

m_pipelineFactory.SetRasterizerStage(createInfo.m_cullMode, FrontFace::CounterClockwise);

CreateRenderPassReferences(createInfo, renderPasses);
CreateInputAttributes(createInfo);
CreateDescriptorHeap(createInfo);

// Create Buffer
// Create Buffers
m_stagingBuffer.Create(device, CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), createInfo.m_byteSize,
D3D12_RESOURCE_STATE_GENERIC_READ, log_D3D12RenderSystem);
m_stagingBuffer.Map();

m_updateBuffer.Create(device, CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), createInfo.m_byteSize,
D3D12_RESOURCE_STATE_GENERIC_READ, log_D3D12RenderSystem);
m_updateBuffer.Map();

m_mainBuffer.Create(device, CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), createInfo.m_byteSize,
D3D12_RESOURCE_STATE_COPY_DEST, log_D3D12RenderSystem);
}
Expand Down Expand Up @@ -300,16 +308,6 @@ void D3D12DrawablePool::Submit() {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "D3D12 Drawable Pool: Submitting");
m_pipelineFactory.Submit(m_device, m_renderPasses, m_pipelines);

// Create a Command Buffer to submit data for drawable
// Describe and create the command queue.
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

ComPtr<ID3D12CommandQueue> commandQueue;
VERIFY_D3D_OP(log_D3D12RenderSystem, m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)),
"Failed to create command Queue");

auto oneTimeSubmitBuffer = D3D12ScopedCommandBuffer(m_device, D3D12_COMMAND_LIST_TYPE_DIRECT, log_D3D12RenderSystem);
oneTimeSubmitBuffer.CreateGraphicsCommandList(m_device, nullptr, log_D3D12RenderSystem);

Expand All @@ -328,12 +326,12 @@ void D3D12DrawablePool::Submit() {

oneTimeCommandList->Close();

oneTimeSubmitBuffer.Execute(m_device, commandQueue.Get(), log_D3D12RenderSystem);
oneTimeSubmitBuffer.WaitForComplete(commandQueue.Get(), log_D3D12RenderSystem);
oneTimeSubmitBuffer.Execute(m_device, m_graphicsCommandQueue.Get(), log_D3D12RenderSystem);
oneTimeSubmitBuffer.WaitForComplete(m_graphicsCommandQueue.Get(), log_D3D12RenderSystem);

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

const U32 drawableHeapOffset = m_descriptorsPerDrawable * m_cbvSrvDescriptorElementSize;
const U32 drawableHeapOffset = m_descriptorsPerDrawable * m_cbvSrvDescriptorElementSize;

CD3DX12_CPU_DESCRIPTOR_HANDLE heapHandle(m_descriptorDrawableHeap->GetCPUDescriptorHandleForHeapStart(),
m_offsetToDrawableHeap, m_cbvSrvDescriptorElementSize);
Expand Down Expand Up @@ -401,7 +399,8 @@ void D3D12DrawablePool::Submit() {

if (renderPassInputs.GetSize() > 0) {
bundleCommandList->SetGraphicsRootDescriptorTable(renderPassRootSignatureTable.GetSize(), inputsGPUHandle);
LOG_DEBUG(log_D3D12RenderSystem, LOG_LEVEL, "Setting Input Attachment Descriptor Table at %d", renderPassRootSignatureTable.GetSize());
LOG_DEBUG(log_D3D12RenderSystem, LOG_LEVEL, "Setting Input Attachment Descriptor Table at %d",
renderPassRootSignatureTable.GetSize());
}

inputsRecorded += renderPassInputs.GetSize();
Expand All @@ -423,6 +422,61 @@ void D3D12DrawablePool::Submit() {
}
}

void D3D12DrawablePool::BeginUpdates() {
m_updateBuffer.Reset();
m_bufferUpdates.Reset();
}

void D3D12DrawablePool::UpdateUniformData(DrawableID drawableId, SlotID slot, const U8* buffer, U32 size) {
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL,
"D3D12 Drawable Pool: Update Uniform Requested for Drawable: %d for Slot: %d of Size: %d bytes", drawableId, slot,
size);

assert(m_drawables.GetSize() > drawableId);

auto& drawable = m_drawables[drawableId];

size = (size + D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1) & ~(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1);

const U32 offset = m_updateBuffer.AppendData(buffer, size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT, log_D3D12RenderSystem);

const auto& descriptorSlot = m_globalDescriptorSlots[slot];
const U32 bufferId = drawable.GetSingleUniformBufferInfo(descriptorSlot);

const auto& allUboInfos = drawable.GetUniformBufferInfos();

BufferUpdate info = {};
info.m_idx = bufferId;
info.m_updateOffset = offset;
info.m_updateByteSize = size;
info.m_gpuOffset = allUboInfos[bufferId].m_offset;
info.m_gpuByteSize = allUboInfos[bufferId].m_byteSize;

m_bufferUpdates.PushBack(info);
}

void D3D12DrawablePool::SubmitUpdates() {
auto oneTimeSubmitBuffer = D3D12ScopedCommandBuffer(m_device, D3D12_COMMAND_LIST_TYPE_DIRECT, log_D3D12RenderSystem);
oneTimeSubmitBuffer.CreateGraphicsCommandList(m_device, nullptr, log_D3D12RenderSystem);

auto oneTimeCommandList = oneTimeSubmitBuffer.GetGraphicsCommandList();

m_mainBuffer.Transition(oneTimeCommandList,D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_RESOURCE_STATE_COPY_DEST);

// Copy Custom Regions
for(const auto& updateRegion : m_bufferUpdates)
{
oneTimeCommandList->CopyBufferRegion(m_mainBuffer.Real(), updateRegion.m_gpuOffset, m_updateBuffer.Real(), updateRegion.m_updateOffset, updateRegion.m_updateByteSize);
}

m_mainBuffer.Transition(oneTimeCommandList, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);

oneTimeCommandList->Close();

oneTimeSubmitBuffer.Execute(m_device, m_graphicsCommandQueue.Get(), log_D3D12RenderSystem);
oneTimeSubmitBuffer.WaitForComplete(m_graphicsCommandQueue.Get(), log_D3D12RenderSystem);
}

const Vector<ID3D12DescriptorHeap*>& D3D12DrawablePool::GetAllDescriptorHeaps() const {
return m_allHeaps;
}
Expand Down
1 change: 1 addition & 0 deletions Source/Azura/RenderSystem/Src/D3D12/D3D12Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ DrawablePool& D3D12Renderer::CreateDrawablePool(const DrawablePoolCreateInfo& cr
m_descriptorSlots,
m_shaders,
m_renderPasses,
m_commandQueue,
m_drawPoolAllocator,
m_initAllocator,
log_D3D12RenderSystem);
Expand Down
5 changes: 5 additions & 0 deletions Source/Azura/RenderSystem/Src/D3D12/D3D12ScopedBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ U32 D3D12ScopedBuffer::GetCurrentOffset() const {
return U32(p_dataCur - p_dataBegin);
}

void D3D12ScopedBuffer::Reset()
{
p_dataCur = p_dataBegin;
}

void D3D12ScopedBuffer::Transition(ID3D12GraphicsCommandList* commandList,
D3D12_RESOURCE_STATES fromState,
D3D12_RESOURCE_STATES toState) const {
Expand Down
22 changes: 22 additions & 0 deletions Source/Azura/RenderSystem/Src/Generic/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ void Drawable::AddUniformBufferInfo(UniformBufferInfo&& info) {
m_uniformBufferInfos.PushBack(info);
}

U32 Drawable::GetSingleUniformBufferInfo(const DescriptorSlot& slot) {
U32 idx = 0;
for(const auto& ubInfo : m_uniformBufferInfos)
{
if (ubInfo.m_binding == slot.m_bindIdx && ubInfo.m_set == slot.m_setIdx)
{
return idx;
}

++idx;
}

throw std::runtime_error("Tried to Update Slot that was never bound");
}

void Drawable::SetIndexBufferInfo(BufferInfo&& info) {
m_indexBufferInfo = info;
}
Expand Down Expand Up @@ -105,6 +120,7 @@ DrawablePool::DrawablePool(const DrawablePoolCreateInfo& createInfo,
m_renderPasses(createInfo.m_renderPasses, allocator),
m_textureBufferInfos(allocator),
m_samplerInfos(allocator),
m_bufferUpdates(allocator),
m_cullMode(createInfo.m_cullMode),
m_byteSize(createInfo.m_byteSize),
m_drawType(createInfo.m_drawType),
Expand All @@ -122,6 +138,8 @@ DrawablePool::DrawablePool(const DrawablePoolCreateInfo& createInfo,
}
}

m_bufferUpdates.Reserve(m_descriptorCount.m_numSampledImageSlots + m_descriptorCount.m_numUniformSlots);

m_textureBufferInfos.Reserve(m_descriptorCount.m_numSampledImageSlots);
m_samplerInfos.Reserve(m_descriptorCount.m_numSamplerSlots);
}
Expand All @@ -142,6 +160,10 @@ void DrawablePool::SetIndexData(DrawableID drawableId, const Containers::Vector<
SetIndexData(drawableId, buffer.Data(), buffer.GetSize());
}

void DrawablePool::UpdateUniformData(DrawableID drawableId, SlotID slot, const Containers::Vector<U8>& buffer) {
UpdateUniformData(drawableId, slot, buffer.Data(), buffer.GetSize());
}

U32 DrawablePool::GetSize() const {
return m_byteSize;
}
Expand Down
6 changes: 2 additions & 4 deletions Source/Azura/RenderSystem/Src/Generic/GLFWWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ void GLFWWindow::Destroy() {
}

void GLFWWindow::StartListening() {
#ifdef BUILD_DEBUG

int frameCount{0};
double previousTime = glfwGetTime();
#endif

// TODO(vasumahesh1):[GAME]: Need a Performance Timer here

while (glfwWindowShouldClose(p_window) == GLFW_FALSE) {
#ifdef BUILD_DEBUG

const double currentTime = glfwGetTime();
frameCount++;

Expand All @@ -54,7 +53,6 @@ void GLFWWindow::StartListening() {
frameCount = 0;
previousTime = currentTime;
}
#endif

double currCursorX;
double currCursorY;
Expand Down
13 changes: 13 additions & 0 deletions Source/Azura/RenderSystem/Src/Vulkan/VkDrawablePool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,19 @@ void VkDrawablePool::AppendToMainBuffer(const U8* buffer, U32 bufferSize) {
m_mainBufferOffset += bufferSize;
}

void VkDrawablePool::BeginUpdates() {
}

void VkDrawablePool::UpdateUniformData(DrawableID drawableId, SlotID slot, const U8* buffer, U32 size) {
UNUSED(drawableId);
UNUSED(slot);
UNUSED(buffer);
UNUSED(size);
}

void VkDrawablePool::SubmitUpdates() {
}


void VkDrawablePool::SubmitTextureData() {
if (m_textureBufferInfos.GetSize() == 0)
Expand Down
7 changes: 7 additions & 0 deletions Source/Containers/Inc/Containers/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ class Vector {

const Type* Data() const;

void Reset();

Type& operator[](U32 idx);
Type& operator[](U32 idx) const;

Expand Down Expand Up @@ -594,6 +596,11 @@ const Type* Vector<Type>::Data() const {
return m_base.get();
}

template <typename Type>
void Vector<Type>::Reset() {
m_size = 0;
}

template <typename Type>
Type& Vector<Type>::operator[](const U32 idx) {
assert(idx < m_size);
Expand Down
Loading

0 comments on commit 1c9f296

Please sign in to comment.