From e7f10d3a849f42be645c6639aa0036d8a16a517b Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 15 Jul 2025 15:06:43 +0100 Subject: [PATCH] Detect differences in opaque capture address and fail capture load * This should not happen, the vulkan spec guarantees that this function must return the same value passed in if there was one, and this can help detect BDA addresses moving. --- renderdoc/driver/vulkan/vk_info.cpp | 9 ++++++++ renderdoc/driver/vulkan/vk_info.h | 2 ++ .../vulkan/wrappers/vk_resource_funcs.cpp | 22 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index c48008656..0e9df2f5e 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -2293,6 +2293,15 @@ void VulkanCreationInfo::Memory::Init(VulkanResourceManager *resourceMan, Vulkan { memoryTypeIndex = pAllocInfo->memoryTypeIndex; allocSize = wholeMemBufSize = pAllocInfo->allocationSize; + + const VkMemoryOpaqueCaptureAddressAllocateInfo *memoryDeviceAddress = + (const VkMemoryOpaqueCaptureAddressAllocateInfo *)FindNextStruct( + pAllocInfo, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO); + + if(memoryDeviceAddress) + { + opaqueAddr = memoryDeviceAddress->opaqueCaptureAddress; + } } void VulkanCreationInfo::Memory::SimplifyBindings() diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index f90dab8f4..63772511d 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -579,6 +579,8 @@ struct VulkanCreationInfo VkBuffer wholeMemBuf; + VkDeviceAddress opaqueAddr; + enum MemoryBinding { None = 0x0, diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index b0bf6f58b..384a58990 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -370,6 +370,28 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &AllocateInfo); + if(m_CreationInfo.m_Memory[live].opaqueAddr != 0) + { + VkDeviceMemoryOpaqueCaptureAddressInfo getInfo = { + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + NULL, + Unwrap(mem), + }; + + uint64_t opaque = + ObjDisp(device)->GetDeviceMemoryOpaqueCaptureAddress(Unwrap(device), &getInfo); + + if(m_CreationInfo.m_Memory[live].opaqueAddr != opaque) + { + SET_ERROR_RESULT( + m_FailedReplayResult, ResultCode::APIReplayFailed, + "Allocating memory failed, opaque address 0x%llx has changed on replay to 0x%llx." + "This is illegal and indicates a potential driver bug.", + m_CreationInfo.m_Memory[live].opaqueAddr, opaque); + return false; + } + } + VkMemoryDedicatedAllocateInfo *dedicated = (VkMemoryDedicatedAllocateInfo *)FindNextStruct( &AllocateInfo, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO); if(dedicated && dedicated->buffer == VK_NULL_HANDLE && dedicated->image == VK_NULL_HANDLE)