Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Qt, Windows] Crash when switching from monitor to monitor with different DPI values #352

Closed
Tracked by #387
Korijn opened this issue Feb 17, 2023 · 9 comments · Fixed by #429
Closed
Tracked by #387

[Qt, Windows] Crash when switching from monitor to monitor with different DPI values #352

Korijn opened this issue Feb 17, 2023 · 9 comments · Fixed by #429
Labels
bug Something isn't working

Comments

@Korijn
Copy link
Collaborator

Korijn commented Feb 17, 2023

When I drag the window from one monitor to another, with different DPI settings, pygfx crashes:

❯ python .\examples\feature_demo\colormap_channels.py
QWindowsWindow::setDarkBorderToWindow: Unable to set dark window border.
Requested size 640x480 is outside of the supported range: Extent3d { width: 1600, height: 1200, depth_or_array_layers: 1 }..=Extent3d { width: 1600, height: 1200, depth_or_array_layers: 1 }
Uncaught WGPU error (Unknown):
Outdated
thread '<unnamed>' panicked at 'Unable to end render pass: RenderPassError { scope: Pass((0, 122, Vulkan)), inner: MissingAttachments }', src\command.rs:298:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
@almarklein almarklein added the bug Something isn't working label Feb 17, 2023
@Korijn Korijn transferred this issue from pygfx/pygfx Feb 28, 2023
@Korijn
Copy link
Collaborator Author

Korijn commented Feb 28, 2023

This also happens on the examples here, so I transferred the issue.

@Korijn
Copy link
Collaborator Author

Korijn commented Mar 31, 2023

Seems like we might be resizing our rendering pipelines and buffers 1 frame too late after becoming aware of the resize event?

@Korijn
Copy link
Collaborator Author

Korijn commented Mar 31, 2023

I can only reproduce this with Qt window, glfw window works fine

@almarklein
Copy link
Member

I cannot reproduce it on MacOS with PySide 6.4.1.

@Korijn Korijn changed the title Crash when switching from monitor to monitor with different DPI values [Qt, Windows] Crash when switching from monitor to monitor with different DPI values Jul 20, 2023
@almarklein
Copy link
Member

almarklein commented Oct 20, 2023

I can reproduce this bug on Windows. Exactly what you said: works fine on GLFW, but with Qt (PySide 6.6.0 in this case) it gives an error. The error is now a genuine Exception though, with a traceback, so I have more to go on.

What I do observe with GLFW is that quickly moving the window back and forth between the two screens can make the window change size (it grew larger in my case). This may be related to the fact that when dragging near an edge, Windows may snap it to half-screen width. Anyway, not a big deal, but worth mentioning here.

@almarklein
Copy link
Member

Investigating this further:

There first is a warning, emitted by wgpu-core, that the Requested size WxH is outside of the supported range. (originating here: https://github.com/gfx-rs/wgpu/blob/v0.17/wgpu-core/src/device/global.rs#L2009-L2013). This happens when the surface is configured, not exactly sure from what wgpu-native call yet.

Although this is only a warning, the surface becomes invalid because of the size mismatch, causing an exception in the call wgpuSwapChainGetCurrentTextureView().

I've not managed to get much further on this, and am careful not to spent too much time on it, because the whole swap-chain stuff has been removed in wgpu-native trunk, so on the next new version it'll be different, needing refactoring, and perhaps the error is then resolved or is easier to fix.

What I did try is forcing obtaining a new swap chain in our _get_native_swap_chain_if_needed() method, when it detects that the pixel ratio has changed. I made it such that the next n draws it forces recreation of the swap chain. This worked for the triangle example, but not for examples that constantly redraw (like the shadertoys).

I also tried try-catch on the call to wgpuSwapChainGetCurrentTextureView(), and forcing the creation of a new swap-chain object. This did not fully work, because the errors kept being generated and the viz was still stuck. Could move to the other screen, where it worked, then back and it hanged, consistently. Looks a bit like internally wgpu re-uses a swap-chain, even if its invalid?

@Korijn
Copy link
Collaborator Author

Korijn commented Nov 10, 2023

Given what you observed in gfx-rs/wgpu-native#315 do you think it could be this line that needs a None check?

libf.wgpuSurfaceRelease(surface_id)

Or this one:

https://github.com/pygfx/wgpu-py/blob/dbb991d23f31bbbb568bbe3e6d8cb797e0f111a2/wgpu/backends/rs.py#L441C29-L441C29

@almarklein
Copy link
Member

Yeah. I think the equivalence would be something like == ffi.NULL.

@almarklein
Copy link
Member

The crashing was fixed, but we still got warnings that we could not prevent. Looks like these will be gone soon too: gfx-rs/wgpu#4796

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants