From 87936f9bc85c59ad3734aa4a8dab873e66838e17 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 8 Aug 2023 13:40:56 +0200 Subject: [PATCH] Resolve a validation layer warnings on destruction order of Image/Buffer and bound DeviceMemory. (#1636) --- .../06_InitDepthBuffer/06_InitDepthBuffer.cpp | 4 ++++ .../07_InitUniformBuffer/07_InitUniformBuffer.cpp | 4 ++++ RAII_Samples/utils/utils.hpp | 23 ++++++++++++---------- samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp | 4 ++-- .../07_InitUniformBuffer/07_InitUniformBuffer.cpp | 2 +- samples/utils/utils.hpp | 4 ++-- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/RAII_Samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp b/RAII_Samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp index 8aa3e3c..77b2fa5 100644 --- a/RAII_Samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp +++ b/RAII_Samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp @@ -92,6 +92,10 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::ImageViewCreateInfo imageViewCreateInfo( {}, *depthImage, vk::ImageViewType::e2D, depthFormat, {}, { vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1 } ); vk::raii::ImageView depthView( device, imageViewCreateInfo ); + // while all vk::raii objects are automatically destroyed on scope leave, the Image should to be destroyed before the bound DeviceMemory + // but the standard destruction order would destroy the DeviceMemory before the Image, so destroy the Image here + depthImage.clear(); + /* VULKAN_HPP_KEY_END */ } catch ( vk::SystemError & err ) diff --git a/RAII_Samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp b/RAII_Samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp index ab240ba..099a228 100644 --- a/RAII_Samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp +++ b/RAII_Samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp @@ -78,6 +78,10 @@ int main( int /*argc*/, char ** /*argv*/ ) uniformDataBuffer.bindMemory( *uniformDataMemory, 0 ); + // while all vk::raii objects are automatically destroyed on scope leave, the Buffer should to be destroyed before the bound DeviceMemory + // but the standard destruction order would destroy the DeviceMemory before the Buffer, so destroy the Buffer here + uniformDataBuffer.clear(); + /* VULKAN_HPP_KEY_END */ } catch ( vk::SystemError & err ) diff --git a/RAII_Samples/utils/utils.hpp b/RAII_Samples/utils/utils.hpp index 490d227..b8e79e9 100644 --- a/RAII_Samples/utils/utils.hpp +++ b/RAII_Samples/utils/utils.hpp @@ -185,13 +185,13 @@ namespace vk vk::BufferUsageFlags usage, vk::MemoryPropertyFlags propertyFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent ) : buffer( device, vk::BufferCreateInfo( {}, size, usage ) ) - , deviceMemory( vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), buffer.getMemoryRequirements(), propertyFlags ) ) #if !defined( NDEBUG ) , m_size( size ) , m_usage( usage ) , m_propertyFlags( propertyFlags ) #endif { + deviceMemory = vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), buffer.getMemoryRequirements(), propertyFlags ); buffer.bindMemory( *deviceMemory, 0 ); } @@ -246,9 +246,10 @@ namespace vk { commandBuffer.copyBuffer( *stagingBuffer.buffer, *this->buffer, vk::BufferCopy( 0, 0, dataSize ) ); } ); } - // the order of buffer and deviceMemory here is important to get the constructor running ! - vk::raii::Buffer buffer = nullptr; + // the DeviceMemory should be destroyed before the Buffer it is bound to; to get that order with the standard destructor + // of the BufferData, the order of DeviceMemory and Buffer here matters vk::raii::DeviceMemory deviceMemory = nullptr; + vk::raii::Buffer buffer = nullptr; #if !defined( NDEBUG ) private: vk::DeviceSize m_size; @@ -282,17 +283,19 @@ namespace vk vk::SharingMode::eExclusive, {}, initialLayout } ) - , deviceMemory( vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), image.getMemoryRequirements(), memoryProperties ) ) { + deviceMemory = vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), image.getMemoryRequirements(), memoryProperties ); image.bindMemory( *deviceMemory, 0 ); imageView = vk::raii::ImageView( device, vk::ImageViewCreateInfo( {}, *image, vk::ImageViewType::e2D, format, {}, { aspectMask, 0, 1, 0, 1 } ) ); } ImageData( std::nullptr_t ) {} + // the DeviceMemory should be destroyed before the Image it is bound to; to get that order with the standard destructor + // of the ImageData, the order of DeviceMemory and Image here matters vk::Format format; - vk::raii::Image image = nullptr; vk::raii::DeviceMemory deviceMemory = nullptr; + vk::raii::Image image = nullptr; vk::raii::ImageView imageView = nullptr; }; @@ -360,10 +363,10 @@ namespace vk ? vk::SurfaceTransformFlagBitsKHR::eIdentity : surfaceCapabilities.currentTransform; vk::CompositeAlphaFlagBitsKHR compositeAlpha = - ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePreMultiplied ) ? vk::CompositeAlphaFlagBitsKHR::ePreMultiplied + ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePreMultiplied ) ? vk::CompositeAlphaFlagBitsKHR::ePreMultiplied : ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::ePostMultiplied ) ? vk::CompositeAlphaFlagBitsKHR::ePostMultiplied - : ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit ) ? vk::CompositeAlphaFlagBitsKHR::eInherit - : vk::CompositeAlphaFlagBitsKHR::eOpaque; + : ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit ) ? vk::CompositeAlphaFlagBitsKHR::eInherit + : vk::CompositeAlphaFlagBitsKHR::eOpaque; vk::PresentModeKHR presentMode = vk::su::pickPresentMode( physicalDevice.getSurfacePresentModesKHR( *surface ) ); vk::SwapchainCreateInfoKHR swapChainCreateInfo( {}, *surface, @@ -784,9 +787,9 @@ namespace vk vk::AttachmentReference depthAttachment( 1, vk::ImageLayout::eDepthStencilAttachmentOptimal ); vk::SubpassDescription subpassDescription( vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, - {}, + {}, colorAttachment, - {}, + {}, ( depthFormat != vk::Format::eUndefined ) ? &depthAttachment : nullptr ); vk::RenderPassCreateInfo renderPassCreateInfo( vk::RenderPassCreateFlags(), attachmentDescriptions, subpassDescription ); return vk::raii::RenderPass( device, renderPassCreateInfo ); diff --git a/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp b/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp index 5403838..1892ce7 100644 --- a/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp +++ b/samples/06_InitDepthBuffer/06_InitDepthBuffer.cpp @@ -89,10 +89,10 @@ int main( int /*argc*/, char ** /*argv*/ ) vk::ImageView depthView = device.createImageView( vk::ImageViewCreateInfo( vk::ImageViewCreateFlags(), depthImage, vk::ImageViewType::e2D, depthFormat, {}, { vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1 } ) ); - // destroy depthView, depthMemory, and depthImage + // destroy depthView, depthImage, and depthMemory device.destroyImageView( depthView ); + device.destroyImage( depthImage ); // the Image should to be destroyed before the bound DeviceMemory is freed device.freeMemory( depthMemory ); - device.destroyImage( depthImage ); /* VULKAN_HPP_KEY_END */ diff --git a/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp b/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp index f78e70a..c22793b 100644 --- a/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp +++ b/samples/07_InitUniformBuffer/07_InitUniformBuffer.cpp @@ -78,8 +78,8 @@ int main( int /*argc*/, char ** /*argv*/ ) device.bindBufferMemory( uniformDataBuffer, uniformDataMemory, 0 ); // free device memory and destroy buffer + device.destroyBuffer( uniformDataBuffer ); // the Buffer should be destroyed before the bound DeviceMemory is freed device.freeMemory( uniformDataMemory ); - device.destroyBuffer( uniformDataBuffer ); /* VULKAN_HPP_KEY_END */ diff --git a/samples/utils/utils.hpp b/samples/utils/utils.hpp index 70e58d0..d35cf3c 100644 --- a/samples/utils/utils.hpp +++ b/samples/utils/utils.hpp @@ -107,8 +107,8 @@ namespace vk void clear( vk::Device const & device ) { + device.destroyBuffer( buffer ); // to prevent some validation layer warning, the Buffer needs to be destroyed before the bound DeviceMemory device.freeMemory( deviceMemory ); - device.destroyBuffer( buffer ); } template @@ -187,8 +187,8 @@ namespace vk void clear( vk::Device const & device ) { device.destroyImageView( imageView ); + device.destroyImage( image ); // the Image should to be destroyed before the bound DeviceMemory is freed device.freeMemory( deviceMemory ); - device.destroyImage( image ); } vk::Format format; -- 2.7.4