Handle a memory object that can't be covered by a buffer. Closes #2185

* On some drivers like older NV hardware, there are memory types which can only
  be bound to images and never to buffers, so ensure we don't try to create a
  memory-spanning buffer for such allocations and avoid marking memory behind
  images as written or it will become dirty in subsequent captures.
This commit is contained in:
baldurk
2021-02-22 12:38:43 +00:00
parent 11268b358a
commit 795d7e0910
3 changed files with 37 additions and 10 deletions
+10 -1
View File
@@ -423,13 +423,22 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res)
}
else if(type == eResDeviceMemory)
{
VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id);
// if the memory has no wholeMemBuf we cannot fetch its contents. We shouldn't get here with
// only images bound to the memory so something has gone wrong
if(record->memMapState->wholeMemBuf == VK_NULL_HANDLE)
{
RDCERR("Trying to fetch device memory initial states without wholeMemBuf");
return true;
}
VkResult vkr = VK_SUCCESS;
VkDevice d = GetDev();
// INITSTATEBATCH
VkCommandBuffer cmd = GetNextCmd();
VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id);
VkDeviceMemory datamem = ToUnwrappedHandle<VkDeviceMemory>(res);
VkDeviceSize datasize = record->Length;
+3 -6
View File
@@ -3854,12 +3854,9 @@ void VkResourceRecord::MarkImageViewFrameReferenced(VkResourceRecord *view, cons
// mark image view as read
MarkResourceFrameReferenced(view->GetResourceID(), eFrameRef_Read);
// mark memory backing image. For dedicated images we always treat the memory as read only so
// we don't try and include its initial contents.
if(view->dedicated)
MarkResourceFrameReferenced(mem, eFrameRef_Read);
else
MarkResourceFrameReferenced(mem, refType);
// mark memory backing image as read only so we don't try and include its initial contents just
// because of an image's writes
MarkResourceFrameReferenced(mem, eFrameRef_Read);
ImageSubresourceRange imgRange;
imgRange.aspectMask = view->viewRange.aspectMask;
@@ -535,9 +535,20 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
RDCASSERTEQUAL(mrq.size, info.allocationSize);
bufid = GetResourceManager()->WrapResource(Unwrap(device), wholeMemBuf);
if((mrq.memoryTypeBits & (1U << info.memoryTypeIndex)) != 0)
{
bufid = GetResourceManager()->WrapResource(Unwrap(device), wholeMemBuf);
ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(wholeMemBuf), Unwrap(*pMemory), 0);
ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(wholeMemBuf), Unwrap(*pMemory), 0);
}
else
{
// can't create a memory-spanning buffer for this allocation. Assume this is a case where
// this memory type is only available to images and is not mappable - in which case the
// whole memory buffer won't be needed so we can skip this.
ObjDisp(device)->DestroyBuffer(Unwrap(device), wholeMemBuf, NULL);
wholeMemBuf = VK_NULL_HANDLE;
}
}
if((dedicated != NULL || dedicatedNV != NULL) && wholeMemBuf != VK_NULL_HANDLE)
@@ -626,8 +637,18 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
// command buffer.
if(Vulkan_GPUReadbackDeviceLocal() &&
m_PhysicalDeviceData.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
record->memMapState->readbackOnGPU =
((memProps & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0);
// we need a wholeMemBuf to readback on the GPU
if(record->memMapState->readbackOnGPU && wholeMemBuf == VK_NULL_HANDLE)
{
RDCWARN(
"Memory allocation would have been readback on GPU, but can't without wholeMemBuf");
record->memMapState->readbackOnGPU = false;
}
}
}
GetResourceManager()->AddDeviceMemory(id);
@@ -638,7 +659,7 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
m_CreationInfo.m_Memory[id].Init(GetResourceManager(), m_CreationInfo, &info);
if(dedicated == NULL && dedicatedNV == NULL)
if(dedicated == NULL && dedicatedNV == NULL && wholeMemBuf != VK_NULL_HANDLE)
{
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(bufid, wholeMemBuf);