diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp index 8b085d374..0d3309219 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.cpp @@ -153,7 +153,7 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC if (state.AreAllSubresourcesSame()) { // Transition entire resource at once - const D3D12_RESOURCE_STATES before = state.GetSubresourceState(subresourceIndex); + const D3D12_RESOURCE_STATES before = state.GetSubresourceState(-1); if (ResourceStateDX12::IsTransitionNeeded(before, after)) { AddTransitionBarrier(resource, before, after, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES); @@ -163,6 +163,7 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC else { // Slow path to transition each subresource + bool hadAnyTransition = false; for (int32 i = 0; i < state.GetSubresourcesCount(); i++) { const D3D12_RESOURCE_STATES before = state.GetSubresourceState(i); @@ -170,10 +171,20 @@ void GPUContextDX12::SetResourceState(ResourceOwnerDX12* resource, D3D12_RESOURC { AddTransitionBarrier(resource, before, after, i); state.SetSubresourceState(i, after); + hadAnyTransition = true; } } - ASSERT(state.CheckResourceState(after)); - state.SetResourceState(after); + if (hadAnyTransition) + { + // Try merge all subresources states into a single state + after = state.GetSubresourceState(0); + for (int32 i = 1; i < state.GetSubresourcesCount(); i++) + { + if (state.GetSubresourceState(i) != after) + return; + } + state.SetResourceState(after); + } } } else @@ -357,6 +368,21 @@ void GPUContextDX12::flushRTVs() { depthBuffer = _rtDepth->DSV(); auto states = _rtDepth->ReadOnlyDepthView ? D3D12_RESOURCE_STATE_DEPTH_READ : D3D12_RESOURCE_STATE_DEPTH_WRITE; + if (_currentState && _rtDepth->ReadOnlyDepthView) + { + // If read-only depth buffer is also binded as shader input then ensure it has proper state bit + const uint32 srMask = _currentState->GetUsedSRsMask(); + const uint32 srCount = Math::FloorLog2(srMask) + 1; + for (uint32 i = 0; i < srCount; i++) + { + const auto handle = _srHandles[i]; + if (srMask & (1 << i) && handle == _rtDepth) + { + states |= D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + break; + } + } + } SetResourceState(_rtDepth->GetResourceOwner(), states, _rtDepth->SubresourceIndex); } else @@ -483,7 +509,7 @@ void GPUContextDX12::flushPS() } } -void GPUContextDX12::onDrawCall() +void GPUContextDX12::OnDrawCall() { // Ensure state of the vertex and index buffers for (int32 i = 0; i < _vbCount; i++) @@ -510,7 +536,7 @@ void GPUContextDX12::onDrawCall() if (srMask & (1 << i) && handle != nullptr && handle->GetResourceOwner()) { const auto resourceOwner = handle->GetResourceOwner(); - bool isRtv = false; + bool isRtv = _rtDepth == handle; for (int32 j = 0; j < _rtCount; j++) { if (_rtHandles[j] && _rtHandles[j]->GetResourceOwner() == resourceOwner) @@ -970,14 +996,14 @@ void GPUContextDX12::ResolveMultisample(GPUTexture* sourceMultisampleTexture, GP void GPUContextDX12::DrawInstanced(uint32 verticesCount, uint32 instanceCount, int32 startInstance, int32 startVertex) { - onDrawCall(); + OnDrawCall(); _commandList->DrawInstanced(verticesCount, instanceCount, startVertex, startInstance); RENDER_STAT_DRAW_CALL(verticesCount * instanceCount, verticesCount * instanceCount / 3); } void GPUContextDX12::DrawIndexedInstanced(uint32 indicesCount, uint32 instanceCount, int32 startInstance, int32 startVertex, int32 startIndex) { - onDrawCall(); + OnDrawCall(); _commandList->DrawIndexedInstanced(indicesCount, instanceCount, startIndex, startVertex, startInstance); RENDER_STAT_DRAW_CALL(0, indicesCount / 3 * instanceCount); } @@ -990,7 +1016,7 @@ void GPUContextDX12::DrawInstancedIndirect(GPUBuffer* bufferForArgs, uint32 offs auto signature = _device->DrawIndirectCommandSignature->GetSignature(); SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); - onDrawCall(); + OnDrawCall(); _commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0); RENDER_STAT_DRAW_CALL(0, 0); } @@ -1003,7 +1029,7 @@ void GPUContextDX12::DrawIndexedInstancedIndirect(GPUBuffer* bufferForArgs, uint auto signature = _device->DrawIndexedIndirectCommandSignature->GetSignature(); SetResourceState(bufferForArgsDX12, D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT); - onDrawCall(); + OnDrawCall(); _commandList->ExecuteIndirect(signature, 1, bufferForArgsDX12->GetResource(), (UINT64)offsetForArgs, nullptr, 0); RENDER_STAT_DRAW_CALL(0, 0); } diff --git a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h index 1551edc76..b102cfa6b 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX12/GPUContextDX12.h @@ -138,7 +138,7 @@ private: void flushCBs(); void flushRBs(); void flushPS(); - void onDrawCall(); + void OnDrawCall(); public: diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 3a3e41b27..63b5503a8 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -33,10 +33,46 @@ static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartIndex) == OFFSET_OF(VkD static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartVertex) == OFFSET_OF(VkDrawIndexedIndirectCommand, vertexOffset), "Wrong offset for GPUDrawIndexedIndirectArgs::StartVertex"); static_assert(OFFSET_OF(GPUDrawIndexedIndirectArgs, StartInstance) == OFFSET_OF(VkDrawIndexedIndirectCommand, firstInstance), "Wrong offset for GPUDrawIndexedIndirectArgs::StartInstance"); +#if VK_ENABLE_BARRIERS_DEBUG + +const Char* ToString(VkImageLayout layout) +{ + switch (layout) + { +#define TO_STR(type) case type: return TEXT(#type) + TO_STR(VK_IMAGE_LAYOUT_UNDEFINED); + TO_STR(VK_IMAGE_LAYOUT_GENERAL); + TO_STR(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_PREINITIALIZED); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL); + TO_STR(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + TO_STR(VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR); + TO_STR(VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV); + TO_STR(VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT); + TO_STR(VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR); + TO_STR(VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR); +#undef TO_STR + default: + return TEXT("?"); + } +} + +#endif + void PipelineBarrierVulkan::AddImageBarrier(VkImage image, const VkImageSubresourceRange& range, VkImageLayout srcLayout, VkImageLayout dstLayout, GPUTextureViewVulkan* handle) { #if VK_ENABLE_BARRIERS_DEBUG - ImageBarriersDebug.Add(handle); + ImageBarriersDebug.Add(handle); #endif VkImageMemoryBarrier& imageBarrier = ImageBarriers.AddOne(); RenderToolsVulkan::ZeroStruct(imageBarrier, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); @@ -44,21 +80,21 @@ void PipelineBarrierVulkan::AddImageBarrier(VkImage image, const VkImageSubresou imageBarrier.subresourceRange = range; imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - RenderToolsVulkan::SetImageBarrierInfo(srcLayout, dstLayout, imageBarrier, SourceStage, DestStage); - + imageBarrier.oldLayout = srcLayout; + imageBarrier.newLayout = dstLayout; + SourceStage |= RenderToolsVulkan::GetImageBarrierFlags(srcLayout, imageBarrier.srcAccessMask); + DestStage |= RenderToolsVulkan::GetImageBarrierFlags(dstLayout, imageBarrier.dstAccessMask); #if VK_ENABLE_BARRIERS_DEBUG - LOG(Warning, "Image Barrier: 0x{0:x}, {1} -> {2} for baseMipLevel: {3}, baseArrayLayer: {4}, levelCount: {5}, layerCount: {6} ({7})", - (int)image, - srcLayout, - dstLayout, - range.baseMipLevel, - range.baseArrayLayer, - range.levelCount, - range.layerCount, - - handle && handle->Owner->AsGPUResource() ? handle->Owner->AsGPUResource()->ToString() : String::Empty - ); + LOG(Warning, "Image Barrier: 0x{0:x}, {1} -> {2} for baseMipLevel: {3}, baseArrayLayer: {4}, levelCount: {5}, layerCount: {6} ({7})", + (uintptr)image, + ToString(srcLayout), + ToString(dstLayout), + range.baseMipLevel, + range.baseArrayLayer, + range.levelCount, + range.layerCount, + handle && handle->Owner->AsGPUResource() ? handle->Owner->AsGPUResource()->ToString() : String::Empty + ); #endif } @@ -73,16 +109,14 @@ void PipelineBarrierVulkan::AddBufferBarrier(VkBuffer buffer, VkDeviceSize offse bufferBarrier.dstAccessMask = dstAccess; bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - RenderToolsVulkan::SetBufferBarrierInfo(srcAccess, dstAccess, SourceStage, DestStage); + SourceStage |= RenderToolsVulkan::GetBufferBarrierFlags(srcAccess); + DestStage |= RenderToolsVulkan::GetBufferBarrierFlags(dstAccess); } void PipelineBarrierVulkan::Execute(CmdBufferVulkan* cmdBuffer) { ASSERT(cmdBuffer->IsOutsideRenderPass()); - vkCmdPipelineBarrier(cmdBuffer->GetHandle(), SourceStage, DestStage, 0, 0, nullptr, BufferBarriers.Count(), BufferBarriers.Get(), ImageBarriers.Count(), ImageBarriers.Get()); - Reset(); } @@ -127,11 +161,11 @@ void GPUContextVulkan::AddImageBarrier(VkImage image, VkImageLayout srcLayout, V _barriers.AddImageBarrier(image, subresourceRange, srcLayout, dstLayout, handle); #if !VK_ENABLE_BARRIERS_BATCHING - // Auto-flush without batching - const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); - if (cmdBuffer->IsInsideRenderPass()) - EndRenderPass(); - _barriers.Execute(cmdBuffer); + // Auto-flush without batching + const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); + if (cmdBuffer->IsInsideRenderPass()) + EndRenderPass(); + _barriers.Execute(cmdBuffer); #endif } @@ -144,15 +178,19 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo const int32 mipLevels = state.GetSubresourcesCount() / handle->Owner->ArraySlices; if (state.AreAllSubresourcesSame()) { - // Transition entire resource at once - const VkImageLayout srcLayout = state.GetSubresourceState(0); - VkImageSubresourceRange range; - range.aspectMask = handle->Info.subresourceRange.aspectMask; - range.baseMipLevel = 0; - range.levelCount = mipLevels; - range.baseArrayLayer = 0; - range.layerCount = handle->Owner->ArraySlices; - AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle); + const VkImageLayout srcLayout = state.GetSubresourceState(-1); + if (srcLayout != dstLayout) + { + // Transition entire resource at once + VkImageSubresourceRange range; + range.aspectMask = handle->Info.subresourceRange.aspectMask; + range.baseMipLevel = 0; + range.levelCount = mipLevels; + range.baseArrayLayer = 0; + range.layerCount = handle->Owner->ArraySlices; + AddImageBarrier(handle->Image, srcLayout, dstLayout, range, handle); + state.SetResourceState(dstLayout); + } } else { @@ -172,8 +210,8 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo state.SetSubresourceState(i, dstLayout); } } - ASSERT(state.CheckResourceState(dstLayout)); } + ASSERT(state.CheckResourceState(dstLayout)); state.SetResourceState(dstLayout); } else @@ -262,11 +300,11 @@ void GPUContextVulkan::AddBufferBarrier(GPUBufferVulkan* buffer, VkAccessFlags d buffer->Access = dstAccess; #if !VK_ENABLE_BARRIERS_BATCHING - // Auto-flush without batching - const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); - if (cmdBuffer->IsInsideRenderPass()) - EndRenderPass(); - _barriers.Execute(cmdBuffer); + // Auto-flush without batching + const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); + if (cmdBuffer->IsInsideRenderPass()) + EndRenderPass(); + _barriers.Execute(cmdBuffer); #endif } @@ -628,6 +666,18 @@ void GPUContextVulkan::OnDrawCall() UpdateDescriptorSets(pipelineState); } + // Bind any missing vertex buffers to null if required by the current state + const auto vertexInputState = pipelineState->GetVertexInputState(); + const int32 missingVBs = vertexInputState->vertexBindingDescriptionCount - _vbCount; + if (missingVBs > 0) + { + VkBuffer buffers[GPU_MAX_VB_BINDED]; + VkDeviceSize offsets[GPU_MAX_VB_BINDED] = {}; + for (int32 i = 0; i < missingVBs; i++) + buffers[i] = _device->HelperResources.GetDummyVertexBuffer()->GetHandle(); + vkCmdBindVertexBuffers(cmdBuffer->GetHandle(), _vbCount, missingVBs, buffers, offsets); + } + // Start render pass if not during one if (cmdBuffer->IsOutsideRenderPass()) BeginRenderPass(); @@ -652,7 +702,7 @@ void GPUContextVulkan::OnDrawCall() _rtDirtyFlag = false; #if VK_ENABLE_BARRIERS_DEBUG - LOG(Warning, "Draw"); + LOG(Warning, "Draw"); #endif } @@ -668,6 +718,7 @@ void GPUContextVulkan::FrameBegin() _srDirtyFlag = 0; _uaDirtyFlag = 0; _rtCount = 0; + _vbCount = 0; _renderPass = nullptr; _currentState = nullptr; _rtDepth = nullptr; @@ -922,6 +973,7 @@ void GPUContextVulkan::BindUA(int32 slot, GPUResourceView* view) void GPUContextVulkan::BindVB(const Span& vertexBuffers, const uint32* vertexBuffersOffsets) { + _vbCount = vertexBuffers.Length(); if (vertexBuffers.Length() == 0) return; const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); @@ -955,7 +1007,7 @@ void GPUContextVulkan::UpdateCB(GPUConstantBuffer* cb, const void* data) const auto cmdBuffer = _cmdBufferManager->GetCmdBuffer(); // Allocate bytes for the buffer - const auto allocation = _device->UniformBufferUploader->Allocate(size, 0, cmdBuffer); + const auto allocation = _device->UniformBufferUploader->Allocate(size, 0, this); // Copy data Platform::MemoryCopy(allocation.CPUAddress, data, allocation.Size); @@ -1002,7 +1054,7 @@ void GPUContextVulkan::Dispatch(GPUShaderProgramCS* shader, uint32 threadGroupCo RENDER_STAT_DISPATCH_CALL(); #if VK_ENABLE_BARRIERS_DEBUG - LOG(Warning, "Dispatch"); + LOG(Warning, "Dispatch"); #endif } @@ -1036,7 +1088,7 @@ void GPUContextVulkan::DispatchIndirect(GPUShaderProgramCS* shader, GPUBuffer* b RENDER_STAT_DISPATCH_CALL(); #if VK_ENABLE_BARRIERS_DEBUG - LOG(Warning, "DispatchIndirect"); + LOG(Warning, "DispatchIndirect"); #endif } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h index a3d26f017..da2054ab3 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.h @@ -35,8 +35,6 @@ class DescriptorSetLayoutVulkan; /// #define VK_BARRIER_BUFFER_SIZE 16 -#if VK_ENABLE_BARRIERS_BATCHING - /// /// The Vulkan pipeline resources layout barrier batching structure. /// @@ -81,8 +79,6 @@ public: void Execute(CmdBufferVulkan* cmdBuffer); }; -#endif - /// /// GPU Context for Vulkan backend. /// @@ -93,9 +89,7 @@ private: GPUDeviceVulkan* _device; QueueVulkan* _queue; CmdBufferManagerVulkan* _cmdBufferManager; -#if VK_ENABLE_BARRIERS_BATCHING PipelineBarrierVulkan _barriers; -#endif int32 _psDirtyFlag : 1; int32 _rtDirtyFlag : 1; @@ -104,6 +98,7 @@ private: int32 _uaDirtyFlag : 1; int32 _rtCount; + int32 _vbCount; RenderPassVulkan* _renderPass; GPUPipelineStateVulkan* _currentState; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp index cdb76e1cf..991bd5766 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.cpp @@ -270,7 +270,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc) _descDynamic.pDynamicStates = _dynamicStates; _dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; _dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; - _dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + //_dynamicStates[_descDynamic.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; static_assert(ARRAY_COUNT(_dynamicStates) <= 3, "Invalid dynamic states array."); _desc.pDynamicState = &_descDynamic; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h index 29b71a3bc..142dd9f91 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUPipelineStateVulkan.h @@ -152,6 +152,11 @@ public: /// const SpirvShaderDescriptorInfo* DescriptorInfoPerStage[DescriptorSet::GraphicsStagesCount]; + const VkPipelineVertexInputStateCreateInfo* GetVertexInputState() const + { + return _desc.pVertexInputState; + } + DescriptorSetWriteContainerVulkan DSWriteContainer; DescriptorSetWriterVulkan DSWriter[DescriptorSet::GraphicsStagesCount]; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp index 5b38b926a..863ebdc46 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.cpp @@ -3,6 +3,7 @@ #if GRAPHICS_API_VULKAN #include "GPUShaderVulkan.h" +#include "GPUContextVulkan.h" #include "GPUShaderProgramVulkan.h" #include "RenderToolsVulkan.h" #include "CmdBufferVulkan.h" @@ -12,7 +13,7 @@ #include "Engine/Graphics/PixelFormatExtensions.h" #if PLATFORM_DESKTOP -#define VULKAN_UNIFORM_RING_BUFFER_SIZE 16 * 1024 * 1024 +#define VULKAN_UNIFORM_RING_BUFFER_SIZE 24 * 1024 * 1024 #else #define VULKAN_UNIFORM_RING_BUFFER_SIZE 8 * 1024 * 1024 #endif @@ -45,7 +46,7 @@ UniformBufferUploaderVulkan::UniformBufferUploaderVulkan(GPUDeviceVulkan* device LOG_VULKAN_RESULT(result); } -UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(uint64 size, uint32 alignment, CmdBufferVulkan* cmdBuffer) +UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(uint64 size, uint32 alignment, GPUContextVulkan* context) { alignment = Math::Max(_minAlignment, alignment); uint64 offset = Math::AlignUp(_offset, alignment); @@ -53,16 +54,12 @@ UniformBufferUploaderVulkan::Allocation UniformBufferUploaderVulkan::Allocate(ui // Check if wrap around ring buffer if (offset + size >= _size) { - if (_fenceCmdBuffer) + auto cmdBuffer = context->GetCmdBufferManager()->GetActiveCmdBuffer(); + if (_fenceCmdBuffer && _fenceCounter == cmdBuffer->GetFenceSignaledCounter()) { - if (_fenceCmdBuffer == cmdBuffer && _fenceCounter == cmdBuffer->GetFenceSignaledCounter()) - { - LOG(Error, "Wrapped around the ring buffer. Requested more bytes than possible in the same cmd buffer!"); - } - else if (_fenceCounter == _fenceCmdBuffer->GetFenceSignaledCounter()) - { - LOG(Error, "Wrapped around the ring buffer! Need to wait on the GPU!!!"); - } + LOG(Error, "Wrapped around the ring buffer! Need to wait on the GPU!"); + context->Flush(); + cmdBuffer = context->GetCmdBufferManager()->GetActiveCmdBuffer(); } offset = 0; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.h index 842dfc145..5158baefa 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUShaderVulkan.h @@ -62,7 +62,7 @@ public: public: - Allocation Allocate(uint64 size, uint32 alignment, CmdBufferVulkan* cmdBuffer); + Allocation Allocate(uint64 size, uint32 alignment, GPUContextVulkan* context); public: diff --git a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h index 1380d221d..c7c11fb0c 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/RenderToolsVulkan.h @@ -164,37 +164,6 @@ public: return stageFlags; } - static inline void SetBufferBarrierInfo(VkAccessFlags source, VkAccessFlags dest, VkPipelineStageFlags& sourceStage, VkPipelineStageFlags& destStage) - { - sourceStage |= GetBufferBarrierFlags(source); - destStage |= GetBufferBarrierFlags(dest); - } - - static inline void SetImageBarrierInfo(VkImageLayout source, VkImageLayout dest, VkImageMemoryBarrier& barrier, VkPipelineStageFlags& sourceStage, VkPipelineStageFlags& destStage) - { - barrier.oldLayout = source; - barrier.newLayout = dest; - - sourceStage |= GetImageBarrierFlags(source, barrier.srcAccessMask); - destStage |= GetImageBarrierFlags(dest, barrier.dstAccessMask); - } - - static void ImagePipelineBarrier(VkCommandBuffer cmdBuffer, VkImage img, VkImageLayout src, VkImageLayout dest, const VkImageSubresourceRange& subresourceRange) - { - VkImageMemoryBarrier imageBarrier; - ZeroStruct(imageBarrier, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); - imageBarrier.image = img; - imageBarrier.subresourceRange = subresourceRange; - imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - VkPipelineStageFlags srcStages = (VkPipelineStageFlags)0; - VkPipelineStageFlags destStages = (VkPipelineStageFlags)0; - SetImageBarrierInfo(src, dest, imageBarrier, srcStages, destStages); - - vkCmdPipelineBarrier(cmdBuffer, srcStages, destStages, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier); - } - template static FORCE_INLINE void ZeroStruct(T& data, VkStructureType type) { diff --git a/Source/Engine/Renderer/LightPass.cpp b/Source/Engine/Renderer/LightPass.cpp index 648f934d3..b44f3f452 100644 --- a/Source/Engine/Renderer/LightPass.cpp +++ b/Source/Engine/Renderer/LightPass.cpp @@ -206,8 +206,10 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB // Bind output GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer; - GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : nullptr; - context->SetRenderTarget(depthBufferHandle, lightBuffer); + const bool depthBufferReadOnly = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView; + GPUTextureView* depthBufferRTV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : nullptr; + GPUTextureView* depthBufferSRV = depthBufferReadOnly ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); + context->SetRenderTarget(depthBufferRTV, lightBuffer); // Set per frame data GBufferPass::SetInputs(renderContext.View, perFrame.GBuffer); @@ -225,7 +227,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB context->BindSR(0, renderContext.Buffers->GBuffer0); context->BindSR(1, renderContext.Buffers->GBuffer1); context->BindSR(2, renderContext.Buffers->GBuffer2); - context->BindSR(3, depthBuffer); + context->BindSR(3, depthBufferSRV); context->BindSR(4, renderContext.Buffers->GBuffer3); // Check if debug lights @@ -274,7 +276,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView); // Bind output - context->SetRenderTarget(depthBufferHandle, lightBuffer); + context->SetRenderTarget(depthBufferRTV, lightBuffer); // Set shadow mask context->BindSR(5, shadowMaskView); @@ -329,7 +331,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB ShadowsPass::Instance()->RenderShadow(renderContext, light, shadowMaskView); // Bind output - context->SetRenderTarget(depthBufferHandle, lightBuffer); + context->SetRenderTarget(depthBufferRTV, lightBuffer); // Set shadow mask context->BindSR(5, shadowMaskView); @@ -370,7 +372,7 @@ void LightPass::RenderLight(RenderContext& renderContext, GPUTextureView* lightB ShadowsPass::Instance()->RenderShadow(renderContext, light, lightIndex, shadowMaskView); // Bind output - context->SetRenderTarget(depthBufferHandle, lightBuffer); + context->SetRenderTarget(depthBufferRTV, lightBuffer); // Set shadow mask context->BindSR(5, shadowMaskView); diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp index 707aa461d..319e9f09a 100644 --- a/Source/Engine/Renderer/ShadowsPass.cpp +++ b/Source/Engine/Renderer/ShadowsPass.cpp @@ -315,12 +315,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererPointLightD context->ResetRenderTarget(); const Viewport viewport = renderContext.Task->GetViewport(); GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer; - GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); + GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); context->SetViewportAndScissors(viewport); context->BindSR(0, renderContext.Buffers->GBuffer0); context->BindSR(1, renderContext.Buffers->GBuffer1); context->BindSR(2, renderContext.Buffers->GBuffer2); - context->BindSR(3, depthBufferHandle); + context->BindSR(3, depthBufferSRV); context->BindSR(4, renderContext.Buffers->GBuffer3); // Setup shader data @@ -417,12 +417,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererSpotLightDa context->ResetRenderTarget(); const Viewport viewport = renderContext.Task->GetViewport(); GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer; - GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); + GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); context->SetViewportAndScissors(viewport); context->BindSR(0, renderContext.Buffers->GBuffer0); context->BindSR(1, renderContext.Buffers->GBuffer1); context->BindSR(2, renderContext.Buffers->GBuffer2); - context->BindSR(3, depthBufferHandle); + context->BindSR(3, depthBufferSRV); context->BindSR(4, renderContext.Buffers->GBuffer3); // Setup shader data @@ -693,12 +693,12 @@ void ShadowsPass::RenderShadow(RenderContext& renderContext, RendererDirectional context->ResetRenderTarget(); const Viewport viewport = renderContext.Task->GetViewport(); GPUTexture* depthBuffer = renderContext.Buffers->DepthBuffer; - GPUTextureView* depthBufferHandle = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); + GPUTextureView* depthBufferSRV = depthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); context->SetViewportAndScissors(viewport); context->BindSR(0, renderContext.Buffers->GBuffer0); context->BindSR(1, renderContext.Buffers->GBuffer1); context->BindSR(2, renderContext.Buffers->GBuffer2); - context->BindSR(3, depthBufferHandle); + context->BindSR(3, depthBufferSRV); context->BindSR(4, renderContext.Buffers->GBuffer3); // Setup shader data