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

Backends: D3D12: Use FramebufferScale #8412

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

WSSDude
Copy link

@WSSDude WSSDude commented Feb 19, 2025

Use FramebufferScale similar to how OpenGL backend does.

Fixes issue when DisplaySize is bigger than real framebuffer due to eg. fullscreen window when specified, provided that user or window backend sets it up correctly.

@ocornut
Copy link
Owner

ocornut commented Feb 19, 2025

I hope to tackle those soon in a batch, but I would like to ask: can you clarify which setup are you using where window size is != framebuffer size on window?

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

Exclusive fullscreen causes this for example - you can have resolution set to 1920x1080 but on 4k display, client size is getting reported as 3840x2160, messing the cursor positions at minimum, unsure if it breaks anything else on top.

Another one I found which may cause this is DPI scaling in specific instances, not always. Sometimes when changing DPI, Windows seems to report weird resolution for the window (eg. when I swap from 200% -> 100%, client rect reports as having 0.5% of size for some reason, causing mismatch again).

This seemed to help in both cases.

@ocornut
Copy link
Owner

ocornut commented Feb 19, 2025

But, this would only be useful if someone was setting FramebufferScale, where and how are you setting it? Win32 backend doesn't set it and use ClientRect size to set io.DisplaySize. So this change is assuming something else which you have not described.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

Oh right I understand now what you mean. Like pseudocode of sorts is basically this

// init stuff
ImGui_ImplWin32_NewFrame();
ImGui::GetIO().DisplayFramebufferScale = ImVec2(framebufferWidth / io.DisplaySize.x, framebufferHeight / io.DisplaySize.y);
ImGui::NewFrame();
// do rest of ImGui things

I set it manually before each NewFrame basically, following one issue I found here which mentioned this for Android setup with OpenGL, tried it, realised it doesn't work still and looking at the code of the respective backends, figured out that it is unused. Tried to plug it in in similar manner and it started to work.

Not ideal and yeah, definitely not able to get it just from Win32 backend (unsure how I could do that at least, maybe there is some message I could try to catch?), but other backends do set it, like GLFW or SDL from what I saw so I suppose it should work fine there?

Manual setup before new ImGui frame though seems to work just fine for this when it is not available, it just need to actually do something in that case.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

#6064 This is where I found the io.DisplayFramebufferScale specifically this comment #6064 (comment)

But yeah, didn't work, looked at backends, effectively copied it, started to work.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

Actually I see now that the person which made the issue was also using the same combination of backends as me (Win32+D3D12). Maybe worth noting.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

I hope to tackle those soon in a batch

In any case, if you would rather do it in batch, no hard feelings I suppose, but would be really useful as this is currently practically only real reason we have to include the backend in our project, so we can do this tiny change to the backend.

Otherwise, we would be able to just have it included from XMake package directly am pretty sure, trying to remove last 2 hacks which I believe are not needed upon further inspection if I utilize DrawLists more properly. Need to set different shader and font which I am pretty sure should be doable via custom draw commands and callbacks, but maybe am wrong, will see soon I suppose 😁

@ocornut
Copy link
Owner

ocornut commented Feb 19, 2025

I'll have to try exclusive fullscreen to dig further, but since I assumed this field would never be set to != 1.0f on Windows it is probably harmless to merge this.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

Like one potential issue I see with this is inside imgui.cpp in InitViewportDrawData function

draw_data->FramebufferScale = io.DisplayFramebufferScale; // FIXME-VIEWPORT: This may vary on a per-monitor/viewport basis?

I am a bit uncertain how this would behave on multi-monitor setup when windows are detached. Can't really test that properly.

I would assume it may cause some issues there.

@WSSDude
Copy link
Author

WSSDude commented Feb 19, 2025

But on the other hand, unless someone explicitly sets it up it shouldn't affect anything. And would guess same issue may happen with other backends unless it is somehow handled there per-viewport basis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants