diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 186ac02a5..6cf744647 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -321,6 +321,10 @@ bool VkInitParams::IsSupportedVersion(uint64_t ver) if(ver == CurrentVersion) return true; + // 0x10 -> 0x11 - non-breaking changes to image state serialization + if(ver == 0x10) + return true; + // 0xF -> 0x10 - added serialisation of VkPhysicalDeviceDriverPropertiesKHR into enumerated // physical devices if(ver == 0xF) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 6f894c889..24fd462fb 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -53,7 +53,7 @@ struct VkInitParams uint64_t GetSerialiseSize(); // check if a frame capture section version is supported - static const uint64_t CurrentVersion = 0x10; + static const uint64_t CurrentVersion = 0x11; static bool IsSupportedVersion(uint64_t ver); }; diff --git a/renderdoc/driver/vulkan/vk_image_states.cpp b/renderdoc/driver/vulkan/vk_image_states.cpp index 7ed0b7a07..9384a46ab 100644 --- a/renderdoc/driver/vulkan/vk_image_states.cpp +++ b/renderdoc/driver/vulkan/vk_image_states.cpp @@ -447,6 +447,63 @@ size_t ImageSubresourceMap::SubresourceIndex(uint32_t aspectIndex, uint32_t leve slice; } +void ImageSubresourceMap::ToArray(rdcarray &arr) +{ + arr.reserve(arr.size() + m_values.size()); + for(auto src = begin(); src != end(); ++src) + { + arr.push_back(*src); + } +} + +void ImageSubresourceMap::FromArray(const rdcarray &arr) +{ + if(arr.empty()) + { + RDCERR("No values for ImageSubresourceMap"); + return; + } + Split(arr.front().range); + if(m_values.size() != arr.size()) + { + RDCERR("Incorrect number of values for ImageSubresourceMap"); + return; + } + auto src = arr.begin(); + auto dst = begin(); + while(src != arr.end()) + { + if(src->range != dst->range()) + RDCERR("Subresource range mismatch in ImageSubresourceMap"); + else + dst->SetState(src->state); + ++src; + ++dst; + } +} + +void ImageSubresourceMap::FromImgRefs(const ImgRefs &imgRefs) +{ + bool splitLayers = imgRefs.areLayersSplit; + bool splitDepth = false; + if(GetImageInfo().extent.depth > 1) + { + RDCASSERT(GetImageInfo().layerCount == 1); + splitDepth = splitLayers; + splitLayers = false; + } + Split(imgRefs.areAspectsSplit, imgRefs.areLevelsSplit, splitLayers, splitDepth); + RDCASSERT(!(AreLayersSplit() && IsDepthSplit())); + + for(auto dstIt = begin(); dstIt != end(); ++dstIt) + { + int aspectIndex = imgRefs.AspectIndex((VkImageAspectFlagBits)dstIt->range().aspectMask); + int level = (int)dstIt->range().baseMipLevel; + int layer = (int)(dstIt->range().baseArrayLayer + dstIt->range().baseDepthSlice); + dstIt->state().refType = imgRefs.SubresourceRef(aspectIndex, level, layer); + } +} + bool IntervalsOverlap(uint32_t base1, uint32_t count1, uint32_t base2, uint32_t count2) { if((base1 + count1) < base1) diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 65a00d414..e92f142b0 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1267,6 +1267,8 @@ struct ImageSubresourceRange } }; +DECLARE_REFLECTION_STRUCT(ImageSubresourceRange); + struct ImageSubresourceState { uint32_t oldQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -1304,6 +1306,18 @@ struct ImageSubresourceState FrameRefCompFunc compose) const; }; +DECLARE_REFLECTION_STRUCT(ImageSubresourceState); + +struct ImageSubresourceStateForRange +{ + ImageSubresourceRange range; + ImageSubresourceState state; +}; + +DECLARE_REFLECTION_STRUCT(ImageSubresourceStateForRange); + +struct ImgRefs; + class ImageSubresourceMap { friend class SubresourceRangeIterator; @@ -1365,6 +1379,12 @@ public: ImageSubresourceState(VK_QUEUE_FAMILY_IGNORED, UNKNOWN_PREV_IMG_LAYOUT, refType)); } + void ToArray(rdcarray &arr); + + void FromArray(const rdcarray &arr); + + void FromImgRefs(const ImgRefs &imgRefs); + inline ImageSubresourceState &SubresourceValue(uint32_t aspectIndex, uint32_t level, uint32_t layer, uint32_t slice) { @@ -1452,6 +1472,7 @@ public: inline const ImageSubresourceRange &range() const { return m_range; } inline State &state() { return *m_state; } inline const State &state() const { return *m_state; } + operator ImageSubresourceStateForRange() const { return {range(), state()}; } SubresourcePairRefTemplate &operator=(const SubresourcePairRefTemplate &other) = delete; protected: @@ -1678,6 +1699,13 @@ private: ImageState m_state; Threading::SpinLock m_lock; }; +struct TaggedImageState +{ + ResourceId id; + ImageState state; +}; + +DECLARE_REFLECTION_STRUCT(TaggedImageState); struct ImgRefs { diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index 7d5edb42c..084c2e879 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -3947,6 +3947,61 @@ void DoSerialise(SerialiserType &ser, ImageLayouts &el) SERIALISE_MEMBER(imageInfo); } +template +void DoSerialise(SerialiserType &ser, ImageSubresourceRange &el) +{ + SERIALISE_MEMBER_VKFLAGS(VkImageAspectFlags, aspectMask); + SERIALISE_MEMBER(baseMipLevel); + SERIALISE_MEMBER(levelCount); + SERIALISE_MEMBER(baseArrayLayer); + SERIALISE_MEMBER(layerCount); + SERIALISE_MEMBER(baseDepthSlice); + SERIALISE_MEMBER(sliceCount); +} + +template +void DoSerialise(SerialiserType &ser, ImageSubresourceState &el) +{ + SERIALISE_MEMBER(oldQueueFamilyIndex); + SERIALISE_MEMBER(newQueueFamilyIndex); + SERIALISE_MEMBER(oldLayout); + SERIALISE_MEMBER(newLayout); + SERIALISE_MEMBER(refType); +} + +template +void DoSerialise(SerialiserType &ser, ImageSubresourceStateForRange &el) +{ + SERIALISE_MEMBER(range); + SERIALISE_MEMBER(state); +} + +template +void DoSerialise(SerialiserType &ser, ImageState &el) +{ + SERIALISE_ELEMENT_LOCAL(imageInfo, el.GetImageInfo()); + + rdcarray subresourceStates; + if(ser.IsWriting()) + { + el.subresourceStates.ToArray(subresourceStates); + } + SERIALISE_ELEMENT(subresourceStates); + + if(ser.IsReading()) + { + FrameRefType maxRefType = eFrameRef_None; + for(auto it = subresourceStates.begin(); it != subresourceStates.end(); ++it) + { + maxRefType = ComposeFrameRefsDisjoint(maxRefType, it->state.refType); + } + el = ImageState(VK_NULL_HANDLE, imageInfo, maxRefType); + el.subresourceStates.FromArray(subresourceStates); + } + SERIALISE_MEMBER(oldQueueFamilyTransfers); + SERIALISE_MEMBER(newQueueFamilyTransfers); +} + template void DoSerialise(SerialiserType &ser, ImageInfo &el) { @@ -3955,6 +4010,12 @@ void DoSerialise(SerialiserType &ser, ImageInfo &el) SERIALISE_MEMBER(sampleCount); SERIALISE_MEMBER(extent); SERIALISE_MEMBER(format); + if(ser.VersionAtLeast(0x11)) + { + SERIALISE_MEMBER(imageType); + SERIALISE_MEMBER(initialLayout); + SERIALISE_MEMBER(sharingMode); + } } template @@ -8229,6 +8290,9 @@ INSTANTIATE_SERIALISE_TYPE(DescriptorSetSlot); INSTANTIATE_SERIALISE_TYPE(ImageRegionState); INSTANTIATE_SERIALISE_TYPE(ImageLayouts); INSTANTIATE_SERIALISE_TYPE(ImageInfo); +INSTANTIATE_SERIALISE_TYPE(ImageSubresourceRange); +INSTANTIATE_SERIALISE_TYPE(ImageSubresourceStateForRange); +INSTANTIATE_SERIALISE_TYPE(ImageState); #if ENABLED(RDOC_WIN32) template