From 1f49e43724b7f4104bf1c005e88bfaac7809dc0d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 25 Aug 2023 14:43:43 +0100 Subject: [PATCH] c/main: Always use the mode's extents when creating the surface This fixes a bug on NVIDIA Jetson. Note this isn't so much the NVIDIA Jetson fault, while the code was working on desktop, Monado did something wrong. What happned was that Monado would select a mode with one size, while then creating a VkSurface/VkSwapchain of a different size. This would work on hardware with scalers/panning modes. The NVIDIA Jetson apparently doesn't have support for that so failed when presenting. This patch makes sure that the VkSurface/VkSwapchain extents match the mode for all direct mode targets. --- src/xrt/compositor/main/comp_window_direct.c | 52 ++++++++++++++++++-- src/xrt/compositor/main/comp_window_direct.h | 3 +- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/xrt/compositor/main/comp_window_direct.c b/src/xrt/compositor/main/comp_window_direct.c index 7b2a7e8dc..ca62e5e3e 100644 --- a/src/xrt/compositor/main/comp_window_direct.c +++ b/src/xrt/compositor/main/comp_window_direct.c @@ -74,8 +74,11 @@ print_modes(struct comp_target *ct, VkDisplayModePropertiesKHR *mode_properties, COMP_PRINT_MODE(ct->c, "Listed %d modes", mode_count); } -VkDisplayModeKHR -comp_window_direct_get_primary_display_mode(struct comp_target_swapchain *cts, VkDisplayKHR display) +static VkDisplayModeKHR +get_primary_display_mode(struct comp_target_swapchain *cts, + VkDisplayKHR display, + uint32_t *out_width, + uint32_t *out_height) { struct vk_bundle *vk = get_vk(cts); struct comp_target *ct = &cts->base; @@ -142,6 +145,9 @@ comp_window_direct_get_primary_display_mode(struct comp_target_swapchain *cts, V free(mode_properties); + *out_width = props.parameters.visibleRegion.width; + *out_height = props.parameters.visibleRegion.height; + return props.displayMode; } @@ -157,6 +163,13 @@ choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags) return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR; } + +/* + * + * 'Exported' functions. + * + */ + VkResult comp_window_direct_create_surface(struct comp_target_swapchain *cts, VkDisplayKHR display, @@ -188,7 +201,36 @@ comp_window_direct_create_surface(struct comp_target_swapchain *cts, plane_properties = NULL; // Select the mode. - VkDisplayModeKHR display_mode = comp_window_direct_get_primary_display_mode(cts, display); + uint32_t mode_width = 0, mode_height = 0; + VkDisplayModeKHR display_mode = get_primary_display_mode( // + cts, // + display, // + &mode_width, // + &mode_height); // + + if (display_mode == VK_NULL_HANDLE) { + COMP_ERROR(cts->base.c, "Failed to find display mode!"); + return VK_ERROR_INITIALIZATION_FAILED; + } + + /* + * This fixes a bug on NVIDIA Jetson. Note this isn't so much the NVIDIA + * Jetson fault, while the code was working on desktop, Monado did + * something wrong. What happned was that Monado would select a mode + * with one size, while then creating a VkSurface/VkSwapchain of a + * different size. This would work on hardware with scalers/panning + * modes. The NVIDIA Jetson apparently doesn't have support for that so + * failed when presenting. This patch makes sure that the VkSurface & + * VkSwapchain extents match the mode for all direct mode targets. + */ + if (mode_width != width || mode_height != height) { + COMP_INFO(cts->base.c, + "Ignoring given extent %dx%d and using %dx%d from mode, bugs could happen otherwise.", + width, // + height, // + mode_width, // + mode_height); // + } // We need the capabilities of the selected plane. VkDisplayPlaneCapabilitiesKHR plane_caps; @@ -206,8 +248,8 @@ comp_window_direct_create_surface(struct comp_target_swapchain *cts, .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha), .imageExtent = { - .width = width, - .height = height, + .width = mode_width, + .height = mode_height, }, }; diff --git a/src/xrt/compositor/main/comp_window_direct.h b/src/xrt/compositor/main/comp_window_direct.h index d1c37bfe0..97a74fcfa 100644 --- a/src/xrt/compositor/main/comp_window_direct.h +++ b/src/xrt/compositor/main/comp_window_direct.h @@ -16,8 +16,6 @@ extern "C" { #endif -VkDisplayModeKHR -comp_window_direct_get_primary_display_mode(struct comp_target_swapchain *cts, VkDisplayKHR display); VkResult comp_window_direct_create_surface(struct comp_target_swapchain *cts, @@ -39,6 +37,7 @@ comp_window_direct_init_swapchain( #endif + #ifdef __cplusplus } #endif