GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
8 / 17
47.1%
Branches:
0 / 14
0.0%
Functions:
-
-%

device/external.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file external.h
3 /// @brief Sharing memory and timeline semaphores with other APIs and contexts through OS handles:
4 /// file descriptors on Linux and macOS, NT handles on Windows. Only external.cpp sees the
5 /// platform's declarations, so <windows.h> stays out of the rest of Ernie.
6 #pragma once
7
8 #include "ernie/device/vulkan.h"
9
10 #include <cstdint>
11 #include <string_view>
12
13 namespace ernie {
14
15 #if defined(_WIN32)
16 constexpr const char* kExternalMemoryExtension = "VK_KHR_external_memory_win32";
17 constexpr const char* kExternalSemaphoreExtension = "VK_KHR_external_semaphore_win32";
18 constexpr VkExternalMemoryHandleTypeFlagBits kExternalMemoryType =
19 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
20 constexpr VkExternalSemaphoreHandleTypeFlagBits kExternalSemaphoreType =
21 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
22 #else
23 constexpr const char* kExternalMemoryExtension = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
24 constexpr const char* kExternalSemaphoreExtension = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
25 constexpr VkExternalMemoryHandleTypeFlagBits kExternalMemoryType =
26 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
27 constexpr VkExternalSemaphoreHandleTypeFlagBits kExternalSemaphoreType =
28 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
29 #endif
30
31 /// @brief An OS handle to exported memory or a semaphore, closed when destroyed unless an import
32 /// took it.
33 class ExternalHandle {
34 public:
35 ExternalHandle() = default;
36 1 explicit ExternalHandle(std::intptr_t value) : value_(value) {}
37 ~ExternalHandle();
38 ✗ ExternalHandle(ExternalHandle&& other) noexcept : value_(other.Release()) {}
39 ExternalHandle& operator=(ExternalHandle&& other) noexcept;
40 ExternalHandle(const ExternalHandle&) = delete;
41 ExternalHandle& operator=(const ExternalHandle&) = delete;
42
43 1 std::intptr_t Get() const {
44
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ return value_;
45 }
46 ✗ explicit operator bool() const {
47
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ return value_ != kNone;
48 }
49 /// @brief Marks the handle imported: an import takes file descriptors, not NT handles, which
50 /// stay the importer's to close.
51 1 void Imported() {
52 #if !defined(_WIN32)
53 1 Release();
54 #endif
55 }
56 /// @brief Gives up the handle without closing it.
57 1 std::intptr_t Release() {
58 1 const std::intptr_t value = value_;
59 1 value_ = kNone;
60
0/10
<unknown function 36>:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
<unknown function 38>:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 return value;
61 }
62
63 private:
64 static constexpr std::intptr_t kNone = -1;
65 std::intptr_t value_ = kNone;
66 };
67
68 /// @return Whether the device exports and imports Ernie's buffers.
69 bool SharesMemory(VkPhysicalDevice physical);
70 /// @return Whether the device exports and imports timeline semaphores.
71 bool SharesTimelines(VkPhysicalDevice physical);
72
73 /// @brief Allocates a buffer with dedicated memory that `ExportMemory` can share.
74 void CreateExportableBuffer(VmaAllocator allocator, const VkBufferCreateInfo& info,
75 VkBuffer& buffer, VmaAllocation& allocation,
76 VmaAllocationInfo& allocated);
77 /// @brief Creates a buffer on memory imported from `handle`, taking the handle where the platform
78 /// does (file descriptors).
79 void CreateImportedBuffer(VmaAllocator allocator, const VkBufferCreateInfo& info,
80 ExternalHandle& handle, VkBuffer& buffer, VmaAllocation& allocation,
81 VmaAllocationInfo& allocated);
82 /// @brief Creates a buffer bound to device memory another API allocated, such as CUDA's virtual
83 /// memory, which no Vulkan dedicated allocation made, taking `handle` where the platform does.
84 /// @param size The size of the shared allocation, which the buffer spans.
85 void CreateImportedBuffer(VkDevice device, VkPhysicalDevice physical,
86 const VkBufferCreateInfo& info, ExternalHandle& handle, VkBuffer& buffer,
87 VkDeviceMemory& memory);
88 ExternalHandle ExportMemory(VkDevice device, VkDeviceMemory memory, std::string_view name);
89
90 ExternalHandle ExportSemaphore(VkDevice device, VkSemaphore semaphore, std::string_view name);
91 /// @brief Makes `semaphore` share the payload behind `handle`, taking the handle where the
92 /// platform does.
93 void ImportSemaphore(VkDevice device, VkSemaphore semaphore, ExternalHandle& handle,
94 std::string_view name);
95
96 } // namespace ernie
97