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
14namespace 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 ) )
65      , 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>
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>
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 )
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
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
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>
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>
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>
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>
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>
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 ) )
935      , 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
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 ) )
978      , 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
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
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
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
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