Add a "single flush validate" mode, to track device lost errors

* It tries to submit commands one at a time (except those replayed from
  the log) and flushes and checks status after each one.
This commit is contained in:
baldurk
2016-05-12 07:52:50 +02:00
parent c6b1307da5
commit 68228db199
6 changed files with 98 additions and 1 deletions
+5
View File
@@ -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);
+21 -1
View File
@@ -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];
}
}
+4
View File
@@ -150,6 +150,10 @@ vector<CounterResult> VulkanReplay::FetchCounters(const vector<uint32_t> &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);
+16
View File
@@ -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);
}
+16
View File
@@ -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
{
+36
View File
@@ -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<uint32_t> &passEvents)
@@ -1938,6 +1950,10 @@ void VulkanReplay::RenderMesh(uint32_t eventID, const vector<MeshFormat> &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<MeshFormat> &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,