The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/direct: Move common direct mode code to comp_window_direct.

Create code file for common direct mode code.

Make common functions take generic parameters.

Use common code in randr and nvidia back ends.

Remove redunant includes.

authored by

Lubosz Sarnecki and committed by
Jakob Bornecrantz
29b77181 94bc4cba

+335 -585
+1
src/xrt/compositor/CMakeLists.txt
··· 86 86 endif() 87 87 if(BUILD_WITH_XCB AND BUILD_WITH_XLIB) 88 88 list(APPEND MAIN_SOURCE_FILES 89 + main/comp_window_direct.c 89 90 main/comp_window_direct_randr.c 90 91 main/comp_window_direct_nvidia.c 91 92 )
+262
src/xrt/compositor/main/comp_window_direct.c
··· 1 + // Copyright 2019, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Common direct mode window code. 6 + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 7 + * @author Jakob Bornecrantz <jakob@collabora.com> 8 + * @ingroup comp_main 9 + */ 10 + 11 + #include <inttypes.h> 12 + 13 + #include "comp_window_direct.h" 14 + 15 + #include "util/u_misc.h" 16 + 17 + static int 18 + choose_best_vk_mode_auto(struct comp_window *w, 19 + VkDisplayModePropertiesKHR *mode_properties, 20 + int mode_count) 21 + { 22 + if (mode_count == 1) 23 + return 0; 24 + 25 + int best_index = 0; 26 + 27 + // First priority: choose mode that maximizes rendered pixels. 28 + // Second priority: choose mode with highest refresh rate. 29 + for (int i = 1; i < mode_count; i++) { 30 + VkDisplayModeParametersKHR current = 31 + mode_properties[i].parameters; 32 + COMP_DEBUG(w->c, "Available Vk direct mode %d: %dx%d@%.2f", i, 33 + current.visibleRegion.width, 34 + current.visibleRegion.height, 35 + (float)current.refreshRate / 1000.); 36 + 37 + 38 + VkDisplayModeParametersKHR best = 39 + mode_properties[best_index].parameters; 40 + 41 + int best_pixels = 42 + best.visibleRegion.width * best.visibleRegion.height; 43 + int pixels = 44 + current.visibleRegion.width * current.visibleRegion.height; 45 + if (pixels > best_pixels) { 46 + best_index = i; 47 + } else if (pixels == best_pixels && 48 + current.refreshRate > best.refreshRate) { 49 + best_index = i; 50 + } 51 + } 52 + VkDisplayModeParametersKHR best = 53 + mode_properties[best_index].parameters; 54 + COMP_DEBUG(w->c, "Auto choosing Vk direct mode %d: %dx%d@%.2f", 55 + best_index, best.visibleRegion.width, 56 + best.visibleRegion.width, (float)best.refreshRate / 1000.); 57 + return best_index; 58 + } 59 + 60 + static void 61 + print_modes(struct comp_window *w, 62 + VkDisplayModePropertiesKHR *mode_properties, 63 + int mode_count) 64 + { 65 + COMP_PRINT_MODE(w->c, "Available Vk modes for direct mode"); 66 + for (int i = 0; i < mode_count; i++) { 67 + VkDisplayModePropertiesKHR props = mode_properties[i]; 68 + uint16_t width = props.parameters.visibleRegion.width; 69 + uint16_t height = props.parameters.visibleRegion.height; 70 + float refresh = (float)props.parameters.refreshRate / 1000.; 71 + 72 + COMP_PRINT_MODE(w->c, "| %2d | %dx%d@%.2f", i, width, height, 73 + refresh); 74 + } 75 + COMP_PRINT_MODE(w->c, "Listed %d modes", mode_count); 76 + } 77 + 78 + VkDisplayModeKHR 79 + comp_window_direct_get_primary_display_mode(struct comp_window *w, 80 + VkDisplayKHR display) 81 + { 82 + struct vk_bundle *vk = w->swapchain.vk; 83 + uint32_t mode_count; 84 + VkResult ret; 85 + 86 + ret = vk->vkGetDisplayModePropertiesKHR(vk->physical_device, display, 87 + &mode_count, NULL); 88 + if (ret != VK_SUCCESS) { 89 + COMP_ERROR(w->c, "vkGetDisplayModePropertiesKHR: %s", 90 + vk_result_string(ret)); 91 + return VK_NULL_HANDLE; 92 + } 93 + 94 + COMP_DEBUG(w->c, "Found %d modes", mode_count); 95 + 96 + VkDisplayModePropertiesKHR *mode_properties = 97 + U_TYPED_ARRAY_CALLOC(VkDisplayModePropertiesKHR, mode_count); 98 + ret = vk->vkGetDisplayModePropertiesKHR(vk->physical_device, display, 99 + &mode_count, mode_properties); 100 + if (ret != VK_SUCCESS) { 101 + COMP_ERROR(w->c, "vkGetDisplayModePropertiesKHR: %s", 102 + vk_result_string(ret)); 103 + free(mode_properties); 104 + return VK_NULL_HANDLE; 105 + } 106 + 107 + print_modes(w, mode_properties, mode_count); 108 + 109 + 110 + int chosen_mode = 0; 111 + 112 + int desired_mode = w->c->settings.desired_mode; 113 + if (desired_mode + 1 > (int)mode_count) { 114 + COMP_ERROR(w->c, 115 + "Requested mode index %d, but max is %d. Falling " 116 + "back to automatic mode selection", 117 + desired_mode, mode_count); 118 + chosen_mode = 119 + choose_best_vk_mode_auto(w, mode_properties, mode_count); 120 + } else if (desired_mode < 0) { 121 + chosen_mode = 122 + choose_best_vk_mode_auto(w, mode_properties, mode_count); 123 + } else { 124 + COMP_DEBUG(w->c, "Using manually chosen mode %d", desired_mode); 125 + chosen_mode = desired_mode; 126 + } 127 + 128 + VkDisplayModePropertiesKHR props = mode_properties[chosen_mode]; 129 + 130 + COMP_DEBUG(w->c, "found display mode %dx%d@%.2f", 131 + props.parameters.visibleRegion.width, 132 + props.parameters.visibleRegion.height, 133 + (float)props.parameters.refreshRate / 1000.); 134 + 135 + int64_t new_frame_interval = 136 + 1000. * 1000. * 1000. * 1000. / props.parameters.refreshRate; 137 + 138 + COMP_DEBUG( 139 + w->c, 140 + "Updating compositor settings nominal frame interval from %" PRIu64 141 + " (%f Hz) to %" PRIu64 " (%f Hz)", 142 + w->c->settings.nominal_frame_interval_ns, 143 + 1000. * 1000. * 1000. / 144 + (float)w->c->settings.nominal_frame_interval_ns, 145 + new_frame_interval, (float)props.parameters.refreshRate / 1000.); 146 + 147 + w->c->settings.nominal_frame_interval_ns = new_frame_interval; 148 + 149 + free(mode_properties); 150 + 151 + return props.displayMode; 152 + } 153 + 154 + static VkDisplayPlaneAlphaFlagBitsKHR 155 + choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags) 156 + { 157 + if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR) { 158 + return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR; 159 + } 160 + if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR) { 161 + return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR; 162 + } 163 + return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR; 164 + } 165 + 166 + VkResult 167 + comp_window_direct_create_surface(struct comp_window *w, 168 + VkDisplayKHR display, 169 + uint32_t width, 170 + uint32_t height) 171 + { 172 + struct vk_bundle *vk = w->swapchain.vk; 173 + 174 + // Get plane properties 175 + uint32_t plane_property_count; 176 + VkResult ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 177 + w->swapchain.vk->physical_device, &plane_property_count, NULL); 178 + if (ret != VK_SUCCESS) { 179 + COMP_ERROR(w->c, 180 + "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 181 + vk_result_string(ret)); 182 + return ret; 183 + } 184 + 185 + COMP_DEBUG(w->c, "Found %d plane properites.", plane_property_count); 186 + 187 + VkDisplayPlanePropertiesKHR *plane_properties = U_TYPED_ARRAY_CALLOC( 188 + VkDisplayPlanePropertiesKHR, plane_property_count); 189 + 190 + ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 191 + w->swapchain.vk->physical_device, &plane_property_count, 192 + plane_properties); 193 + if (ret != VK_SUCCESS) { 194 + COMP_ERROR(w->c, 195 + "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 196 + vk_result_string(ret)); 197 + free(plane_properties); 198 + return ret; 199 + } 200 + 201 + uint32_t plane_index = 0; 202 + 203 + VkDisplayModeKHR display_mode = 204 + comp_window_direct_get_primary_display_mode(w, display); 205 + 206 + VkDisplayPlaneCapabilitiesKHR plane_caps; 207 + vk->vkGetDisplayPlaneCapabilitiesKHR(w->swapchain.vk->physical_device, 208 + display_mode, plane_index, 209 + &plane_caps); 210 + 211 + VkDisplaySurfaceCreateInfoKHR surface_info = { 212 + .sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, 213 + .pNext = NULL, 214 + .flags = 0, 215 + .displayMode = display_mode, 216 + .planeIndex = plane_index, 217 + .planeStackIndex = plane_properties[plane_index].currentStackIndex, 218 + .transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, 219 + .globalAlpha = 1.0, 220 + .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha), 221 + .imageExtent = 222 + { 223 + .width = width, 224 + .height = height, 225 + }, 226 + }; 227 + 228 + VkResult result = vk->vkCreateDisplayPlaneSurfaceKHR( 229 + vk->instance, &surface_info, NULL, &w->swapchain.surface); 230 + 231 + free(plane_properties); 232 + 233 + return result; 234 + } 235 + 236 + int 237 + comp_window_direct_connect(struct comp_window *w, Display **dpy) 238 + { 239 + *dpy = XOpenDisplay(NULL); 240 + if (*dpy == NULL) { 241 + COMP_ERROR(w->c, "Could not open X display."); 242 + return false; 243 + } 244 + return true; 245 + } 246 + 247 + VkResult 248 + comp_window_direct_acquire_xlib_display(struct comp_window *w, 249 + Display *dpy, 250 + VkDisplayKHR display) 251 + { 252 + struct vk_bundle *vk = w->swapchain.vk; 253 + VkResult ret; 254 + 255 + ret = vk->vkAcquireXlibDisplayEXT(w->swapchain.vk->physical_device, dpy, 256 + display); 257 + if (ret != VK_SUCCESS) { 258 + COMP_ERROR(w->c, "vkAcquireXlibDisplayEXT: %s (%p)", 259 + vk_result_string(ret), (void *)display); 260 + } 261 + return ret; 262 + }
+39
src/xrt/compositor/main/comp_window_direct.h
··· 1 + // Copyright 2019, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Common direct mode window code header. 6 + * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 7 + * @author Jakob Bornecrantz <jakob@collabora.com> 8 + * @ingroup comp_main 9 + */ 10 + 11 + #pragma once 12 + 13 + #include "main/comp_window.h" 14 + 15 + #ifdef __cplusplus 16 + extern "C" { 17 + #endif 18 + 19 + VkDisplayModeKHR 20 + comp_window_direct_get_primary_display_mode(struct comp_window *w, 21 + VkDisplayKHR display); 22 + 23 + VkResult 24 + comp_window_direct_create_surface(struct comp_window *w, 25 + VkDisplayKHR display, 26 + uint32_t width, 27 + uint32_t height); 28 + 29 + int 30 + comp_window_direct_connect(struct comp_window *w, Display **dpy); 31 + 32 + VkResult 33 + comp_window_direct_acquire_xlib_display(struct comp_window *w, 34 + Display *dpy, 35 + VkDisplayKHR display); 36 + 37 + #ifdef __cplusplus 38 + } 39 + #endif
+13 -289
src/xrt/compositor/main/comp_window_direct_nvidia.c
··· 8 8 * @ingroup comp_main 9 9 */ 10 10 11 - #include <inttypes.h> 12 - 13 11 #include "util/u_misc.h" 14 12 15 - #include "xrt/xrt_compiler.h" 16 - #include "main/comp_window.h" 17 - 13 + #include "main/comp_window_direct.h" 18 14 19 15 /* 20 16 * ··· 62 58 static struct comp_window_direct_nvidia_display * 63 59 comp_window_direct_nvidia_current_display(struct comp_window_direct_nvidia *w); 64 60 65 - static VkDisplayModeKHR 66 - comp_window_direct_nvidia_get_primary_display_mode( 67 - struct comp_window_direct_nvidia *w, VkDisplayKHR display); 68 - 69 - static VkDisplayPlaneAlphaFlagBitsKHR 70 - choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags); 71 - 72 - static VkResult 73 - comp_window_direct_nvidia_create_surface(struct comp_window_direct_nvidia *w, 74 - VkInstance instance, 75 - VkSurfaceKHR *surface, 76 - uint32_t width, 77 - uint32_t height); 78 - 79 61 static bool 80 62 comp_window_direct_nvidia_init_swapchain(struct comp_window *w, 81 63 uint32_t width, 82 64 uint32_t height); 83 - 84 - static int 85 - comp_window_direct_nvidia_connect(struct comp_window_direct_nvidia *w); 86 - 87 - static VkResult 88 - comp_window_direct_nvidia_acquire_xlib_display( 89 - struct comp_window_direct_nvidia *w, VkDisplayKHR display); 90 65 91 66 /* 92 67 * ··· 193 168 struct comp_window_direct_nvidia *w_direct = 194 169 (struct comp_window_direct_nvidia *)w; 195 170 196 - if (!comp_window_direct_nvidia_connect(w_direct)) { 171 + if (!comp_window_direct_connect(w, &w_direct->dpy)) { 197 172 return false; 198 173 } 199 174 ··· 269 244 return &w->nv_displays[index]; 270 245 } 271 246 272 - static int 273 - choose_best_vk_mode_auto(struct comp_window_direct_nvidia *w, 274 - VkDisplayModePropertiesKHR *mode_properties, 275 - int mode_count) 276 - { 277 - if (mode_count == 1) 278 - return 0; 279 - 280 - int best_index = 0; 281 - 282 - // First priority: choose mode that maximizes rendered pixels. 283 - // Second priority: choose mode with highest refresh rate. 284 - for (int i = 1; i < mode_count; i++) { 285 - VkDisplayModeParametersKHR current = 286 - mode_properties[i].parameters; 287 - COMP_DEBUG(w->base.c, "Available Vk direct mode %d: %dx%d@%.2f", 288 - i, current.visibleRegion.width, 289 - current.visibleRegion.height, 290 - (float)current.refreshRate / 1000.); 291 - 292 - 293 - VkDisplayModeParametersKHR best = 294 - mode_properties[best_index].parameters; 295 - 296 - int best_pixels = 297 - best.visibleRegion.width * best.visibleRegion.height; 298 - int pixels = 299 - current.visibleRegion.width * current.visibleRegion.height; 300 - if (pixels > best_pixels) { 301 - best_index = i; 302 - } else if (pixels == best_pixels && 303 - current.refreshRate > best.refreshRate) { 304 - best_index = i; 305 - } 306 - } 307 - VkDisplayModeParametersKHR best = 308 - mode_properties[best_index].parameters; 309 - COMP_DEBUG(w->base.c, "Auto choosing Vk direct mode %d: %dx%d@%.2f", 310 - best_index, best.visibleRegion.width, 311 - best.visibleRegion.width, (float)best.refreshRate / 1000.); 312 - return best_index; 313 - } 314 - 315 - static void 316 - print_modes(struct comp_window_direct_nvidia *w, 317 - VkDisplayModePropertiesKHR *mode_properties, 318 - int mode_count) 319 - { 320 - COMP_PRINT_MODE(w->base.c, "Available Vk modes for direct mode"); 321 - for (int i = 0; i < mode_count; i++) { 322 - VkDisplayModePropertiesKHR props = mode_properties[i]; 323 - uint16_t width = props.parameters.visibleRegion.width; 324 - uint16_t height = props.parameters.visibleRegion.height; 325 - float refresh = (float)props.parameters.refreshRate / 1000.; 326 - 327 - COMP_PRINT_MODE(w->base.c, "| %2d | %dx%d@%.2f", i, width, 328 - height, refresh); 329 - } 330 - COMP_PRINT_MODE(w->base.c, "Listed %d modes", mode_count); 331 - } 332 - 333 - static VkDisplayModeKHR 334 - comp_window_direct_nvidia_get_primary_display_mode( 335 - struct comp_window_direct_nvidia *w, VkDisplayKHR display) 336 - { 337 - struct vk_bundle *vk = w->base.swapchain.vk; 338 - uint32_t mode_count; 339 - VkResult ret; 340 - 341 - ret = vk->vkGetDisplayModePropertiesKHR( 342 - w->base.swapchain.vk->physical_device, display, &mode_count, NULL); 343 - if (ret != VK_SUCCESS) { 344 - COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s", 345 - vk_result_string(ret)); 346 - return VK_NULL_HANDLE; 347 - } 348 - 349 - COMP_DEBUG(w->base.c, "Found %d modes", mode_count); 350 - 351 - VkDisplayModePropertiesKHR *mode_properties = 352 - U_TYPED_ARRAY_CALLOC(VkDisplayModePropertiesKHR, mode_count); 353 - ret = vk->vkGetDisplayModePropertiesKHR( 354 - w->base.swapchain.vk->physical_device, display, &mode_count, 355 - mode_properties); 356 - if (ret != VK_SUCCESS) { 357 - COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s", 358 - vk_result_string(ret)); 359 - free(mode_properties); 360 - return VK_NULL_HANDLE; 361 - } 362 - 363 - print_modes(w, mode_properties, mode_count); 364 - 365 - 366 - int chosen_mode = 0; 367 - 368 - int desired_mode = w->base.c->settings.desired_mode; 369 - if (desired_mode + 1 > (int)mode_count) { 370 - COMP_ERROR(w->base.c, 371 - "Requested mode index %d, but max is %d. Falling " 372 - "back to automatic mode selection", 373 - desired_mode, mode_count); 374 - chosen_mode = 375 - choose_best_vk_mode_auto(w, mode_properties, mode_count); 376 - } else if (desired_mode < 0) { 377 - chosen_mode = 378 - choose_best_vk_mode_auto(w, mode_properties, mode_count); 379 - } else { 380 - COMP_DEBUG(w->base.c, "Using manually chosen mode %d", 381 - desired_mode); 382 - chosen_mode = desired_mode; 383 - } 384 - 385 - VkDisplayModePropertiesKHR props = mode_properties[chosen_mode]; 386 - 387 - COMP_DEBUG(w->base.c, "found display mode %dx%d@%.2f", 388 - props.parameters.visibleRegion.width, 389 - props.parameters.visibleRegion.height, 390 - (float)props.parameters.refreshRate / 1000.); 391 - 392 - int64_t new_frame_interval = 393 - 1000. * 1000. * 1000. * 1000. / props.parameters.refreshRate; 394 - 395 - COMP_DEBUG( 396 - w->base.c, 397 - "Updating compositor settings nominal frame interval from %" PRIu64 398 - " (%f Hz) to %" PRIu64 " (%f Hz)", 399 - w->base.c->settings.nominal_frame_interval_ns, 400 - 1000. * 1000. * 1000. / 401 - (float)w->base.c->settings.nominal_frame_interval_ns, 402 - new_frame_interval, (float)props.parameters.refreshRate / 1000.); 403 - 404 - w->base.c->settings.nominal_frame_interval_ns = new_frame_interval; 405 - 406 - free(mode_properties); 407 - 408 - return props.displayMode; 409 - } 410 - 411 - static VkDisplayPlaneAlphaFlagBitsKHR 412 - choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags) 413 - { 414 - if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR) { 415 - return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR; 416 - } 417 - if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR) { 418 - return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR; 419 - } 420 - return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR; 421 - } 422 - 423 - static VkResult 424 - comp_window_direct_nvidia_create_surface(struct comp_window_direct_nvidia *w, 425 - VkInstance instance, 426 - VkSurfaceKHR *surface, 247 + static bool 248 + comp_window_direct_nvidia_init_swapchain(struct comp_window *w, 427 249 uint32_t width, 428 250 uint32_t height) 429 251 { 252 + struct comp_window_direct_nvidia *w_direct = 253 + (struct comp_window_direct_nvidia *)w; 254 + 430 255 struct comp_window_direct_nvidia_display *nvd = 431 - comp_window_direct_nvidia_current_display(w); 432 - struct vk_bundle *vk = w->base.swapchain.vk; 256 + comp_window_direct_nvidia_current_display(w_direct); 433 257 434 258 VkResult ret = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR; 259 + 435 260 VkDisplayKHR _display = VK_NULL_HANDLE; 436 261 437 262 if (nvd) { 438 - COMP_DEBUG(w->base.c, "Will use display: %s", nvd->name); 439 - ret = comp_window_direct_nvidia_acquire_xlib_display( 440 - w, nvd->display); 263 + COMP_DEBUG(w->c, "Will use display: %s", nvd->name); 264 + ret = comp_window_direct_acquire_xlib_display(w, w_direct->dpy, 265 + nvd->display); 441 266 _display = nvd->display; 442 267 } 443 268 ··· 445 270 return ret; 446 271 } 447 272 448 - 449 - // Get plane properties 450 - uint32_t plane_property_count; 451 - ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 452 - w->base.swapchain.vk->physical_device, &plane_property_count, NULL); 453 - if (ret != VK_SUCCESS) { 454 - COMP_ERROR(w->base.c, 455 - "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 456 - vk_result_string(ret)); 457 - return ret; 458 - } 459 - 460 - COMP_DEBUG(w->base.c, "Found %d plane properites.", 461 - plane_property_count); 462 - 463 - VkDisplayPlanePropertiesKHR *plane_properties = U_TYPED_ARRAY_CALLOC( 464 - VkDisplayPlanePropertiesKHR, plane_property_count); 465 - 466 - ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 467 - w->base.swapchain.vk->physical_device, &plane_property_count, 468 - plane_properties); 469 - if (ret != VK_SUCCESS) { 470 - COMP_ERROR(w->base.c, 471 - "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 472 - vk_result_string(ret)); 473 - free(plane_properties); 474 - return ret; 475 - } 476 - 477 - uint32_t plane_index = 0; 478 - 479 - VkDisplayModeKHR display_mode = 480 - comp_window_direct_nvidia_get_primary_display_mode(w, _display); 481 - 482 - VkDisplayPlaneCapabilitiesKHR plane_caps; 483 - vk->vkGetDisplayPlaneCapabilitiesKHR( 484 - w->base.swapchain.vk->physical_device, display_mode, plane_index, 485 - &plane_caps); 486 - 487 - VkDisplaySurfaceCreateInfoKHR surface_info = { 488 - .sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, 489 - .pNext = NULL, 490 - .flags = 0, 491 - .displayMode = display_mode, 492 - .planeIndex = plane_index, 493 - .planeStackIndex = plane_properties[plane_index].currentStackIndex, 494 - .transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, 495 - .globalAlpha = 1.0, 496 - .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha), 497 - .imageExtent = 498 - { 499 - .width = width, 500 - .height = height, 501 - }, 502 - }; 503 - 504 - VkResult result = vk->vkCreateDisplayPlaneSurfaceKHR( 505 - instance, &surface_info, NULL, surface); 506 - 507 - free(plane_properties); 508 - 509 - return result; 510 - } 511 - 512 - static bool 513 - comp_window_direct_nvidia_init_swapchain(struct comp_window *w, 514 - uint32_t width, 515 - uint32_t height) 516 - { 517 - struct comp_window_direct_nvidia *w_direct = 518 - (struct comp_window_direct_nvidia *)w; 519 - 520 - VkResult ret = comp_window_direct_nvidia_create_surface( 521 - w_direct, w->swapchain.vk->instance, &w->swapchain.surface, width, 522 - height); 273 + ret = comp_window_direct_create_surface(w, _display, width, height); 523 274 if (ret != VK_SUCCESS) { 524 275 COMP_ERROR(w->c, "Failed to create surface!"); 525 276 return false; ··· 531 282 532 283 return true; 533 284 } 534 - 535 - static int 536 - comp_window_direct_nvidia_connect(struct comp_window_direct_nvidia *w) 537 - { 538 - w->dpy = XOpenDisplay(NULL); 539 - if (w->dpy == NULL) { 540 - COMP_ERROR(w->base.c, "Could not open X display."); 541 - return false; 542 - } 543 - return true; 544 - } 545 - 546 - static VkResult 547 - comp_window_direct_nvidia_acquire_xlib_display( 548 - struct comp_window_direct_nvidia *w, VkDisplayKHR display) 549 - { 550 - struct vk_bundle *vk = w->base.swapchain.vk; 551 - VkResult ret; 552 - 553 - ret = vk->vkAcquireXlibDisplayEXT(w->base.swapchain.vk->physical_device, 554 - w->dpy, display); 555 - if (ret != VK_SUCCESS) { 556 - COMP_ERROR(w->base.c, "vkAcquireXlibDisplayEXT: %s (%p)", 557 - vk_result_string(ret), (void *)display); 558 - } 559 - return ret; 560 - }
+18 -295
src/xrt/compositor/main/comp_window_direct_randr.c
··· 13 13 #include <X11/Xlib-xcb.h> 14 14 #include <X11/extensions/Xrandr.h> 15 15 16 - #include <inttypes.h> 17 - 18 16 #include "util/u_misc.h" 19 17 20 - #include "xrt/xrt_compiler.h" 21 - #include "main/comp_window.h" 22 - 18 + #include "main/comp_window_direct.h" 23 19 24 20 /* 25 21 * ··· 73 69 74 70 static struct comp_window_direct_randr_display * 75 71 comp_window_direct_randr_current_display(struct comp_window_direct_randr *w); 76 - 77 - static VkDisplayModeKHR 78 - comp_window_direct_randr_get_primary_display_mode( 79 - struct comp_window_direct_randr *w, VkDisplayKHR display); 80 - 81 - static VkDisplayPlaneAlphaFlagBitsKHR 82 - choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags); 83 - 84 - static VkResult 85 - comp_window_direct_randr_create_surface(struct comp_window_direct_randr *w, 86 - VkInstance instance, 87 - VkSurfaceKHR *surface, 88 - uint32_t width, 89 - uint32_t height); 90 72 91 73 static bool 92 74 comp_window_direct_randr_init_swapchain(struct comp_window *w, 93 75 uint32_t width, 94 76 uint32_t height); 95 77 96 - static int 97 - comp_window_direct_randr_connect(struct comp_window_direct_randr *w); 98 - 99 - static VkResult 100 - comp_window_direct_randr_acquire_xlib_display( 101 - struct comp_window_direct_randr *w, VkDisplayKHR display); 102 - 103 78 static VkDisplayKHR 104 - comp_window_direct_randr_get_xlib_randr_output( 105 - struct comp_window_direct_randr *w, RROutput output); 79 + comp_window_direct_randr_get_output(struct comp_window_direct_randr *w, 80 + RROutput output); 106 81 107 82 static void 108 83 comp_window_direct_randr_get_outputs(struct comp_window_direct_randr *w); ··· 195 170 struct comp_window_direct_randr *w_direct = 196 171 (struct comp_window_direct_randr *)w; 197 172 198 - if (!comp_window_direct_randr_connect(w_direct)) { 173 + if (!comp_window_direct_connect(w, &w_direct->dpy)) { 199 174 return false; 200 175 } 201 176 ··· 255 230 return &w->randr_displays[index]; 256 231 } 257 232 258 - static int 259 - choose_best_vk_mode_auto(struct comp_window_direct_randr *w, 260 - VkDisplayModePropertiesKHR *mode_properties, 261 - int mode_count) 262 - { 263 - if (mode_count == 1) 264 - return 0; 265 - 266 - int best_index = 0; 267 - 268 - // First priority: choose mode that maximizes rendered pixels. 269 - // Second priority: choose mode with highest refresh rate. 270 - for (int i = 1; i < mode_count; i++) { 271 - VkDisplayModeParametersKHR current = 272 - mode_properties[i].parameters; 273 - COMP_DEBUG(w->base.c, "Available Vk direct mode %d: %dx%d@%.2f", 274 - i, current.visibleRegion.width, 275 - current.visibleRegion.height, 276 - (float)current.refreshRate / 1000.); 277 - 278 - 279 - VkDisplayModeParametersKHR best = 280 - mode_properties[best_index].parameters; 281 - 282 - int best_pixels = 283 - best.visibleRegion.width * best.visibleRegion.height; 284 - int pixels = 285 - current.visibleRegion.width * current.visibleRegion.height; 286 - if (pixels > best_pixels) { 287 - best_index = i; 288 - } else if (pixels == best_pixels && 289 - current.refreshRate > best.refreshRate) { 290 - best_index = i; 291 - } 292 - } 293 - VkDisplayModeParametersKHR best = 294 - mode_properties[best_index].parameters; 295 - COMP_DEBUG(w->base.c, "Auto choosing Vk direct mode %d: %dx%d@%.2f", 296 - best_index, best.visibleRegion.width, 297 - best.visibleRegion.width, (float)best.refreshRate / 1000.); 298 - return best_index; 299 - } 300 - 301 - static void 302 - print_modes(struct comp_window_direct_randr *w, 303 - VkDisplayModePropertiesKHR *mode_properties, 304 - int mode_count) 305 - { 306 - COMP_PRINT_MODE(w->base.c, "Available Vk modes for direct mode"); 307 - for (int i = 0; i < mode_count; i++) { 308 - VkDisplayModePropertiesKHR props = mode_properties[i]; 309 - uint16_t width = props.parameters.visibleRegion.width; 310 - uint16_t height = props.parameters.visibleRegion.height; 311 - float refresh = (float)props.parameters.refreshRate / 1000.; 312 - 313 - COMP_PRINT_MODE(w->base.c, "| %2d | %dx%d@%.2f", i, width, 314 - height, refresh); 315 - } 316 - COMP_PRINT_MODE(w->base.c, "Listed %d modes", mode_count); 317 - } 318 - 319 - static VkDisplayModeKHR 320 - comp_window_direct_randr_get_primary_display_mode( 321 - struct comp_window_direct_randr *w, VkDisplayKHR display) 322 - { 323 - struct vk_bundle *vk = w->base.swapchain.vk; 324 - uint32_t mode_count; 325 - VkResult ret; 326 - 327 - ret = vk->vkGetDisplayModePropertiesKHR( 328 - w->base.swapchain.vk->physical_device, display, &mode_count, NULL); 329 - if (ret != VK_SUCCESS) { 330 - COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s", 331 - vk_result_string(ret)); 332 - return VK_NULL_HANDLE; 333 - } 334 - 335 - COMP_DEBUG(w->base.c, "Found %d modes", mode_count); 336 - 337 - VkDisplayModePropertiesKHR *mode_properties = 338 - U_TYPED_ARRAY_CALLOC(VkDisplayModePropertiesKHR, mode_count); 339 - ret = vk->vkGetDisplayModePropertiesKHR( 340 - w->base.swapchain.vk->physical_device, display, &mode_count, 341 - mode_properties); 342 - if (ret != VK_SUCCESS) { 343 - COMP_ERROR(w->base.c, "vkGetDisplayModePropertiesKHR: %s", 344 - vk_result_string(ret)); 345 - free(mode_properties); 346 - return VK_NULL_HANDLE; 347 - } 348 - 349 - print_modes(w, mode_properties, mode_count); 350 - 351 - 352 - int chosen_mode = 0; 353 - 354 - int desired_mode = w->base.c->settings.desired_mode; 355 - if (desired_mode + 1 > (int)mode_count) { 356 - COMP_ERROR(w->base.c, 357 - "Requested mode index %d, but max is %d. Falling " 358 - "back to automatic mode selection", 359 - desired_mode, mode_count); 360 - chosen_mode = 361 - choose_best_vk_mode_auto(w, mode_properties, mode_count); 362 - } else if (desired_mode < 0) { 363 - chosen_mode = 364 - choose_best_vk_mode_auto(w, mode_properties, mode_count); 365 - } else { 366 - COMP_DEBUG(w->base.c, "Using manually chosen mode %d", 367 - desired_mode); 368 - chosen_mode = desired_mode; 369 - } 370 - 371 - VkDisplayModePropertiesKHR props = mode_properties[chosen_mode]; 372 - 373 - COMP_DEBUG(w->base.c, "found display mode %dx%d@%.2f", 374 - props.parameters.visibleRegion.width, 375 - props.parameters.visibleRegion.height, 376 - (float)props.parameters.refreshRate / 1000.); 377 - 378 - int64_t new_frame_interval = 379 - 1000. * 1000. * 1000. * 1000. / props.parameters.refreshRate; 380 - 381 - COMP_DEBUG( 382 - w->base.c, 383 - "Updating compositor settings nominal frame interval from %" PRIu64 384 - " (%f Hz) to %" PRIu64 " (%f Hz)", 385 - w->base.c->settings.nominal_frame_interval_ns, 386 - 1000. * 1000. * 1000. / 387 - (float)w->base.c->settings.nominal_frame_interval_ns, 388 - new_frame_interval, (float)props.parameters.refreshRate / 1000.); 389 - 390 - w->base.c->settings.nominal_frame_interval_ns = new_frame_interval; 391 - 392 - free(mode_properties); 393 - 394 - return props.displayMode; 395 - } 396 - 397 - static VkDisplayPlaneAlphaFlagBitsKHR 398 - choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags) 399 - { 400 - if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR) { 401 - return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR; 402 - } 403 - if (flags & VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR) { 404 - return VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR; 405 - } 406 - return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR; 407 - } 408 - 409 - static VkResult 410 - comp_window_direct_randr_create_surface(struct comp_window_direct_randr *w, 411 - VkInstance instance, 412 - VkSurfaceKHR *surface, 233 + static bool 234 + comp_window_direct_randr_init_swapchain(struct comp_window *w, 413 235 uint32_t width, 414 236 uint32_t height) 415 237 { 238 + struct comp_window_direct_randr *w_direct = 239 + (struct comp_window_direct_randr *)w; 240 + 416 241 struct comp_window_direct_randr_display *d = 417 - comp_window_direct_randr_current_display(w); 418 - struct vk_bundle *vk = w->base.swapchain.vk; 242 + comp_window_direct_randr_current_display(w_direct); 419 243 420 244 VkResult ret = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR; 421 245 VkDisplayKHR _display = VK_NULL_HANDLE; 422 246 if (d) { 423 247 COMP_DEBUG( 424 - w->base.c, "Will use display: %s %dx%d@%.2f", d->name, 248 + w->c, "Will use display: %s %dx%d@%.2f", d->name, 425 249 d->primary_mode.width, d->primary_mode.height, 426 250 (double)d->primary_mode.dot_clock / 427 251 (d->primary_mode.htotal * d->primary_mode.vtotal)); 428 252 429 - d->display = comp_window_direct_randr_get_xlib_randr_output( 430 - w, d->output); 253 + d->display = 254 + comp_window_direct_randr_get_output(w_direct, d->output); 431 255 if (d->display == VK_NULL_HANDLE) { 432 256 return VK_ERROR_INITIALIZATION_FAILED; 433 257 } 434 - ret = comp_window_direct_randr_acquire_xlib_display(w, 435 - d->display); 258 + ret = comp_window_direct_acquire_xlib_display(w, w_direct->dpy, 259 + d->display); 436 260 _display = d->display; 437 261 } 438 262 ··· 440 264 return ret; 441 265 } 442 266 443 - 444 - // Get plane properties 445 - uint32_t plane_property_count; 446 - ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 447 - w->base.swapchain.vk->physical_device, &plane_property_count, NULL); 448 - if (ret != VK_SUCCESS) { 449 - COMP_ERROR(w->base.c, 450 - "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 451 - vk_result_string(ret)); 452 - return ret; 453 - } 454 - 455 - COMP_DEBUG(w->base.c, "Found %d plane properites.", 456 - plane_property_count); 457 - 458 - VkDisplayPlanePropertiesKHR *plane_properties = U_TYPED_ARRAY_CALLOC( 459 - VkDisplayPlanePropertiesKHR, plane_property_count); 460 - 461 - ret = vk->vkGetPhysicalDeviceDisplayPlanePropertiesKHR( 462 - w->base.swapchain.vk->physical_device, &plane_property_count, 463 - plane_properties); 464 - if (ret != VK_SUCCESS) { 465 - COMP_ERROR(w->base.c, 466 - "vkGetPhysicalDeviceDisplayPlanePropertiesKHR: %s", 467 - vk_result_string(ret)); 468 - free(plane_properties); 469 - return ret; 470 - } 471 - 472 - uint32_t plane_index = 0; 473 - 474 - VkDisplayModeKHR display_mode = 475 - comp_window_direct_randr_get_primary_display_mode(w, _display); 476 - 477 - VkDisplayPlaneCapabilitiesKHR plane_caps; 478 - vk->vkGetDisplayPlaneCapabilitiesKHR( 479 - w->base.swapchain.vk->physical_device, display_mode, plane_index, 480 - &plane_caps); 481 - 482 - VkDisplaySurfaceCreateInfoKHR surface_info = { 483 - .sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, 484 - .pNext = NULL, 485 - .flags = 0, 486 - .displayMode = display_mode, 487 - .planeIndex = plane_index, 488 - .planeStackIndex = plane_properties[plane_index].currentStackIndex, 489 - .transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, 490 - .globalAlpha = 1.0, 491 - .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha), 492 - .imageExtent = 493 - { 494 - .width = width, 495 - .height = height, 496 - }, 497 - }; 498 - 499 - VkResult result = vk->vkCreateDisplayPlaneSurfaceKHR( 500 - instance, &surface_info, NULL, surface); 501 - 502 - free(plane_properties); 503 - 504 - return result; 505 - } 506 - 507 - static bool 508 - comp_window_direct_randr_init_swapchain(struct comp_window *w, 509 - uint32_t width, 510 - uint32_t height) 511 - { 512 - struct comp_window_direct_randr *w_direct = 513 - (struct comp_window_direct_randr *)w; 514 - 515 - VkResult ret = comp_window_direct_randr_create_surface( 516 - w_direct, w->swapchain.vk->instance, &w->swapchain.surface, width, 517 - height); 267 + ret = comp_window_direct_create_surface(w, _display, width, height); 518 268 if (ret != VK_SUCCESS) { 519 269 COMP_ERROR(w->c, "Failed to create surface!"); 520 270 return false; ··· 527 277 return true; 528 278 } 529 279 530 - static int 531 - comp_window_direct_randr_connect(struct comp_window_direct_randr *w) 532 - { 533 - w->dpy = XOpenDisplay(NULL); 534 - if (w->dpy == NULL) { 535 - COMP_ERROR(w->base.c, "Could not open X display."); 536 - return false; 537 - } 538 - return true; 539 - } 540 - 541 - static VkResult 542 - comp_window_direct_randr_acquire_xlib_display( 543 - struct comp_window_direct_randr *w, VkDisplayKHR display) 544 - { 545 - struct vk_bundle *vk = w->base.swapchain.vk; 546 - VkResult ret; 547 - 548 - ret = vk->vkAcquireXlibDisplayEXT(w->base.swapchain.vk->physical_device, 549 - w->dpy, display); 550 - if (ret != VK_SUCCESS) { 551 - COMP_ERROR(w->base.c, "vkAcquireXlibDisplayEXT: %s (%p)", 552 - vk_result_string(ret), (void *)display); 553 - } 554 - return ret; 555 - } 556 - 557 280 static VkDisplayKHR 558 - comp_window_direct_randr_get_xlib_randr_output( 559 - struct comp_window_direct_randr *w, RROutput output) 281 + comp_window_direct_randr_get_output(struct comp_window_direct_randr *w, 282 + RROutput output) 560 283 { 561 284 struct vk_bundle *vk = w->base.swapchain.vk; 562 285 VkResult ret;
+2 -1
src/xrt/compositor/meson.build
··· 33 33 endif 34 34 35 35 if build_xcb_xrandr_direct 36 - compositor_srcs += ['main/comp_window_direct_randr.c', 36 + compositor_srcs += ['main/comp_window_direct.c', 37 + 'main/comp_window_direct_randr.c', 37 38 'main/comp_window_direct_nvidia.c'] 38 39 compositor_deps += [xcb_randr, x11_xcb] 39 40 endif