[Vulkan] New Image and ImageView for Swapchain
[platform/core/uifw/dali-core.git] / dali / graphics / vulkan / vulkan-types.h
1 #ifndef DALI_GRAPHICS_VULKAN_TYPES
2 #define DALI_GRAPHICS_VULKAN_TYPES
3
4 /*
5  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <atomic>
23 #include <unordered_map>
24 #include <memory>
25
26 #include <dali/integration-api/graphics/vulkan/vulkan-hpp-wrapper.h>
27
28 namespace Dali
29 {
30 namespace Graphics
31 {
32
33 template< typename T, typename... Args >
34 std::unique_ptr< T > MakeUnique(Args&&... args)
35 {
36   return std::unique_ptr< T  >(new T(std::forward< Args >(args)...));
37 }
38
39 namespace Vulkan
40 {
41
42 /**
43  * Forward class declarations
44  */
45 class Graphics;
46 class Surface;
47 class Queue;
48
49 /**
50  * Unique pointers to Vulkan types
51  */
52 using UniqueSurface       = std::unique_ptr< Surface >;
53 using UniqueQueue         = std::unique_ptr< Queue >;
54
55 /**
56  * Reference wrappers
57  */
58 using QueueRef         = std::reference_wrapper< Queue >;
59 using SurfaceRef       = std::reference_wrapper< Surface >;
60
61
62 template< typename T >
63 T VkAssert(const vk::ResultValue< T >& result, vk::Result expected = vk::Result::eSuccess)
64 {
65   assert(result.result == expected);
66   return result.value;
67 }
68
69 inline vk::Result VkAssert(vk::Result result, vk::Result expected = vk::Result::eSuccess)
70 {
71   assert(result == expected);
72   return result;
73 }
74
75 inline vk::Result VkTest(vk::Result result, vk::Result expected = vk::Result::eSuccess)
76 {
77   // todo: log if result different than expected?
78   return result;
79 }
80
81 template< typename T >
82 inline uint32_t U32(T value)
83 {
84   return static_cast< uint32_t >(value);
85 }
86
87 class Resource
88 {
89 public:
90   Resource() : mUserCount{0u} {}
91   virtual ~Resource() = default;
92
93   void IncreaseUserCount()
94   {
95     ++mUserCount;
96   }
97
98   void DecreaseUserCount()
99   {
100     --mUserCount;
101   }
102
103   uint32_t GetUserCount() const
104   {
105     return mUserCount;
106   }
107
108 private:
109
110   std::atomic<uint32_t> mUserCount;
111 };
112
113 /**
114  * Vulkan object handle
115  * @tparam T
116  */
117 template<class T>
118 class Handle
119 {
120 public:
121
122   Handle();
123   explicit Handle(T* object );
124   Handle( const Handle& handle);
125   Handle& operator=( const Handle& handle );
126   Handle& operator=( Handle&& handle );
127   Handle( Handle&& handle ) noexcept;
128   ~Handle();
129
130   operator bool() const;
131
132   T* operator->() const
133   {
134     return mObject;
135   }
136
137   uint32_t GetRefCount() const
138   {
139     return mObject->GetRefCount();
140   }
141
142   T& operator*() const
143   {
144     return *mObject;
145   }
146
147   template <class K>
148   Handle<K> StaticCast()
149   {
150     return Handle<K>(static_cast<K*>(mObject));
151   }
152
153   template<class K>
154   bool operator==( const Handle<K>& object ) const
155   {
156     return mObject == &*object;
157   }
158
159   template <class K>
160   Handle<K> DynamicCast();
161
162   void Reset()
163   {
164     if( mObject )
165     {
166       mObject->Release();
167       mObject = nullptr;
168     }
169   }
170
171 private:
172
173   T* mObject { nullptr };
174 };
175
176 template <class K, class T>
177 static Handle<K> VkTypeCast( const Handle<T>& inval )
178 {
179   return Handle<K>(static_cast<K*>(&*inval));
180 }
181
182 template<class T>
183 Handle<T>::Handle(T* object)
184   : mObject( object )
185 {
186   if(mObject)
187   {
188     mObject->Retain();
189   }
190 }
191
192 template<class T>
193 Handle<T>::Handle()
194   : mObject( nullptr )
195 {
196 }
197
198 template<class T>
199 Handle<T>::Handle(const Handle& handle)
200 {
201   mObject = handle.mObject;
202   if(mObject)
203   {
204     mObject->Retain();
205   }
206 }
207
208 template<class T>
209 Handle<T>::Handle( Handle&& handle ) noexcept
210 {
211   mObject = handle.mObject;
212   handle.mObject = nullptr;
213 }
214
215 template<class T>
216 Handle<T>::operator bool() const
217 {
218   return mObject != nullptr;
219 }
220
221 template<class T>
222 Handle<T>& Handle<T>::operator=( Handle&& handle )
223 {
224   mObject = handle.mObject;
225   handle.mObject = nullptr;
226   return *this;
227 }
228
229 template<class T>
230 Handle<T>& Handle<T>::operator=( const Handle<T>& handle )
231 {
232   mObject = handle.mObject;
233   if(mObject)
234   {
235     mObject->Retain();
236   }
237   return *this;
238 }
239
240 template<class T>
241 Handle<T>::~Handle()
242 {
243   if(mObject)
244   {
245     mObject->Release();
246   }
247 }
248
249 template<class T>
250 template<class K>
251 Handle<K> Handle<T>::DynamicCast()
252 {
253   auto val = dynamic_cast<K*>(mObject);
254   if(val)
255   {
256     return Handle<K>(val);
257   }
258   return Handle<K>();
259 }
260
261 template< typename T, typename... Args >
262 Handle< T > MakeRef(Args&&... args)
263 {
264   return Handle< T >(new T(std::forward< Args >(args)...));
265 }
266
267 template< typename T, typename... Args >
268 Handle< T > NewRef(Args&&... args)
269 {
270   return Handle< T >(T::New(std::forward< Args >(args)...));
271 }
272
273
274 template<class T>
275 typename T::Impl& GetImpl( Handle<T>& object )
276 {
277   return static_cast<typename T::Impl&>(*object->mImpl);
278 }
279
280 class VkManaged
281 {
282 public:
283
284   VkManaged() = default;
285   virtual ~VkManaged() = default;
286
287   void Release()
288   {
289     OnRelease(--mRefCount);
290     if(mRefCount == 0)
291     {
292       // orphaned
293       if(!Destroy())
294       {
295         delete this;
296       }
297     }
298   }
299
300   void Retain()
301   {
302     OnRetain(++mRefCount);
303   }
304
305   uint32_t GetRefCount()
306   {
307     return mRefCount;
308   }
309
310   bool Destroy()
311   {
312     return OnDestroy();
313   }
314
315   virtual void OnRetain( uint32_t refcount ) {};
316
317   virtual void OnRelease( uint32_t refcount ) {};
318
319   virtual bool OnDestroy() { return false; };
320
321 private:
322
323   std::atomic_uint mRefCount { 0u };
324 };
325
326 using FBID = uint32_t;
327
328 #define NotImplemented() \
329 {\
330 printf("Function %s isn't implemented!\n", __FUNCTION__);\
331 assert( "Function no implemented" );\
332 }
333
334 /*
335  * Forward declarations of reference types
336  */
337 using ShaderRef = Handle<class Shader>;
338 using PipelineRef = Handle<class Pipeline>;
339 using FenceRef = Handle<class Fence>;
340 using BufferRef = Handle<class Buffer>;
341 using FramebufferRef = Handle<class Framebuffer>;
342 using ImageRef = Handle<class Image>;
343 using ImageViewRef = Handle<class ImageView>;
344 using DescriptorPoolRef = Handle<class DescriptorPool>;
345 using CommandPoolRef = Handle<class CommandPool>;
346 using CommandBufferRef = Handle<class CommandBuffer>;
347 using GpuMemoryBlockRef = Handle<class GpuMemoryBlock>;
348 /*
349 #pragma GCC diagnostic push
350 #pragma GCC diagnostic ignored "-Wframe-larger-than="
351 #pragma GCC diagnostic pop
352 */
353 } // namespace Vulkan
354 } // namespace Graphics
355 } // namespace Dali
356
357 #endif // DALI_GRAPHICS_VULKAN_TYPES