diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.h | 144 |
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; | |||
| 278 | VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept; | 278 | VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept; |
| 279 | VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept; | 279 | VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept; |
| 280 | 280 | ||
| 281 | template <typename Type, typename OwnerType, typename Dispatch> | ||
| 282 | class Handle; | ||
| 283 | |||
| 284 | /// Handle with an owning type. | ||
| 285 | /// Analogue to std::unique_ptr. | ||
| 286 | template <typename Type, typename OwnerType, typename Dispatch> | ||
| 287 | class Handle { | ||
| 288 | public: | ||
| 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 | |||
| 341 | protected: | ||
| 342 | Type handle = nullptr; | ||
| 343 | OwnerType owner = nullptr; | ||
| 344 | const Dispatch* dld = nullptr; | ||
| 345 | |||
| 346 | private: | ||
| 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. | ||
| 356 | struct NoOwner {}; | ||
| 357 | |||
| 358 | /// Handle without an owning type. | ||
| 359 | /// Analogue to std::unique_ptr | ||
| 360 | template <typename Type, typename Dispatch> | ||
| 361 | class Handle<Type, NoOwner, Dispatch> { | ||
| 362 | public: | ||
| 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 | |||
| 412 | protected: | ||
| 413 | Type handle = nullptr; | ||
| 414 | const Dispatch* dld = nullptr; | ||
| 415 | |||
| 416 | private: | ||
| 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 |