From 3d34cf07ede6984dcdd147cc0b144c993e228e95 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 28 Jan 2021 20:43:57 -0800 Subject: Updated CMake to use VulkanSDK 1.2.162.1 --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index e5cd319c..a8048dfc 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -270,7 +270,7 @@ elseif(PLATFORM_IOS) # The linker will issue a warning, but this will work for both device and the simulator. list(APPEND PRIVATE_DEPENDENCIES "${MoltenVK_FRAMEWORK}/ios-arm64/libMoltenVK.a" - "${MoltenVK_FRAMEWORK}/ios-x86_64-simulator/libMoltenVK.a" + "${MoltenVK_FRAMEWORK}/ios-arm64_x86_64-simulator/libMoltenVK.a" ) find_library(CORE_GRAPHICS CoreGraphics) -- cgit v1.2.3 From 3b4b2022d216ff0d91fdcb0fde96760b93399c5f Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 2 Feb 2021 21:40:57 -0800 Subject: Disabled (for now) linking with simulator MoltenVK library to fix the iOS build --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index a8048dfc..f4f0aa35 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -270,7 +270,7 @@ elseif(PLATFORM_IOS) # The linker will issue a warning, but this will work for both device and the simulator. list(APPEND PRIVATE_DEPENDENCIES "${MoltenVK_FRAMEWORK}/ios-arm64/libMoltenVK.a" - "${MoltenVK_FRAMEWORK}/ios-arm64_x86_64-simulator/libMoltenVK.a" + #"${MoltenVK_FRAMEWORK}/ios-arm64_x86_64-simulator/libMoltenVK.a" ) find_library(CORE_GRAPHICS CoreGraphics) -- cgit v1.2.3 From 30f6c40c138e6e535d2c1d13c8679111b12415fa Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 3 Feb 2021 22:45:03 -0800 Subject: CMake: added selection of simulator or device MoltenVK library for iOS --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index f4f0aa35..2c02b7c9 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -266,12 +266,15 @@ if(PLATFORM_WIN32) elseif(PLATFORM_MACOS) # Use Volk elseif(PLATFORM_IOS) - # For the apparent lack of a better way, link with both arm64 and x64 libraries. - # The linker will issue a warning, but this will work for both device and the simulator. - list(APPEND PRIVATE_DEPENDENCIES - "${MoltenVK_FRAMEWORK}/ios-arm64/libMoltenVK.a" - #"${MoltenVK_FRAMEWORK}/ios-arm64_x86_64-simulator/libMoltenVK.a" - ) + if(CMAKE_OSX_SYSROOT STREQUAL "iphonesimulator" OR PLATFORM_IOS_SIMULATOR) + list(APPEND PRIVATE_DEPENDENCIES + "${MoltenVK_FRAMEWORK}/ios-arm64_x86_64-simulator/libMoltenVK.a" + ) + else() + list(APPEND PRIVATE_DEPENDENCIES + "${MoltenVK_FRAMEWORK}/ios-arm64/libMoltenVK.a" + ) + endif() find_library(CORE_GRAPHICS CoreGraphics) find_library(METAL_LIBRARY Metal) -- cgit v1.2.3 From a13fe40ab6b365270a2f438ecb0c0d615f29e3e5 Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 5 Feb 2021 21:49:10 -0800 Subject: Vulkan backend: added output for SPIRV Optimizer --- Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 338f0f50..8cbe331f 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -44,6 +44,18 @@ namespace Diligent { + +#if !DILIGENT_NO_HLSL +namespace GLSLangUtils +{ +void SpvOptimizerMessageConsumer( + spv_message_level_t level, + const char* /* source */, + const spv_position_t& /* position */, + const char* message); +} +#endif + namespace { @@ -62,6 +74,7 @@ bool StripReflection(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, Target = SPV_ENV_VULKAN_1_1_SPIRV_1_4; spvtools::Optimizer SpirvOptimizer(Target); + SpirvOptimizer.SetMessageConsumer(GLSLangUtils::SpvOptimizerMessageConsumer); // Decorations defined in SPV_GOOGLE_hlsl_functionality1 are the only instructions // removed by strip-reflect-info pass. SPIRV offsets become INVALID after this operation. SpirvOptimizer.RegisterPass(spvtools::CreateStripReflectInfoPass()); -- cgit v1.2.3 From 3734f7335badd666a9df8f8a92b1c17eb86df420 Mon Sep 17 00:00:00 2001 From: MikhailGorobets Date: Sat, 6 Feb 2021 15:10:06 +0500 Subject: Fixed return type in function AccessMaskFromImageLayout --- .../src/VulkanUtilities/VulkanCommandBuffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp index b0d72e70..b646a2ed 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp @@ -152,12 +152,12 @@ static VkPipelineStageFlags PipelineStageFromAccessFlags(VkAccessFlags } -static VkPipelineStageFlags AccessMaskFromImageLayout(VkImageLayout Layout, - bool IsDstMask // false - source mask - // true - destination mask +static VkAccessFlags AccessMaskFromImageLayout(VkImageLayout Layout, + bool IsDstMask // false - source mask + // true - destination mask ) { - VkPipelineStageFlags AccessMask = 0; + VkAccessFlags AccessMask = 0; switch (Layout) { // does not support device access. This layout must only be used as the initialLayout member -- cgit v1.2.3 From 74a4a2d1f14db25e50a1f4fbd3611d55494dc5af Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 6 Feb 2021 17:11:35 -0800 Subject: Swap chain Vk: improved presentation mode selection (fixed https://github.com/DiligentGraphics/DiligentCore/issues/181) --- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 44 +++++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index ee266edc..bd7c0d55 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -331,19 +331,39 @@ void SwapChainVkImpl::CreateVulkanSwapChain() m_SwapChainDesc.Width = swapchainExtent.width; m_SwapChainDesc.Height = swapchainExtent.height; - // Mailbox is the lowest latency non-tearing presentation mode. - VkPresentModeKHR swapchainPresentMode = m_VSyncEnabled ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_MAILBOX_KHR; - - bool PresentModeSupported = std::find(presentModes.begin(), presentModes.end(), swapchainPresentMode) != presentModes.end(); - if (!PresentModeSupported) + // The FIFO present mode is guaranteed by the spec to always be supported. + VkPresentModeKHR PresentMode = VK_PRESENT_MODE_FIFO_KHR; { - VERIFY(swapchainPresentMode != VK_PRESENT_MODE_FIFO_KHR, "The FIFO present mode is guaranteed by the spec to be supported"); + std::vector PreferredPresentModes; + if (m_VSyncEnabled) + { + // FIFO relaxed waits for the next VSync, but if the frame is late, + // it still shows it even if VSync has already passed, which may + // result in tearing. + PreferredPresentModes.push_back(VK_PRESENT_MODE_FIFO_RELAXED_KHR); + PreferredPresentModes.push_back(VK_PRESENT_MODE_FIFO_KHR); + } + else + { + // Mailbox is the lowest latency non-tearing presentation mode. + PreferredPresentModes.push_back(VK_PRESENT_MODE_MAILBOX_KHR); + PreferredPresentModes.push_back(VK_PRESENT_MODE_IMMEDIATE_KHR); + PreferredPresentModes.push_back(VK_PRESENT_MODE_FIFO_KHR); + } - const char* PresentModeName = nullptr; + for (auto PreferredMode : PreferredPresentModes) + { + if (std::find(presentModes.begin(), presentModes.end(), PreferredMode) != presentModes.end()) + { + PresentMode = PreferredMode; + break; + } + } + const char* PresentModeName = nullptr; #define PRESENT_MODE_CASE(Mode) \ case Mode: PresentModeName = #Mode; break; - switch (swapchainPresentMode) + switch (PresentMode) { PRESENT_MODE_CASE(VK_PRESENT_MODE_IMMEDIATE_KHR) PRESENT_MODE_CASE(VK_PRESENT_MODE_MAILBOX_KHR) @@ -354,11 +374,7 @@ void SwapChainVkImpl::CreateVulkanSwapChain() default: PresentModeName = ""; } #undef PRESENT_MODE_CASE - LOG_WARNING_MESSAGE(PresentModeName, " is not supported. Defaulting to VK_PRESENT_MODE_FIFO_KHR"); - - swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; - // The FIFO present mode is guaranteed by the spec to be supported - VERIFY(std::find(presentModes.begin(), presentModes.end(), swapchainPresentMode) != presentModes.end(), "FIFO present mode must be supported"); + LOG_INFO_MESSAGE("Using ", PresentModeName, " swap chain present mode"); } // Determine the number of VkImage's to use in the swap chain. @@ -417,7 +433,7 @@ void SwapChainVkImpl::CreateVulkanSwapChain() swapchain_ci.preTransform = vkPreTransform; swapchain_ci.compositeAlpha = compositeAlpha; swapchain_ci.imageArrayLayers = 1; - swapchain_ci.presentMode = swapchainPresentMode; + swapchain_ci.presentMode = PresentMode; swapchain_ci.oldSwapchain = oldSwapchain; swapchain_ci.clipped = VK_TRUE; swapchain_ci.imageColorSpace = ColorSpace; -- cgit v1.2.3 From c6c5bb5ed3d4e3296e6f65e4072db5cf8bf2452c Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 7 Feb 2021 12:50:39 -0800 Subject: Reworked ExecuteCommandList(s) to take multiple command lists instead of one --- .../include/DeviceContextVkImpl.hpp | 5 +- .../include/RenderDeviceVkImpl.hpp | 12 +++-- .../src/DeviceContextVkImpl.cpp | 53 ++++++++++++++++------ .../src/RenderDeviceVkImpl.cpp | 4 +- 4 files changed, 52 insertions(+), 22 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp index d9a2c2f2..a385f8aa 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -233,8 +233,9 @@ public: /// Implementation of IDeviceContext::FinishCommandList() in Vulkan backend. virtual void DILIGENT_CALL_TYPE FinishCommandList(class ICommandList** ppCommandList) override final; - /// Implementation of IDeviceContext::ExecuteCommandList() in Vulkan backend. - virtual void DILIGENT_CALL_TYPE ExecuteCommandList(class ICommandList* pCommandList) override final; + /// Implementation of IDeviceContext::ExecuteCommandLists() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE ExecuteCommandLists(Uint32 NumCommandLists, + ICommandList* const* ppCommandLists) override final; /// Implementation of IDeviceContext::SignalFence() in Vulkan backend. virtual void DILIGENT_CALL_TYPE SignalFence(IFence* pFence, Uint64 Value) override final; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 37052725..60b8ebf1 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -230,12 +230,18 @@ private: virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; - // Submits command buffer for execution to the command queue - // Returns the submitted command buffer number and the fence value + // Submits command buffer(s) for execution to the command queue and + // returns the submitted command buffer(s) number and the fence value. + // If SubmitInfo contains multiple command buffers, they all are treated + // like one and sumbitted atomically. // Parameters: // * SubmittedCmdBuffNumber - submitted command buffer number // * SubmittedFenceValue - fence value associated with the submitted command buffer - void SubmitCommandBuffer(Uint32 QueueIndex, const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue, std::vector>>* pFences); + void SubmitCommandBuffer(Uint32 QueueIndex, + const VkSubmitInfo& SubmitInfo, + Uint64& SubmittedCmdBuffNumber, + Uint64& SubmittedFenceValue, + std::vector>>* pFences); std::shared_ptr m_VulkanInstance; std::unique_ptr m_PhysicalDevice; diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 8516a174..3259e07e 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -26,7 +26,10 @@ */ #include "pch.h" + #include +#include + #include "RenderDeviceVkImpl.hpp" #include "DeviceContextVkImpl.hpp" #include "PipelineStateVkImpl.hpp" @@ -2098,7 +2101,8 @@ void DeviceContextVkImpl::FinishCommandList(class ICommandList** ppCommandList) InvalidateState(); } -void DeviceContextVkImpl::ExecuteCommandList(class ICommandList* pCommandList) +void DeviceContextVkImpl::ExecuteCommandLists(Uint32 NumCommandLists, + ICommandList* const* ppCommandLists) { if (m_bIsDeferred) { @@ -2106,31 +2110,50 @@ void DeviceContextVkImpl::ExecuteCommandList(class ICommandList* pCommandList) return; } + if (NumCommandLists == 0) + return; + DEV_CHECK_ERR(ppCommandLists != nullptr, "ppCommandLists must not be null when NumCommandLists is not zero"); + Flush(); InvalidateState(); - CommandListVkImpl* pCmdListVk = ValidatedCast(pCommandList); - VkCommandBuffer vkCmdBuff = VK_NULL_HANDLE; + // TODO: replace with small_vector + std::vector vkCmdBuffs; + std::vector> DeferredCtxs; + vkCmdBuffs.reserve(NumCommandLists); + DeferredCtxs.reserve(NumCommandLists); + for (Uint32 i = 0; i < NumCommandLists; ++i) + { + auto* pCmdListVk = ValidatedCast(ppCommandLists[i]); + DEV_CHECK_ERR(pCmdListVk != nullptr, "Command list must not be null"); + VkCommandBuffer vkCmdBuff = VK_NULL_HANDLE; + RefCntAutoPtr pDeferredCtx; + pCmdListVk->Close(vkCmdBuff, pDeferredCtx); + VERIFY(vkCmdBuff != VK_NULL_HANDLE, "Trying to execute empty command buffer"); + VERIFY_EXPR(pDeferredCtx); + vkCmdBuffs.emplace_back(vkCmdBuff); + DeferredCtxs.emplace_back(std::move(pDeferredCtx)); + } - RefCntAutoPtr pDeferredCtx; - pCmdListVk->Close(vkCmdBuff, pDeferredCtx); - VERIFY(vkCmdBuff != VK_NULL_HANDLE, "Trying to execute empty command buffer"); - VERIFY_EXPR(pDeferredCtx); VkSubmitInfo SubmitInfo = {}; SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; SubmitInfo.pNext = nullptr; - SubmitInfo.commandBufferCount = 1; - SubmitInfo.pCommandBuffers = &vkCmdBuff; + SubmitInfo.commandBufferCount = NumCommandLists; + SubmitInfo.pCommandBuffers = vkCmdBuffs.data(); VERIFY_EXPR(m_PendingFences.empty()); - auto pDeferredCtxVkImpl = pDeferredCtx.RawPtr(); auto SubmittedFenceValue = m_pDevice->ExecuteCommandBuffer(m_CommandQueueId, SubmitInfo, this, nullptr); - // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context - pDeferredCtxVkImpl->m_SubmittedBuffersCmdQueueMask |= Uint64{1} << m_CommandQueueId; - // It is OK to dispose command buffer from another thread. We are not going to - // record any commands and only need to add the buffer to the queue - pDeferredCtxVkImpl->DisposeVkCmdBuffer(m_CommandQueueId, vkCmdBuff, SubmittedFenceValue); + + for (Uint32 i = 0; i < NumCommandLists; ++i) + { + auto pDeferredCtxVkImpl = DeferredCtxs[i].RawPtr(); + // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context + pDeferredCtxVkImpl->m_SubmittedBuffersCmdQueueMask |= Uint64{1} << m_CommandQueueId; + // It is OK to dispose command buffer from another thread. We are not going to + // record any commands and only need to add the buffer to the queue + pDeferredCtxVkImpl->DisposeVkCmdBuffer(m_CommandQueueId, std::move(vkCmdBuffs[i]), SubmittedFenceValue); + } } void DeviceContextVkImpl::SignalFence(IFence* pFence, Uint64 Value) diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 90c1a88e..b09d8068 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -399,7 +399,7 @@ void RenderDeviceVkImpl::SubmitCommandBuffer(Uint32 ) { // Submit the command list to the queue - auto CmbBuffInfo = TRenderDeviceBase::SubmitCommandBuffer(QueueIndex, SubmitInfo, true); + auto CmbBuffInfo = TRenderDeviceBase::SubmitCommandBuffer(QueueIndex, true, SubmitInfo); SubmittedFenceValue = CmbBuffInfo.FenceValue; SubmittedCmdBuffNumber = CmbBuffInfo.CmdBufferNumber; if (pFences != nullptr) @@ -443,7 +443,7 @@ void RenderDeviceVkImpl::FlushStaleResources(Uint32 CmdQueueIndex) // Submit empty command buffer to the queue. This will effectively signal the fence and // discard all resources VkSubmitInfo DummySumbitInfo = {}; - TRenderDeviceBase::SubmitCommandBuffer(0, DummySumbitInfo, true); + TRenderDeviceBase::SubmitCommandBuffer(0, true, DummySumbitInfo); } void RenderDeviceVkImpl::ReleaseStaleResources(bool ForceRelease) -- cgit v1.2.3 From 384e0295fe9b187d35d0d9dd53b7dbfa3aba4929 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 7 Feb 2021 15:15:53 -0800 Subject: Reworked DeviceContextVkImpl to submit deferred command list in the same batch with immediate context to avoid redundant submits --- .../include/CommandListVkImpl.hpp | 10 +-- .../include/DeviceContextVkImpl.hpp | 3 + .../src/DeviceContextVkImpl.cpp | 90 +++++++++++----------- 3 files changed, 54 insertions(+), 49 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp index 3b363e30..63707812 100644 --- a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp @@ -60,12 +60,12 @@ public: VERIFY(m_vkCmdBuff == VK_NULL_HANDLE && !m_pDeferredCtx, "Destroying command list that was never executed"); } - void Close(VkCommandBuffer& CmdBuff, - RefCntAutoPtr& pDeferredCtx) + VkCommandBuffer Close(RefCntAutoPtr& pDeferredCtx) { - CmdBuff = m_vkCmdBuff; - m_vkCmdBuff = VK_NULL_HANDLE; - pDeferredCtx = std::move(m_pDeferredCtx); + auto vkCmdBuff = m_vkCmdBuff; + m_vkCmdBuff = VK_NULL_HANDLE; + pDeferredCtx = std::move(m_pDeferredCtx); + return vkCmdBuff; } private: diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp index a385f8aa..9744e8ab 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -398,6 +398,9 @@ private: void CommitViewports(); void CommitScissorRects(); + void Flush(Uint32 NumCommandLists, + ICommandList* const* ppCommandLists); + __forceinline void TransitionOrVerifyBufferState(BufferVkImpl& Buffer, RESOURCE_STATE_TRANSITION_MODE TransitionMode, RESOURCE_STATE RequiredState, diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 3259e07e..8e03acac 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -961,6 +961,12 @@ void DeviceContextVkImpl::FinishFrame() } void DeviceContextVkImpl::Flush() +{ + Flush(0, nullptr); +} + +void DeviceContextVkImpl::Flush(Uint32 NumCommandLists, + ICommandList* const* ppCommandLists) { if (m_bIsDeferred) { @@ -979,10 +985,11 @@ void DeviceContextVkImpl::Flush() LOG_ERROR_MESSAGE("Flushing device context inside an active render pass."); } - VkSubmitInfo SubmitInfo = {}; - - SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - SubmitInfo.pNext = nullptr; + // TODO: replace with small_vector + std::vector vkCmdBuffs; + std::vector> DeferredCtxs; + vkCmdBuffs.reserve(NumCommandLists + 1); + DeferredCtxs.reserve(NumCommandLists + 1); auto vkCmdBuff = m_CommandBuffer.GetVkCmdBuffer(); if (vkCmdBuff != VK_NULL_HANDLE) @@ -1002,14 +1009,32 @@ void DeviceContextVkImpl::Flush() m_CommandBuffer.FlushBarriers(); m_CommandBuffer.EndCommandBuffer(); - SubmitInfo.commandBufferCount = 1; - SubmitInfo.pCommandBuffers = &vkCmdBuff; + vkCmdBuffs.push_back(vkCmdBuff); } } + // Add command buffers from deferred contexts + for (Uint32 i = 0; i < NumCommandLists; ++i) + { + auto* pCmdListVk = ValidatedCast(ppCommandLists[i]); + DEV_CHECK_ERR(pCmdListVk != nullptr, "Command list must not be null"); + RefCntAutoPtr pDeferredCtx; + vkCmdBuffs.emplace_back(pCmdListVk->Close(pDeferredCtx)); + VERIFY(vkCmdBuffs.back() != VK_NULL_HANDLE, "Trying to execute empty command buffer"); + VERIFY_EXPR(pDeferredCtx); + DeferredCtxs.emplace_back(std::move(pDeferredCtx)); + } + VERIFY_EXPR(m_VkWaitSemaphores.size() == m_WaitSemaphores.size()); VERIFY_EXPR(m_VkSignalSemaphores.size() == m_SignalSemaphores.size()); + VkSubmitInfo SubmitInfo = {}; + + SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + SubmitInfo.pNext = nullptr; + + SubmitInfo.commandBufferCount = static_cast(vkCmdBuffs.size()); + SubmitInfo.pCommandBuffers = vkCmdBuffs.data(); SubmitInfo.waitSemaphoreCount = static_cast(m_WaitSemaphores.size()); VERIFY_EXPR(m_WaitSemaphores.size() == m_WaitDstStageMasks.size()); SubmitInfo.pWaitSemaphores = SubmitInfo.waitSemaphoreCount != 0 ? m_VkWaitSemaphores.data() : nullptr; @@ -1028,11 +1053,25 @@ void DeviceContextVkImpl::Flush() m_VkSignalSemaphores.clear(); m_PendingFences.clear(); + size_t buff_idx = 0; if (vkCmdBuff != VK_NULL_HANDLE) { + VERIFY_EXPR(vkCmdBuffs[buff_idx] == vkCmdBuff); DisposeCurrentCmdBuffer(m_CommandQueueId, SubmittedFenceValue); + ++buff_idx; } + for (Uint32 i = 0; i < NumCommandLists; ++i, ++buff_idx) + { + auto pDeferredCtxVkImpl = DeferredCtxs[i].RawPtr(); + // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context + pDeferredCtxVkImpl->m_SubmittedBuffersCmdQueueMask.fetch_or(Uint64{1} << m_CommandQueueId); + // It is OK to dispose command buffer from another thread. We are not going to + // record any commands and only need to add the buffer to the queue + pDeferredCtxVkImpl->DisposeVkCmdBuffer(m_CommandQueueId, std::move(vkCmdBuffs[buff_idx]), SubmittedFenceValue); + } + VERIFY_EXPR(buff_idx == vkCmdBuffs.size()); + m_State = ContextState{}; m_DescrSetBindInfo.Reset(); m_CommandBuffer.Reset(); @@ -2114,46 +2153,9 @@ void DeviceContextVkImpl::ExecuteCommandLists(Uint32 NumCommandLis return; DEV_CHECK_ERR(ppCommandLists != nullptr, "ppCommandLists must not be null when NumCommandLists is not zero"); - Flush(); + Flush(NumCommandLists, ppCommandLists); InvalidateState(); - - // TODO: replace with small_vector - std::vector vkCmdBuffs; - std::vector> DeferredCtxs; - vkCmdBuffs.reserve(NumCommandLists); - DeferredCtxs.reserve(NumCommandLists); - for (Uint32 i = 0; i < NumCommandLists; ++i) - { - auto* pCmdListVk = ValidatedCast(ppCommandLists[i]); - DEV_CHECK_ERR(pCmdListVk != nullptr, "Command list must not be null"); - VkCommandBuffer vkCmdBuff = VK_NULL_HANDLE; - RefCntAutoPtr pDeferredCtx; - pCmdListVk->Close(vkCmdBuff, pDeferredCtx); - VERIFY(vkCmdBuff != VK_NULL_HANDLE, "Trying to execute empty command buffer"); - VERIFY_EXPR(pDeferredCtx); - vkCmdBuffs.emplace_back(vkCmdBuff); - DeferredCtxs.emplace_back(std::move(pDeferredCtx)); - } - - VkSubmitInfo SubmitInfo = {}; - - SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - SubmitInfo.pNext = nullptr; - SubmitInfo.commandBufferCount = NumCommandLists; - SubmitInfo.pCommandBuffers = vkCmdBuffs.data(); - VERIFY_EXPR(m_PendingFences.empty()); - auto SubmittedFenceValue = m_pDevice->ExecuteCommandBuffer(m_CommandQueueId, SubmitInfo, this, nullptr); - - for (Uint32 i = 0; i < NumCommandLists; ++i) - { - auto pDeferredCtxVkImpl = DeferredCtxs[i].RawPtr(); - // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context - pDeferredCtxVkImpl->m_SubmittedBuffersCmdQueueMask |= Uint64{1} << m_CommandQueueId; - // It is OK to dispose command buffer from another thread. We are not going to - // record any commands and only need to add the buffer to the queue - pDeferredCtxVkImpl->DisposeVkCmdBuffer(m_CommandQueueId, std::move(vkCmdBuffs[i]), SubmittedFenceValue); - } } void DeviceContextVkImpl::SignalFence(IFence* pFence, Uint64 Value) -- cgit v1.2.3