mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-21 06:51:35 +00:00
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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user