mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-22 06:26:30 +00:00
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:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ®ion = 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user