7#include "gfx_device_vulkan_intf.hpp"
8#include "gfx_system_vulkan_intf.hpp"
9#include "gfx_surface_vulkan_intf.hpp"
11#include "../utility/utility.hpp"
12#include "../macros.hpp"
13#include <vulkan/vulkan.hpp>
16hi_export_module(hikogui.GFX : gfx_device_impl);
18hi_export
namespace hi::inline
v1 {
20inline gfx_device::gfx_device(vk::PhysicalDevice physicalDevice) :
21 physicalIntrinsic(
std::
move(physicalDevice))
23 auto result = physicalIntrinsic.getProperties2KHR<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceIDProperties>(
26 auto resultDeviceProperties2 = result.get<vk::PhysicalDeviceProperties2>();
27 auto resultDeviceIDProperties = result.get<vk::PhysicalDeviceIDProperties>();
29 requiredExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
30 requiredExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
31 requiredExtensions.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
33 requiredExtensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
34 requiredExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
36 deviceID = resultDeviceProperties2.properties.deviceID;
37 vendorID = resultDeviceProperties2.properties.vendorID;
38 deviceName =
std::string(resultDeviceProperties2.properties.deviceName.data());
39 deviceUUID = uuid::from_big_endian(resultDeviceIDProperties.deviceUUID);
41 physicalProperties = physicalIntrinsic.getProperties();
46inline int gfx_device::score(vk::SurfaceKHR surface)
const
52 hi_log_info(
"Scoring device: {}",
string());
53 if (not hasRequiredFeatures(physicalIntrinsic, gfx_system::global().requiredFeatures)) {
54 hi_log_info(
" - Does not have the required features.");
58 if (not meetsRequiredLimits(physicalIntrinsic, gfx_system::global().requiredLimits)) {
59 hi_log_info(
" - Does not meet the required limits.");
63 if (!hasRequiredExtensions(physicalIntrinsic, requiredExtensions)) {
64 hi_log_info(
" - Does not have the required extensions.");
68 bool device_has_graphics =
false;
69 bool device_has_present =
false;
70 bool device_has_compute =
false;
71 bool device_shares_graphics_and_present =
false;
72 for (
auto const& queue : _queues) {
73 auto const has_present = to_bool(physicalIntrinsic.getSurfaceSupportKHR(queue.family_queue_index, surface));
74 auto const has_graphics = to_bool(queue.flags & vk::QueueFlagBits::eGraphics);
75 auto const has_compute = to_bool(queue.flags & vk::QueueFlagBits::eCompute);
77 device_has_graphics |= has_graphics;
78 device_has_present |= has_present;
79 device_has_compute |= has_compute;
80 if (has_present and has_graphics) {
81 device_shares_graphics_and_present =
true;
85 if (not device_has_graphics) {
86 hi_log_info(
" - Does not have a graphics queue.");
90 if (not device_has_present) {
91 hi_log_info(
" - Does not have a present queue.");
95 if (device_has_compute) {
96 hi_log_info(
" - Device has compute queue.");
100 if (device_shares_graphics_and_present) {
101 hi_log_info(
" - Device shares graphics and present on same queue.");
105 hi_log_info(
" - Surface formats:");
106 int surface_format_score = 0;
107 [[maybe_unused]]
auto surface_format = get_surface_format(surface, &surface_format_score);
108 if (surface_format_score <= 0) {
109 hi_log_info(
" - Does not have a suitable surface format.");
112 total_score += surface_format_score;
114 hi_log_info(
" - Present modes:");
115 int present_mode_score = 0;
116 [[maybe_unused]]
auto present_mode = get_present_mode(surface, &present_mode_score);
117 if (present_mode_score <= 0) {
118 hi_log_info(
" - Does not have a suitable present mode.");
121 total_score += present_mode_score;
124 auto device_type_score = 0;
125 auto const properties = physicalIntrinsic.getProperties();
126 switch (properties.deviceType) {
127 case vk::PhysicalDeviceType::eCpu:
128 device_type_score = 1;
130 case vk::PhysicalDeviceType::eOther:
131 device_type_score = 1;
133 case vk::PhysicalDeviceType::eVirtualGpu:
134 device_type_score = 2;
136 case vk::PhysicalDeviceType::eIntegratedGpu:
137 device_type_score = 3;
139 case vk::PhysicalDeviceType::eDiscreteGpu:
140 device_type_score = 4;
143 hi_log_info(
" - device-type={}, score={}", vk::to_string(properties.deviceType), device_type_score);
144 total_score += device_type_score;
146 hi_log_info(
" - total score {}", total_score);
150inline void gfx_device::initialize_device()
152 auto const device_queue_create_infos = make_device_queue_create_infos();
154 auto const available_device_features = physicalIntrinsic.getFeatures();
157 device_features = gfx_system::global().requiredFeatures;
158 device_features.setDualSrcBlend(available_device_features.dualSrcBlend);
159 device_features.setShaderSampledImageArrayDynamicIndexing(VK_TRUE);
160 auto physical_device_features = vk::PhysicalDeviceFeatures2{device_features};
162 auto device_descriptor_indexing_features = vk::PhysicalDeviceDescriptorIndexingFeatures{};
163 device_descriptor_indexing_features.setPNext(&physical_device_features);
164 device_descriptor_indexing_features.setShaderSampledImageArrayNonUniformIndexing(VK_TRUE);
166 auto device_create_info = vk::DeviceCreateInfo{
167 vk::DeviceCreateFlags(),
168 narrow_cast<uint32_t>(device_queue_create_infos.size()),
169 device_queue_create_infos.data(),
172 narrow_cast<uint32_t>(requiredExtensions.size()),
173 requiredExtensions.data(),
175 device_create_info.setPNext(&device_descriptor_indexing_features);
177 intrinsic = physicalIntrinsic.createDevice(device_create_info);
179 VmaAllocatorCreateInfo allocatorCreateInfo = {};
180 allocatorCreateInfo.physicalDevice = physicalIntrinsic;
181 allocatorCreateInfo.device = intrinsic;
182 allocatorCreateInfo.instance = vulkan_instance();
183 vmaCreateAllocator(&allocatorCreateInfo, &allocator);
185 VmaAllocationCreateInfo lazyAllocationInfo = {};
186 lazyAllocationInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT;
187 lazyAllocationInfo.pUserData =
const_cast<char *
>(
"lazy transient image check");
188 lazyAllocationInfo.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
189 uint32_t typeIndexOut = 0;
190 supportsLazyTransientImages =
191 vmaFindMemoryTypeIndex(allocator, 0, &lazyAllocationInfo, &typeIndexOut) != VK_ERROR_FEATURE_NOT_PRESENT;
193 if (supportsLazyTransientImages) {
194 lazyMemoryUsage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
195 transientImageUsageFlags = vk::ImageUsageFlagBits::eTransientAttachment;
198 initialize_queues(device_queue_create_infos);
199 initialize_quad_index_buffer();
201 box_pipeline = std::make_unique<gfx_pipeline_box::device_shared>(*
this);
202 image_pipeline = std::make_unique<gfx_pipeline_image::device_shared>(*
this);
203 SDF_pipeline = std::make_unique<gfx_pipeline_SDF::device_shared>(*
this);
204 override_pipeline = std::make_unique<gfx_pipeline_override::device_shared>(*
this);
205 tone_mapper_pipeline = std::make_unique<gfx_pipeline_tone_mapper::device_shared>(*
this);
208inline void gfx_device::setDebugUtilsObjectNameEXT(vk::DebugUtilsObjectNameInfoEXT
const& name_info)
const
212 return intrinsic.setDebugUtilsObjectNameEXT(name_info, vulkan_loader());
216inline void gfx_device::cmdBeginDebugUtilsLabelEXT(vk::CommandBuffer buffer, vk::DebugUtilsLabelEXT
const& create_info)
const
219 buffer.beginDebugUtilsLabelEXT(create_info, vulkan_loader());
223inline void gfx_device::cmdEndDebugUtilsLabelEXT(vk::CommandBuffer buffer)
const
226 buffer.endDebugUtilsLabelEXT(vulkan_loader());
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
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