21 #include "display.hpp" 28 Platform &Platform::get()
32 static DisplayPlatform singleton;
36 VkSurfaceKHR DisplayPlatform::createSurface()
40 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetPhysicalDeviceDisplayPropertiesKHR);
41 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetPhysicalDeviceDisplayPlanePropertiesKHR);
42 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetDisplayModePropertiesKHR);
43 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetDisplayPlaneSupportedDisplaysKHR);
44 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkGetDisplayPlaneCapabilitiesKHR);
45 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkCreateDisplayPlaneSurfaceKHR);
48 uint32_t displayPropertyCount;
49 VK_CHECK(vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &displayPropertyCount,
nullptr));
51 if (displayPropertyCount < 1)
53 LOGE(
"No displays available.\n");
54 return VK_NULL_HANDLE;
57 vector<VkDisplayPropertiesKHR> displayProperties(displayPropertyCount);
58 VK_CHECK(vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &displayPropertyCount, displayProperties.data()));
62 VK_CHECK(vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &planeCount,
nullptr));
66 LOGE(
"No display planes available.\n");
67 return VK_NULL_HANDLE;
70 vector<VkDisplayPlanePropertiesKHR> planeProperties(planeCount);
71 VK_CHECK(vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &planeCount, planeProperties.data()));
76 VkDisplayModeKHR mode;
82 vector<Candidate> candidates;
86 for (uint32_t plane = 0; plane < planeCount; plane++)
88 uint32_t supportedCount;
89 VK_CHECK(vkGetDisplayPlaneSupportedDisplaysKHR(gpu, plane, &supportedCount,
nullptr));
91 if (supportedCount < 1)
95 vector<VkDisplayKHR> supportedDisplays(supportedCount);
96 VK_CHECK(vkGetDisplayPlaneSupportedDisplaysKHR(gpu, plane, &supportedCount, supportedDisplays.data()));
98 for (
auto display : supportedDisplays)
101 auto itr = find_if(begin(displayProperties), end(displayProperties),
102 [display](
const VkDisplayPropertiesKHR &props) {
return props.display == display; });
106 if (itr == end(displayProperties))
110 if ((itr->supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) == 0)
114 if (planeProperties[plane].currentDisplay != display &&
115 planeProperties[plane].currentDisplay != VK_NULL_HANDLE)
120 VK_CHECK(vkGetDisplayModePropertiesKHR(gpu, display, &modeCount,
nullptr));
125 vector<VkDisplayModePropertiesKHR> modes(modeCount);
126 VK_CHECK(vkGetDisplayModePropertiesKHR(gpu, display, &modeCount, modes.data()));
128 for (
auto mode : modes)
131 VkDisplayPlaneCapabilitiesKHR caps;
132 VK_CHECK(vkGetDisplayPlaneCapabilitiesKHR(gpu, mode.displayMode, plane, &caps));
135 if ((caps.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) == 0)
139 if (caps.minSrcExtent.width > preferredWidth)
141 if (caps.minSrcExtent.height > preferredHeight)
143 if (caps.maxSrcExtent.width < preferredWidth)
145 if (caps.maxSrcExtent.height < preferredHeight)
148 if (mode.parameters.visibleRegion.width >= preferredWidth &&
149 mode.parameters.visibleRegion.height >= preferredHeight)
152 candidates.push_back(
153 { display, mode.displayMode, plane, planeProperties[plane].currentStackIndex,
154 mode.parameters.visibleRegion.width, mode.parameters.visibleRegion.height });
160 if (candidates.empty())
162 LOGE(
"Could not find a suitable display mode.\n");
163 return VK_NULL_HANDLE;
168 VkDisplaySurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR };
169 info.displayMode = candidates.front().mode;
170 info.planeIndex = candidates.front().plane;
171 info.planeStackIndex = candidates.front().planeStack;
172 info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
173 info.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
174 info.imageExtent.width = candidates.front().width;
175 info.imageExtent.height = candidates.front().height;
177 LOGI(
"Using display mode: %u x %u.\n", info.imageExtent.width, info.imageExtent.height);
179 VK_CHECK(vkCreateDisplayPlaneSurfaceKHR(instance, &info,
nullptr, &surface));
196 preferredWidth = swapchain.
width;
197 preferredHeight = swapchain.
height;
198 return initVulkan(swapchain, {
"VK_KHR_surface",
"VK_KHR_display" }, {
"VK_KHR_swapchain" });