// Copyright 2015-2024 The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 OR MIT // // This header is generated from the Khronos Vulkan XML API Registry. #ifndef VULKAN_SHARED_HPP #define VULKAN_SHARED_HPP #include // std::atomic_size_t #include namespace VULKAN_HPP_NAMESPACE { #if !defined( VULKAN_HPP_NO_SMART_HANDLE ) template class SharedHandleTraits; class NoDestructor { }; template struct HasDestructorType : std::false_type { }; template struct HasDestructorType::DestructorType() )> : std::true_type { }; template struct GetDestructorType { using type = NoDestructor; }; template struct GetDestructorType::value>::type> { using type = typename SharedHandleTraits::DestructorType; }; template using DestructorTypeOf = typename GetDestructorType::type; template struct HasDestructor : std::integral_constant, NoDestructor>::value> { }; template struct HasPoolType : std::false_type { }; template struct HasPoolType::deleter::PoolTypeExport() )> : std::true_type { }; template struct GetPoolType { using type = NoDestructor; }; template struct GetPoolType::value>::type> { using type = typename SharedHandleTraits::deleter::PoolTypeExport; }; //===================================================================================================================== template class SharedHandle; template struct SharedHeader { SharedHeader( SharedHandle parent, Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT : parent( std::move( parent ) ) , deleter( std::move( deleter ) ) { } SharedHandle parent; Deleter deleter; }; template struct SharedHeader { SharedHeader( Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT : deleter( std::move( deleter ) ) {} Deleter deleter; }; //===================================================================================================================== template class ReferenceCounter { public: template ReferenceCounter( Args &&... control_args ) : m_header( std::forward( control_args )... ) { } ReferenceCounter( const ReferenceCounter & ) = delete; ReferenceCounter & operator=( const ReferenceCounter & ) = delete; public: size_t addRef() VULKAN_HPP_NOEXCEPT { // Relaxed memory order is sufficient since this does not impose any ordering on other operations return m_ref_cnt.fetch_add( 1, std::memory_order_relaxed ); } size_t release() VULKAN_HPP_NOEXCEPT { // A release memory order to ensure that all releases are ordered return m_ref_cnt.fetch_sub( 1, std::memory_order_release ); } public: std::atomic_size_t m_ref_cnt{ 1 }; HeaderType m_header{}; }; //===================================================================================================================== template > class SharedHandleBase { public: SharedHandleBase() = default; template SharedHandleBase( HandleType handle, Args &&... control_args ) : m_control( new ReferenceCounter( std::forward( control_args )... ) ), m_handle( handle ) { } SharedHandleBase( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT { o.addRef(); m_handle = o.m_handle; m_control = o.m_control; } SharedHandleBase( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT : m_control( o.m_control ) , m_handle( o.m_handle ) { o.m_handle = nullptr; o.m_control = nullptr; } SharedHandleBase & operator=( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT { SharedHandleBase( o ).swap( *this ); return *this; } SharedHandleBase & operator=( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT { SharedHandleBase( std::move( o ) ).swap( *this ); return *this; } ~SharedHandleBase() { // only this function owns the last reference to the control block // the same principle is used in the default deleter of std::shared_ptr if ( m_control && ( m_control->release() == 1 ) ) { // noop in x86, but does thread synchronization in ARM // it is required to ensure that last thread is getting to destroy the control block // by ordering all atomic operations before this fence std::atomic_thread_fence( std::memory_order_acquire ); ForwardType::internalDestroy( getHeader(), m_handle ); delete m_control; } } public: HandleType get() const VULKAN_HPP_NOEXCEPT { return m_handle; } HandleType operator*() const VULKAN_HPP_NOEXCEPT { return m_handle; } explicit operator bool() const VULKAN_HPP_NOEXCEPT { return bool( m_handle ); } # if defined( VULKAN_HPP_SMART_HANDLE_IMPLICIT_CAST ) operator HandleType() const VULKAN_HPP_NOEXCEPT { return m_handle; } # endif const HandleType * operator->() const VULKAN_HPP_NOEXCEPT { return &m_handle; } HandleType * operator->() VULKAN_HPP_NOEXCEPT { return &m_handle; } void reset() VULKAN_HPP_NOEXCEPT { SharedHandleBase().swap( *this ); } void swap( SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT { std::swap( m_handle, o.m_handle ); std::swap( m_control, o.m_control ); } template typename std::enable_if::value, const SharedHandle> &>::type getDestructorType() const VULKAN_HPP_NOEXCEPT { return getHeader().parent; } protected: template static typename std::enable_if::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT { control.deleter.destroy( handle ); } template static typename std::enable_if::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT { control.deleter.destroy( control.parent.get(), handle ); } const HeaderType & getHeader() const VULKAN_HPP_NOEXCEPT { return m_control->m_header; } private: void addRef() const VULKAN_HPP_NOEXCEPT { if ( m_control ) m_control->addRef(); } protected: ReferenceCounter * m_control = nullptr; HandleType m_handle{}; }; template class SharedHandle : public SharedHandleBase, typename SharedHandleTraits::deleter>> { private: using BaseType = SharedHandleBase, typename SharedHandleTraits::deleter>>; using DeleterType = typename SharedHandleTraits::deleter; friend BaseType; public: SharedHandle() = default; template ::value && !HasPoolType::value>::type> explicit SharedHandle( HandleType handle, SharedHandle> parent, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( parent ), std::move( deleter ) ) { } template ::value && HasPoolType::value>::type> explicit SharedHandle( HandleType handle, SharedHandle> parent, SharedHandle::type> pool, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( parent ), DeleterType{ std::move( pool ), dispatch } ) { } template ::value>::type> explicit SharedHandle( HandleType handle, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( deleter ) ) { } protected: using BaseType::internalDestroy; }; template class SharedHandleTraits; // Silence the function cast warnings. # if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER ) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wcast-function-type" # endif template class ObjectDestroyShared { public: using DestructorType = typename SharedHandleTraits::DestructorType; template using DestroyFunctionPointerType = typename std::conditional::value, void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const, void ( HandleType::* )( const AllocationCallbacks *, const Dispatcher & ) const>::type; using SelectorType = typename std::conditional::value, DestructorType, HandleType>::type; template ObjectDestroyShared( Optional allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) : m_destroy( reinterpret_cast( static_cast>( &SelectorType::destroy ) ) ) , m_dispatch( &dispatch ) , m_allocationCallbacks( allocationCallbacks ) { } public: template typename std::enable_if::value, void>::type destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT { VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch ); } template typename std::enable_if::value, void>::type destroy( HandleType handle ) const VULKAN_HPP_NOEXCEPT { VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); ( handle.*m_destroy )( m_allocationCallbacks, *m_dispatch ); } private: DestroyFunctionPointerType m_destroy = nullptr; const DispatchLoaderBase * m_dispatch = nullptr; Optional m_allocationCallbacks = nullptr; }; template class ObjectFreeShared { public: using DestructorType = typename SharedHandleTraits::DestructorType; template using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const; template ObjectFreeShared( Optional allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) : m_destroy( reinterpret_cast( static_cast>( &DestructorType::free ) ) ) , m_dispatch( &dispatch ) , m_allocationCallbacks( allocationCallbacks ) { } public: void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT { VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch ); } private: DestroyFunctionPointerType m_destroy = nullptr; const DispatchLoaderBase * m_dispatch = nullptr; Optional m_allocationCallbacks = nullptr; }; template class ObjectReleaseShared { public: using DestructorType = typename SharedHandleTraits::DestructorType; template using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const Dispatcher & ) const; template ObjectReleaseShared( const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) : m_destroy( reinterpret_cast( static_cast>( &DestructorType::release ) ) ) , m_dispatch( &dispatch ) { } public: void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT { VULKAN_HPP_ASSERT( m_destroy && m_dispatch ); ( parent.*m_destroy )( handle, *m_dispatch ); } private: DestroyFunctionPointerType m_destroy = nullptr; const DispatchLoaderBase * m_dispatch = nullptr; }; template class PoolFreeShared { public: using DestructorType = typename SharedHandleTraits::DestructorType; using PoolTypeExport = PoolType; template using ReturnType = decltype( std::declval().free( PoolType(), 0u, nullptr, Dispatcher() ) ); template using DestroyFunctionPointerType = ReturnType ( DestructorType::* )( PoolType, uint32_t, const HandleType *, const Dispatcher & ) const; PoolFreeShared() = default; template PoolFreeShared( SharedHandle pool, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) : m_destroy( reinterpret_cast( static_cast>( &DestructorType::free ) ) ) , m_dispatch( &dispatch ) , m_pool( std::move( pool ) ) { } public: void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT { VULKAN_HPP_ASSERT( m_destroy && m_dispatch && m_pool ); ( parent.*m_destroy )( m_pool.get(), 1u, &handle, *m_dispatch ); } private: DestroyFunctionPointerType m_destroy = nullptr; const DispatchLoaderBase * m_dispatch = nullptr; SharedHandle m_pool{}; }; # if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER ) # pragma GCC diagnostic pop # endif //====================== //=== SHARED HANDLEs === //====================== //=== VK_VERSION_1_0 === template <> class SharedHandleTraits { public: using DestructorType = NoDestructor; using deleter = ObjectDestroyShared; }; using SharedInstance = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = NoDestructor; using deleter = ObjectDestroyShared; }; using SharedDevice = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedFence = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedSemaphore = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedEvent = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedBuffer = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedBufferView = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedImage = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedImageView = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedPipelineCache = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedPipeline = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedPipelineLayout = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedSampler = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = PoolFreeShared; }; using SharedDescriptorSet = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedDescriptorSetLayout = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedFramebuffer = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedRenderPass = SharedHandle; template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = PoolFreeShared; }; using SharedCommandBuffer = SharedHandle; //=== VK_VERSION_1_1 === template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedSamplerYcbcrConversion = SharedHandle; using SharedSamplerYcbcrConversionKHR = SharedHandle; //=== VK_VERSION_1_3 === template <> class SharedHandleTraits { public: using DestructorType = Device; using deleter = ObjectDestroyShared; }; using SharedPrivateDataSlot = SharedHandle; using SharedPrivateDataSlotEXT = SharedHandle; //=== VK_KHR_surface === template <> class SharedHandleTraits { public: using DestructorType = Instance; using deleter = ObjectDestroyShared; }; using SharedSurfaceKHR = SharedHandle; //=== VK_KHR_display === template <> class SharedHandleTraits { public: using DestructorType = PhysicalDevice; using deleter = ObjectDestroyShared; }; using SharedDisplayKHR = SharedHandle; //=== VK_EXT_debug_utils === template <> class SharedHandleTraits { public: using DestructorType = Instance; using deleter = ObjectDestroyShared; }; using SharedDebugUtilsMessengerEXT = SharedHandle; enum class SwapchainOwns { no, yes, }; struct ImageHeader : SharedHeader, typename SharedHandleTraits::deleter> { ImageHeader( SharedHandle> parent, typename SharedHandleTraits::deleter deleter = typename SharedHandleTraits::deleter(), SwapchainOwns swapchainOwned = SwapchainOwns::no ) VULKAN_HPP_NOEXCEPT : SharedHeader, typename SharedHandleTraits::deleter>( std::move( parent ), std::move( deleter ) ) , swapchainOwned( swapchainOwned ) { } SwapchainOwns swapchainOwned = SwapchainOwns::no; }; template <> class SharedHandle : public SharedHandleBase { using BaseType = SharedHandleBase; using DeleterType = typename SharedHandleTraits::deleter; friend BaseType; public: SharedHandle() = default; explicit SharedHandle( VULKAN_HPP_NAMESPACE::Image handle, SharedHandle> parent, SwapchainOwns swapchain_owned = SwapchainOwns::no, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( parent ), std::move( deleter ), swapchain_owned ) { } protected: static void internalDestroy( const ImageHeader & control, VULKAN_HPP_NAMESPACE::Image handle ) VULKAN_HPP_NOEXCEPT { if ( control.swapchainOwned == SwapchainOwns::no ) { control.deleter.destroy( control.parent.get(), handle ); } } }; struct SwapchainHeader { SwapchainHeader( SharedHandle surface, SharedHandle> parent, typename SharedHandleTraits::deleter deleter = typename SharedHandleTraits::deleter() ) VULKAN_HPP_NOEXCEPT : surface( std::move( surface ) ) , parent( std::move( parent ) ) , deleter( std::move( deleter ) ) { } SharedHandle surface{}; SharedHandle> parent{}; typename SharedHandleTraits::deleter deleter{}; }; template <> class SharedHandle : public SharedHandleBase { using BaseType = SharedHandleBase; using DeleterType = typename SharedHandleTraits::deleter; friend BaseType; public: SharedHandle() = default; explicit SharedHandle( VULKAN_HPP_NAMESPACE::SwapchainKHR handle, SharedHandle> parent, SharedHandle surface, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( surface ), std::move( parent ), std::move( deleter ) ) { } public: const SharedHandle & getSurface() const VULKAN_HPP_NOEXCEPT { return getHeader().surface; } protected: using BaseType::internalDestroy; }; template class SharedHandleBaseNoDestroy : public SharedHandleBase { public: using SharedHandleBase::SharedHandleBase; const DestructorType & getDestructorType() const VULKAN_HPP_NOEXCEPT { return SharedHandleBase::getHeader(); } protected: static void internalDestroy( const DestructorType &, HandleType ) VULKAN_HPP_NOEXCEPT {} }; //=== VK_VERSION_1_0 === template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( PhysicalDevice handle, SharedInstance parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedPhysicalDevice = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( Queue handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) {} }; using SharedQueue = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( DeviceMemory handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedDeviceMemory = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( QueryPool handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedQueryPool = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( ShaderModule handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedShaderModule = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( DescriptorPool handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedDescriptorPool = SharedHandle; template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( CommandPool handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedCommandPool = SharedHandle; //=== VK_KHR_swapchain === template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( SwapchainKHR handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedSwapchainKHR = SharedHandle; //=== VK_KHR_display === template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( DisplayModeKHR handle, SharedDisplayKHR parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedDisplayModeKHR = SharedHandle; # if defined( VK_USE_PLATFORM_SCI ) //=== VK_NV_external_sci_sync2 === template <> class SharedHandle : public SharedHandleBaseNoDestroy { friend SharedHandleBase; public: SharedHandle() = default; explicit SharedHandle( SemaphoreSciSyncPoolNV handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy( handle, std::move( parent ) ) { } }; using SharedSemaphoreSciSyncPoolNV = SharedHandle; # endif /*VK_USE_PLATFORM_SCI*/ #endif // !VULKAN_HPP_NO_SMART_HANDLE } // namespace VULKAN_HPP_NAMESPACE #endif // VULKAN_SHARED_HPP