Create a buffer bound to the whole of each devicememory

* This is used in initial state application for buffer copies without
  needing to create temporary buffers bound to the memory.
This commit is contained in:
baldurk
2016-02-07 18:45:55 +01:00
parent a27d67d49d
commit 9059ef2dc1
3 changed files with 52 additions and 69 deletions
+2
View File
@@ -212,6 +212,8 @@ struct VulkanCreationInfo
void Init(VulkanResourceManager *resourceMan, const VkMemoryAllocInfo* pAllocInfo);
uint64_t size;
VkBuffer wholeMemBuf;
};
map<ResourceId, Memory> m_Memory;
+6 -69
View File
@@ -768,31 +768,18 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourc
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
};
vector<VkBuffer> bufdeletes;
for(uint32_t i=0; i < info->numUniqueMems; i++)
{
VkDeviceMemory dstMem = GetResourceManager()->GetLiveHandle<VkDeviceMemory>(info->memDataOffs[i].memId);
// since this is short lived it isn't wrapped. Note that we want
// to cache this up front, so it will then be wrapped
VkBuffer dstBuf;
VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf;
bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size;
// VKTODOMED this should be created once up front, not every time
vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, &dstBuf);
RDCASSERT(vkr == VK_SUCCESS);
vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(dstMem), 0);
RDCASSERT(vkr == VK_SUCCESS);
// fill the whole memory from the given offset
VkBufferCopy region = { info->memDataOffs[i].memOffs, 0, bufInfo.size };
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), dstBuf, 1, &region);
bufdeletes.push_back(dstBuf);
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
}
// add memory barrier to ensure this copy completes before any subsequent work
@@ -809,16 +796,6 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourc
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
// VKTODOLOW if this dstBuf was persistent or at least cached
// we could batch these command buffers better and wouldn't
// need to flush at all until application of all init states
// is over
SubmitCmds();
FlushQ();
for(size_t i=0; i < bufdeletes.size(); i++)
ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i]);
return true;
}
@@ -873,31 +850,19 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceM
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
};
vector<VkBuffer> bufdeletes;
for(uint32_t i=0; i < info->numUniqueMems; i++)
{
VkDeviceMemory dstMem = GetResourceManager()->GetLiveHandle<VkDeviceMemory>(info->memDataOffs[i].memId);
// since this is short lived it isn't wrapped. Note that we want
// to cache this up front, so it will then be wrapped
VkBuffer dstBuf;
VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf;
bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size;
// VKTODOMED this should be created once up front, not every time
vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, &dstBuf);
RDCASSERT(vkr == VK_SUCCESS);
vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(dstMem), 0);
RDCASSERT(vkr == VK_SUCCESS);
// fill the whole memory from the given offset
VkBufferCopy region = { info->memDataOffs[i].memOffs, 0, bufInfo.size };
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), dstBuf, 1, &region);
bufdeletes.push_back(dstBuf);
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
}
// add memory barrier to ensure this copy completes before any subsequent work
@@ -914,16 +879,6 @@ bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceM
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
// VKTODOLOW if this dstBuf was persistent or at least cached
// we could batch these command buffers better and wouldn't
// need to flush at all until application of all init states
// is over
SubmitCmds();
FlushQ();
for(size_t i=0; i < bufdeletes.size(); i++)
ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i]);
return true;
}
@@ -1969,20 +1924,11 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
};
// since this is short lived it isn't wrapped. Note that we want
// to cache this up front, so it will then be wrapped
VkBuffer dstBuf;
// VKTODOMED this should be created once up front, not every time
vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, &dstBuf);
RDCASSERT(vkr == VK_SUCCESS);
vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(dstMem), 0);
RDCASSERT(vkr == VK_SUCCESS);
VkBuffer dstBuf = m_CreationInfo.m_Memory[id].wholeMemBuf;
VkBufferCopy region = { 0, dstMemOffs, datasize };
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), dstBuf, 1, &region);
ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, &region);
// add memory barrier to ensure this copy completes before any subsequent work
VkMemoryBarrier memBarrier = {
@@ -1997,15 +1943,6 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager
vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
// VKTODOLOW if this dstBuf was persistent or at least cached
// we could batch these command buffers better and wouldn't
// need to flush at all until application of all init states
// is over
SubmitCmds();
FlushQ();
ObjDisp(d)->DestroyBuffer(Unwrap(d), dstBuf);
}
else
{
@@ -172,6 +172,28 @@ bool WrappedVulkan::Serialise_vkAllocMemory(
GetResourceManager()->AddLiveResource(id, mem);
m_CreationInfo.m_Memory[live].Init(GetResourceManager(), &info);
// create a buffer with the whole memory range bound, for copying to and from
// conveniently (for initial state data)
VkBuffer buf = VK_NULL_HANDLE;
VkBufferCreateInfo bufInfo = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL,
info.allocationSize, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT|VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, 0,
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
};
ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, &buf);
RDCASSERT(ret == VK_SUCCESS);
ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf);
ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0);
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(bufid, buf);
m_CreationInfo.m_Memory[live].wholeMemBuf = buf;
}
}
@@ -230,6 +252,28 @@ VkResult WrappedVulkan::vkAllocMemory(
GetResourceManager()->AddLiveResource(id, *pMem);
m_CreationInfo.m_Memory[id].Init(GetResourceManager(), pAllocInfo);
// create a buffer with the whole memory range bound, for copying to and from
// conveniently (for initial state data)
VkBuffer buf = VK_NULL_HANDLE;
VkBufferCreateInfo bufInfo = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL,
info.allocationSize, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT|VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, 0,
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
};
ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, &buf);
RDCASSERT(ret == VK_SUCCESS);
ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf);
ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(*pMem), 0);
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(bufid, buf);
m_CreationInfo.m_Memory[id].wholeMemBuf = buf;
}
}