diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 4b124cc5b..2ba88beb9 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -46,6 +46,11 @@ #include "vk_dispatchtables.h" +// uncomment this to cause every internal QueueSubmit to immediately call +// DeviceWaitIdle(), and to only submit one command buffer at once to narrow +// down the cause of device lost errors +//#define SINGLE_FLUSH_VALIDATE + ResourceFormat MakeResourceFormat(VkFormat fmt); VkFormat MakeVkFormat(ResourceFormat fmt); PrimitiveTopology MakePrimitiveTopology(VkPrimitiveTopology Topo, uint32_t patchControlPoints); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 4d2f97c3a..0d04bfd36 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -410,6 +410,10 @@ void WrappedVulkan::SubmitCmds() RDCASSERTEQUAL(vkr, VK_SUCCESS); } +#if defined(SINGLE_FLUSH_VALIDATE) + FlushQ(); +#endif + m_InternalCmds.submittedcmds.insert(m_InternalCmds.submittedcmds.end(), m_InternalCmds.pendingcmds.begin(), m_InternalCmds.pendingcmds.end()); m_InternalCmds.pendingcmds.clear(); } @@ -466,6 +470,14 @@ void WrappedVulkan::FlushQ() ObjDisp(m_Queue)->QueueWaitIdle(Unwrap(m_Queue)); } +#if defined(SINGLE_FLUSH_VALIDATE) + { + ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); + VkResult vkr = ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } +#endif + if(!m_InternalCmds.submittedcmds.empty()) { m_InternalCmds.freecmds.insert(m_InternalCmds.freecmds.end(), m_InternalCmds.submittedcmds.begin(), m_InternalCmds.submittedcmds.end()); @@ -1606,6 +1618,10 @@ void WrappedVulkan::ApplyInitialContents() vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } void WrappedVulkan::ContextProcessChunk(uint64_t offset, VulkanChunkType chunk, bool forceExecute) @@ -2104,6 +2120,10 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE; } + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } } @@ -2636,4 +2656,4 @@ const FetchDrawcall *WrappedVulkan::GetDrawcall(uint32_t eventID) return NULL; return m_Drawcalls[eventID]; -} \ No newline at end of file +} diff --git a/renderdoc/driver/vulkan/vk_counters.cpp b/renderdoc/driver/vulkan/vk_counters.cpp index f08469d0b..a78ea8ec2 100644 --- a/renderdoc/driver/vulkan/vk_counters.cpp +++ b/renderdoc/driver/vulkan/vk_counters.cpp @@ -150,6 +150,10 @@ vector VulkanReplay::FetchCounters(const vector &counte vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif GPUTimerCallback cb(m_pDriver, this, pool); diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index f042165ca..a45de35b3 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -2212,6 +2212,10 @@ void VulkanDebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_ vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif + while(sizeRemaining > 0) { VkDeviceSize chunkSize = RDCMIN(sizeRemaining, STAGE_BUFFER_BYTE_SIZE); @@ -3648,6 +3652,10 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif + size_t startEvent = 0; // if we're ClearBeforePass the first event will be a vkBeginRenderPass. @@ -3851,6 +3859,10 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve // end this cmd buffer so the image is in the right state for the next part vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); @@ -3925,6 +3937,10 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif return GetResID(m_OverlayImage); } diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index e16956069..b69ce4ea1 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -1872,6 +1872,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } else if(initial.num == eInitialContents_ClearDepthStencilImage) { @@ -1921,6 +1925,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } else { @@ -2007,6 +2015,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } else if(type == eResDeviceMemory) { @@ -2031,6 +2043,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + SubmitCmds(); +#endif } else { diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index d0b5738b4..939821e9a 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1241,6 +1241,10 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn vt->EndCommandBuffer(Unwrap(cmd)); +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif + return true; } @@ -1353,6 +1357,10 @@ void VulkanReplay::RenderCheckerboard(Vec3f light, Vec3f dark) vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } void VulkanReplay::RenderHighlightBox(float w, float h, float scale) @@ -1430,6 +1438,10 @@ void VulkanReplay::RenderHighlightBox(float w, float h, float scale) vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } ResourceId VulkanReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) @@ -1938,6 +1950,10 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector &second vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif + uint64_t maxIndex = cfg.position.numVerts; if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) @@ -2484,6 +2500,10 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector &second vkr = vt->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } bool VulkanReplay::CheckResizeOutputWindow(uint64_t id) @@ -2602,6 +2622,10 @@ void VulkanReplay::BindOutputWindow(uint64_t id, bool depth) outw.colBarrier[outw.curidx].srcAccessMask = outw.colBarrier[outw.curidx].dstAccessMask; vt->EndCommandBuffer(Unwrap(cmd)); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } void VulkanReplay::ClearOutputWindowColour(uint64_t id, float col[4]) @@ -2641,6 +2665,10 @@ void VulkanReplay::ClearOutputWindowColour(uint64_t id, float col[4]) outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; vt->EndCommandBuffer(Unwrap(cmd)); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } void VulkanReplay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) @@ -2679,6 +2707,10 @@ void VulkanReplay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t sten DoPipelineBarrier(cmd, 1, &outw.depthBarrier); vt->EndCommandBuffer(Unwrap(cmd)); + +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif } void VulkanReplay::FlipOutputWindow(uint64_t id) @@ -4157,6 +4189,10 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m // end this command buffer, the rendertexture below will use its own and we want to ensure ordering vt->EndCommandBuffer(Unwrap(cmd)); +#if defined(SINGLE_FLUSH_VALIDATE) + m_pDriver->SubmitCmds(); +#endif + // create framebuffer/render pass to render to VkAttachmentDescription attDesc = { 0, imCreateInfo.format, VK_SAMPLE_COUNT_1_BIT,