Only apply sparse binding initial contents to resources if they change

* Resources which don't have any sparse binding operations within the captured
  frame don't need to be repeatedly restored.
This commit is contained in:
baldurk
2021-03-09 10:43:46 +00:00
parent 145fd3c001
commit 10aad2a7b1
3 changed files with 23 additions and 13 deletions
+2 -11
View File
@@ -890,17 +890,6 @@ private:
ResourceDescription &GetResourceDesc(ResourceId id);
bool Prepare_SparseInitialState(WrappedVkBuffer *buf);
bool Prepare_SparseInitialState(WrappedVkImage *im);
template <typename SerialiserType>
bool Serialise_SparseBufferInitialState(SerialiserType &ser, ResourceId id,
const VkInitialContents *contents);
template <typename SerialiserType>
bool Serialise_SparseImageInitialState(SerialiserType &ser, ResourceId id,
const VkInitialContents *contents);
bool Apply_SparseInitialState(WrappedVkBuffer *buf, const VkInitialContents &contents);
bool Apply_SparseInitialState(WrappedVkImage *im, const VkInitialContents &contents);
void ApplyInitialContents();
rdcarray<APIEvent> m_RootEvents, m_Events;
@@ -914,6 +903,8 @@ private:
ResourceId m_LastPresentedImage;
std::set<ResourceId> m_SparseBindResources;
ReplayStatus m_FailedReplayStatus = ReplayStatus::APIReplayFailed;
VulkanDrawcallTreeNode m_ParentDrawcall;
+12 -2
View File
@@ -1839,7 +1839,11 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
// we should only get here if we have a sparse page table to apply
RDCASSERT(initial.tag == VkInitialContents::SparseTableOnly, (uint32_t)initial.tag);
if(initial.sparseBind)
// only apply sparse bindings the first time we apply initial contents, OR if there are sparse
// bindings of this resource in the capture. This is a simple optimisation to avoid needing to
// re-bind the sparse pages every time if they don't change.
if(initial.sparseBind &&
(IsLoading(m_State) || m_SparseBindResources.find(id) != m_SparseBindResources.end()))
ObjDisp(m_Queue)->QueueBindSparse(Unwrap(m_Queue), 1, initial.sparseBind, VK_NULL_HANDLE);
}
else if(type == eResImage)
@@ -1869,7 +1873,13 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, const VkInitialConten
// apply sparse page table mappings and skip memory-bound optimisations
if(initial.sparseBind)
{
ObjDisp(m_Queue)->QueueBindSparse(Unwrap(m_Queue), 1, initial.sparseBind, VK_NULL_HANDLE);
// only apply sparse bindings the first time we apply initial contents, OR if there are sparse
// bindings of this resource in the capture. This is a simple optimisation to avoid needing to
// re-bind the sparse pages every time if they don't change.
if(IsLoading(m_State) || m_SparseBindResources.find(id) != m_SparseBindResources.end())
ObjDisp(m_Queue)->QueueBindSparse(Unwrap(m_Queue), 1, initial.sparseBind, VK_NULL_HANDLE);
// however we don't track the memory bound to it, so always consider it uninitialised.
initialized = false;
}
else if(initialized && boundMemory != ResourceId())
@@ -1571,6 +1571,9 @@ bool WrappedVulkan::Serialise_vkQueueBindSparse(SerialiserType &ser, VkQueue que
}
else
{
if(IsLoading(m_State))
m_SparseBindResources.insert(GetResID(buf[i].buffer));
buf[i].buffer = Unwrap(buf[i].buffer);
VkSparseMemoryBind *binds = (VkSparseMemoryBind *)buf[i].pBinds;
@@ -1590,6 +1593,9 @@ bool WrappedVulkan::Serialise_vkQueueBindSparse(SerialiserType &ser, VkQueue que
}
else
{
if(IsLoading(m_State))
m_SparseBindResources.insert(GetResID(imopaque[i].image));
imopaque[i].image = Unwrap(imopaque[i].image);
VkSparseMemoryBind *binds = (VkSparseMemoryBind *)imopaque[i].pBinds;
@@ -1608,6 +1614,9 @@ bool WrappedVulkan::Serialise_vkQueueBindSparse(SerialiserType &ser, VkQueue que
}
else
{
if(IsLoading(m_State))
m_SparseBindResources.insert(GetResID(im[i].image));
im[i].image = Unwrap(im[i].image);
VkSparseImageMemoryBind *binds = (VkSparseImageMemoryBind *)im[i].pBinds;