1 // Copyright 2015-2024 The Khronos Group Inc.
2 //
3 // SPDX-License-Identifier: Apache-2.0 OR MIT
4 //
5 
6 // This header is generated from the Khronos Vulkan XML API Registry.
7 
8 #ifndef VULKAN_SHARED_HPP
9 #define VULKAN_SHARED_HPP
10 
11 #include <atomic>  // std::atomic_size_t
12 #include <vulkan/vulkan.hpp>
13 
14 namespace VULKAN_HPP_NAMESPACE
15 {
16 #if !defined( VULKAN_HPP_NO_SMART_HANDLE )
17 
18   template <typename HandleType>
19   class SharedHandleTraits;
20 
21   class NoDestructor
22   {
23   };
24 
25   template <typename HandleType, typename = void>
26   struct HasDestructorType : std::false_type
27   {
28   };
29 
30   template <typename HandleType>
31   struct HasDestructorType<HandleType, decltype( (void)typename SharedHandleTraits<HandleType>::DestructorType() )> : std::true_type
32   {
33   };
34 
35   template <typename HandleType, typename Enable = void>
36   struct GetDestructorType
37   {
38     using type = NoDestructor;
39   };
40 
41   template <typename HandleType>
42   struct GetDestructorType<HandleType, typename std::enable_if<HasDestructorType<HandleType>::value>::type>
43   {
44     using type = typename SharedHandleTraits<HandleType>::DestructorType;
45   };
46 
47   template <class HandleType>
48   using DestructorTypeOf = typename GetDestructorType<HandleType>::type;
49 
50   template <class HandleType>
51   struct HasDestructor : std::integral_constant<bool, !std::is_same<DestructorTypeOf<HandleType>, NoDestructor>::value>
52   {
53   };
54 
55   //=====================================================================================================================
56 
57   template <typename HandleType>
58   class SharedHandle;
59 
60   template <typename DestructorType, typename Deleter>
61   struct SharedHeader
62   {
63     SharedHeader( SharedHandle<DestructorType> parent, Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT
64       : parent( std::move( parent ) )
moveVULKAN_HPP_NAMESPACE::SharedHeader65       , deleter( std::move( deleter ) )
66     {
67     }
68 
69     SharedHandle<DestructorType> parent;
70     Deleter                      deleter;
71   };
72 
73   template <typename Deleter>
74   struct SharedHeader<NoDestructor, Deleter>
75   {
76     SharedHeader( Deleter deleter = Deleter() ) VULKAN_HPP_NOEXCEPT : deleter( std::move( deleter ) ) {}
77 
78     Deleter deleter;
79   };
80 
81   //=====================================================================================================================
82 
83   template <typename HeaderType>
84   class ReferenceCounter
85   {
86   public:
87     template <typename... Args>
ReferenceCounter( Args &&.... control_args )88     ReferenceCounter( Args &&... control_args ) : m_header( std::forward<Args>( control_args )... )
89     {
90     }
91 
92     ReferenceCounter( const ReferenceCounter & )             = delete;
93     ReferenceCounter & operator=( const ReferenceCounter & ) = delete;
94 
95   public:
96     size_t addRef() VULKAN_HPP_NOEXCEPT
97     {
98       // Relaxed memory order is sufficient since this does not impose any ordering on other operations
99       return m_ref_cnt.fetch_add( 1, std::memory_order_relaxed );
100     }
101 
102     size_t release() VULKAN_HPP_NOEXCEPT
103     {
104       // A release memory order to ensure that all releases are ordered
105       return m_ref_cnt.fetch_sub( 1, std::memory_order_release );
106     }
107 
108   public:
109     std::atomic_size_t m_ref_cnt{ 1 };
110     HeaderType         m_header{};
111   };
112 
113   //=====================================================================================================================
114 
115   template <typename HandleType, typename HeaderType, typename ForwardType = SharedHandle<HandleType>>
116   class SharedHandleBase
117   {
118   public:
119     SharedHandleBase() = default;
120 
121     template <typename... Args>
SharedHandleBase( HandleType handle, Args &&... control_args )122     SharedHandleBase( HandleType handle, Args &&... control_args )
123       : m_control( new ReferenceCounter<HeaderType>( std::forward<Args>( control_args )... ) ), m_handle( handle )
124     {
125     }
126 
127     SharedHandleBase( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT
128     {
129       o.addRef();
130       m_handle  = o.m_handle;
131       m_control = o.m_control;
132     }
133 
134     SharedHandleBase( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT
135       : m_control( o.m_control )
m_handle( o.m_handle )136       , m_handle( o.m_handle )
137     {
138       o.m_handle  = nullptr;
139       o.m_control = nullptr;
140     }
141 
142     SharedHandleBase & operator=( const SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT
143     {
144       SharedHandleBase( o ).swap( *this );
145       return *this;
146     }
147 
148     SharedHandleBase & operator=( SharedHandleBase && o ) VULKAN_HPP_NOEXCEPT
149     {
150       SharedHandleBase( std::move( o ) ).swap( *this );
151       return *this;
152     }
153 
~SharedHandleBase()154     ~SharedHandleBase()
155     {
156       // only this function owns the last reference to the control block
157       // the same principle is used in the default deleter of std::shared_ptr
158       if ( m_control && ( m_control->release() == 1 ) )
159       {
160         // noop in x86, but does thread synchronization in ARM
161         // it is required to ensure that last thread is getting to destroy the control block
162         // by ordering all atomic operations before this fence
163         std::atomic_thread_fence( std::memory_order_acquire );
164         ForwardType::internalDestroy( getHeader(), m_handle );
165         delete m_control;
166       }
167     }
168 
169   public:
170     HandleType get() const VULKAN_HPP_NOEXCEPT
171     {
172       return m_handle;
173     }
174 
175     HandleType operator*() const VULKAN_HPP_NOEXCEPT
176     {
177       return m_handle;
178     }
179 
180     explicit operator bool() const VULKAN_HPP_NOEXCEPT
181     {
182       return bool( m_handle );
183     }
184 
185     const HandleType * operator->() const VULKAN_HPP_NOEXCEPT
186     {
187       return &m_handle;
188     }
189 
190     HandleType * operator->() VULKAN_HPP_NOEXCEPT
191     {
192       return &m_handle;
193     }
194 
195     void reset() VULKAN_HPP_NOEXCEPT
196     {
197       SharedHandleBase().swap( *this );
198     }
199 
200     void swap( SharedHandleBase & o ) VULKAN_HPP_NOEXCEPT
201     {
202       std::swap( m_handle, o.m_handle );
203       std::swap( m_control, o.m_control );
204     }
205 
206     template <typename T = HandleType>
207     typename std::enable_if<HasDestructor<T>::value, const SharedHandle<DestructorTypeOf<HandleType>> &>::type getDestructorType() const VULKAN_HPP_NOEXCEPT
208     {
209       return getHeader().parent;
210     }
211 
212   protected:
213     template <typename T = HandleType>
214     static typename std::enable_if<!HasDestructor<T>::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT
215     {
216       control.deleter.destroy( handle );
217     }
218 
219     template <typename T = HandleType>
220     static typename std::enable_if<HasDestructor<T>::value, void>::type internalDestroy( const HeaderType & control, HandleType handle ) VULKAN_HPP_NOEXCEPT
221     {
222       control.deleter.destroy( control.parent.get(), handle );
223     }
224 
225     const HeaderType & getHeader() const VULKAN_HPP_NOEXCEPT
226     {
227       return m_control->m_header;
228     }
229 
230   private:
231     void addRef() const VULKAN_HPP_NOEXCEPT
232     {
233       if ( m_control )
234         m_control->addRef();
235     }
236 
237   protected:
238     ReferenceCounter<HeaderType> * m_control = nullptr;
239     HandleType                     m_handle{};
240   };
241 
242   template <typename HandleType>
243   class SharedHandle : public SharedHandleBase<HandleType, SharedHeader<DestructorTypeOf<HandleType>, typename SharedHandleTraits<HandleType>::deleter>>
244   {
245   private:
246     using BaseType    = SharedHandleBase<HandleType, SharedHeader<DestructorTypeOf<HandleType>, typename SharedHandleTraits<HandleType>::deleter>>;
247     using DeleterType = typename SharedHandleTraits<HandleType>::deleter;
248     friend BaseType;
249 
250   public:
251     SharedHandle() = default;
252 
253     template <typename T = HandleType, typename = typename std::enable_if<HasDestructor<T>::value>::type>
254     explicit SharedHandle( HandleType handle, SharedHandle<DestructorTypeOf<HandleType>> parent, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT
BaseType( handle, std::move( parent ), std::move( deleter ) )255       : BaseType( handle, std::move( parent ), std::move( deleter ) )
256     {
257     }
258 
259     template <typename T = HandleType, typename = typename std::enable_if<!HasDestructor<T>::value>::type>
BaseType( handle, std::move( deleter ) )260     explicit SharedHandle( HandleType handle, DeleterType deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT : BaseType( handle, std::move( deleter ) )
261     {
262     }
263 
264   protected:
265     using BaseType::internalDestroy;
266   };
267 
268   template <typename HandleType>
269   class SharedHandleTraits;
270 
271 // Silence the function cast warnings.
272 #  if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER )
273 #    pragma GCC diagnostic push
274 #    pragma GCC diagnostic ignored "-Wcast-function-type"
275 #  endif
276 
277   template <typename HandleType>
278   class ObjectDestroyShared
279   {
280   public:
281     using DestructorType = typename SharedHandleTraits<HandleType>::DestructorType;
282 
283     template <class Dispatcher>
284     using DestroyFunctionPointerType =
285       typename std::conditional<HasDestructor<HandleType>::value,
286                                 void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const,
287                                 void ( HandleType::* )( const AllocationCallbacks *, const Dispatcher & ) const>::type;
288 
289     using SelectorType = typename std::conditional<HasDestructor<HandleType>::value, DestructorType, HandleType>::type;
290 
291     template <typename Dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
ObjectDestroyShared( Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )292     ObjectDestroyShared( Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT,
293                          const Dispatcher & dispatch                             VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )
294       : m_destroy( reinterpret_cast<decltype( m_destroy )>( static_cast<DestroyFunctionPointerType<Dispatcher>>( &SelectorType::destroy ) ) )
295       , m_dispatch( &dispatch )
296       , m_allocationCallbacks( allocationCallbacks )
297     {
298     }
299 
300   public:
301     template <typename T = HandleType>
302     typename std::enable_if<HasDestructor<T>::value, void>::type destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT
303     {
304       VULKAN_HPP_ASSERT( m_destroy && m_dispatch );
305       ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch );
306     }
307 
308     template <typename T = HandleType>
309     typename std::enable_if<!HasDestructor<T>::value, void>::type destroy( HandleType handle ) const VULKAN_HPP_NOEXCEPT
310     {
311       VULKAN_HPP_ASSERT( m_destroy && m_dispatch );
312       ( handle.*m_destroy )( m_allocationCallbacks, *m_dispatch );
313     }
314 
315   private:
316     DestroyFunctionPointerType<DispatchLoaderBase> m_destroy             = nullptr;
317     const DispatchLoaderBase *                     m_dispatch            = nullptr;
318     Optional<const AllocationCallbacks>            m_allocationCallbacks = nullptr;
319   };
320 
321   template <typename HandleType>
322   class ObjectFreeShared
323   {
324   public:
325     using DestructorType = typename SharedHandleTraits<HandleType>::DestructorType;
326 
327     template <class Dispatcher>
328     using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const AllocationCallbacks *, const Dispatcher & ) const;
329 
330     template <class Dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
ObjectFreeShared( Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )331     ObjectFreeShared( Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT,
332                       const Dispatcher & dispatch                             VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )
333       : m_destroy( reinterpret_cast<decltype( m_destroy )>( static_cast<DestroyFunctionPointerType<Dispatcher>>( &DestructorType::free ) ) )
334       , m_dispatch( &dispatch )
335       , m_allocationCallbacks( allocationCallbacks )
336     {
337     }
338 
339   public:
340     void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT
341     {
342       VULKAN_HPP_ASSERT( m_destroy && m_dispatch );
343       ( parent.*m_destroy )( handle, m_allocationCallbacks, *m_dispatch );
344     }
345 
346   private:
347     DestroyFunctionPointerType<DispatchLoaderBase> m_destroy             = nullptr;
348     const DispatchLoaderBase *                     m_dispatch            = nullptr;
349     Optional<const AllocationCallbacks>            m_allocationCallbacks = nullptr;
350   };
351 
352   template <typename HandleType>
353   class ObjectReleaseShared
354   {
355   public:
356     using DestructorType = typename SharedHandleTraits<HandleType>::DestructorType;
357 
358     template <class Dispatcher>
359     using DestroyFunctionPointerType = void ( DestructorType::* )( HandleType, const Dispatcher & ) const;
360 
361     template <class Dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
ObjectReleaseShared( const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )362     ObjectReleaseShared( const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )
363       : m_destroy( reinterpret_cast<decltype( m_destroy )>( static_cast<DestroyFunctionPointerType<Dispatcher>>( &DestructorType::release ) ) )
364       , m_dispatch( &dispatch )
365     {
366     }
367 
368   public:
369     void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT
370     {
371       VULKAN_HPP_ASSERT( m_destroy && m_dispatch );
372       ( parent.*m_destroy )( handle, *m_dispatch );
373     }
374 
375   private:
376     DestroyFunctionPointerType<DispatchLoaderBase> m_destroy  = nullptr;
377     const DispatchLoaderBase *                     m_dispatch = nullptr;
378   };
379 
380   template <typename HandleType, typename PoolType>
381   class PoolFreeShared
382   {
383   public:
384     using DestructorType = typename SharedHandleTraits<HandleType>::DestructorType;
385 
386     template <class Dispatcher>
387     using ReturnType = decltype( std::declval<DestructorType>().free( PoolType(), 0u, nullptr, Dispatcher() ) );
388 
389     template <class Dispatcher>
390     using DestroyFunctionPointerType = ReturnType<Dispatcher> ( DestructorType::* )( PoolType, uint32_t, const HandleType *, const Dispatcher & ) const;
391 
392     PoolFreeShared() = default;
393 
394     template <class Dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
PoolFreeShared( SharedHandle<PoolType> pool, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )395     PoolFreeShared( SharedHandle<PoolType> pool, const Dispatcher & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT )
396       : m_destroy( reinterpret_cast<decltype( m_destroy )>( static_cast<DestroyFunctionPointerType<Dispatcher>>( &DestructorType::free ) ) )
397       , m_dispatch( &dispatch )
398       , m_pool( std::move( pool ) )
399     {
400     }
401 
402   public:
403     void destroy( DestructorType parent, HandleType handle ) const VULKAN_HPP_NOEXCEPT
404     {
405       VULKAN_HPP_ASSERT( m_destroy && m_dispatch );
406       ( parent.*m_destroy )( m_pool.get(), 1u, &handle, *m_dispatch );
407     }
408 
409   private:
410     DestroyFunctionPointerType<DispatchLoaderBase> m_destroy  = nullptr;
411     const DispatchLoaderBase *                     m_dispatch = nullptr;
412     SharedHandle<PoolType>                         m_pool{};
413   };
414 
415 #  if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __INTEL_COMPILER )
416 #    pragma GCC diagnostic pop
417 #  endif
418 
419   //======================
420   //=== SHARED HANDLEs ===
421   //======================
422 
423   //=== VK_VERSION_1_0 ===
424   template <>
425   class SharedHandleTraits<Instance>
426   {
427   public:
428     using DestructorType = NoDestructor;
429     using deleter        = ObjectDestroyShared<Instance>;
430   };
431 
432   using SharedInstance = SharedHandle<Instance>;
433 
434   template <>
435   class SharedHandleTraits<Device>
436   {
437   public:
438     using DestructorType = NoDestructor;
439     using deleter        = ObjectDestroyShared<Device>;
440   };
441 
442   using SharedDevice = SharedHandle<Device>;
443 
444   template <>
445   class SharedHandleTraits<DeviceMemory>
446   {
447   public:
448     using DestructorType = Device;
449     using deleter        = ObjectFreeShared<DeviceMemory>;
450   };
451 
452   using SharedDeviceMemory = SharedHandle<DeviceMemory>;
453 
454   template <>
455   class SharedHandleTraits<Fence>
456   {
457   public:
458     using DestructorType = Device;
459     using deleter        = ObjectDestroyShared<Fence>;
460   };
461 
462   using SharedFence = SharedHandle<Fence>;
463 
464   template <>
465   class SharedHandleTraits<Semaphore>
466   {
467   public:
468     using DestructorType = Device;
469     using deleter        = ObjectDestroyShared<Semaphore>;
470   };
471 
472   using SharedSemaphore = SharedHandle<Semaphore>;
473 
474   template <>
475   class SharedHandleTraits<Event>
476   {
477   public:
478     using DestructorType = Device;
479     using deleter        = ObjectDestroyShared<Event>;
480   };
481 
482   using SharedEvent = SharedHandle<Event>;
483 
484   template <>
485   class SharedHandleTraits<QueryPool>
486   {
487   public:
488     using DestructorType = Device;
489     using deleter        = ObjectDestroyShared<QueryPool>;
490   };
491 
492   using SharedQueryPool = SharedHandle<QueryPool>;
493 
494   template <>
495   class SharedHandleTraits<Buffer>
496   {
497   public:
498     using DestructorType = Device;
499     using deleter        = ObjectDestroyShared<Buffer>;
500   };
501 
502   using SharedBuffer = SharedHandle<Buffer>;
503 
504   template <>
505   class SharedHandleTraits<BufferView>
506   {
507   public:
508     using DestructorType = Device;
509     using deleter        = ObjectDestroyShared<BufferView>;
510   };
511 
512   using SharedBufferView = SharedHandle<BufferView>;
513 
514   template <>
515   class SharedHandleTraits<Image>
516   {
517   public:
518     using DestructorType = Device;
519     using deleter        = ObjectDestroyShared<Image>;
520   };
521 
522   using SharedImage = SharedHandle<Image>;
523 
524   template <>
525   class SharedHandleTraits<ImageView>
526   {
527   public:
528     using DestructorType = Device;
529     using deleter        = ObjectDestroyShared<ImageView>;
530   };
531 
532   using SharedImageView = SharedHandle<ImageView>;
533 
534   template <>
535   class SharedHandleTraits<ShaderModule>
536   {
537   public:
538     using DestructorType = Device;
539     using deleter        = ObjectDestroyShared<ShaderModule>;
540   };
541 
542   using SharedShaderModule = SharedHandle<ShaderModule>;
543 
544   template <>
545   class SharedHandleTraits<PipelineCache>
546   {
547   public:
548     using DestructorType = Device;
549     using deleter        = ObjectDestroyShared<PipelineCache>;
550   };
551 
552   using SharedPipelineCache = SharedHandle<PipelineCache>;
553 
554   template <>
555   class SharedHandleTraits<Pipeline>
556   {
557   public:
558     using DestructorType = Device;
559     using deleter        = ObjectDestroyShared<Pipeline>;
560   };
561 
562   using SharedPipeline = SharedHandle<Pipeline>;
563 
564   template <>
565   class SharedHandleTraits<PipelineLayout>
566   {
567   public:
568     using DestructorType = Device;
569     using deleter        = ObjectDestroyShared<PipelineLayout>;
570   };
571 
572   using SharedPipelineLayout = SharedHandle<PipelineLayout>;
573 
574   template <>
575   class SharedHandleTraits<Sampler>
576   {
577   public:
578     using DestructorType = Device;
579     using deleter        = ObjectDestroyShared<Sampler>;
580   };
581 
582   using SharedSampler = SharedHandle<Sampler>;
583 
584   template <>
585   class SharedHandleTraits<DescriptorPool>
586   {
587   public:
588     using DestructorType = Device;
589     using deleter        = ObjectDestroyShared<DescriptorPool>;
590   };
591 
592   using SharedDescriptorPool = SharedHandle<DescriptorPool>;
593 
594   template <>
595   class SharedHandleTraits<DescriptorSet>
596   {
597   public:
598     using DestructorType = Device;
599     using deleter        = PoolFreeShared<DescriptorSet, DescriptorPool>;
600   };
601 
602   using SharedDescriptorSet = SharedHandle<DescriptorSet>;
603 
604   template <>
605   class SharedHandleTraits<DescriptorSetLayout>
606   {
607   public:
608     using DestructorType = Device;
609     using deleter        = ObjectDestroyShared<DescriptorSetLayout>;
610   };
611 
612   using SharedDescriptorSetLayout = SharedHandle<DescriptorSetLayout>;
613 
614   template <>
615   class SharedHandleTraits<Framebuffer>
616   {
617   public:
618     using DestructorType = Device;
619     using deleter        = ObjectDestroyShared<Framebuffer>;
620   };
621 
622   using SharedFramebuffer = SharedHandle<Framebuffer>;
623 
624   template <>
625   class SharedHandleTraits<RenderPass>
626   {
627   public:
628     using DestructorType = Device;
629     using deleter        = ObjectDestroyShared<RenderPass>;
630   };
631 
632   using SharedRenderPass = SharedHandle<RenderPass>;
633 
634   template <>
635   class SharedHandleTraits<CommandPool>
636   {
637   public:
638     using DestructorType = Device;
639     using deleter        = ObjectDestroyShared<CommandPool>;
640   };
641 
642   using SharedCommandPool = SharedHandle<CommandPool>;
643 
644   template <>
645   class SharedHandleTraits<CommandBuffer>
646   {
647   public:
648     using DestructorType = Device;
649     using deleter        = PoolFreeShared<CommandBuffer, CommandPool>;
650   };
651 
652   using SharedCommandBuffer = SharedHandle<CommandBuffer>;
653 
654   //=== VK_VERSION_1_1 ===
655   template <>
656   class SharedHandleTraits<SamplerYcbcrConversion>
657   {
658   public:
659     using DestructorType = Device;
660     using deleter        = ObjectDestroyShared<SamplerYcbcrConversion>;
661   };
662 
663   using SharedSamplerYcbcrConversion    = SharedHandle<SamplerYcbcrConversion>;
664   using SharedSamplerYcbcrConversionKHR = SharedHandle<SamplerYcbcrConversion>;
665 
666   template <>
667   class SharedHandleTraits<DescriptorUpdateTemplate>
668   {
669   public:
670     using DestructorType = Device;
671     using deleter        = ObjectDestroyShared<DescriptorUpdateTemplate>;
672   };
673 
674   using SharedDescriptorUpdateTemplate    = SharedHandle<DescriptorUpdateTemplate>;
675   using SharedDescriptorUpdateTemplateKHR = SharedHandle<DescriptorUpdateTemplate>;
676 
677   //=== VK_VERSION_1_3 ===
678   template <>
679   class SharedHandleTraits<PrivateDataSlot>
680   {
681   public:
682     using DestructorType = Device;
683     using deleter        = ObjectDestroyShared<PrivateDataSlot>;
684   };
685 
686   using SharedPrivateDataSlot    = SharedHandle<PrivateDataSlot>;
687   using SharedPrivateDataSlotEXT = SharedHandle<PrivateDataSlot>;
688 
689   //=== VK_KHR_surface ===
690   template <>
691   class SharedHandleTraits<SurfaceKHR>
692   {
693   public:
694     using DestructorType = Instance;
695     using deleter        = ObjectDestroyShared<SurfaceKHR>;
696   };
697 
698   using SharedSurfaceKHR = SharedHandle<SurfaceKHR>;
699 
700   //=== VK_KHR_swapchain ===
701   template <>
702   class SharedHandleTraits<SwapchainKHR>
703   {
704   public:
705     using DestructorType = Device;
706     using deleter        = ObjectDestroyShared<SwapchainKHR>;
707   };
708 
709   using SharedSwapchainKHR = SharedHandle<SwapchainKHR>;
710 
711   //=== VK_KHR_display ===
712   template <>
713   class SharedHandleTraits<DisplayKHR>
714   {
715   public:
716     using DestructorType = PhysicalDevice;
717     using deleter        = ObjectDestroyShared<DisplayKHR>;
718   };
719 
720   using SharedDisplayKHR = SharedHandle<DisplayKHR>;
721 
722   //=== VK_EXT_debug_report ===
723   template <>
724   class SharedHandleTraits<DebugReportCallbackEXT>
725   {
726   public:
727     using DestructorType = Instance;
728     using deleter        = ObjectDestroyShared<DebugReportCallbackEXT>;
729   };
730 
731   using SharedDebugReportCallbackEXT = SharedHandle<DebugReportCallbackEXT>;
732 
733   //=== VK_KHR_video_queue ===
734   template <>
735   class SharedHandleTraits<VideoSessionKHR>
736   {
737   public:
738     using DestructorType = Device;
739     using deleter        = ObjectDestroyShared<VideoSessionKHR>;
740   };
741 
742   using SharedVideoSessionKHR = SharedHandle<VideoSessionKHR>;
743 
744   template <>
745   class SharedHandleTraits<VideoSessionParametersKHR>
746   {
747   public:
748     using DestructorType = Device;
749     using deleter        = ObjectDestroyShared<VideoSessionParametersKHR>;
750   };
751 
752   using SharedVideoSessionParametersKHR = SharedHandle<VideoSessionParametersKHR>;
753 
754   //=== VK_NVX_binary_import ===
755   template <>
756   class SharedHandleTraits<CuModuleNVX>
757   {
758   public:
759     using DestructorType = Device;
760     using deleter        = ObjectDestroyShared<CuModuleNVX>;
761   };
762 
763   using SharedCuModuleNVX = SharedHandle<CuModuleNVX>;
764 
765   template <>
766   class SharedHandleTraits<CuFunctionNVX>
767   {
768   public:
769     using DestructorType = Device;
770     using deleter        = ObjectDestroyShared<CuFunctionNVX>;
771   };
772 
773   using SharedCuFunctionNVX = SharedHandle<CuFunctionNVX>;
774 
775   //=== VK_EXT_debug_utils ===
776   template <>
777   class SharedHandleTraits<DebugUtilsMessengerEXT>
778   {
779   public:
780     using DestructorType = Instance;
781     using deleter        = ObjectDestroyShared<DebugUtilsMessengerEXT>;
782   };
783 
784   using SharedDebugUtilsMessengerEXT = SharedHandle<DebugUtilsMessengerEXT>;
785 
786   //=== VK_KHR_acceleration_structure ===
787   template <>
788   class SharedHandleTraits<AccelerationStructureKHR>
789   {
790   public:
791     using DestructorType = Device;
792     using deleter        = ObjectDestroyShared<AccelerationStructureKHR>;
793   };
794 
795   using SharedAccelerationStructureKHR = SharedHandle<AccelerationStructureKHR>;
796 
797   //=== VK_EXT_validation_cache ===
798   template <>
799   class SharedHandleTraits<ValidationCacheEXT>
800   {
801   public:
802     using DestructorType = Device;
803     using deleter        = ObjectDestroyShared<ValidationCacheEXT>;
804   };
805 
806   using SharedValidationCacheEXT = SharedHandle<ValidationCacheEXT>;
807 
808   //=== VK_NV_ray_tracing ===
809   template <>
810   class SharedHandleTraits<AccelerationStructureNV>
811   {
812   public:
813     using DestructorType = Device;
814     using deleter        = ObjectDestroyShared<AccelerationStructureNV>;
815   };
816 
817   using SharedAccelerationStructureNV = SharedHandle<AccelerationStructureNV>;
818 
819   //=== VK_INTEL_performance_query ===
820   template <>
821   class SharedHandleTraits<PerformanceConfigurationINTEL>
822   {
823   public:
824     using DestructorType = Device;
825     using deleter        = ObjectDestroyShared<PerformanceConfigurationINTEL>;
826   };
827 
828   using SharedPerformanceConfigurationINTEL = SharedHandle<PerformanceConfigurationINTEL>;
829 
830   //=== VK_KHR_deferred_host_operations ===
831   template <>
832   class SharedHandleTraits<DeferredOperationKHR>
833   {
834   public:
835     using DestructorType = Device;
836     using deleter        = ObjectDestroyShared<DeferredOperationKHR>;
837   };
838 
839   using SharedDeferredOperationKHR = SharedHandle<DeferredOperationKHR>;
840 
841   //=== VK_NV_device_generated_commands ===
842   template <>
843   class SharedHandleTraits<IndirectCommandsLayoutNV>
844   {
845   public:
846     using DestructorType = Device;
847     using deleter        = ObjectDestroyShared<IndirectCommandsLayoutNV>;
848   };
849 
850   using SharedIndirectCommandsLayoutNV = SharedHandle<IndirectCommandsLayoutNV>;
851 
852 #  if defined( VK_ENABLE_BETA_EXTENSIONS )
853   //=== VK_NV_cuda_kernel_launch ===
854   template <>
855   class SharedHandleTraits<CudaModuleNV>
856   {
857   public:
858     using DestructorType = Device;
859     using deleter        = ObjectDestroyShared<CudaModuleNV>;
860   };
861 
862   using SharedCudaModuleNV = SharedHandle<CudaModuleNV>;
863 
864   template <>
865   class SharedHandleTraits<CudaFunctionNV>
866   {
867   public:
868     using DestructorType = Device;
869     using deleter        = ObjectDestroyShared<CudaFunctionNV>;
870   };
871 
872   using SharedCudaFunctionNV = SharedHandle<CudaFunctionNV>;
873 #  endif /*VK_ENABLE_BETA_EXTENSIONS*/
874 
875 #  if defined( VK_USE_PLATFORM_FUCHSIA )
876   //=== VK_FUCHSIA_buffer_collection ===
877   template <>
878   class SharedHandleTraits<BufferCollectionFUCHSIA>
879   {
880   public:
881     using DestructorType = Device;
882     using deleter        = ObjectDestroyShared<BufferCollectionFUCHSIA>;
883   };
884 
885   using SharedBufferCollectionFUCHSIA = SharedHandle<BufferCollectionFUCHSIA>;
886 #  endif /*VK_USE_PLATFORM_FUCHSIA*/
887 
888   //=== VK_EXT_opacity_micromap ===
889   template <>
890   class SharedHandleTraits<MicromapEXT>
891   {
892   public:
893     using DestructorType = Device;
894     using deleter        = ObjectDestroyShared<MicromapEXT>;
895   };
896 
897   using SharedMicromapEXT = SharedHandle<MicromapEXT>;
898 
899   //=== VK_NV_optical_flow ===
900   template <>
901   class SharedHandleTraits<OpticalFlowSessionNV>
902   {
903   public:
904     using DestructorType = Device;
905     using deleter        = ObjectDestroyShared<OpticalFlowSessionNV>;
906   };
907 
908   using SharedOpticalFlowSessionNV = SharedHandle<OpticalFlowSessionNV>;
909 
910   //=== VK_EXT_shader_object ===
911   template <>
912   class SharedHandleTraits<ShaderEXT>
913   {
914   public:
915     using DestructorType = Device;
916     using deleter        = ObjectDestroyShared<ShaderEXT>;
917   };
918 
919   using SharedShaderEXT = SharedHandle<ShaderEXT>;
920 
921   enum class SwapchainOwns
922   {
923     no,
924     yes,
925   };
926 
927   struct ImageHeader : SharedHeader<DestructorTypeOf<VULKAN_HPP_NAMESPACE::Image>, typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::Image>::deleter>
928   {
929     ImageHeader(
930       SharedHandle<DestructorTypeOf<VULKAN_HPP_NAMESPACE::Image>>       parent,
931       typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::Image>::deleter deleter        = typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::Image>::deleter(),
932       SwapchainOwns                                                     swapchainOwned = SwapchainOwns::no ) VULKAN_HPP_NOEXCEPT
933       : SharedHeader<DestructorTypeOf<VULKAN_HPP_NAMESPACE::Image>, typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::Image>::deleter>( std::move( parent ),
934                                                                                                                                         std::move( deleter ) )
swapchainOwnedVULKAN_HPP_NAMESPACE::ImageHeader935       , swapchainOwned( swapchainOwned )
936     {
937     }
938 
939     SwapchainOwns swapchainOwned = SwapchainOwns::no;
940   };
941 
942   template <>
943   class SharedHandle<VULKAN_HPP_NAMESPACE::Image> : public SharedHandleBase<VULKAN_HPP_NAMESPACE::Image, ImageHeader>
944   {
945     using BaseType    = SharedHandleBase<VULKAN_HPP_NAMESPACE::Image, ImageHeader>;
946     using DeleterType = typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::Image>::deleter;
947     friend BaseType;
948 
949   public:
950     SharedHandle() = default;
951 
952     explicit SharedHandle( VULKAN_HPP_NAMESPACE::Image                                 handle,
953                            SharedHandle<DestructorTypeOf<VULKAN_HPP_NAMESPACE::Image>> parent,
954                            SwapchainOwns                                               swapchain_owned = SwapchainOwns::no,
955                            DeleterType                                                 deleter         = DeleterType() ) VULKAN_HPP_NOEXCEPT
BaseType( handle, std::move( parent ), std::move( deleter ), swapchain_owned )956       : BaseType( handle, std::move( parent ), std::move( deleter ), swapchain_owned )
957     {
958     }
959 
960   protected:
961     static void internalDestroy( const ImageHeader & control, VULKAN_HPP_NAMESPACE::Image handle ) VULKAN_HPP_NOEXCEPT
962     {
963       if ( control.swapchainOwned == SwapchainOwns::no )
964       {
965         control.deleter.destroy( control.parent.get(), handle );
966       }
967     }
968   };
969 
970   struct SwapchainHeader
971   {
972     SwapchainHeader( SharedHandle<VULKAN_HPP_NAMESPACE::SurfaceKHR>                           surface,
973                      SharedHandle<DestructorTypeOf<VULKAN_HPP_NAMESPACE::SwapchainKHR>>       parent,
974                      typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::SwapchainKHR>::deleter deleter =
975                        typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::SwapchainKHR>::deleter() ) VULKAN_HPP_NOEXCEPT
976       : surface( std::move( surface ) )
977       , parent( std::move( parent ) )
moveVULKAN_HPP_NAMESPACE::SwapchainHeader978       , deleter( std::move( deleter ) )
979     {
980     }
981 
982     SharedHandle<VULKAN_HPP_NAMESPACE::SurfaceKHR>                           surface{};
983     SharedHandle<DestructorTypeOf<VULKAN_HPP_NAMESPACE::SwapchainKHR>>       parent{};
984     typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::SwapchainKHR>::deleter deleter{};
985   };
986 
987   template <>
988   class SharedHandle<VULKAN_HPP_NAMESPACE::SwapchainKHR> : public SharedHandleBase<VULKAN_HPP_NAMESPACE::SwapchainKHR, SwapchainHeader>
989   {
990     using BaseType    = SharedHandleBase<VULKAN_HPP_NAMESPACE::SwapchainKHR, SwapchainHeader>;
991     using DeleterType = typename SharedHandleTraits<VULKAN_HPP_NAMESPACE::SwapchainKHR>::deleter;
992     friend BaseType;
993 
994   public:
995     SharedHandle() = default;
996 
997     explicit SharedHandle( VULKAN_HPP_NAMESPACE::SwapchainKHR                                 handle,
998                            SharedHandle<DestructorTypeOf<VULKAN_HPP_NAMESPACE::SwapchainKHR>> parent,
999                            SharedHandle<VULKAN_HPP_NAMESPACE::SurfaceKHR>                     surface,
1000                            DeleterType                                                        deleter = DeleterType() ) VULKAN_HPP_NOEXCEPT
BaseType( handle, std::move( surface ), std::move( parent ), std::move( deleter ) )1001       : BaseType( handle, std::move( surface ), std::move( parent ), std::move( deleter ) )
1002     {
1003     }
1004 
1005   public:
1006     const SharedHandle<VULKAN_HPP_NAMESPACE::SurfaceKHR> & getSurface() const VULKAN_HPP_NOEXCEPT
1007     {
1008       return getHeader().surface;
1009     }
1010 
1011   protected:
1012     using BaseType::internalDestroy;
1013   };
1014 
1015   template <typename HandleType, typename DestructorType>
1016   class SharedHandleBaseNoDestroy : public SharedHandleBase<HandleType, DestructorType>
1017   {
1018   public:
1019     using SharedHandleBase<HandleType, DestructorType>::SharedHandleBase;
1020 
1021     const DestructorType & getDestructorType() const VULKAN_HPP_NOEXCEPT
1022     {
1023       return SharedHandleBase<HandleType, DestructorType>::getHeader();
1024     }
1025 
1026   protected:
1027     static void internalDestroy( const DestructorType &, HandleType ) VULKAN_HPP_NOEXCEPT {}
1028   };
1029 
1030   //=== VK_VERSION_1_0 ===
1031 
1032   template <>
1033   class SharedHandle<PhysicalDevice> : public SharedHandleBaseNoDestroy<PhysicalDevice, SharedInstance>
1034   {
1035     friend SharedHandleBase<PhysicalDevice, SharedInstance>;
1036 
1037   public:
1038     SharedHandle() = default;
1039 
1040     explicit SharedHandle( PhysicalDevice handle, SharedInstance parent ) noexcept
SharedHandleBaseNoDestroy( handle, std::move( parent ) )1041       : SharedHandleBaseNoDestroy<PhysicalDevice, SharedInstance>( handle, std::move( parent ) )
1042     {
1043     }
1044   };
1045 
1046   using SharedPhysicalDevice = SharedHandle<PhysicalDevice>;
1047 
1048   template <>
1049   class SharedHandle<Queue> : public SharedHandleBaseNoDestroy<Queue, SharedDevice>
1050   {
1051     friend SharedHandleBase<Queue, SharedDevice>;
1052 
1053   public:
1054     SharedHandle() = default;
1055 
SharedHandleBaseNoDestroy( handle, std::move( parent ) )1056     explicit SharedHandle( Queue handle, SharedDevice parent ) noexcept : SharedHandleBaseNoDestroy<Queue, SharedDevice>( handle, std::move( parent ) ) {}
1057   };
1058 
1059   using SharedQueue = SharedHandle<Queue>;
1060 
1061   //=== VK_KHR_display ===
1062 
1063   template <>
1064   class SharedHandle<DisplayModeKHR> : public SharedHandleBaseNoDestroy<DisplayModeKHR, SharedDisplayKHR>
1065   {
1066     friend SharedHandleBase<DisplayModeKHR, SharedDisplayKHR>;
1067 
1068   public:
1069     SharedHandle() = default;
1070 
1071     explicit SharedHandle( DisplayModeKHR handle, SharedDisplayKHR parent ) noexcept
SharedHandleBaseNoDestroy( handle, std::move( parent ) )1072       : SharedHandleBaseNoDestroy<DisplayModeKHR, SharedDisplayKHR>( handle, std::move( parent ) )
1073     {
1074     }
1075   };
1076 
1077   using SharedDisplayModeKHR = SharedHandle<DisplayModeKHR>;
1078 #endif  // !VULKAN_HPP_NO_SMART_HANDLE
1079 }  // namespace VULKAN_HPP_NAMESPACE
1080 #endif  // VULKAN_SHARED_HPP
1081