3 /*-------------------------------------------------------------------------
7 * Copyright (c) 2015 Google Inc.
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief Vulkan object reference holder.
24 *//*--------------------------------------------------------------------*/
27 #include "vkStrUtil.hpp"
43 explicit inline Checked (T object_) : object(object_) {}
48 //! Check that object is not null
50 inline Checked<T> check (T object)
53 throw tcu::TestError("Object check() failed", (std::string(getTypeName<T>()) + " = 0").c_str(), __FILE__, __LINE__);
54 return Checked<T>(object);
57 //! Declare object as checked earlier
59 inline Checked<T> notNull (T 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);
68 inline Checked<T> allowNull (T object)
70 return Checked<T>(object);
77 Deleter (const DeviceInterface& deviceIface, VkDevice device, const VkAllocationCallbacks* allocator)
78 : m_deviceIface (&deviceIface)
80 , m_allocator (allocator)
83 : m_deviceIface (DE_NULL)
85 , m_allocator (DE_NULL)
88 void operator() (T obj) const;
91 const DeviceInterface* m_deviceIface;
93 const VkAllocationCallbacks* m_allocator;
97 class Deleter<VkInstance>
100 Deleter (const PlatformInterface& platformIface, VkInstance instance, const VkAllocationCallbacks* allocator)
101 : m_destroyInstance ((DestroyInstanceFunc)platformIface.getInstanceProcAddr(instance, "vkDestroyInstance"))
102 , m_allocator (allocator)
105 : m_destroyInstance ((DestroyInstanceFunc)DE_NULL)
106 , m_allocator (DE_NULL)
109 void operator() (VkInstance obj) const { m_destroyInstance(obj, m_allocator); }
112 DestroyInstanceFunc m_destroyInstance;
113 const VkAllocationCallbacks* m_allocator;
117 class Deleter<VkDevice>
120 Deleter (const InstanceInterface& instanceIface, VkDevice device, const VkAllocationCallbacks* allocator)
121 : m_destroyDevice ((DestroyDeviceFunc)instanceIface.getDeviceProcAddr(device, "vkDestroyDevice"))
122 , m_allocator (allocator)
125 : m_destroyDevice ((DestroyDeviceFunc)DE_NULL)
126 , m_allocator (DE_NULL)
129 void operator() (VkDevice obj) const { m_destroyDevice(obj, m_allocator); }
132 DestroyDeviceFunc m_destroyDevice;
133 const VkAllocationCallbacks* m_allocator;
137 class Deleter<VkSurfaceKHR>
140 Deleter (const InstanceInterface& instanceIface, VkInstance instance, const VkAllocationCallbacks* allocator)
141 : m_instanceIface (&instanceIface)
142 , m_instance (instance)
143 , m_allocator (allocator)
146 : m_instanceIface (DE_NULL)
147 , m_instance ((VkInstance)0)
148 , m_allocator (DE_NULL)
151 void operator() (VkSurfaceKHR obj) const { m_instanceIface->destroySurfaceKHR(m_instance, obj, m_allocator); }
154 const InstanceInterface* m_instanceIface;
155 VkInstance m_instance;
156 const VkAllocationCallbacks* m_allocator;
160 class Deleter<VkDebugReportCallbackEXT>
163 Deleter (const InstanceInterface& instanceIface, VkInstance instance, const VkAllocationCallbacks* allocator)
164 : m_instanceIface (&instanceIface)
165 , m_instance (instance)
166 , m_allocator (allocator)
169 : m_instanceIface (DE_NULL)
170 , m_instance ((VkInstance)0)
171 , m_allocator (DE_NULL)
174 void operator() (VkDebugReportCallbackEXT obj) const { m_instanceIface->destroyDebugReportCallbackEXT(m_instance, obj, m_allocator); }
177 const InstanceInterface* m_instanceIface;
178 VkInstance m_instance;
179 const VkAllocationCallbacks* m_allocator;
183 class Deleter<VkDescriptorSet>
186 Deleter (const DeviceInterface& deviceIface, VkDevice device, VkDescriptorPool pool)
187 : m_deviceIface (&deviceIface)
192 : m_deviceIface (DE_NULL)
197 void operator() (VkDescriptorSet obj) const { m_deviceIface->freeDescriptorSets(m_device, m_pool, 1, &obj); }
200 const DeviceInterface* m_deviceIface;
202 VkDescriptorPool m_pool;
206 class Deleter<VkCommandBuffer>
209 Deleter (const DeviceInterface& deviceIface, VkDevice device, VkCommandPool pool)
210 : m_deviceIface (&deviceIface)
215 : m_deviceIface (DE_NULL)
220 void operator() (VkCommandBuffer obj) const { m_deviceIface->freeCommandBuffers(m_device, m_pool, 1, &obj); }
223 const DeviceInterface* m_deviceIface;
225 VkCommandPool m_pool;
231 RefData (T object_, Deleter<T> deleter_)
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(); }
254 RefBase (RefData<T> data) : m_data(data) {}
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.
265 inline RefBase<T>::~RefBase (void)
271 inline void RefBase<T>::reset (void)
274 m_data.deleter(m_data.object);
276 m_data = RefData<T>();
280 inline RefData<T> RefBase<T>::disown (void) throw()
288 inline void RefBase<T>::assign (RefData<T> data)
294 /*--------------------------------------------------------------------*//*!
295 * \brief Movable Vulkan object reference.
297 * Similar to de::MovePtr.
298 *//*--------------------------------------------------------------------*/
300 class Move : public RefBase<T>
304 Move (Checked<U> object, Deleter<U> deleter)
305 : RefBase<T>(RefData<T>(object.object, deleter))
308 Move (RefData<T> data)
311 Move (Move<T>& other)
312 : RefBase<T>(other.RefBase<T>::disown())
315 : RefBase<T>(RefData<T>())
318 T disown (void) { return this->RefBase<T>::disown().object; }
319 Move<T>& operator= (Move<T>& other);
320 Move<T>& operator= (RefData<T> data);
322 operator RefData<T> (void) { return this->RefBase<T>::disown(); }
326 inline Move<T>& Move<T>::operator= (Move<T>& other)
329 this->assign(other.RefBase<T>::disown());
335 inline Move<T>& Move<T>::operator= (RefData<T> data)
341 /*--------------------------------------------------------------------*//*!
342 * \brief Unique Vulkan object reference.
344 * Similar to de::UniquePtr.
345 *//*--------------------------------------------------------------------*/
347 class Unique : public RefBase<T>
351 Unique (Checked<U> object, Deleter<U> deleter)
352 : RefBase<T>(RefData<T>(object.object, deleter))
355 Unique (RefData<T> data)
360 Unique (const Unique<T>&);
361 Unique<T>& operator= (const Unique<T>&);
366 using refdetails::Move;
367 using refdetails::Unique;
368 using refdetails::Deleter;
369 using refdetails::check;
370 using refdetails::notNull;
371 using refdetails::allowNull;