From c73c54dd6f4cd8e84d7f4b501f481b2106efac80 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 6 Jun 2022 12:51:23 +0100 Subject: [PATCH] Be more informative with 'capture incompatible' error messages on vulkan --- renderdoc/driver/vulkan/vk_common.h | 14 +- renderdoc/driver/vulkan/vk_core.cpp | 63 +++++++++ renderdoc/driver/vulkan/vk_core.h | 6 +- renderdoc/driver/vulkan/vk_info.cpp | 10 +- renderdoc/driver/vulkan/vk_info.h | 8 +- .../vulkan/wrappers/vk_device_funcs.cpp | 72 +++++----- .../vulkan/wrappers/vk_resource_funcs.cpp | 124 ++++++++++-------- 7 files changed, 206 insertions(+), 91 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index f6b331710..67dd66f27 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -238,12 +238,18 @@ extern void *LoadVulkanLibrary(); class VkDriverInfo { public: - GPUVendor Vendor() { return m_Vendor; } - uint32_t Major() { return m_Major; } - uint32_t Minor() { return m_Minor; } - uint32_t Patch() { return m_Patch; } + GPUVendor Vendor() const { return m_Vendor; } + uint32_t Major() const { return m_Major; } + uint32_t Minor() const { return m_Minor; } + uint32_t Patch() const { return m_Patch; } VkDriverInfo(const VkPhysicalDeviceProperties &physProps, bool active = false); + bool operator==(const VkDriverInfo &o) const + { + return m_Vendor == o.m_Vendor && m_Major == o.m_Major && m_Minor == o.m_Minor && + m_Patch == o.m_Patch; + } + // checks for when we're running on metal and some non-queryable things aren't supported bool RunningOnMetal() const { return metalBackend; } // A workaround for a couple of bugs, removing texelFetch use from shaders. diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 56f771331..50c668e84 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -4098,6 +4098,69 @@ void WrappedVulkan::AddDebugMessage(DebugMessage msg) } } +rdcstr WrappedVulkan::GetPhysDeviceCompatString(bool externalResource, bool origInvalid) +{ + const VkDriverInfo &capture = m_OrigPhysicalDeviceData.driverInfo; + const VkDriverInfo &replay = m_PhysicalDeviceData.driverInfo; + + if(origInvalid) + { + return StringFormat::Fmt( + "This was invalid at capture time.\n" + "You must use API validation, as RenderDoc does not handle invalid API use like this.\n\n" + "Captured on device: %s %s, %u.%u.%u", + ToStr(capture.Vendor()).c_str(), m_OrigPhysicalDeviceData.props.deviceName, capture.Major(), + capture.Minor(), capture.Patch()); + } + + rdcstr ret; + + if(externalResource) + { + ret = + "This resource was externally imported, which cannot happen at replay time.\n" + "Some drivers do not allow externally-imported resources to be bound to non-external " + "memory, meaning that captures using resources like this can't be replayed.\n\n"; + } + + if(capture == replay) + { + ret += StringFormat::Fmt("Captured and replayed on the same device: %s %s, %u.%u.%u", + ToStr(capture.Vendor()).c_str(), + m_OrigPhysicalDeviceData.props.deviceName, capture.Major(), + capture.Minor(), capture.Patch()); + } + else + { + ret += StringFormat::Fmt( + "Capture was made on: %s %s, %u.%u.%u\n" + "Replayed on: %s %s, %u.%u.%u\n", + + // capture device + ToStr(capture.Vendor()).c_str(), m_OrigPhysicalDeviceData.props.deviceName, capture.Major(), + capture.Minor(), capture.Patch(), + + // replay device + ToStr(replay.Vendor()).c_str(), m_PhysicalDeviceData.props.deviceName, replay.Major(), + replay.Minor(), replay.Patch()); + + if(capture.Vendor() != replay.Vendor()) + { + ret += "Captures are not commonly portable between GPUs from different vendors."; + } + else if(strcmp(m_OrigPhysicalDeviceData.props.deviceName, m_PhysicalDeviceData.props.deviceName)) + { + ret += "Captures are sometimes not portable between different GPUs from a vendor."; + } + else + { + ret += "Driver changes can sometimes cause captures to no longer work."; + } + } + + return ret; +} + void WrappedVulkan::CheckErrorVkResult(VkResult vkr) { if(vkr == VK_SUCCESS || HasFatalError() || IsCaptureMode(m_State)) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 83055940a..073cfe896 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -434,6 +434,8 @@ private: VkDevice m_Device; // the data about the physical device used for the above device PhysicalDeviceData m_PhysicalDeviceData; + // the driver info for the original device + PhysicalDeviceData m_OrigPhysicalDeviceData; // the family index that we've selected in CreateDevice for our queue. During replay, this is an // index in the replay-time queues, not the capture-time queues (i.e. after remapping) uint32_t m_QueueFamilyIdx; @@ -903,8 +905,10 @@ private: void FirstFrame(); + rdcstr GetPhysDeviceCompatString(bool external, bool origInvalid); bool CheckMemoryRequirements(const char *resourceName, ResourceId memId, - VkDeviceSize memoryOffset, VkMemoryRequirements mrq, bool external); + VkDeviceSize memoryOffset, const VkMemoryRequirements &mrq, + bool external, const VkMemoryRequirements &origMrq); void AddImplicitResolveResourceUsage(uint32_t subpass = 0); rdcarray GetImplicitRenderPassBarriers(uint32_t subpass = 0); diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index edb0551c3..cd12c4056 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -1497,12 +1497,15 @@ void VulkanCreationInfo::Memory::SimplifyBindings() } void VulkanCreationInfo::Buffer::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, - const VkBufferCreateInfo *pCreateInfo) + const VkBufferCreateInfo *pCreateInfo, + VkMemoryRequirements origMrq) { usage = pCreateInfo->usage; size = pCreateInfo->size; gpuAddress = 0; + mrq = origMrq; + external = false; if(FindNextStruct(pCreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO)) @@ -1522,7 +1525,8 @@ void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, } void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, - const VkImageCreateInfo *pCreateInfo) + const VkImageCreateInfo *pCreateInfo, + VkMemoryRequirements origMrq) { type = pCreateInfo->imageType; format = pCreateInfo->format; @@ -1531,6 +1535,8 @@ void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanC mipLevels = pCreateInfo->mipLevels; samples = RDCMAX(VK_SAMPLE_COUNT_1_BIT, pCreateInfo->samples); + mrq = origMrq; + linear = pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR; external = false; diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index add20a6a7..f684aeb91 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -558,12 +558,14 @@ struct VulkanCreationInfo struct Buffer { void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, - const VkBufferCreateInfo *pCreateInfo); + const VkBufferCreateInfo *pCreateInfo, VkMemoryRequirements origMrq); VkBufferUsageFlags usage; uint64_t size; uint64_t gpuAddress; bool external; + + VkMemoryRequirements mrq; }; std::unordered_map m_Buffer; @@ -582,7 +584,7 @@ struct VulkanCreationInfo struct Image { void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, - const VkImageCreateInfo *pCreateInfo); + const VkImageCreateInfo *pCreateInfo, VkMemoryRequirements origMrq); VkImageType type; VkFormat format; @@ -594,6 +596,8 @@ struct VulkanCreationInfo bool external; bool cube; TextureCategory creationFlags; + + VkMemoryRequirements mrq; }; std::unordered_map m_Image; diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 89afa5a18..16bbd0aa2 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -332,7 +332,7 @@ RDResult WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVersion if(supportedExtensions.find(params.Extensions[i]) == supportedExtensions.end()) { RETURN_ERROR_RESULT(ResultCode::APIHardwareUnsupported, - "Capture requires extension '%s' which is not supported", + "Capture requires instance extension '%s' which is not supported\n", params.Extensions[i].c_str()); } } @@ -1609,6 +1609,17 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi RDCLOG("Creating replay device from physical device %u", physicalDeviceIndex); + ObjDisp(physicalDevice) + ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); + + ObjDisp(physicalDevice) + ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); + + ObjDisp(physicalDevice) + ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures); + + m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true); + rdcarray queuePriorities; for(uint32_t i = 0; i < CreateInfo.queueCreateInfoCount; i++) @@ -1622,6 +1633,11 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi queuePriorities.push_back(queuePrio); } + const PhysicalDeviceData &origData = m_OriginalPhysicalDevices[physicalDeviceIndex]; + + m_OrigPhysicalDeviceData = origData; + m_OrigPhysicalDeviceData.driverInfo = VkDriverInfo(origData.props, false); + // we must make any modifications locally, so the free of pointers // in the serialised VkDeviceCreateInfo don't double-free VkDeviceCreateInfo createInfo = CreateInfo; @@ -1671,8 +1687,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi if(supportedExtensions.find(Extensions[i]) == supportedExtensions.end()) { SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Capture requires extension '%s' which is not supported", - Extensions[i].c_str()); + "Capture requires extension '%s' which is not supported\n" + "\n%s", + Extensions[i].c_str(), GetPhysDeviceCompatString(false, false).c_str()); return false; } } @@ -1816,10 +1833,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi q.queueFlags |= VK_QUEUE_TRANSFER_BIT; } - PhysicalDeviceData &origData = m_OriginalPhysicalDevices[physicalDeviceIndex]; - uint32_t origQCount = origData.queueCount; - VkQueueFamilyProperties *origprops = origData.queueProps; + const VkQueueFamilyProperties *origprops = origData.queueProps; // create queue remapping for(uint32_t origQIndex = 0; origQIndex < origQCount; origQIndex++) @@ -2105,7 +2120,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi { \ SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \ "Capture requires physical device feature '" #feature \ - "' which is not supported"); \ + "' which is not supported\n\n%s", \ + GetPhysDeviceCompatString(false, false).c_str()); \ return false; \ } @@ -2176,14 +2192,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi #define END_PHYS_EXT_CHECK() } -#define CHECK_PHYS_EXT_FEATURE(feature) \ - if(ext->feature && !avail.feature) \ - { \ - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \ - "Capture requires physical device feature '" #feature \ - "' in struct '%s' which is not supported", \ - structName); \ - return false; \ +#define CHECK_PHYS_EXT_FEATURE(feature) \ + if(ext->feature && !avail.feature) \ + { \ + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, \ + "Capture requires physical device feature '" #feature \ + "' in struct '%s' which is not supported\n\n%s", \ + structName, GetPhysDeviceCompatString(false, false).c_str()); \ + return false; \ } VkPhysicalDeviceDescriptorIndexingFeatures descIndexingFeatures = {}; @@ -2272,7 +2288,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi m_FailedReplayResult, ResultCode::APIHardwareUnsupported, "Capture requires bufferDeviceAddress support, which is available, but " "bufferDeviceAddressCaptureReplay support is not available which is required to " - "replay"); + "replay\n" + "\n%s", + GetPhysDeviceCompatString(false, false).c_str()); return false; } } @@ -2478,7 +2496,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi m_FailedReplayResult, ResultCode::APIHardwareUnsupported, "Capture requires bufferDeviceAddress support, which is available, but " "bufferDeviceAddressCaptureReplay support is not available which is required to " - "replay"); + "replay\n" + "\n%s", + GetPhysDeviceCompatString(false, false).c_str()); return false; } } @@ -2497,7 +2517,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi m_FailedReplayResult, ResultCode::APIHardwareUnsupported, "Capture requires bufferDeviceAddress support, which is available, but " "bufferDeviceAddressCaptureReplay support is not available which is required to " - "replay"); + "replay\n" + "\n%s", + GetPhysDeviceCompatString(false, false).c_str()); return false; } } @@ -3573,20 +3595,10 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi } } - ObjDisp(physicalDevice) - ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); - - ObjDisp(physicalDevice) - ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); - - ObjDisp(physicalDevice) - ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures); - m_PhysicalDeviceData.enabledFeatures = enabledFeatures; - - m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true); - m_Replay->SetDriverInformation(m_PhysicalDeviceData.props); + m_PhysicalDeviceData.enabledFeatures = enabledFeatures; + // MoltenVK reports 0x3fffffff for this limit so just ignore that value if it comes up RDCASSERT(m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets < ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID[0]) || diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 2bbb4b7f8..a66b9dbbc 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -191,8 +191,9 @@ VkBindImageMemoryInfo *WrappedVulkan::UnwrapInfos(CaptureState state, } bool WrappedVulkan::CheckMemoryRequirements(const char *resourceName, ResourceId memId, - VkDeviceSize memoryOffset, VkMemoryRequirements mrq, - bool external) + VkDeviceSize memoryOffset, + const VkMemoryRequirements &mrq, bool external, + const VkMemoryRequirements &origMrq) { // verify that the memory meets basic requirements. If not, something changed and we should // bail loading this capture. This is a bit of an under-estimate since we just make sure @@ -203,65 +204,80 @@ bool WrappedVulkan::CheckMemoryRequirements(const char *resourceName, ResourceId VulkanCreationInfo::Memory &memInfo = m_CreationInfo.m_Memory[memId]; uint32_t bit = 1U << memInfo.memoryTypeIndex; + bool origInvalid = false; + // verify type if((mrq.memoryTypeBits & bit) == 0) { rdcstr bitsString; - for(uint32_t i = 0; i < 32; i++) + if((origMrq.memoryTypeBits & bit) == 0) { - if(mrq.memoryTypeBits & (1U << i)) - bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i); - } + for(uint32_t i = 0; i < 32; i++) + { + if(origMrq.memoryTypeBits & (1U << i)) + bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i); + } - if(external) + origInvalid = true; + } + else { - SET_ERROR_RESULT( - m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Trying to bind %s to memory %s which is type %u, " - "but only these types are allowed: %s\n" - "This resource was created with external memory bindings, which is not represented in " - "the capture.\n" - "Some drivers do not allow externally-imported resources to be bound to non-external " - "memory, meaning this cannot be replayed.", - resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, bitsString.c_str()); - return false; + for(uint32_t i = 0; i < 32; i++) + { + if(mrq.memoryTypeBits & (1U << i)) + bitsString += StringFormat::Fmt("%s%u", bitsString.empty() ? "" : ", ", i); + } } SET_ERROR_RESULT( m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Trying to bind %s to memory %s which is type %u, " - "but only these types are allowed: %s\n" - "This is most likely caused by incompatible hardware or drivers between capture and " - "replay, causing a change in memory requirements.", - resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, bitsString.c_str()); + "Trying to bind %s to %s, but memory type is %u and only types %s are allowed.\n" + "\n%s", + resourceName, GetResourceDesc(memOrigId).name.c_str(), memInfo.memoryTypeIndex, + bitsString.c_str(), GetPhysDeviceCompatString(external, origInvalid).c_str()); return false; } // verify offset alignment if((memoryOffset % mrq.alignment) != 0) { + VkDeviceSize align = mrq.alignment; + + if((memoryOffset % origMrq.alignment) != 0) + { + origInvalid = true; + + align = origMrq.alignment; + } + SET_ERROR_RESULT( m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Trying to bind %s to memory %s which is type %u, " - "but offset 0x%llx doesn't satisfy alignment 0x%llx.\n" - "This is most likely caused by incompatible hardware or drivers between capture and " - "replay, causing a change in memory requirements.", - resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, memoryOffset, mrq.alignment); + "Trying to bind %s to %s, but memory offset 0x%llx doesn't satisfy alignment 0x%llx.\n" + "\n%s", + resourceName, GetResourceDesc(memOrigId).name.c_str(), memoryOffset, mrq.alignment, + GetPhysDeviceCompatString(external, origInvalid).c_str()); return false; } // verify size if(mrq.size > memInfo.allocSize - memoryOffset) { - SET_ERROR_RESULT( - m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Trying to bind %s to memory %s which is type %u, " - "but at offset 0x%llx the reported size of 0x%llx won't fit the 0x%llx bytes of memory.\n" - "This is most likely caused by incompatible hardware or drivers between capture and " - "replay, causing a change in memory requirements.", - resourceName, ToStr(memOrigId).c_str(), memInfo.memoryTypeIndex, memoryOffset, mrq.size, - memInfo.allocSize); + VkDeviceSize size = mrq.size; + + if(origMrq.size > memInfo.allocSize - memoryOffset) + { + origInvalid = true; + + size = origMrq.size; + } + + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Trying to bind %s to %s, but at memory offset 0x%llx the reported size of " + "0x%llx won't fit the 0x%llx bytes of memory.\n" + "\n%s", + resourceName, GetResourceDesc(memOrigId).name.c_str(), memoryOffset, size, + memInfo.allocSize, GetPhysDeviceCompatString(external, origInvalid).c_str()); return false; } @@ -296,9 +312,11 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev SET_ERROR_RESULT( m_FailedReplayResult, ResultCode::APIHardwareUnsupported, "Tried to allocate memory from index %u, but on replay we only have %u memory types.\n" - "This is most likely caused by incompatible hardware or drivers between capture and " - "replay, causing a change in memory requirements.", - patched.memoryTypeIndex, m_PhysicalDeviceData.memProps.memoryTypeCount); + "\n%s", + patched.memoryTypeIndex, m_PhysicalDeviceData.memProps.memoryTypeCount, + GetPhysDeviceCompatString( + false, patched.memoryTypeIndex >= m_OrigPhysicalDeviceData.memProps.memoryTypeCount) + .c_str()); return false; } @@ -1338,8 +1356,8 @@ bool WrappedVulkan::Serialise_vkBindBufferMemory(SerialiserType &ser, VkDevice d VkMemoryRequirements mrq = {}; ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(buffer), &mrq); - bool ok = CheckMemoryRequirements(("Buffer " + ToStr(resOrigId)).c_str(), GetResID(memory), - memoryOffset, mrq, bufInfo.external); + bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), GetResID(memory), + memoryOffset, mrq, bufInfo.external, bufInfo.mrq); if(!ok) return false; @@ -1461,8 +1479,8 @@ bool WrappedVulkan::Serialise_vkBindImageMemory(SerialiserType &ser, VkDevice de VulkanCreationInfo::Image &imgInfo = m_CreationInfo.m_Image[GetResID(image)]; - bool ok = CheckMemoryRequirements(("Image " + ToStr(resOrigId)).c_str(), GetResID(memory), - memoryOffset, mrq, imgInfo.external); + bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), GetResID(memory), + memoryOffset, mrq, imgInfo.external, imgInfo.mrq); if(!ok) return false; @@ -1631,7 +1649,8 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf); GetResourceManager()->AddLiveResource(Buffer, buf); - m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); + m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo, + memoryRequirements); } AddResource(Buffer, ResourceType::Buffer, "Buffer"); @@ -1841,7 +1860,7 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo { GetResourceManager()->AddLiveResource(id, *pBuffer); - m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo, {}); } } else @@ -2132,7 +2151,8 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device NameVulkanObject(img, StringFormat::Fmt("Image %s", ToStr(Image).c_str())); - m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); + m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo, + memoryRequirements); bool inserted = false; auto state = InsertImageState(img, live, CreateInfo, eFrameRef_Unknown, &inserted); @@ -2525,7 +2545,7 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo * { GetResourceManager()->AddLiveResource(id, *pImage); - m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo, {}); } LockedImageStateRef state = @@ -2732,9 +2752,9 @@ bool WrappedVulkan::Serialise_vkBindBufferMemory2(SerialiserType &ser, VkDevice ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(bindInfo.buffer), &mrqs[i]); - bool ok = - CheckMemoryRequirements(("Buffer " + ToStr(resOrigId)).c_str(), GetResID(bindInfo.memory), - bindInfo.memoryOffset, mrqs[i], bufInfo.external); + bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), + GetResID(bindInfo.memory), bindInfo.memoryOffset, mrqs[i], + bufInfo.external, bufInfo.mrq); if(!ok) return false; @@ -2877,9 +2897,9 @@ bool WrappedVulkan::Serialise_vkBindImageMemory2(SerialiserType &ser, VkDevice d VkMemoryRequirements mrq = {}; ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(bindInfo.image), &mrq); - bool ok = - CheckMemoryRequirements(("Image " + ToStr(resOrigId)).c_str(), GetResID(bindInfo.memory), - bindInfo.memoryOffset, mrq, imgInfo.external); + bool ok = CheckMemoryRequirements(GetResourceDesc(resOrigId).name.c_str(), + GetResID(bindInfo.memory), bindInfo.memoryOffset, mrq, + imgInfo.external, imgInfo.mrq); if(!ok) return false;