vulkan: work around Arm drivers ignoring negative viewport heights - #10058
Open
lexoliu wants to merge 1 commit into
Open
vulkan: work around Arm drivers ignoring negative viewport heights#10058lexoliu wants to merge 1 commit into
lexoliu wants to merge 1 commit into
Conversation
Arm's proprietary driver (observed on r54p2, Mali-G715, Pixel 9 Pro, Android 16) rasterizes as if the viewport height were positive even when a negative-height viewport is submitted, so every render pass comes out vertically flipped. The driver receives the standard maintenance1-style viewport (y = height, height = -height); capturing the submitted values confirms wgpu's side is correct, and replaying the same pipeline into an offscreen texture reproduces the flip without presentation involved. On that driver, flip Y in the vertex shader epilogue via naga's ADJUST_COORDINATE_SPACE, submit positive-height viewports, and invert the front-face winding (and stencil face state) to compensate.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a Vulkan backend workaround for Arm proprietary drivers that ignore negative viewport heights, causing vertically flipped render passes. It introduces a driver-gated path that moves the Y flip into shader generation and adjusts pipeline state to preserve expected rasterization behavior.
Changes:
- Add a new Vulkan
Workarounds::IGNORED_NEGATIVE_VIEWPORT_HEIGHTflag and enable it forVK_DRIVER_ID_ARM_PROPRIETARY. - When enabled, compile shaders with Naga
spv::WriterFlags::ADJUST_COORDINATE_SPACE, submit positive-height viewports, and adjust pipeline rasterization state (front-face inversion). - Document the user-visible behavior change in
CHANGELOG.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| wgpu-hal/src/vulkan/mod.rs | Introduces a new Vulkan workaround bitflag with rationale. |
| wgpu-hal/src/vulkan/device.rs | Adjusts pipeline state under the workaround (front-face and stencil facing). |
| wgpu-hal/src/vulkan/command.rs | Switches render-pass and dynamic viewport submission to positive-height viewports under the workaround. |
| wgpu-hal/src/vulkan/adapter.rs | Enables the workaround by driver ID and toggles Naga SPIR-V writer coordinate adjustment. |
| CHANGELOG.md | Notes the Vulkan behavior change for affected Arm proprietary drivers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
2080
to
+2087
| let s = &ds.stencil; | ||
| let front = conv::map_stencil_face(&s.front, s.read_mask, s.write_mask); | ||
| let back = conv::map_stencil_face(&s.back, s.read_mask, s.write_mask); | ||
| let (front, back) = if flip_winding { | ||
| (back, front) | ||
| } else { | ||
| (front, back) | ||
| }; |
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.
Fixes #10057.
The Arm proprietary driver on a Pixel 9 Pro (Mali-G715, r54p2, Android 16) rasterizes as if the viewport height were positive even when the standard maintenance1-style negative-height viewport is submitted, so every render pass comes out vertically flipped. The submitted values were captured on the device from
begin_render_pass(x=0 y=1935 w=960 h=-1935), the flip reproduces when replaying the same pipeline into an offscreen texture with presentation out of the picture, and re-issuing the viewport after the pipeline bind changes nothing, which rules out lost dynamic state. Details in the issue.This adds
Workarounds::IGNORED_NEGATIVE_VIEWPORT_HEIGHT, set forVK_DRIVER_ID_ARM_PROPRIETARY. When active:ADJUST_COORDINATE_SPACE, so the Y flip moves into the vertex shader epilogue;begin_render_passandset_viewportsubmit positive-height viewports;Frag coord, scissor, and derivative semantics are unaffected: the geometry lands on the same framebuffer rows as under a honored negative viewport, so framebuffer-space values match. SPIR-V passthrough shaders would bypass the naga flip, which is a reason to keep this gated to the broken driver rather than making it the default path.
Verified on the device: previously-flipped content renders upright, culling unchanged, and the rest of the app (compute-produced textures, presentation) behaves as before. Desktop backends are untouched. I have the device on adb and can test revisions of this change.