mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 23:16:31 +00:00
Batch together initial state application into fewer command buffers
* Some drivers struggle with one command buffer per resource and that's certainly inefficient, so batching work together (without going too far) keeps things working better.
This commit is contained in:
@@ -202,6 +202,49 @@ WrappedVulkan::~WrappedVulkan()
|
||||
delete m_Replay;
|
||||
}
|
||||
|
||||
VkCommandBuffer WrappedVulkan::GetInitStateCmd()
|
||||
{
|
||||
if(initStateCurBatch >= initialStateMaxBatch)
|
||||
{
|
||||
CloseInitStateCmd();
|
||||
}
|
||||
|
||||
if(initStateCurCmd == VK_NULL_HANDLE)
|
||||
{
|
||||
initStateCurCmd = GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
VkResult vkr = ObjDisp(initStateCurCmd)->BeginCommandBuffer(Unwrap(initStateCurCmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
if(IsReplayMode(m_State))
|
||||
{
|
||||
VkMarkerRegion::Begin("!!!!RenderDoc Internal: ApplyInitialContents batched list",
|
||||
initStateCurCmd);
|
||||
}
|
||||
}
|
||||
|
||||
initStateCurBatch++;
|
||||
|
||||
return initStateCurCmd;
|
||||
}
|
||||
|
||||
void WrappedVulkan::CloseInitStateCmd()
|
||||
{
|
||||
if(initStateCurCmd == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
VkMarkerRegion::End(initStateCurCmd);
|
||||
|
||||
VkResult vkr = ObjDisp(initStateCurCmd)->EndCommandBuffer(Unwrap(initStateCurCmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
initStateCurCmd = VK_NULL_HANDLE;
|
||||
initStateCurBatch = 0;
|
||||
}
|
||||
|
||||
VkCommandBuffer WrappedVulkan::GetNextCmd()
|
||||
{
|
||||
VkCommandBuffer ret;
|
||||
@@ -224,13 +267,12 @@ VkCommandBuffer WrappedVulkan::GetNextCmd()
|
||||
};
|
||||
VkResult vkr = ObjDisp(m_Device)->AllocateCommandBuffers(Unwrap(m_Device), &cmdInfo, &ret);
|
||||
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
if(m_SetDeviceLoaderData)
|
||||
m_SetDeviceLoaderData(m_Device, ret);
|
||||
else
|
||||
SetDispatchTableOverMagicNumber(m_Device, ret);
|
||||
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
GetResourceManager()->WrapResource(Unwrap(m_Device), ret);
|
||||
}
|
||||
|
||||
@@ -2768,6 +2810,9 @@ void WrappedVulkan::ApplyInitialContents()
|
||||
RENDERDOC_PROFILEFUNCTION();
|
||||
VkMarkerRegion region("ApplyInitialContents");
|
||||
|
||||
initStateCurBatch = 0;
|
||||
initStateCurCmd = VK_NULL_HANDLE;
|
||||
|
||||
// check that we have all external queues necessary
|
||||
for(size_t i = 0; i < m_ExternalQueues.size(); i++)
|
||||
{
|
||||
@@ -2816,6 +2861,15 @@ void WrappedVulkan::ApplyInitialContents()
|
||||
// actually apply the initial contents here
|
||||
GetResourceManager()->ApplyInitialContents();
|
||||
|
||||
// close the final command buffer
|
||||
if(initStateCurCmd != VK_NULL_HANDLE)
|
||||
{
|
||||
CloseInitStateCmd();
|
||||
}
|
||||
|
||||
initStateCurBatch = 0;
|
||||
initStateCurCmd = VK_NULL_HANDLE;
|
||||
|
||||
for(auto it = m_ImageStates.begin(); it != m_ImageStates.end(); ++it)
|
||||
{
|
||||
if(GetResourceManager()->HasCurrentResource(it->first))
|
||||
@@ -3359,6 +3413,15 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
{
|
||||
GetResourceManager()->CreateInitialContents(ser);
|
||||
|
||||
if(initStateCurCmd != VK_NULL_HANDLE)
|
||||
{
|
||||
CloseInitStateCmd();
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
SubmitAndFlushImageStateBarriers(m_cleanupImageBarriers);
|
||||
}
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
}
|
||||
else if(system == SystemChunk::InitialContents)
|
||||
|
||||
@@ -534,6 +534,10 @@ private:
|
||||
// -> FlushQ() ----back to freesems-------^
|
||||
} m_InternalCmds;
|
||||
|
||||
static const int initialStateMaxBatch = 100;
|
||||
int initStateCurBatch = 0;
|
||||
VkCommandBuffer initStateCurCmd = VK_NULL_HANDLE;
|
||||
|
||||
// Internal lumped/pooled memory allocations
|
||||
|
||||
// Each memory scope gets a separate vector of allocation objects. The vector contains the list of
|
||||
@@ -1087,6 +1091,8 @@ public:
|
||||
return m_PhysicalDevice;
|
||||
}
|
||||
VkCommandBuffer GetNextCmd();
|
||||
VkCommandBuffer GetInitStateCmd();
|
||||
void CloseInitStateCmd();
|
||||
void RemovePendingCommandBuffer(VkCommandBuffer cmd);
|
||||
void AddPendingCommandBuffer(VkCommandBuffer cmd);
|
||||
void AddFreeCommandBuffer(VkCommandBuffer cmd);
|
||||
|
||||
@@ -1794,21 +1794,6 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool)
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, rdcarray<VkImageMemoryBarrier>> GetExtQBarriers(
|
||||
const rdcarray<VkImageMemoryBarrier> &barriers)
|
||||
{
|
||||
std::map<uint32_t, rdcarray<VkImageMemoryBarrier>> extQBarriers;
|
||||
|
||||
for(auto barrierIt = barriers.begin(); barrierIt != barriers.end(); ++barrierIt)
|
||||
{
|
||||
if(barrierIt->srcQueueFamilyIndex != barrierIt->dstQueueFamilyIndex)
|
||||
{
|
||||
extQBarriers[barrierIt->srcQueueFamilyIndex].push_back(*barrierIt);
|
||||
}
|
||||
}
|
||||
return extQBarriers;
|
||||
}
|
||||
|
||||
void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialContents &initial)
|
||||
{
|
||||
VkResourceType type = initial.type;
|
||||
@@ -1971,10 +1956,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
if(IsBlockFormat(format) || IsYUVFormat(format))
|
||||
return;
|
||||
|
||||
VkCommandBuffer cmd = GetNextCmd();
|
||||
VkCommandBuffer cmd = GetInitStateCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkMarkerRegion::Begin(StringFormat::Fmt("Clear colour state for %s", ToStr(orig).c_str()),
|
||||
cmd);
|
||||
|
||||
ImageBarrierSequence setupBarriers;
|
||||
state->DiscardContents();
|
||||
@@ -1990,9 +1975,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToUnwrappedHandle<VkImage>(live),
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, &range);
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkMarkerRegion::End(cmd);
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
CloseInitStateCmd();
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
@@ -2001,10 +1987,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
}
|
||||
else if(initial.tag == VkInitialContents::ClearDepthStencilImage)
|
||||
{
|
||||
VkCommandBuffer cmd = GetNextCmd();
|
||||
VkCommandBuffer cmd = GetInitStateCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkMarkerRegion::Begin(StringFormat::Fmt("Clear depth state for %s", ToStr(orig).c_str()),
|
||||
cmd);
|
||||
|
||||
ImageBarrierSequence setupBarriers; // , cleanupBarriers;
|
||||
state->DiscardContents();
|
||||
@@ -2020,9 +2006,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1,
|
||||
&range);
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkMarkerRegion::End(cmd);
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
CloseInitStateCmd();
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
@@ -2039,6 +2026,8 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
|
||||
if(m_CreationInfo.m_Image[id].samples != VK_SAMPLE_COUNT_1_BIT)
|
||||
{
|
||||
CloseInitStateCmd();
|
||||
|
||||
VkCommandBuffer cmd = GetNextCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
@@ -2064,13 +2053,6 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
GetDebugManager()->CopyArrayToTex2DMS(ToUnwrappedHandle<VkImage>(live), Unwrap(arrayIm),
|
||||
c.extent, c.arrayLayers, (uint32_t)c.samples, fmt);
|
||||
|
||||
cmd = GetNextCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
@@ -2265,10 +2247,7 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
|
||||
if(copyRegions.size() + clearRegions.size() > 0)
|
||||
{
|
||||
VkCommandBuffer cmd = GetNextCmd();
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkCommandBuffer cmd = GetInitStateCmd();
|
||||
|
||||
VkMarkerRegion::Begin(StringFormat::Fmt("Initial state for %s", ToStr(orig).c_str()), cmd);
|
||||
|
||||
@@ -2303,12 +2282,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(cmd);
|
||||
|
||||
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
|
||||
#if ENABLED(SINGLE_FLUSH_VALIDATE)
|
||||
CloseInitStateCmd();
|
||||
SubmitAndFlushImageStateBarriers(m_setupImageBarriers);
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
|
||||
Reference in New Issue
Block a user