Refactor chunk-allocator to two level pool and allocator

* This fixes a bug with granular command buffer resetting. On vulkan we assume
  each command buffer owns the entirety of the pages it uses, so they can be
  reset all together. However there's nothing to stop an application from
  allocating from the same pool on the same thread interleaved to two command
  buffers. It's unexpected because of the threading rules but perfectly legal.
* In this case we need to ensure that the command buffers have disjoint sets of
  pages because they may not be reset together and one may be in used while
  another is reset and even re-recorded over. This can't be achieved with a
  single allocator, so instead we split the pool (that owns/provides/frees
  pages) from the allocator (that grabs whole pages and suballocates for
  chunks).
This commit is contained in:
baldurk
2020-11-26 11:39:28 +00:00
parent 593a903cf1
commit b8f7029d59
9 changed files with 314 additions and 263 deletions
+4 -1
View File
@@ -333,6 +333,7 @@ class WrappedID3D12CommandAllocator : public WrappedDeviceChild12<ID3D12CommandA
public:
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12CommandAllocator);
ChunkPagePool allocPool;
ChunkAllocator alloc;
bool m_Internal = false;
@@ -342,7 +343,7 @@ public:
};
WrappedID3D12CommandAllocator(ID3D12CommandAllocator *real, WrappedID3D12Device *device)
: WrappedDeviceChild12(real, device), alloc(32 * 1024)
: WrappedDeviceChild12(real, device), allocPool(32 * 1024), alloc(allocPool)
{
}
virtual ~WrappedID3D12CommandAllocator() { Shutdown(); }
@@ -353,6 +354,8 @@ public:
virtual HRESULT STDMETHODCALLTYPE Reset()
{
// reset the allocator. D3D12 munges the pool and the allocator together, so the allocator
// becomes redundant as the only pool client and the pool is reset together.
if(Atomic::CmpExch32(&m_ResetEnabled, 1, 1) == 1)
alloc.Reset();
return m_pReal->Reset();
+7 -2
View File
@@ -2048,10 +2048,15 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd)
// otherwise order must be preserved (vs. queue submits and desc set updates)
for(size_t i = 0; i < m_CmdBufferRecords.size(); i++)
{
RDCDEBUG("Adding chunks from command buffer %s",
ToStr(m_CmdBufferRecords[i]->GetResourceID()).c_str());
size_t prevSize = recordlist.size();
(void)prevSize;
m_CmdBufferRecords[i]->Insert(recordlist);
RDCDEBUG("Adding %u chunks to file serialiser from command buffer %s",
(uint32_t)recordlist.size(), ToStr(m_CmdBufferRecords[i]->GetResourceID()).c_str());
RDCDEBUG("Added %zu chunks to file serialiser", recordlist.size() - prevSize);
}
m_FrameCaptureRecord->Insert(recordlist);
+21 -15
View File
@@ -989,19 +989,35 @@ struct MemRefs;
struct ImgRefs;
struct ImageState;
struct CmdPoolInfo
{
CmdPoolInfo() : pool(4 * 1024) {}
CmdPoolInfo(const CmdPoolInfo &) = delete;
CmdPoolInfo(CmdPoolInfo &&) = delete;
CmdPoolInfo &operator=(const CmdPoolInfo &) = delete;
~CmdPoolInfo()
{ // nothing to do, pool will free its pages
}
uint32_t queueFamilyIndex;
ChunkPagePool pool;
};
struct CmdBufferRecordingInfo
{
CmdBufferRecordingInfo(CmdPoolInfo &pool) : alloc(pool.pool) {}
CmdBufferRecordingInfo(const CmdBufferRecordingInfo &) = delete;
CmdBufferRecordingInfo(CmdBufferRecordingInfo &&) = delete;
CmdBufferRecordingInfo &operator=(const CmdBufferRecordingInfo &) = delete;
~CmdBufferRecordingInfo()
{
if(alloc)
alloc->ResetPageSet(pageSet);
// nothing to do explicitly, the alloc destructor will clean up any pages it holds
}
VkDevice device;
VkCommandBufferAllocateInfo allocInfo;
ChunkAllocator *alloc = NULL;
rdcarray<uint32_t> pageSet;
ChunkAllocator alloc;
VkResourceRecord *framebuffer = NULL;
VkResourceRecord *allocRecord = NULL;
@@ -1076,17 +1092,6 @@ struct DescPoolInfo
rdcarray<VkResourceRecord *> freelist;
};
struct CmdPoolInfo
{
CmdPoolInfo(uint32_t allocPageSize, bool allowReset)
: alloc(allocPageSize), allowCmdBufReset(allowReset)
{
}
uint32_t queueFamilyIndex;
bool allowCmdBufReset;
ChunkAllocator alloc;
};
struct MemMapState
{
VkBuffer wholeMemBuf = VK_NULL_HANDLE;
@@ -2129,6 +2134,7 @@ public:
{
RDCASSERT(cmdInfo);
SwapChunks(bakedCommands);
cmdInfo->alloc.swap(bakedCommands->cmdInfo->alloc);
cmdInfo->boundDescSets.swap(bakedCommands->cmdInfo->boundDescSets);
cmdInfo->subcmds.swap(bakedCommands->cmdInfo->subcmds);
cmdInfo->sparse.swap(bakedCommands->cmdInfo->sparse);
@@ -523,14 +523,12 @@ VkResult WrappedVulkan::vkCreateCommandPool(VkDevice device,
chunk = scope.Get();
}
bool allowReset = (pCreateInfo->flags & VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) != 0;
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pCmdPool);
// if we can reset command buffers we need to allocate smaller pages because command buffers
// may be reset, so each page can only be allocated by at most one command buffer.
// if not, we allocate bigger pages on the assumption that the application won't waste memory
// by allocating lots of command pools that barely get used.
record->cmdPoolInfo = new CmdPoolInfo(allowReset ? 4 * 1024 : 128 * 1024, allowReset);
record->cmdPoolInfo = new CmdPoolInfo;
record->cmdPoolInfo->queueFamilyIndex = pCreateInfo->queueFamilyIndex;
record->AddChunk(chunk);
}
@@ -547,7 +545,7 @@ VkResult WrappedVulkan::vkResetCommandPool(VkDevice device, VkCommandPool cmdPoo
VkCommandPoolResetFlags flags)
{
if(Atomic::CmpExch32(&m_ReuseEnabled, 1, 1) == 1)
GetRecord(cmdPool)->cmdPoolInfo->alloc.Reset();
GetRecord(cmdPool)->cmdPoolInfo->pool.Reset();
return ObjDisp(device)->ResetCommandPool(Unwrap(device), Unwrap(cmdPool), flags);
}
@@ -555,7 +553,7 @@ VkResult WrappedVulkan::vkResetCommandPool(VkDevice device, VkCommandPool cmdPoo
void WrappedVulkan::vkTrimCommandPool(VkDevice device, VkCommandPool commandPool,
VkCommandPoolTrimFlags flags)
{
GetRecord(commandPool)->cmdPoolInfo->alloc.Trim();
GetRecord(commandPool)->cmdPoolInfo->pool.Trim();
return ObjDisp(device)->TrimCommandPool(Unwrap(device), Unwrap(commandPool), flags);
}
@@ -687,7 +685,7 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device,
// we don't support any extensions on VkCommandBufferCreateInfo anyway
RDCASSERT(pAllocateInfo->pNext == NULL);
record->cmdInfo = new CmdBufferRecordingInfo();
record->cmdInfo = new CmdBufferRecordingInfo(*record->pool->cmdPoolInfo);
record->cmdInfo->device = device;
record->cmdInfo->allocInfo = *pAllocateInfo;
@@ -696,7 +694,6 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device,
record->cmdInfo->present = false;
record->cmdInfo->beginCapture = false;
record->cmdInfo->endCapture = false;
record->cmdInfo->alloc = &record->pool->cmdPoolInfo->alloc;
}
else
{
@@ -1028,10 +1025,9 @@ VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
record->bakedCommands->DisableChunkLocking();
record->bakedCommands->InternalResource = true;
record->bakedCommands->Resource = (WrappedVkRes *)commandBuffer;
record->bakedCommands->cmdInfo = new CmdBufferRecordingInfo();
record->bakedCommands->cmdInfo = new CmdBufferRecordingInfo(*record->pool->cmdPoolInfo);
record->bakedCommands->cmdInfo->device = record->cmdInfo->device;
record->bakedCommands->cmdInfo->alloc = record->cmdInfo->alloc;
record->bakedCommands->cmdInfo->allocInfo = record->cmdInfo->allocInfo;
record->bakedCommands->cmdInfo->present = false;
record->bakedCommands->cmdInfo->beginCapture = false;
@@ -1043,7 +1039,7 @@ VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkBeginCommandBuffer);
Serialise_vkBeginCommandBuffer(ser, commandBuffer, pBeginInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
if(pBeginInfo->pInheritanceInfo)
@@ -1242,13 +1238,9 @@ VkResult WrappedVulkan::vkEndCommandBuffer(VkCommandBuffer commandBuffer)
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkEndCommandBuffer);
Serialise_vkEndCommandBuffer(ser, commandBuffer);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
// if we can't reset command buffers there's no need to claim a set of pages
if(record->pool->cmdPoolInfo->allowCmdBufReset)
record->bakedCommands->cmdInfo->pageSet = record->cmdInfo->alloc->GetPageSet();
record->Bake();
}
@@ -1598,7 +1590,7 @@ void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginRenderPass);
Serialise_vkCmdBeginRenderPass(ser, commandBuffer, pRenderPassBegin, contents);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read);
VkResourceRecord *fb = GetRecord(pRenderPassBegin->framebuffer);
@@ -1764,7 +1756,7 @@ void WrappedVulkan::vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassCon
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdNextSubpass);
Serialise_vkCmdNextSubpass(ser, commandBuffer, contents);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1896,7 +1888,7 @@ void WrappedVulkan::vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndRenderPass);
Serialise_vkCmdEndRenderPass(ser, commandBuffer);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
const rdcarray<VkImageMemoryBarrier> &barriers = record->cmdInfo->rpbarriers;
@@ -2209,7 +2201,7 @@ void WrappedVulkan::vkCmdBeginRenderPass2(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginRenderPass2);
Serialise_vkCmdBeginRenderPass2(ser, commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read);
VkResourceRecord *fb = GetRecord(pRenderPassBegin->framebuffer);
@@ -2401,7 +2393,7 @@ void WrappedVulkan::vkCmdNextSubpass2(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdNextSubpass2);
Serialise_vkCmdNextSubpass2(ser, commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -2539,7 +2531,7 @@ void WrappedVulkan::vkCmdEndRenderPass2(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndRenderPass2);
Serialise_vkCmdEndRenderPass2(ser, commandBuffer, pSubpassEndInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
const rdcarray<VkImageMemoryBarrier> &barriers = record->cmdInfo->rpbarriers;
@@ -2766,7 +2758,7 @@ void WrappedVulkan::vkCmdBindPipeline(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindPipeline);
Serialise_vkCmdBindPipeline(ser, commandBuffer, pipelineBindPoint, pipeline);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(pipeline), eFrameRef_Read);
}
}
@@ -2925,7 +2917,7 @@ void WrappedVulkan::vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
Serialise_vkCmdBindDescriptorSets(ser, commandBuffer, pipelineBindPoint, layout, firstSet,
setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read);
record->cmdInfo->boundDescSets.insert(pDescriptorSets, pDescriptorSets + setCount);
}
@@ -3014,7 +3006,7 @@ void WrappedVulkan::vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32
Serialise_vkCmdBindVertexBuffers(ser, commandBuffer, firstBinding, bindingCount, pBuffers,
pOffsets);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < bindingCount; i++)
{
// binding NULL is legal with robustness2
@@ -3118,7 +3110,7 @@ void WrappedVulkan::vkCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, ui
Serialise_vkCmdBindVertexBuffers2EXT(ser, commandBuffer, firstBinding, bindingCount, pBuffers,
pOffsets, pSizes, pStrides);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < bindingCount; i++)
{
// binding NULL is legal with robustness2
@@ -3207,7 +3199,7 @@ void WrappedVulkan::vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindIndexBuffer);
Serialise_vkCmdBindIndexBuffer(ser, commandBuffer, buffer, offset, indexType);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(buffer), 0, VK_WHOLE_SIZE, eFrameRef_Read);
}
}
@@ -3271,7 +3263,7 @@ void WrappedVulkan::vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer de
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdUpdateBuffer);
Serialise_vkCmdUpdateBuffer(ser, commandBuffer, destBuffer, destOffset, dataSize, pData);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(destBuffer), destOffset, dataSize,
eFrameRef_CompleteWrite);
@@ -3348,7 +3340,7 @@ void WrappedVulkan::vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipeline
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdPushConstants);
Serialise_vkCmdPushConstants(ser, commandBuffer, layout, stageFlags, start, length, values);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read);
}
}
@@ -3544,7 +3536,7 @@ void WrappedVulkan::vkCmdPipelineBarrier(
pBufferMemoryBarriers, imageMemoryBarrierCount,
pImageMemoryBarriers);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
if(imageMemoryBarrierCount > 0)
{
@@ -3610,7 +3602,7 @@ void WrappedVulkan::vkCmdWriteTimestamp(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdWriteTimestamp);
Serialise_vkCmdWriteTimestamp(ser, commandBuffer, pipelineStage, queryPool, query);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
@@ -3680,7 +3672,7 @@ void WrappedVulkan::vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQ
Serialise_vkCmdCopyQueryPoolResults(ser, commandBuffer, queryPool, firstQuery, queryCount,
destBuffer, destOffset, destStride, flags);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
@@ -3744,7 +3736,7 @@ void WrappedVulkan::vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool q
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginQuery);
Serialise_vkCmdBeginQuery(ser, commandBuffer, queryPool, query, flags);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
}
@@ -3796,7 +3788,7 @@ void WrappedVulkan::vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool que
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndQuery);
Serialise_vkCmdEndQuery(ser, commandBuffer, queryPool, query);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
}
@@ -3857,7 +3849,7 @@ void WrappedVulkan::vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPo
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdResetQueryPool);
Serialise_vkCmdResetQueryPool(ser, commandBuffer, queryPool, firstQuery, queryCount);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
}
@@ -4189,7 +4181,7 @@ void WrappedVulkan::vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdExecuteCommands);
Serialise_vkCmdExecuteCommands(ser, commandBuffer, commandBufferCount, pCommandBuffers);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < commandBufferCount; i++)
{
@@ -4274,7 +4266,7 @@ void WrappedVulkan::vkCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerBeginEXT);
Serialise_vkCmdDebugMarkerBeginEXT(ser, commandBuffer, pMarker);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -4347,7 +4339,7 @@ void WrappedVulkan::vkCmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer)
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerEndEXT);
Serialise_vkCmdDebugMarkerEndEXT(ser, commandBuffer);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -4417,7 +4409,7 @@ void WrappedVulkan::vkCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerInsertEXT);
Serialise_vkCmdDebugMarkerInsertEXT(ser, commandBuffer, pMarker);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -4756,7 +4748,7 @@ void WrappedVulkan::vkCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,
Serialise_vkCmdPushDescriptorSetKHR(ser, commandBuffer, pipelineBindPoint, layout, set,
descriptorWriteCount, pDescriptorWrites);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < descriptorWriteCount; i++)
{
const VkWriteDescriptorSet &write = pDescriptorWrites[i];
@@ -5040,7 +5032,7 @@ void WrappedVulkan::vkCmdPushDescriptorSetWithTemplateKHR(
Serialise_vkCmdPushDescriptorSetWithTemplateKHR(ser, commandBuffer, descriptorUpdateTemplate,
layout, set, pData);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(descriptorUpdateTemplate), eFrameRef_Read);
for(size_t i = 0; i < frameRefs.size(); i++)
record->MarkResourceFrameReferenced(frameRefs[i].first, frameRefs[i].second);
@@ -5120,7 +5112,7 @@ void WrappedVulkan::vkCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer,
Serialise_vkCmdWriteBufferMarkerAMD(ser, commandBuffer, pipelineStage, dstBuffer, dstOffset,
marker);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(dstBuffer), dstOffset, 4, eFrameRef_PartialWrite);
}
@@ -5192,7 +5184,7 @@ void WrappedVulkan::vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginDebugUtilsLabelEXT);
Serialise_vkCmdBeginDebugUtilsLabelEXT(ser, commandBuffer, pLabelInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -5265,7 +5257,7 @@ void WrappedVulkan::vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer)
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndDebugUtilsLabelEXT);
Serialise_vkCmdEndDebugUtilsLabelEXT(ser, commandBuffer);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -5335,7 +5327,7 @@ void WrappedVulkan::vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdInsertDebugUtilsLabelEXT);
Serialise_vkCmdInsertDebugUtilsLabelEXT(ser, commandBuffer, pLabelInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -5386,7 +5378,7 @@ void WrappedVulkan::vkCmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t d
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDeviceMask);
Serialise_vkCmdSetDeviceMask(ser, commandBuffer, deviceMask);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -5476,7 +5468,7 @@ void WrappedVulkan::vkCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer command
Serialise_vkCmdBindTransformFeedbackBuffersEXT(ser, commandBuffer, firstBinding, bindingCount,
pBuffers, pOffsets, pSizes);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < bindingCount; i++)
{
VkDeviceSize size = VK_WHOLE_SIZE;
@@ -5572,7 +5564,7 @@ void WrappedVulkan::vkCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer
Serialise_vkCmdBeginTransformFeedbackEXT(ser, commandBuffer, firstBuffer, bufferCount,
pCounterBuffers, pCounterBufferOffsets);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < bufferCount; i++)
{
if(pCounterBuffers && pCounterBuffers[i] != VK_NULL_HANDLE)
@@ -5660,7 +5652,7 @@ void WrappedVulkan::vkCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer,
Serialise_vkCmdEndTransformFeedbackEXT(ser, commandBuffer, firstBuffer, bufferCount,
pCounterBuffers, pCounterBufferOffsets);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < bufferCount; i++)
{
if(pCounterBuffers && pCounterBuffers[i] != VK_NULL_HANDLE)
@@ -5728,7 +5720,7 @@ void WrappedVulkan::vkCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQ
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginQueryIndexedEXT);
Serialise_vkCmdBeginQueryIndexedEXT(ser, commandBuffer, queryPool, query, flags, index);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
}
@@ -5786,7 +5778,7 @@ void WrappedVulkan::vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQue
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndQueryIndexedEXT);
Serialise_vkCmdEndQueryIndexedEXT(ser, commandBuffer, queryPool, query, index);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read);
}
}
@@ -5857,7 +5849,7 @@ void WrappedVulkan::vkCmdBeginConditionalRenderingEXT(
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginConditionalRenderingEXT);
Serialise_vkCmdBeginConditionalRenderingEXT(ser, commandBuffer, pConditionalRenderingBegin);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
VkResourceRecord *buf = GetRecord(pConditionalRenderingBegin->buffer);
@@ -5918,7 +5910,7 @@ void WrappedVulkan::vkCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffe
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndConditionalRenderingEXT);
Serialise_vkCmdEndConditionalRenderingEXT(ser, commandBuffer);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -274,7 +274,7 @@ void WrappedVulkan::vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCoun
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDraw);
Serialise_vkCmdDraw(ser, commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -376,7 +376,7 @@ void WrappedVulkan::vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t ind
Serialise_vkCmdDrawIndexed(ser, commandBuffer, indexCount, instanceCount, firstIndex,
vertexOffset, firstInstance);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -792,7 +792,7 @@ void WrappedVulkan::vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer bu
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDrawIndirect);
Serialise_vkCmdDrawIndirect(ser, commandBuffer, buffer, offset, count, stride);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
VkDeviceSize size = 0;
if(count > 0)
@@ -1178,7 +1178,7 @@ void WrappedVulkan::vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBu
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDrawIndexedIndirect);
Serialise_vkCmdDrawIndexedIndirect(ser, commandBuffer, buffer, offset, count, stride);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
VkDeviceSize size = 0;
if(count > 0)
@@ -1262,7 +1262,7 @@ void WrappedVulkan::vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uin
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDispatch);
Serialise_vkCmdDispatch(ser, commandBuffer, x, y, z);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1351,7 +1351,7 @@ void WrappedVulkan::vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffe
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDispatchIndirect);
Serialise_vkCmdDispatchIndirect(ser, commandBuffer, buffer, offset);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(buffer), offset, sizeof(VkDispatchIndirectCommand),
eFrameRef_Read);
@@ -1478,7 +1478,7 @@ void WrappedVulkan::vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcIma
Serialise_vkCmdBlitImage(ser, commandBuffer, srcImage, srcImageLayout, destImage,
destImageLayout, regionCount, pRegions, filter);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < regionCount; i++)
{
@@ -1627,7 +1627,7 @@ void WrappedVulkan::vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage src
Serialise_vkCmdResolveImage(ser, commandBuffer, srcImage, srcImageLayout, destImage,
destImageLayout, regionCount, pRegions);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < regionCount; i++)
{
@@ -1765,7 +1765,7 @@ void WrappedVulkan::vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcIma
Serialise_vkCmdCopyImage(ser, commandBuffer, srcImage, srcImageLayout, destImage,
destImageLayout, regionCount, pRegions);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < regionCount; i++)
{
const VkImageCopy &region = pRegions[i];
@@ -1888,7 +1888,7 @@ void WrappedVulkan::vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuff
Serialise_vkCmdCopyBufferToImage(ser, commandBuffer, srcBuffer, destImage, destImageLayout,
regionCount, pRegions);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferImageCopyFrameReferenced(GetRecord(srcBuffer), GetRecord(destImage),
regionCount, pRegions, eFrameRef_Read,
eFrameRef_CompleteWrite);
@@ -2001,7 +2001,7 @@ void WrappedVulkan::vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImag
Serialise_vkCmdCopyImageToBuffer(ser, commandBuffer, srcImage, srcImageLayout, destBuffer,
regionCount, pRegions);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferImageCopyFrameReferenced(GetRecord(destBuffer), GetRecord(srcImage),
regionCount, pRegions, eFrameRef_CompleteWrite,
eFrameRef_Read);
@@ -2114,7 +2114,7 @@ void WrappedVulkan::vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcB
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyBuffer);
Serialise_vkCmdCopyBuffer(ser, commandBuffer, srcBuffer, destBuffer, regionCount, pRegions);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < regionCount; i++)
{
record->MarkBufferFrameReferenced(GetRecord(srcBuffer), pRegions[i].srcOffset,
@@ -2211,7 +2211,7 @@ void WrappedVulkan::vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dest
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdFillBuffer);
Serialise_vkCmdFillBuffer(ser, commandBuffer, destBuffer, destOffset, fillSize, data);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(destBuffer), destOffset, fillSize,
eFrameRef_CompleteWrite);
@@ -2320,7 +2320,7 @@ void WrappedVulkan::vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage
Serialise_vkCmdClearColorImage(ser, commandBuffer, image, imageLayout, pColor, rangeCount,
pRanges);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read);
VkResourceRecord *imageRecord = GetRecord(image);
if(imageRecord->resInfo && imageRecord->resInfo->IsSparse())
@@ -2437,7 +2437,7 @@ void WrappedVulkan::vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, V
Serialise_vkCmdClearDepthStencilImage(ser, commandBuffer, image, imageLayout, pDepthStencil,
rangeCount, pRanges);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(image), eFrameRef_PartialWrite);
record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read);
VkResourceRecord *imageRecord = GetRecord(image);
@@ -2591,7 +2591,7 @@ void WrappedVulkan::vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_
Serialise_vkCmdClearAttachments(ser, commandBuffer, attachmentCount, pAttachments, rectCount,
pRects);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
// image/attachments are referenced when the render pass is started and the framebuffer is
// bound.
@@ -2691,7 +2691,7 @@ void WrappedVulkan::vkCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t ba
Serialise_vkCmdDispatchBase(ser, commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
groupCountY, groupCountZ);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -3002,7 +3002,7 @@ void WrappedVulkan::vkCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuff
Serialise_vkCmdDrawIndirectCount(ser, commandBuffer, buffer, offset, countBuffer,
countBufferOffset, maxDrawCount, stride);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(buffer), offset,
stride * (maxDrawCount - 1) + sizeof(VkDrawIndirectCommand),
@@ -3365,7 +3365,7 @@ void WrappedVulkan::vkCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer,
Serialise_vkCmdDrawIndexedIndirectCount(ser, commandBuffer, buffer, offset, countBuffer,
countBufferOffset, maxDrawCount, stride);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(buffer), offset,
stride * (maxDrawCount - 1) + sizeof(VkDrawIndirectCommand),
@@ -3493,7 +3493,7 @@ void WrappedVulkan::vkCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer,
counterBuffer, counterBufferOffset, counterOffset,
vertexStride);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkBufferFrameReferenced(GetRecord(counterBuffer), counterBufferOffset, 4,
eFrameRef_Read);
@@ -3612,7 +3612,7 @@ void WrappedVulkan::vkCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyBuffer2KHR);
Serialise_vkCmdCopyBuffer2KHR(ser, commandBuffer, pCopyBufferInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < pCopyBufferInfo->regionCount; i++)
{
@@ -3735,7 +3735,7 @@ void WrappedVulkan::vkCmdCopyImage2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyImage2KHR);
Serialise_vkCmdCopyImage2KHR(ser, commandBuffer, pCopyImageInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < pCopyImageInfo->regionCount; i++)
{
@@ -3865,7 +3865,7 @@ void WrappedVulkan::vkCmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyBufferToImage2KHR);
Serialise_vkCmdCopyBufferToImage2KHR(ser, commandBuffer, pCopyBufferToImageInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
// downcast the VkBufferImageCopy2KHR to VkBufferImageCopy for ease of use, as we don't need
// anything in the next chains here
@@ -3998,7 +3998,7 @@ void WrappedVulkan::vkCmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyImageToBuffer2KHR);
Serialise_vkCmdCopyImageToBuffer2KHR(ser, commandBuffer, pCopyImageToBufferInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
// downcast the VkBufferImageCopy2KHR to VkBufferImageCopy for ease of use, as we don't need
// anything in the next chains here
@@ -4133,7 +4133,7 @@ void WrappedVulkan::vkCmdBlitImage2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBlitImage2KHR);
Serialise_vkCmdBlitImage2KHR(ser, commandBuffer, pBlitImageInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < pBlitImageInfo->regionCount; i++)
{
@@ -4278,7 +4278,7 @@ void WrappedVulkan::vkCmdResolveImage2KHR(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdResolveImage2KHR);
Serialise_vkCmdResolveImage2KHR(ser, commandBuffer, pResolveImageInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < pResolveImageInfo->regionCount; i++)
{
@@ -89,7 +89,7 @@ void WrappedVulkan::vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t fir
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetViewport);
Serialise_vkCmdSetViewport(ser, commandBuffer, firstViewport, viewportCount, pViewports);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -153,7 +153,7 @@ void WrappedVulkan::vkCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetViewportWithCountEXT);
Serialise_vkCmdSetViewportWithCountEXT(ser, commandBuffer, viewportCount, pViewports);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -221,7 +221,7 @@ void WrappedVulkan::vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firs
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetScissor);
Serialise_vkCmdSetScissor(ser, commandBuffer, firstScissor, scissorCount, pScissors);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -284,7 +284,7 @@ void WrappedVulkan::vkCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetScissorWithCountEXT);
Serialise_vkCmdSetScissorWithCountEXT(ser, commandBuffer, scissorCount, pScissors);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -341,7 +341,7 @@ void WrappedVulkan::vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineW
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetLineWidth);
Serialise_vkCmdSetLineWidth(ser, commandBuffer, lineWidth);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -408,7 +408,7 @@ void WrappedVulkan::vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depth
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthBias);
Serialise_vkCmdSetDepthBias(ser, commandBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -467,7 +467,7 @@ void WrappedVulkan::vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetBlendConstants);
Serialise_vkCmdSetBlendConstants(ser, commandBuffer, blendConst);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -529,7 +529,7 @@ void WrappedVulkan::vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float min
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthBounds);
Serialise_vkCmdSetDepthBounds(ser, commandBuffer, minDepthBounds, maxDepthBounds);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -595,7 +595,7 @@ void WrappedVulkan::vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetStencilCompareMask);
Serialise_vkCmdSetStencilCompareMask(ser, commandBuffer, faceMask, compareMask);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -661,7 +661,7 @@ void WrappedVulkan::vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetStencilWriteMask);
Serialise_vkCmdSetStencilWriteMask(ser, commandBuffer, faceMask, writeMask);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -727,7 +727,7 @@ void WrappedVulkan::vkCmdSetStencilReference(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetStencilReference);
Serialise_vkCmdSetStencilReference(ser, commandBuffer, faceMask, reference);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -791,7 +791,7 @@ void WrappedVulkan::vkCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetSampleLocationsEXT);
Serialise_vkCmdSetSampleLocationsEXT(ser, commandBuffer, pSampleLocationsInfo);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -866,7 +866,7 @@ void WrappedVulkan::vkCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer,
Serialise_vkCmdSetDiscardRectangleEXT(ser, commandBuffer, firstDiscardRectangle,
discardRectangleCount, pDiscardRectangles);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -932,7 +932,7 @@ void WrappedVulkan::vkCmdSetLineStippleEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetLineStippleEXT);
Serialise_vkCmdSetLineStippleEXT(ser, commandBuffer, lineStippleFactor, lineStipplePattern);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -990,7 +990,7 @@ void WrappedVulkan::vkCmdSetCullModeEXT(VkCommandBuffer commandBuffer, VkCullMod
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetCullModeEXT);
Serialise_vkCmdSetCullModeEXT(ser, commandBuffer, cullMode);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1048,7 +1048,7 @@ void WrappedVulkan::vkCmdSetFrontFaceEXT(VkCommandBuffer commandBuffer, VkFrontF
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetFrontFaceEXT);
Serialise_vkCmdSetFrontFaceEXT(ser, commandBuffer, frontFace);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1113,7 +1113,7 @@ void WrappedVulkan::vkCmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetPrimitiveTopologyEXT);
Serialise_vkCmdSetPrimitiveTopologyEXT(ser, commandBuffer, primitiveTopology);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1173,7 +1173,7 @@ void WrappedVulkan::vkCmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer, Vk
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthTestEnableEXT);
Serialise_vkCmdSetDepthTestEnableEXT(ser, commandBuffer, depthTestEnable);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1234,7 +1234,7 @@ void WrappedVulkan::vkCmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthWriteEnableEXT);
Serialise_vkCmdSetDepthWriteEnableEXT(ser, commandBuffer, depthWriteEnable);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1295,7 +1295,7 @@ void WrappedVulkan::vkCmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthCompareOpEXT);
Serialise_vkCmdSetDepthCompareOpEXT(ser, commandBuffer, depthCompareOp);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1357,7 +1357,7 @@ void WrappedVulkan::vkCmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuff
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetDepthBoundsTestEnableEXT);
Serialise_vkCmdSetDepthBoundsTestEnableEXT(ser, commandBuffer, depthBoundsTestEnable);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1418,7 +1418,7 @@ void WrappedVulkan::vkCmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetStencilTestEnableEXT);
Serialise_vkCmdSetStencilTestEnableEXT(ser, commandBuffer, stencilTestEnable);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -1502,7 +1502,7 @@ void WrappedVulkan::vkCmdSetStencilOpEXT(VkCommandBuffer commandBuffer, VkStenci
Serialise_vkCmdSetStencilOpEXT(ser, commandBuffer, faceMask, failOp, passOp, depthFailOp,
compareOp);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
}
}
@@ -686,7 +686,7 @@ void WrappedVulkan::vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetEvent);
Serialise_vkCmdSetEvent(ser, commandBuffer, event, stageMask);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read);
}
}
@@ -743,7 +743,7 @@ void WrappedVulkan::vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdResetEvent);
Serialise_vkCmdResetEvent(ser, commandBuffer, event, stageMask);
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read);
}
}
@@ -948,7 +948,7 @@ void WrappedVulkan::vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t even
imageMemoryBarrierCount, pImageMemoryBarriers);
}
record->AddChunk(scope.Get(record->cmdInfo->alloc));
record->AddChunk(scope.Get(&record->cmdInfo->alloc));
for(uint32_t i = 0; i < eventCount; i++)
record->MarkResourceFrameReferenced(GetResID(pEvents[i]), eFrameRef_Read);
}
+106 -88
View File
@@ -1046,21 +1046,116 @@ Chunk *Chunk::Create(Serialiser<SerialiserMode::Writing> &ser, uint16_t chunkTyp
return ret;
}
ChunkAllocator::~ChunkAllocator()
ChunkPagePool::~ChunkPagePool()
{
for(Page &p : freePages)
// all allocated pages are in precisely one list, so just free the contents of both lists
for(ChunkPage &p : freePages)
{
FreeAlignedBuffer(p.chunkBase);
FreeAlignedBuffer(p.bufferBase);
}
for(Page &p : fullPages)
for(ChunkPage &p : allocatedPages)
{
FreeAlignedBuffer(p.chunkBase);
FreeAlignedBuffer(p.bufferBase);
}
}
ChunkPage ChunkPagePool::AllocPage()
{
if(!freePages.empty())
{
// if there's a free page, move it to the allocated list and return it
ChunkPage free = freePages.back();
freePages.pop_back();
allocatedPages.push_back(free);
}
else
{
// otherwise allocate a new one straight into the allocated list
byte *buffers = ::AllocAlignedBuffer(BufferPageSize);
byte *chunks = ::AllocAlignedBuffer(ChunkPageSize);
allocatedPages.push_back({m_ID++, buffers, buffers, chunks, chunks});
}
return allocatedPages.back();
}
void ChunkPagePool::Trim()
{
// truly release any currently free pages back to the system
for(ChunkPage &p : freePages)
{
FreeAlignedBuffer(p.chunkBase);
FreeAlignedBuffer(p.bufferBase);
}
freePages.clear();
}
void ChunkPagePool::Reset()
{
// forcibly move all allocated pages into the free list
freePages.append(allocatedPages);
allocatedPages.clear();
for(ChunkPage &p : freePages)
{
// reset head pointers
p.bufferHead = p.bufferBase;
p.chunkHead = p.chunkBase;
// assign a new ID so these pages can't get reset again by any allocator currently holding them
p.ID = m_ID++;
}
}
void ChunkPagePool::ResetPageSet(const rdcarray<ChunkPage> &pages)
{
// iterate over each page being freed
for(const ChunkPage &p : pages)
{
// try to find it in the allocated page list. This compares by ID, so if the page was already
// freed with a pool reset we won't find it at all because it will have a new ID - that's fine.
int32_t idx = allocatedPages.indexOf(p);
if(idx >= 0)
{
ChunkPage &alloc = allocatedPages[idx];
// give a new ID to be safe
alloc.ID = m_ID++;
// reset head pointers
alloc.bufferHead = alloc.bufferBase;
alloc.chunkHead = alloc.chunkBase;
// move to free list
freePages.push_back(alloc);
allocatedPages.erase(idx);
continue;
}
}
}
ChunkAllocator::~ChunkAllocator()
{
// move any pages we have back to the pool on destruction
Reset();
}
void ChunkAllocator::swap(ChunkAllocator &alloc)
{
if(&m_Pool != &alloc.m_Pool)
{
RDCERR(
"Allocator swap with allocator from another pool! Losing all pages to leak instead of "
"crashing");
pages.clear();
alloc.pages.clear();
return;
}
pages.swap(alloc.pages);
}
byte *ChunkAllocator::AllocAlignedBuffer(uint64_t size)
{
// always allocate 64-bytes at a time even if the size is smaller
@@ -1073,102 +1168,25 @@ byte *ChunkAllocator::AllocChunk()
return AllocateFromPages(true, sizeof(Chunk));
}
void ChunkAllocator::Trim()
{
for(Page &p : freePages)
{
FreeAlignedBuffer(p.chunkBase);
FreeAlignedBuffer(p.bufferBase);
}
freePages.clear();
}
void ChunkAllocator::Reset()
{
freePages.append(fullPages);
fullPages.clear();
for(Page &p : freePages)
{
p.bufferHead = p.bufferBase;
p.chunkHead = p.chunkBase;
}
}
void ChunkAllocator::ResetPageSet(const rdcarray<uint32_t> &pages)
{
// any full pages in this set go back into the free pages list
for(size_t i = 0; i < fullPages.size();)
{
Page &p = fullPages[i];
if(pages.contains(p.ID))
{
p.bufferHead = p.bufferBase;
p.chunkHead = p.chunkBase;
freePages.push_back(p);
fullPages.erase(i);
continue;
}
i++;
}
}
rdcarray<uint32_t> ChunkAllocator::GetPageSet()
{
// see if the last free page has been partially used
if(!freePages.empty())
{
Page &p = freePages.back();
if(p.bufferBase != p.bufferHead || p.chunkBase != p.chunkHead)
{
usedPages.push_back(freePages.back().ID);
fullPages.push_back(freePages.back());
freePages.pop_back();
}
}
rdcarray<uint32_t> ret;
ret.swap(usedPages);
return ret;
m_Pool.ResetPageSet(pages);
pages.clear();
}
byte *ChunkAllocator::AllocateFromPages(bool chunkAlloc, size_t size)
{
// if the size can't be satisfied in a page, return NULL and we'll force a full allocation which
// will be freed on its own
if(size > BufferPageSize)
if(size > m_Pool.GetBufferPageSize())
return NULL;
while(!freePages.empty())
{
// if the last free page can satisfy this allocation, stop iterating as we'll use it.
if(GetRemainingBytes(chunkAlloc, freePages.back()) >= size)
break;
// if we don't have a current page, or it can't satisfy the allocation, get a new page from the
// pool
if(pages.empty() || GetRemainingBytes(chunkAlloc, pages.back()) < size)
pages.push_back(m_Pool.AllocPage());
// otherwise the last page doesn't have enough free, so remove it from the free list
// mark this page as used in the current set
usedPages.push_back(freePages.back().ID);
fullPages.push_back(freePages.back());
freePages.pop_back();
}
// if there are no free pages, allocate a new one
if(freePages.empty())
{
// the first free ID is the sum of the free and full lists, because all pages are in one or the
// other
uint32_t ID = uint32_t(freePages.size() + fullPages.size());
byte *buffers = ::AllocAlignedBuffer(BufferPageSize);
byte *chunks = ::AllocAlignedBuffer(ChunkPageSize);
freePages.push_back({ID, buffers, buffers, chunks, chunks});
}
Page &p = freePages.back();
ChunkPage &p = pages.back();
byte *ret = NULL;
+80 -53
View File
@@ -1522,16 +1522,42 @@ DECLARE_STRINGISE_TYPE(SDObject *);
class ScopedChunk;
class ChunkAllocator
struct ChunkPage
{
// compare just with the ID, so that old pages w hich have been reset in the pool don't get reset
// again if an allocator subsequently tries to free them
bool operator==(const ChunkPage &o) { return ID == o.ID; }
size_t ID;
// we allocate at two granularities, chunks are 16 bytes, buffers are multiples of 64-bytes
// to keep things simple we allocate the chunk memory as 16/64 = a quarter the size of the
// buffer memory. This will waste a bit of memory because we expect buffers to be on average
// larger than 64 bytes.
// base of the buffer
byte *bufferBase;
// head of the buffer
byte *bufferHead;
byte *chunkBase;
byte *chunkHead;
};
// this is the first level, it allocates whole pages and returns them to allocators for finer
// grained allocation, and those allocators can return whole pages back. This is necessary because
// when fine-grained resetting is allowed we need to associate whole pages with objects and if those
// objects are allocating interleaved we need to immediately associate pages with them.
class ChunkPagePool
{
public:
ChunkAllocator(size_t PageSize) : BufferPageSize(PageSize), ChunkPageSize(PageSize / 4) {}
ChunkAllocator(const ChunkAllocator &) = delete;
ChunkAllocator(ChunkAllocator &&) = delete;
ChunkAllocator &operator=(const ChunkAllocator &) = delete;
~ChunkAllocator();
byte *AllocAlignedBuffer(uint64_t size);
byte *AllocChunk();
ChunkPagePool(size_t PageSize) : BufferPageSize(PageSize), ChunkPageSize(PageSize / 32) {}
ChunkPagePool(const ChunkPagePool &) = delete;
ChunkPagePool(ChunkPagePool &&) = delete;
ChunkPagePool &operator=(const ChunkPagePool &) = delete;
~ChunkPagePool();
// Allocate a page
ChunkPage AllocPage();
// really free any unused pages
void Trim();
@@ -1540,63 +1566,64 @@ public:
void Reset();
// reset a page set, other pages will remain in use
void ResetPageSet(const rdcarray<uint32_t> &pages);
// get the pages that have been used since the last reset, or call to GetPageSet.
// these can then be freed later without affecting any other pages.
// note that not all pages will be full (e.g. even if only one 64-bit chunk is used in the last
// page it will be marked as full so it can be freed without another allocation overlapping).
rdcarray<uint32_t> GetPageSet();
void ResetPageSet(const rdcarray<ChunkPage> &pages);
size_t GetBufferPageSize() { return BufferPageSize; }
size_t GetChunkPageSize() { return ChunkPageSize; }
private:
size_t BufferPageSize;
size_t ChunkPageSize;
struct Page
size_t m_ID = 1;
// a page is in precisely ONE of these arrays at any time.
// Reset() will move all allocated pages back to free pages and reclaim all that memory
// ResetPageSet() will move any referenced pages from allocatedPages back to freePages
rdcarray<ChunkPage> freePages;
rdcarray<ChunkPage> allocatedPages;
};
// this is the second level, it should only be used by one object (or a group of objects that are
// always reset together). It pulls pages from the pool and allocates from them, and can then
// release those pages back again with a reset operation.
class ChunkAllocator
{
public:
ChunkAllocator(ChunkPagePool &pool) : m_Pool(pool) {}
ChunkAllocator(const ChunkAllocator &) = delete;
ChunkAllocator(ChunkAllocator &&) = delete;
ChunkAllocator &operator=(const ChunkAllocator &) = delete;
~ChunkAllocator();
// swap with another chunk allocator - must be from the same pool
void swap(ChunkAllocator &alloc);
byte *AllocAlignedBuffer(uint64_t size);
byte *AllocChunk();
void Reset();
private:
ChunkPagePool &m_Pool;
// as we're recording each new page we start gets added here. The last page is the one we're
// currently allocating from.
rdcarray<ChunkPage> pages;
// given a page and the known page size, how much is left
inline size_t GetRemainingBufferBytes(const ChunkPage &p)
{
// this is an ID we can use to find this page in a pageset
uint32_t ID;
// we allocate at two granularities, chunks are 16 bytes, buffers are multiples of 64-bytes
// to keep things simple we allocate the chunk memory as 16/64 = a quarter the size of the
// buffer memory. This will waste a bit of memory because we expect buffers to be on average
// larger than 64 bytes.
// base of the buffer
byte *bufferBase;
// head of the buffer
byte *bufferHead;
byte *chunkBase;
byte *chunkHead;
};
// a page is in precisely ONE of these arrays at any time, either it's free (and the last free
// page may be partially used) or it's "full".
// Reset() will move all full pages back to free pages and reclaim all that memory
// ResetPageSet() will move any referenced pages from fullPages back to freePages
rdcarray<Page> freePages;
rdcarray<Page> fullPages;
// as we're recording each new page we start gets added here. If the user calls GetPageSet we
// return this and the user can then free it later without freeing all pages.
// note, the *current* page (freePages.back) isn't in this list, we only append to this list when
// we retire a full page. That means GetPageSet checks if the last page has been used at all and
// includes it there
rdcarray<uint32_t> usedPages;
inline size_t GetRemainingBufferBytes(const Page &p)
{
return BufferPageSize - (p.bufferHead - p.bufferBase);
return m_Pool.GetBufferPageSize() - (p.bufferHead - p.bufferBase);
}
inline size_t GetRemainingChunkBytes(const Page &p)
inline size_t GetRemainingChunkBytes(const ChunkPage &p)
{
return ChunkPageSize - (p.chunkHead - p.chunkBase);
return m_Pool.GetChunkPageSize() - (p.chunkHead - p.chunkBase);
}
inline size_t GetRemainingBytes(bool chunkAlloc, const Page &p)
inline size_t GetRemainingBytes(bool chunkAlloc, const ChunkPage &p)
{
return chunkAlloc ? GetRemainingChunkBytes(p) : GetRemainingBufferBytes(p);
}
byte *AllocateFromPages(bool chunkAlloc, size_t size);
};