Ignore A channel in EGL RGB5_A1 clear color tests am: 9da1b45a8e am: 4e33c51c88 am...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkRef.hpp
1 #ifndef _VKREF_HPP
2 #define _VKREF_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan CTS Framework
5  * --------------------
6  *
7  * Copyright (c) 2015 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan object reference holder.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vkDefs.hpp"
27 #include "vkStrUtil.hpp"
28 #include "deMeta.hpp"
29
30 #include <algorithm>
31
32 namespace vk
33 {
34
35 namespace refdetails
36 {
37
38 using std::swap;
39
40 template<typename T>
41 struct Checked
42 {
43         explicit inline         Checked         (T object_) : object(object_) {}
44
45         T                                       object;
46 };
47
48 //! Check that object is not null
49 template<typename T>
50 inline Checked<T> check (T object)
51 {
52         if (!object)
53                 throw tcu::TestError("Object check() failed", (std::string(getTypeName<T>()) + " = 0").c_str(), __FILE__, __LINE__);
54         return Checked<T>(object);
55 }
56
57 //! Declare object as checked earlier
58 template<typename T>
59 inline Checked<T> notNull (T object)
60 {
61         if (!object)
62                 throw tcu::InternalError("Null object was given to notNull()", (std::string(getTypeName<T>()) + " = 0").c_str(), __FILE__, __LINE__);
63         return Checked<T>(object);
64 }
65
66 //! Allow null object
67 template<typename T>
68 inline Checked<T> allowNull (T object)
69 {
70         return Checked<T>(object);
71 }
72
73 template<typename T>
74 class Deleter
75 {
76 public:
77                                                                         Deleter         (const DeviceInterface& deviceIface, VkDevice device, const VkAllocationCallbacks* allocator)
78                                                                                 : m_deviceIface (&deviceIface)
79                                                                                 , m_device              (device)
80                                                                                 , m_allocator   (allocator)
81                                                                         {}
82                                                                         Deleter         (void)
83                                                                                 : m_deviceIface (DE_NULL)
84                                                                                 , m_device              (DE_NULL)
85                                                                                 , m_allocator   (DE_NULL)
86                                                                         {}
87
88         void                                                    operator()      (T obj) const;
89
90 private:
91         const DeviceInterface*                  m_deviceIface;
92         VkDevice                                                m_device;
93         const VkAllocationCallbacks*    m_allocator;
94 };
95
96 template<>
97 class Deleter<VkInstance>
98 {
99 public:
100                                                                         Deleter         (const PlatformInterface& platformIface, VkInstance instance, const VkAllocationCallbacks* allocator)
101                                                                                 : m_destroyInstance     ((DestroyInstanceFunc)platformIface.getInstanceProcAddr(instance, "vkDestroyInstance"))
102                                                                                 , m_allocator           (allocator)
103                                                                         {}
104                                                                         Deleter         (void)
105                                                                                 : m_destroyInstance     ((DestroyInstanceFunc)DE_NULL)
106                                                                                 , m_allocator           (DE_NULL)
107                                                                         {}
108
109         void                                                    operator()      (VkInstance obj) const { m_destroyInstance(obj, m_allocator); }
110
111 private:
112         DestroyInstanceFunc                             m_destroyInstance;
113         const VkAllocationCallbacks*    m_allocator;
114 };
115
116 template<>
117 class Deleter<VkDevice>
118 {
119 public:
120                                                                         Deleter         (const InstanceInterface& instanceIface, VkDevice device, const VkAllocationCallbacks* allocator)
121                                                                                 : m_destroyDevice       ((DestroyDeviceFunc)instanceIface.getDeviceProcAddr(device, "vkDestroyDevice"))
122                                                                                 , m_allocator           (allocator)
123                                                                         {}
124                                                                         Deleter         (void)
125                                                                                 : m_destroyDevice       ((DestroyDeviceFunc)DE_NULL)
126                                                                                 , m_allocator           (DE_NULL)
127                                                                         {}
128
129         void                                                    operator()      (VkDevice obj) const { m_destroyDevice(obj, m_allocator); }
130
131 private:
132         DestroyDeviceFunc                               m_destroyDevice;
133         const VkAllocationCallbacks*    m_allocator;
134 };
135
136 template<>
137 class Deleter<VkSurfaceKHR>
138 {
139 public:
140                                                                         Deleter         (const InstanceInterface& instanceIface, VkInstance instance, const VkAllocationCallbacks* allocator)
141                                                                                 : m_instanceIface       (&instanceIface)
142                                                                                 , m_instance            (instance)
143                                                                                 , m_allocator           (allocator)
144                                                                         {}
145                                                                         Deleter         (void)
146                                                                                 : m_instanceIface       (DE_NULL)
147                                                                                 , m_instance            ((VkInstance)0)
148                                                                                 , m_allocator           (DE_NULL)
149                                                                         {}
150
151         void                                                    operator()      (VkSurfaceKHR obj) const { m_instanceIface->destroySurfaceKHR(m_instance, obj, m_allocator); }
152
153 private:
154         const InstanceInterface*                m_instanceIface;
155         VkInstance                                              m_instance;
156         const VkAllocationCallbacks*    m_allocator;
157 };
158
159 template<>
160 class Deleter<VkDebugReportCallbackEXT>
161 {
162 public:
163                                                                         Deleter         (const InstanceInterface& instanceIface, VkInstance instance, const VkAllocationCallbacks* allocator)
164                                                                                 : m_instanceIface       (&instanceIface)
165                                                                                 , m_instance            (instance)
166                                                                                 , m_allocator           (allocator)
167                                                                         {}
168                                                                         Deleter         (void)
169                                                                                 : m_instanceIface       (DE_NULL)
170                                                                                 , m_instance            ((VkInstance)0)
171                                                                                 , m_allocator           (DE_NULL)
172                                                                         {}
173
174         void                                                    operator()      (VkDebugReportCallbackEXT obj) const { m_instanceIface->destroyDebugReportCallbackEXT(m_instance, obj, m_allocator); }
175
176 private:
177         const InstanceInterface*                m_instanceIface;
178         VkInstance                                              m_instance;
179         const VkAllocationCallbacks*    m_allocator;
180 };
181
182 template<>
183 class Deleter<VkDescriptorSet>
184 {
185 public:
186                                                         Deleter         (const DeviceInterface& deviceIface, VkDevice device, VkDescriptorPool pool)
187                                                                 : m_deviceIface (&deviceIface)
188                                                                 , m_device              (device)
189                                                                 , m_pool                (pool)
190                                                         {}
191                                                         Deleter         (void)
192                                                                 : m_deviceIface (DE_NULL)
193                                                                 , m_device              (DE_NULL)
194                                                                 , m_pool                (DE_NULL)
195                                                         {}
196
197         void                                    operator()      (VkDescriptorSet obj) const { m_deviceIface->freeDescriptorSets(m_device, m_pool, 1, &obj); }
198
199 private:
200         const DeviceInterface*  m_deviceIface;
201         VkDevice                                m_device;
202         VkDescriptorPool                m_pool;
203 };
204
205 template<>
206 class Deleter<VkCommandBuffer>
207 {
208 public:
209                                                         Deleter         (const DeviceInterface& deviceIface, VkDevice device, VkCommandPool pool)
210                                                                 : m_deviceIface (&deviceIface)
211                                                                 , m_device              (device)
212                                                                 , m_pool                (pool)
213                                                         {}
214                                                         Deleter         (void)
215                                                                 : m_deviceIface (DE_NULL)
216                                                                 , m_device              (DE_NULL)
217                                                                 , m_pool                (DE_NULL)
218                                                         {}
219
220         void                                    operator()      (VkCommandBuffer obj) const { m_deviceIface->freeCommandBuffers(m_device, m_pool, 1, &obj); }
221
222 private:
223         const DeviceInterface*  m_deviceIface;
224         VkDevice                                m_device;
225         VkCommandPool                   m_pool;
226 };
227
228 template<typename T>
229 struct RefData
230 {
231                                 RefData         (T object_, Deleter<T> deleter_)
232                                                                 : object        (object_)
233                                                                 , deleter       (deleter_)
234                                 {}
235                                 RefData         (void)
236                                                                 : object        (0)
237                                 {}
238
239         T                       object;
240         Deleter<T>      deleter;
241 };
242
243 template<typename T>
244 class RefBase
245 {
246 public:
247                                                 ~RefBase        (void);
248
249         inline const T&         get                     (void) const throw() { return m_data.object;    }
250         inline const T&         operator*       (void) const throw() { return get();                    }
251         inline operator         bool            (void) const throw() { return !!get();                  }
252
253 protected:
254                                                 RefBase         (RefData<T> data) : m_data(data)        {}
255
256         void                            reset           (void);                         //!< Release previous object, set to null.
257         RefData<T>                      disown          (void) throw();         //!< Disown and return object (ownership transferred to caller).
258         void                            assign          (RefData<T> data);      //!< Set new pointer, release previous pointer.
259
260 private:
261         RefData<T>                      m_data;
262 };
263
264 template<typename T>
265 inline RefBase<T>::~RefBase (void)
266 {
267         this->reset();
268 }
269
270 template<typename T>
271 inline void RefBase<T>::reset (void)
272 {
273         if (!!m_data.object)
274                 m_data.deleter(m_data.object);
275
276         m_data = RefData<T>();
277 }
278
279 template<typename T>
280 inline RefData<T> RefBase<T>::disown (void) throw()
281 {
282         RefData<T> tmp;
283         swap(m_data, tmp);
284         return tmp;
285 }
286
287 template<typename T>
288 inline void RefBase<T>::assign (RefData<T> data)
289 {
290         this->reset();
291         m_data = data;
292 }
293
294 /*--------------------------------------------------------------------*//*!
295  * \brief Movable Vulkan object reference.
296  *
297  * Similar to de::MovePtr.
298  *//*--------------------------------------------------------------------*/
299 template<typename T>
300 class Move : public RefBase<T>
301 {
302 public:
303         template<typename U>
304                                 Move            (Checked<U> object, Deleter<U> deleter)
305                                                                 : RefBase<T>(RefData<T>(object.object, deleter))
306                                 {}
307
308                                 Move            (RefData<T> data)
309                                                                 : RefBase<T>(data)
310                                 {}
311                                 Move            (Move<T>& other)
312                                                                 : RefBase<T>(other.RefBase<T>::disown())
313                                 {}
314                                 Move            (void)
315                                                                 : RefBase<T>(RefData<T>())
316                                 {}
317
318         T                       disown          (void) { return this->RefBase<T>::disown().object; }
319         Move<T>&        operator=       (Move<T>& other);
320         Move<T>&        operator=       (RefData<T> data);
321
322         operator        RefData<T>      (void) { return this->RefBase<T>::disown(); }
323 };
324
325 template<typename T>
326 inline Move<T>& Move<T>::operator= (Move<T>& other)
327 {
328         if (this != &other)
329                 this->assign(other.RefBase<T>::disown());
330
331         return *this;
332 }
333
334 template<typename T>
335 inline Move<T>& Move<T>::operator= (RefData<T> data)
336 {
337         this->assign(data);
338         return *this;
339 }
340
341 /*--------------------------------------------------------------------*//*!
342  * \brief Unique Vulkan object reference.
343  *
344  * Similar to de::UniquePtr.
345  *//*--------------------------------------------------------------------*/
346 template<typename T>
347 class Unique : public RefBase<T>
348 {
349 public:
350         template<typename U>
351                                 Unique          (Checked<U> object, Deleter<U> deleter)
352                                                                 : RefBase<T>(RefData<T>(object.object, deleter))
353                                 {}
354
355                                 Unique          (RefData<T> data)
356                                                                 : RefBase<T>(data)
357                                 {}
358
359 private:
360                                 Unique          (const Unique<T>&);
361         Unique<T>&      operator=       (const Unique<T>&);
362 };
363
364 } // refdetails
365
366 using refdetails::Move;
367 using refdetails::Unique;
368 using refdetails::Deleter;
369 using refdetails::check;
370 using refdetails::notNull;
371 using refdetails::allowNull;
372
373 } // vk
374
375 #endif // _VKREF_HPP