SDL
SDL copied to clipboard
SDL3 GPU: Orientation change triggers endless swapchain recreation (Android)
When changing the orientation, the swapchain is recreated. When creating the swapchain on Android, preTransform is set to VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR. Setting the preTransform to something different than the currentTransform (which is what is desired in this case, so the transformations are handled by the developer) will generate VK_SUBOPTIMAL_KHR in subsequent presentations.
When detecting this flag, the swapchain is recreated , which effectively means that the swapchain is recreated in every frame, unless the device has the orientation that is considered optimal, causing severe frame stuttering.
I have verified this behavior with 3 different devices. When removing condition presentResult == VK_SUBOPTIMAL_KHR, rendering proceeds normally.
For context: I proposed to change it to VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR in #12425.
Another discussion about it: #11334.
We can try to remove the presentResult == VK_SUBOPTIMAL_KHR, but then maybe it will create other problems on other platforms like previously with Nintendo Switch. I'm not sure.
I don't think we can remove the SUBOPTIMAL_KHR check, it's used by certain drivers. The driver returning that constantly is definitely odd behavior.
According to this article:
Detect Device Orientation Changes (Android 10+)
To know when the application has encountered an orientation change, the most reliable means of tracking this change involves checking the return value of vkQueuePresentKHR() and seeing if it returned VK_SUBOPTIMAL_KHR
and
In order for your application to get the most out of Vulkan on Android, implementing pre-rotation is a must.
This means it is intentional behavior and not device specific. The developer is expected to implement pre-rotation because, as described in the linked article, not doing so may introduce overhead.
Also, according to this presentation, on page 12:
• DPU units may or may not have HW support for all rotations (You can’t check for support) • Vulkan calls* will return SUBOPTIMAL when Swapchain doesn’t match Surface rotation even if DPU supports that rotation - Either way Suboptimal means the application should recreate
Based on a quick search, I could not find any other cause to generate VK_SUBOPTIMAL_KHR beside orientation change. Which leaves, basically, two viable options for Android:
- Ignore VK_SUBOPTIMAL_KHR for this platform, and accept the potential overhead.
- Adjust to the orientation change and force the developer to handle pre-rotation, per the official stand. For this option, though, additional information must be provided to the developer, that is which is the expected orientation (it is not guaranteed to be portrait or landscape, is device specific) in order to make the right MVP adjustments.
This is a situation where a hint makes sense. I think we should ignore VK_SUBOPTIMAL_KHR by default, and all a hint to specify that the application handles pre-rotation. The expected orientation can potentially be a global property or a property on the device.
I think we should ignore VK_SUBOPTIMAL_KHR by default
Maybe only on Android? I really hate touching presentation stuff, most of the logic is in there specifically because some driver needed it to work that way and it's really easy to cause regressions.
I think we should ignore VK_SUBOPTIMAL_KHR by default
Maybe only on Android? I really hate touching presentation stuff, most of the logic is in there specifically because some driver needed it to work that way and it's really easy to cause regressions.
Sure
I went ahead and ignored VK_SUBOPTIMAL_KHR on Android for now.