diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 39f2ff003..195800c34 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -525,6 +525,7 @@ enum class VulkanChunk : uint32_t vkCmdEndConditionalRenderingEXT, vkCmdSetSampleLocationsEXT, vkCmdSetDiscardRectangleEXT, + DeviceMemoryRefs, Max, }; diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 3051cb6e5..0e458c712 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1690,6 +1690,7 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) RDCDEBUG("Creating Capture Scope"); GetResourceManager()->Serialise_InitialContentsNeeded(ser); + GetResourceManager()->InsertDeviceMemoryRefs(ser); { SCOPED_SERIALISE_CHUNK(SystemChunk::CaptureScope, 16); @@ -2792,6 +2793,11 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk) return Serialise_vkCmdSetSampleLocationsEXT(ser, VK_NULL_HANDLE, NULL); case VulkanChunk::vkCmdSetDiscardRectangleEXT: return Serialise_vkCmdSetDiscardRectangleEXT(ser, VK_NULL_HANDLE, 0, 0, NULL); + case VulkanChunk::DeviceMemoryRefs: + { + std::vector data; + return GetResourceManager()->Serialise_DeviceMemoryRefs(ser, data); + } default: { SystemChunk system = (SystemChunk)chunk; diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index 30369fc2b..d0e34479b 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -356,6 +356,76 @@ template void VulkanResourceManager::SerialiseImageStates(WriteSerialiser &ser, std::map &states, std::vector &barriers); +template +void DoSerialise(SerialiserType &ser, MemRefInterval &el) +{ + SERIALISE_MEMBER(memory); + SERIALISE_MEMBER(start); + SERIALISE_MEMBER(refType); +} + +template +bool VulkanResourceManager::Serialise_DeviceMemoryRefs(SerialiserType &ser, + std::vector &data) +{ + SERIALISE_ELEMENT(data); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + // unpack data into m_MemFrameRefs + auto it_data = data.begin(); + while(it_data != data.end()) + { + ResourceId mem = it_data->memory; + + auto res = m_MemFrameRefs.insert(std::make_pair(mem, MemRefs())); + RDCASSERTMSG("MemRefIntervals for each memory resource must be contigous", res.second); + Intervals &rangeRefs = res.first->second.rangeRefs; + + auto it_ints = rangeRefs.begin(); + uint64_t last = 0; + while(it_data != data.end() && it_data->memory == mem) + { + RDCASSERT("MemRefInterval starts must be strictly increasing", + it_data->start > last || last == 0); + last = it_data->start; + it_ints->split(it_data->start); + it_ints->setValue(it_data->refType); + it_data++; + } + } + } + + return true; +} + +template bool VulkanResourceManager::Serialise_DeviceMemoryRefs(ReadSerialiser &ser, + std::vector &data); +template bool VulkanResourceManager::Serialise_DeviceMemoryRefs(WriteSerialiser &ser, + std::vector &data); + +void VulkanResourceManager::InsertDeviceMemoryRefs(WriteSerialiser &ser) +{ + std::vector data; + + for(auto it = m_MemFrameRefs.begin(); it != m_MemFrameRefs.end(); it++) + { + ResourceId mem = it->first; + Intervals &rangeRefs = it->second.rangeRefs; + for(auto jt = rangeRefs.begin(); jt != rangeRefs.end(); jt++) + data.push_back({mem, jt->start(), jt->value()}); + } + + uint32_t sizeEstimate = (uint32_t)data.size() * sizeof(MemRefInterval) + 32; + + { + SCOPED_SERIALISE_CHUNK(VulkanChunk::DeviceMemoryRefs, sizeEstimate); + Serialise_DeviceMemoryRefs(ser, data); + } +} + void VulkanResourceManager::MarkSparseMapReferenced(ResourceInfo *sparse) { if(sparse == NULL) diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 81166e107..b656aa020 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -176,6 +176,15 @@ struct VulkanResourceManagerConfiguration typedef VkInitialContents InitialContentData; }; +struct MemRefInterval +{ + ResourceId memory; + uint64_t start; + FrameRefType refType; +}; + +DECLARE_REFLECTION_STRUCT(MemRefInterval); + class VulkanResourceManager : public ResourceManager { public: @@ -262,6 +271,11 @@ public: void SerialiseImageStates(SerialiserType &ser, std::map &states, std::vector &barriers); + template + bool Serialise_DeviceMemoryRefs(SerialiserType &ser, std::vector &data); + + void InsertDeviceMemoryRefs(WriteSerialiser &ser); + ResourceId GetID(WrappedVkRes *res) { if(res == NULL) diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp index 0dbd93a70..358a5caf1 100644 --- a/renderdoc/driver/vulkan/vk_stringise.cpp +++ b/renderdoc/driver/vulkan/vk_stringise.cpp @@ -28,7 +28,7 @@ template <> std::string DoStringise(const VulkanChunk &el) { - RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1132, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1133, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(VulkanChunk) { @@ -164,6 +164,7 @@ std::string DoStringise(const VulkanChunk &el) STRINGISE_ENUM_CLASS(vkCmdEndConditionalRenderingEXT) STRINGISE_ENUM_CLASS(vkCmdSetSampleLocationsEXT) STRINGISE_ENUM_CLASS(vkCmdSetDiscardRectangleEXT) + STRINGISE_ENUM_CLASS_NAMED(DeviceMemoryRefs, "Device Memory References") STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk"); } END_ENUM_STRINGISE()