Disallow dedicated memory on external images where memory reqs change

This commit is contained in:
baldurk
2024-04-15 16:22:45 +01:00
parent 3c265b8ad0
commit ade34bb59d
3 changed files with 44 additions and 1 deletions
+1 -1
View File
@@ -1013,7 +1013,7 @@ void ImageState::RecordBarrier(VkImageMemoryBarrier barrier, uint32_t queueFamil
barrier.dstQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL ||
barrier.dstQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT)
{
RDCERR("External/foreign queue families are not supported");
RDCDEBUG("External/foreign queue families are not supported");
return;
}
if(GetImageInfo().sharingMode == VK_SHARING_MODE_CONCURRENT)
+5
View File
@@ -995,6 +995,11 @@ struct ResourceInfo
// METADATA) we put them in the array.
Sparse::PageTable sparseTable;
rdcarray<AspectSparseTable> altSparseAspects;
// for external images if we query both external and non-external and the sizes are different, we
// can't allow dedicated memory as it is required to precisely match in size.
bool banDedicated = false;
VkImageAspectFlags sparseAspect;
ResourceId dedicatedMemory;
@@ -307,6 +307,23 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev
UnwrapNextChain(m_State, "VkMemoryAllocateInfo", tempMem, (VkBaseInStructure *)&patched);
// remove dedicated memory struct if it is not allowed due to changing memory sizes
{
VkMemoryDedicatedAllocateInfo *dedicated = (VkMemoryDedicatedAllocateInfo *)FindNextStruct(
&AllocateInfo, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
if(dedicated && dedicated->image != VK_NULL_HANDLE)
{
VkMemoryRequirements mrq = {};
ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(dedicated->image), &mrq);
if(mrq.size != AllocateInfo.allocationSize)
{
RDCDEBUG("Removing dedicated allocation for incompatible size");
RemoveNextStruct(&patched, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
}
}
}
if(patched.memoryTypeIndex >= m_PhysicalDeviceData.memProps.memoryTypeCount)
{
SET_ERROR_RESULT(
@@ -496,6 +513,19 @@ VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocate
if(IsCaptureMode(m_State) && memFlags && (memFlags->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT))
memFlags->flags |= VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
// remove dedicated memory struct if it is not allowed
{
VkMemoryDedicatedAllocateInfo *dedicated = (VkMemoryDedicatedAllocateInfo *)FindNextStruct(
pAllocateInfo, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
if(dedicated && dedicated->image != VK_NULL_HANDLE)
{
VkResourceRecord *imageRecord = GetRecord(dedicated->image);
if(imageRecord->resInfo->banDedicated)
RemoveNextStruct(&unwrapped, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO);
}
}
VkResult ret;
SERIALISE_TIME_CALL(
ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &unwrapped, NULL, pMemory));
@@ -2507,6 +2537,14 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *
"Non-external version requires %llu bytes at %llu alignment, in %x memory types",
mrq.size, mrq.alignment, mrq.memoryTypeBits);
if(resInfo.memreqs.size != mrq.size)
{
RDCWARN(
"Required size changed on image between external/non-external, banning "
"dedicated memory");
resInfo.banDedicated = true;
}
resInfo.memreqs.size = RDCMAX(resInfo.memreqs.size, mrq.size);
resInfo.memreqs.alignment = RDCMAX(resInfo.memreqs.alignment, mrq.alignment);