Resolve a validation layer warnings on destruction order of Image/Buffer and bound DeviceMemory. (#1636)

This commit is contained in:
Andreas Süßenbach 2023-08-08 13:40:56 +02:00 committed by GitHub
parent 0e3e8967be
commit 87936f9bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 15 deletions

View File

@ -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::ImageViewCreateInfo imageViewCreateInfo( {}, *depthImage, vk::ImageViewType::e2D, depthFormat, {}, { vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1 } );
vk::raii::ImageView depthView( device, imageViewCreateInfo ); 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 */ /* VULKAN_HPP_KEY_END */
} }
catch ( vk::SystemError & err ) catch ( vk::SystemError & err )

View File

@ -78,6 +78,10 @@ int main( int /*argc*/, char ** /*argv*/ )
uniformDataBuffer.bindMemory( *uniformDataMemory, 0 ); 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 */ /* VULKAN_HPP_KEY_END */
} }
catch ( vk::SystemError & err ) catch ( vk::SystemError & err )

View File

@ -185,13 +185,13 @@ namespace vk
vk::BufferUsageFlags usage, vk::BufferUsageFlags usage,
vk::MemoryPropertyFlags propertyFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent ) vk::MemoryPropertyFlags propertyFlags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent )
: buffer( device, vk::BufferCreateInfo( {}, size, usage ) ) : buffer( device, vk::BufferCreateInfo( {}, size, usage ) )
, deviceMemory( vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), buffer.getMemoryRequirements(), propertyFlags ) )
#if !defined( NDEBUG ) #if !defined( NDEBUG )
, m_size( size ) , m_size( size )
, m_usage( usage ) , m_usage( usage )
, m_propertyFlags( propertyFlags ) , m_propertyFlags( propertyFlags )
#endif #endif
{ {
deviceMemory = vk::raii::su::allocateDeviceMemory( device, physicalDevice.getMemoryProperties(), buffer.getMemoryRequirements(), propertyFlags );
buffer.bindMemory( *deviceMemory, 0 ); buffer.bindMemory( *deviceMemory, 0 );
} }
@ -246,9 +246,10 @@ namespace vk
{ commandBuffer.copyBuffer( *stagingBuffer.buffer, *this->buffer, vk::BufferCopy( 0, 0, dataSize ) ); } ); { 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 ! // the DeviceMemory should be destroyed before the Buffer it is bound to; to get that order with the standard destructor
vk::raii::Buffer buffer = nullptr; // of the BufferData, the order of DeviceMemory and Buffer here matters
vk::raii::DeviceMemory deviceMemory = nullptr; vk::raii::DeviceMemory deviceMemory = nullptr;
vk::raii::Buffer buffer = nullptr;
#if !defined( NDEBUG ) #if !defined( NDEBUG )
private: private:
vk::DeviceSize m_size; vk::DeviceSize m_size;
@ -282,17 +283,19 @@ namespace vk
vk::SharingMode::eExclusive, vk::SharingMode::eExclusive,
{}, {},
initialLayout } ) 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 ); image.bindMemory( *deviceMemory, 0 );
imageView = vk::raii::ImageView( device, vk::ImageViewCreateInfo( {}, *image, vk::ImageViewType::e2D, format, {}, { aspectMask, 0, 1, 0, 1 } ) ); imageView = vk::raii::ImageView( device, vk::ImageViewCreateInfo( {}, *image, vk::ImageViewType::e2D, format, {}, { aspectMask, 0, 1, 0, 1 } ) );
} }
ImageData( std::nullptr_t ) {} 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::Format format;
vk::raii::Image image = nullptr;
vk::raii::DeviceMemory deviceMemory = nullptr; vk::raii::DeviceMemory deviceMemory = nullptr;
vk::raii::Image image = nullptr;
vk::raii::ImageView imageView = nullptr; vk::raii::ImageView imageView = nullptr;
}; };
@ -360,10 +363,10 @@ namespace vk
? vk::SurfaceTransformFlagBitsKHR::eIdentity ? vk::SurfaceTransformFlagBitsKHR::eIdentity
: surfaceCapabilities.currentTransform; : surfaceCapabilities.currentTransform;
vk::CompositeAlphaFlagBitsKHR compositeAlpha = 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::ePostMultiplied ) ? vk::CompositeAlphaFlagBitsKHR::ePostMultiplied
: ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit ) ? vk::CompositeAlphaFlagBitsKHR::eInherit : ( surfaceCapabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eInherit ) ? vk::CompositeAlphaFlagBitsKHR::eInherit
: vk::CompositeAlphaFlagBitsKHR::eOpaque; : vk::CompositeAlphaFlagBitsKHR::eOpaque;
vk::PresentModeKHR presentMode = vk::su::pickPresentMode( physicalDevice.getSurfacePresentModesKHR( *surface ) ); vk::PresentModeKHR presentMode = vk::su::pickPresentMode( physicalDevice.getSurfacePresentModesKHR( *surface ) );
vk::SwapchainCreateInfoKHR swapChainCreateInfo( {}, vk::SwapchainCreateInfoKHR swapChainCreateInfo( {},
*surface, *surface,
@ -784,9 +787,9 @@ namespace vk
vk::AttachmentReference depthAttachment( 1, vk::ImageLayout::eDepthStencilAttachmentOptimal ); vk::AttachmentReference depthAttachment( 1, vk::ImageLayout::eDepthStencilAttachmentOptimal );
vk::SubpassDescription subpassDescription( vk::SubpassDescriptionFlags(), vk::SubpassDescription subpassDescription( vk::SubpassDescriptionFlags(),
vk::PipelineBindPoint::eGraphics, vk::PipelineBindPoint::eGraphics,
{}, {},
colorAttachment, colorAttachment,
{}, {},
( depthFormat != vk::Format::eUndefined ) ? &depthAttachment : nullptr ); ( depthFormat != vk::Format::eUndefined ) ? &depthAttachment : nullptr );
vk::RenderPassCreateInfo renderPassCreateInfo( vk::RenderPassCreateFlags(), attachmentDescriptions, subpassDescription ); vk::RenderPassCreateInfo renderPassCreateInfo( vk::RenderPassCreateFlags(), attachmentDescriptions, subpassDescription );
return vk::raii::RenderPass( device, renderPassCreateInfo ); return vk::raii::RenderPass( device, renderPassCreateInfo );

View File

@ -89,10 +89,10 @@ int main( int /*argc*/, char ** /*argv*/ )
vk::ImageView depthView = device.createImageView( vk::ImageViewCreateInfo( vk::ImageView depthView = device.createImageView( vk::ImageViewCreateInfo(
vk::ImageViewCreateFlags(), depthImage, vk::ImageViewType::e2D, depthFormat, {}, { vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1 } ) ); 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.destroyImageView( depthView );
device.destroyImage( depthImage ); // the Image should to be destroyed before the bound DeviceMemory is freed
device.freeMemory( depthMemory ); device.freeMemory( depthMemory );
device.destroyImage( depthImage );
/* VULKAN_HPP_KEY_END */ /* VULKAN_HPP_KEY_END */

View File

@ -78,8 +78,8 @@ int main( int /*argc*/, char ** /*argv*/ )
device.bindBufferMemory( uniformDataBuffer, uniformDataMemory, 0 ); device.bindBufferMemory( uniformDataBuffer, uniformDataMemory, 0 );
// free device memory and destroy buffer // free device memory and destroy buffer
device.destroyBuffer( uniformDataBuffer ); // the Buffer should be destroyed before the bound DeviceMemory is freed
device.freeMemory( uniformDataMemory ); device.freeMemory( uniformDataMemory );
device.destroyBuffer( uniformDataBuffer );
/* VULKAN_HPP_KEY_END */ /* VULKAN_HPP_KEY_END */

View File

@ -107,8 +107,8 @@ namespace vk
void clear( vk::Device const & device ) 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.freeMemory( deviceMemory );
device.destroyBuffer( buffer );
} }
template <typename DataType> template <typename DataType>
@ -187,8 +187,8 @@ namespace vk
void clear( vk::Device const & device ) void clear( vk::Device const & device )
{ {
device.destroyImageView( imageView ); device.destroyImageView( imageView );
device.destroyImage( image ); // the Image should to be destroyed before the bound DeviceMemory is freed
device.freeMemory( deviceMemory ); device.freeMemory( deviceMemory );
device.destroyImage( image );
} }
vk::Format format; vk::Format format;