7#include "gfx_device_vulkan.hpp"
8#include "gfx_system_vulkan.hpp"
9#include "gfx_surface_vulkan.hpp"
11#include "../utility/utility.hpp"
12#include "../macros.hpp"
21 auto result = physicalIntrinsic.getProperties2KHR<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceIDProperties>(
24 auto resultDeviceProperties2 = result.get<vk::PhysicalDeviceProperties2>();
25 auto resultDeviceIDProperties = result.get<vk::PhysicalDeviceIDProperties>();
27 requiredExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
28 requiredExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
29 requiredExtensions.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
31 requiredExtensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
32 requiredExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
34 deviceID = resultDeviceProperties2.properties.deviceID;
35 vendorID = resultDeviceProperties2.properties.vendorID;
36 deviceName =
std::string(resultDeviceProperties2.properties.deviceName.data());
37 deviceUUID = uuid::from_big_endian(resultDeviceIDProperties.deviceUUID);
39 physicalProperties = physicalIntrinsic.getProperties();
44inline int gfx_device::score(vk::SurfaceKHR surface)
const
50 hi_log_info(
"Scoring device: {}",
string());
51 if (not hasRequiredFeatures(physicalIntrinsic, gfx_system::global().requiredFeatures)) {
52 hi_log_info(
" - Does not have the required features.");
56 if (not meetsRequiredLimits(physicalIntrinsic, gfx_system::global().requiredLimits)) {
57 hi_log_info(
" - Does not meet the required limits.");
61 if (!hasRequiredExtensions(physicalIntrinsic, requiredExtensions)) {
62 hi_log_info(
" - Does not have the required extensions.");
66 bool device_has_graphics =
false;
67 bool device_has_present =
false;
68 bool device_has_compute =
false;
69 bool device_shares_graphics_and_present =
false;
70 for (hilet& queue : _queues) {
71 hilet has_present = to_bool(physicalIntrinsic.getSurfaceSupportKHR(queue.family_queue_index, surface));
72 hilet has_graphics = to_bool(queue.flags & vk::QueueFlagBits::eGraphics);
73 hilet has_compute = to_bool(queue.flags & vk::QueueFlagBits::eCompute);
75 device_has_graphics |= has_graphics;
76 device_has_present |= has_present;
77 device_has_compute |= has_compute;
78 if (has_present and has_graphics) {
79 device_shares_graphics_and_present =
true;
83 if (not device_has_graphics) {
84 hi_log_info(
" - Does not have a graphics queue.");
88 if (not device_has_present) {
89 hi_log_info(
" - Does not have a present queue.");
93 if (device_has_compute) {
94 hi_log_info(
" - Device has compute queue.");
98 if (device_shares_graphics_and_present) {
99 hi_log_info(
" - Device shares graphics and present on same queue.");
103 hi_log_info(
" - Surface formats:");
104 int surface_format_score = 0;
105 [[maybe_unused]]
auto surface_format = get_surface_format(surface, &surface_format_score);
106 if (surface_format_score <= 0) {
107 hi_log_info(
" - Does not have a suitable surface format.");
110 total_score += surface_format_score;
112 hi_log_info(
" - Present modes:");
113 int present_mode_score = 0;
114 [[maybe_unused]]
auto present_mode = get_present_mode(surface, &present_mode_score);
115 if (present_mode_score <= 0) {
116 hi_log_info(
" - Does not have a suitable present mode.");
119 total_score += present_mode_score;
122 auto device_type_score = 0;
123 hilet properties = physicalIntrinsic.getProperties();
124 switch (properties.deviceType) {
125 case vk::PhysicalDeviceType::eCpu:
126 device_type_score = 1;
128 case vk::PhysicalDeviceType::eOther:
129 device_type_score = 1;
131 case vk::PhysicalDeviceType::eVirtualGpu:
132 device_type_score = 2;
134 case vk::PhysicalDeviceType::eIntegratedGpu:
135 device_type_score = 3;
137 case vk::PhysicalDeviceType::eDiscreteGpu:
138 device_type_score = 4;
141 hi_log_info(
" - device-type={}, score={}", vk::to_string(properties.deviceType), device_type_score);
142 total_score += device_type_score;
144 hi_log_info(
" - total score {}", total_score);
148inline void gfx_device::initialize_device()
150 hilet device_queue_create_infos = make_device_queue_create_infos();
152 hilet available_device_features = physicalIntrinsic.getFeatures();
155 device_features = gfx_system::global().requiredFeatures;
156 device_features.setDualSrcBlend(available_device_features.dualSrcBlend);
157 device_features.setShaderSampledImageArrayDynamicIndexing(VK_TRUE);
158 auto physical_device_features = vk::PhysicalDeviceFeatures2{device_features};
160 auto device_descriptor_indexing_features = vk::PhysicalDeviceDescriptorIndexingFeatures{};
161 device_descriptor_indexing_features.setPNext(&physical_device_features);
162 device_descriptor_indexing_features.setShaderSampledImageArrayNonUniformIndexing(VK_TRUE);
164 auto device_create_info = vk::DeviceCreateInfo{
165 vk::DeviceCreateFlags(),
166 narrow_cast<uint32_t>(device_queue_create_infos.size()),
167 device_queue_create_infos.data(),
170 narrow_cast<uint32_t>(requiredExtensions.size()),
171 requiredExtensions.data(),
173 device_create_info.setPNext(&device_descriptor_indexing_features);
175 intrinsic = physicalIntrinsic.createDevice(device_create_info);
177 VmaAllocatorCreateInfo allocatorCreateInfo = {};
178 allocatorCreateInfo.physicalDevice = physicalIntrinsic;
179 allocatorCreateInfo.device = intrinsic;
180 allocatorCreateInfo.instance = vulkan_instance();
181 vmaCreateAllocator(&allocatorCreateInfo, &allocator);
183 VmaAllocationCreateInfo lazyAllocationInfo = {};
184 lazyAllocationInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
185 lazyAllocationInfo.pUserData =
const_cast<char *
>(
"lazy transient image check");
186 lazyAllocationInfo.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
187 uint32_t typeIndexOut = 0;
188 supportsLazyTransientImages =
189 vmaFindMemoryTypeIndex(allocator, 0, &lazyAllocationInfo, &typeIndexOut) != VK_ERROR_FEATURE_NOT_PRESENT;
191 if (supportsLazyTransientImages) {
192 lazyMemoryUsage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
193 transientImageUsageFlags = vk::ImageUsageFlagBits::eTransientAttachment;
196 initialize_queues(device_queue_create_infos);
197 initialize_quad_index_buffer();
199 box_pipeline = std::make_unique<gfx_pipeline_box::device_shared>(*
this);
200 image_pipeline = std::make_unique<gfx_pipeline_image::device_shared>(*
this);
201 SDF_pipeline = std::make_unique<gfx_pipeline_SDF::device_shared>(*
this);
202 alpha_pipeline = std::make_unique<gfx_pipeline_alpha::device_shared>(*
this);
203 tone_mapper_pipeline = std::make_unique<gfx_pipeline_tone_mapper::device_shared>(*
this);
206inline void gfx_device::setDebugUtilsObjectNameEXT(vk::DebugUtilsObjectNameInfoEXT
const& name_info)
const
210 return intrinsic.setDebugUtilsObjectNameEXT(name_info, vulkan_loader());
214inline void gfx_device::cmdBeginDebugUtilsLabelEXT(vk::CommandBuffer buffer, vk::DebugUtilsLabelEXT
const& create_info)
const
217 buffer.beginDebugUtilsLabelEXT(create_info, vulkan_loader());
221inline void gfx_device::cmdEndDebugUtilsLabelEXT(vk::CommandBuffer buffer)
const
224 buffer.endDebugUtilsLabelEXT(vulkan_loader());
DOXYGEN BUG.
Definition algorithm.hpp:16
unfair_recursive_mutex gfx_system_mutex
Global mutex for GUI elements, like gfx_system, gfx_device, Windows and Widgets.
Definition gfx_system_globals.hpp:18
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377