Add a heavy weight global memory barrier around frame restart

* This is reaaaally conservative, but will avoid bugs.
This commit is contained in:
baldurk
2016-01-07 20:16:06 +01:00
parent 9fc96e398a
commit 078bd67bec
3 changed files with 48 additions and 36 deletions
+45 -2
View File
@@ -1247,7 +1247,7 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
// (not undefined)
if(readType == READING)
{
GetResourceManager()->ApplyInitialContents();
ApplyInitialContents();
SubmitCmds();
FlushQ();
@@ -1372,6 +1372,49 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
m_State = READING;
}
void WrappedVulkan::ApplyInitialContents()
{
// add a global memory barrier to ensure all writes have finished and are synchronised
// add memory barrier to ensure this copy completes before any subsequent work
// this is a very blunt instrument but it ensures we don't get random artifacts around
// frame restart where we may be skipping a lot of important synchronisation
VkMemoryBarrier memBarrier = {
VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL,
VK_ACCESS_ALL_WRITE_BITS,
VK_ACCESS_ALL_READ_BITS,
};
void *barrier = (void *)&memBarrier;
VkCommandBuffer cmd = GetNextCmd();
VkResult vkr = VK_SUCCESS;
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT };
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
// actually apply the initial contents here
GetResourceManager()->ApplyInitialContents();
// likewise again to make sure the initial states are all applied
cmd = GetNextCmd();
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
}
void WrappedVulkan::ContextProcessChunk(uint64_t offset, VulkanChunkType chunk, bool forceExecute)
{
m_CurChunkOffset = offset;
@@ -1788,7 +1831,7 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
if(!partial)
{
GetResourceManager()->ApplyInitialContents();
ApplyInitialContents();
SubmitCmds();
FlushQ();
+2
View File
@@ -466,6 +466,8 @@ private:
bool Serialise_SparseInitialState(ResourceId id, WrappedVkImage *im, VulkanResourceManager::InitialContentData contents);
bool Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents);
bool Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceManager::InitialContentData contents);
void ApplyInitialContents();
vector<FetchAPIEvent> m_RootEvents, m_Events;
bool m_AddedDrawcall;
+1 -34
View File
@@ -790,17 +790,6 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourc
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
}
// add memory barrier to ensure this copy completes before any subsequent work
VkMemoryBarrier memBarrier = {
VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_ALL_READ_BITS,
};
void *barrier = (void *)&memBarrier;
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
@@ -929,17 +918,6 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceM
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
}
// add memory barrier to ensure this copy completes before any subsequent work
VkMemoryBarrier memBarrier = {
VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_ALL_READ_BITS,
};
void *barrier = (void *)&memBarrier;
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
@@ -2033,18 +2011,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager
VkBufferCopy region = { 0, dstMemOffs, datasize };
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
// add memory barrier to ensure this copy completes before any subsequent work
VkMemoryBarrier memBarrier = {
VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL,
VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_ALL_READ_BITS,
};
void *barrier = (void *)&memBarrier;
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
}