device/device.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | /// @file device.h | ||
| 3 | /// @brief The devices Ernie can run on, what they can do, and device errors, in Ernie's types: | ||
| 4 | /// what the layers above `device/` see. | ||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstdint> | ||
| 8 | #include <stdexcept> | ||
| 9 | #include <string> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | namespace ernie { | ||
| 13 | |||
| 14 | /// @brief What kind of device a physical device is. | ||
| 15 | enum class VulkanDeviceType : std::uint8_t { | ||
| 16 | Other, | ||
| 17 | IntegratedGpu, | ||
| 18 | DiscreteGpu, | ||
| 19 | VirtualGpu, | ||
| 20 | Cpu, | ||
| 21 | }; | ||
| 22 | |||
| 23 | /// @brief What a device can do beyond what Ernie requires; passes test these before relying on | ||
| 24 | /// them. | ||
| 25 | struct DeviceCapabilities { | ||
| 26 | /// Ray queries over hardware acceleration structures; the software BVH otherwise. | ||
| 27 | bool rayQuery = false; | ||
| 28 | /// Memory shared with CUDA, HIP and other contexts. | ||
| 29 | bool externalMemory = false; | ||
| 30 | /// Timeline semaphores shared the same way, so work is ordered without the host. | ||
| 31 | bool externalTimeline = false; | ||
| 32 | bool shaderInt64 = false; | ||
| 33 | bool shaderFloat16 = false; | ||
| 34 | /// The driver's memory budget per heap. | ||
| 35 | bool memoryBudget = false; | ||
| 36 | /// What went wrong on device loss. | ||
| 37 | bool deviceFault = false; | ||
| 38 | /// The device's and host's clocks read together, so GPU zones line up with CPU zones. | ||
| 39 | bool calibratedTimestamps = false; | ||
| 40 | /// Swapchains, so a window can show what the device draws. | ||
| 41 | bool present = false; | ||
| 42 | bool sparseResidency = false; | ||
| 43 | }; | ||
| 44 | |||
| 45 | /// @brief A device and what it can do. | ||
| 46 | 92 | struct VulkanDeviceInfo { | |
| 47 | std::string name; | ||
| 48 | VulkanDeviceType type = VulkanDeviceType::Other; | ||
| 49 | std::uint32_t apiMajor = 0; ///< Vulkan version the driver supports, major part. | ||
| 50 | std::uint32_t apiMinor = 0; ///< Vulkan version the driver supports, minor part. | ||
| 51 | /// The device's UUID in hex: stable across runs, and how CUDA and HIP name the same device. | ||
| 52 | std::string uuid; | ||
| 53 | /// Meets Ernie's requirements (Vulkan 1.3 and the features it builds on). | ||
| 54 | bool supported = false; | ||
| 55 | DeviceCapabilities capabilities; | ||
| 56 | }; | ||
| 57 | |||
| 58 | /// @brief What went wrong on a device, in Ernie's terms. | ||
| 59 | enum class DeviceErrorKind : std::uint8_t { OutOfMemory, DeviceLost, Unsupported, Failed }; | ||
| 60 | |||
| 61 | /// @brief A device call that failed: which call, on what, and how. | ||
| 62 | class DeviceError : public std::runtime_error { | ||
| 63 | public: | ||
| 64 | 6 | DeviceError(DeviceErrorKind kind, const std::string& message) | |
| 65 | 6 | : std::runtime_error(message), kind_(kind) {} | |
| 66 | DeviceErrorKind Kind() const { | ||
| 67 | return kind_; | ||
| 68 | } | ||
| 69 | |||
| 70 | private: | ||
| 71 | DeviceErrorKind kind_; | ||
| 72 | }; | ||
| 73 | |||
| 74 | /// @brief Lists the Vulkan devices of the installed drivers. | ||
| 75 | /// @return Every physical device, in the loader's order. | ||
| 76 | /// @throws DeviceError When no Vulkan loader is installed or the instance cannot be created. | ||
| 77 | std::vector<VulkanDeviceInfo> ListVulkanDevices(); | ||
| 78 | |||
| 79 | /// @return A short lowercase name of a device type, such as "cpu". | ||
| 80 | const char* ToString(VulkanDeviceType type); | ||
| 81 | |||
| 82 | } // namespace ernie | ||
| 83 |