summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/wrapper.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h
index e5d9b34f2..5c6729dbc 100644
--- a/src/video_core/renderer_vulkan/wrapper.h
+++ b/src/video_core/renderer_vulkan/wrapper.h
@@ -278,4 +278,148 @@ void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept;
278VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept; 278VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept;
279VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept; 279VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept;
280 280
281template <typename Type, typename OwnerType, typename Dispatch>
282class Handle;
283
284/// Handle with an owning type.
285/// Analogue to std::unique_ptr.
286template <typename Type, typename OwnerType, typename Dispatch>
287class Handle {
288public:
289 /// Construct a handle and hold it's ownership.
290 explicit Handle(Type handle_, OwnerType owner_, const Dispatch& dld_) noexcept
291 : handle{handle_}, owner{owner_}, dld{&dld_} {}
292
293 /// Construct an empty handle.
294 Handle() = default;
295
296 /// Copying Vulkan objects is not supported and will never be.
297 Handle(const Handle&) = delete;
298 Handle& operator=(const Handle&) = delete;
299
300 /// Construct a handle transfering the ownership from another handle.
301 Handle(Handle&& rhs) noexcept
302 : handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, dld{rhs.dld} {}
303
304 /// Assign the current handle transfering the ownership from another handle.
305 /// Destroys any previously held object.
306 Handle& operator=(Handle&& rhs) noexcept {
307 Release();
308 handle = std::exchange(rhs.handle, nullptr);
309 owner = rhs.owner;
310 dld = rhs.dld;
311 return *this;
312 }
313
314 /// Destroys the current handle if it existed.
315 ~Handle() noexcept {
316 Release();
317 }
318
319 /// Destroys any held object.
320 void reset() noexcept {
321 Release();
322 handle = nullptr;
323 }
324
325 /// Returns the address of the held object.
326 /// Intended for Vulkan structures that expect a pointer to an array.
327 const Type* address() const noexcept {
328 return &handle;
329 }
330
331 /// Returns the held Vulkan handle.
332 Type operator*() const noexcept {
333 return handle;
334 }
335
336 /// Returns true when there's a held object.
337 operator bool() const noexcept {
338 return handle != nullptr;
339 }
340
341protected:
342 Type handle = nullptr;
343 OwnerType owner = nullptr;
344 const Dispatch* dld = nullptr;
345
346private:
347 /// Destroys the held object if it exists.
348 void Release() noexcept {
349 if (handle) {
350 Destroy(owner, handle, *dld);
351 }
352 }
353};
354
355/// Dummy type used to specify a handle has no owner.
356struct NoOwner {};
357
358/// Handle without an owning type.
359/// Analogue to std::unique_ptr
360template <typename Type, typename Dispatch>
361class Handle<Type, NoOwner, Dispatch> {
362public:
363 /// Construct a handle and hold it's ownership.
364 explicit Handle(Type handle_, const Dispatch& dld_) noexcept : handle{handle_}, dld{&dld_} {}
365
366 /// Construct an empty handle.
367 Handle() noexcept = default;
368
369 /// Copying Vulkan objects is not supported and will never be.
370 Handle(const Handle&) = delete;
371 Handle& operator=(const Handle&) = delete;
372
373 /// Construct a handle transfering ownership from another handle.
374 Handle(Handle&& rhs) noexcept : handle{std::exchange(rhs.handle, nullptr)}, dld{rhs.dld} {}
375
376 /// Assign the current handle transfering the ownership from another handle.
377 /// Destroys any previously held object.
378 Handle& operator=(Handle&& rhs) noexcept {
379 Release();
380 handle = std::exchange(rhs.handle, nullptr);
381 dld = rhs.dld;
382 return *this;
383 }
384
385 /// Destroys the current handle if it existed.
386 ~Handle() noexcept {
387 Release();
388 }
389
390 /// Destroys any held object.
391 void reset() noexcept {
392 Release();
393 handle = nullptr;
394 }
395
396 /// Returns the address of the held object.
397 /// Intended for Vulkan structures that expect a pointer to an array.
398 const Type* address() const noexcept {
399 return &handle;
400 }
401
402 /// Returns the held Vulkan handle.
403 Type operator*() const noexcept {
404 return handle;
405 }
406
407 /// Returns true when there's a held object.
408 operator bool() const noexcept {
409 return handle != nullptr;
410 }
411
412protected:
413 Type handle = nullptr;
414 const Dispatch* dld = nullptr;
415
416private:
417 /// Destroys the held object if it exists.
418 void Release() noexcept {
419 if (handle) {
420 Destroy(handle, *dld);
421 }
422 }
423};
424
281} // namespace Vulkan::vk 425} // namespace Vulkan::vk