Repository navigation
vulkan: end the HDR UI layer's render pass when a shader is loaded - #19946
Merged
Merged
Conversation
With HDR on and a shader preset loaded, the game pass ends the main render pass and clears end_main_pass. When the menu, an overlay, a message or a widget is drawn on top, the UI layer then begins sdr_render_pass on the off-screen buffer, and with end_main_pass still false nothing ends it. The composite that follows records its barriers and begins the next render pass inside it, which Vulkan does not allow (VUID-vkCmdBeginRenderPass-renderpass, VUID-vkCmdPipelineBarrier-None-07889). RADV draws these frames correctly anyway. On Android the touch overlay is on by default, so every frame takes this path, and it is the likely cause of the lost device in libretro#19699 (HDR plus any shader on an Adreno tablet).
No CI lane ran the Vulkan driver with an HDR swapchain: lavapipe on X11 has no HDR10 surface format. So nothing saw the UI layer's render pass left open under the composite whenever a shader preset and any UI met, which the previous commit fixes. samples/gfx/vulkan_hdr_ui_pass runs the shipping frontend from the VULKAN_DEBUG=1 build on lavapipe under an Xvfb of depth 30, which gives the surface a real 10-bit format. A layer, fake_hdr_layer.c, reports that format a second time paired with HDR10_ST2084 and passes an HDR10 swapchain on in sRGB with the same format and images. The driver then selects HDR10 and takes its whole HDR path; what it records is unchanged. The cases: a two-pass preset with the menu open, with the statistics, and with an OSD message; the menu case again on the video thread; and the controls, the preset with no UI and the menu with no preset. Each must create an HDR10 swapchain and log the HDR game pass and composite pass it is meant to take, so a run that fell back to SDR, or did not draw the UI, fails rather than passing vacuously. Any validation error fails a case. Without the previous commit, the four preset-plus-UI cases fail with VUID-vkCmdPipelineBarrier-None-07889 and VUID-vkCmdBeginRenderPass-renderpass, the two errors in the report; the controls pass either way. It runs in the Vulkan validation workflow's harness job, which already builds the tree VULKAN_DEBUG=1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LBQPGctE3xjHw1i9kE5EzK
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With HDR on and a slang preset loaded,
vulkan_frame()leaves the UI layer's render pass open whenever something is drawn over the game (menu, overlay, notification, statistics). The game pass ends the main pass and clearsend_main_pass. The UI layer then beginssdr_render_passon the off-screen buffer, and withend_main_passstill false nothing ends it. The HDR composite then records its barriers and begins its own render pass inside the open one.This sets
end_main_passonce that pass is begun, so the existingvkCmdEndRenderPasscloses it. HDR without a shader and SDR with one already ended the pass and are unchanged.Testing
No Android device here gives an HDR10 swapchain. An AYN Thor on Android 13 offers no HDR10 surface format, and RetroArch falls back to SDR there. So this was checked on Linux instead:
subframe-bfi/crt-beam-simulator+crt/crt-gdv-mini-ultra) applied at runtime, as the reporter didVUID-vkCmdBeginRenderPass-renderpassonce andVUID-vkCmdPipelineBarrier-None-07889twice per frame with UIThe scRGB, SDR and single-pass runs without the commit were on 83edb80. The rest were run on this base, 770391e. GPU-assisted validation found nothing more. RADV draws these frames correctly either way, and with the commit the game and the menu still draw.
The four CI jobs that name
vulkan.c(compile-matrix, samples-formats, samples-gfx, linux-vulkan-resize) pass locally, andvulkan.cbuilds clean withC89_BUILD=1.Related Issues
#19699: on an Adreno 830 tablet (Android 16), Vulkan + HDR + any slang shader gives
VK_ERROR_DEVICE_LOST. The touch overlay is on by default on Android, so every frame there takes this path. This is the likely cause, but it hasn't been confirmed on that device yet.