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.
This commit is contained in:
Jakob Bornecrantz 2023-08-25 14:43:43 +01:00
parent 9bac7ed30e
commit 1f49e43724
2 changed files with 48 additions and 7 deletions

View file

@ -74,8 +74,11 @@ print_modes(struct comp_target *ct, VkDisplayModePropertiesKHR *mode_properties,
COMP_PRINT_MODE(ct->c, "Listed %d modes", mode_count); COMP_PRINT_MODE(ct->c, "Listed %d modes", mode_count);
} }
VkDisplayModeKHR static VkDisplayModeKHR
comp_window_direct_get_primary_display_mode(struct comp_target_swapchain *cts, VkDisplayKHR display) 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 vk_bundle *vk = get_vk(cts);
struct comp_target *ct = &cts->base; 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); free(mode_properties);
*out_width = props.parameters.visibleRegion.width;
*out_height = props.parameters.visibleRegion.height;
return props.displayMode; return props.displayMode;
} }
@ -157,6 +163,13 @@ choose_alpha_mode(VkDisplayPlaneAlphaFlagsKHR flags)
return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR; return VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR;
} }
/*
*
* 'Exported' functions.
*
*/
VkResult VkResult
comp_window_direct_create_surface(struct comp_target_swapchain *cts, comp_window_direct_create_surface(struct comp_target_swapchain *cts,
VkDisplayKHR display, VkDisplayKHR display,
@ -188,7 +201,36 @@ comp_window_direct_create_surface(struct comp_target_swapchain *cts,
plane_properties = NULL; plane_properties = NULL;
// Select the mode. // 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. // We need the capabilities of the selected plane.
VkDisplayPlaneCapabilitiesKHR plane_caps; VkDisplayPlaneCapabilitiesKHR plane_caps;
@ -206,8 +248,8 @@ comp_window_direct_create_surface(struct comp_target_swapchain *cts,
.alphaMode = choose_alpha_mode(plane_caps.supportedAlpha), .alphaMode = choose_alpha_mode(plane_caps.supportedAlpha),
.imageExtent = .imageExtent =
{ {
.width = width, .width = mode_width,
.height = height, .height = mode_height,
}, },
}; };

View file

@ -16,8 +16,6 @@
extern "C" { extern "C" {
#endif #endif
VkDisplayModeKHR
comp_window_direct_get_primary_display_mode(struct comp_target_swapchain *cts, VkDisplayKHR display);
VkResult VkResult
comp_window_direct_create_surface(struct comp_target_swapchain *cts, comp_window_direct_create_surface(struct comp_target_swapchain *cts,
@ -39,6 +37,7 @@ comp_window_direct_init_swapchain(
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif