D3D12 vs Vulkan: window size calc issue

147 views
Skip to first unread message

Jean-Colas Prunier

unread,
Apr 2, 2023, 6:33:11 AM4/2/23
to Dawn Graphics

I have a windows app where I create the window myself (not using GLFW). When I use the Vulkan backend and need to recreate the swapchain after the window size changed, I use 

```
RECT client_rect;
GetClientRect(hwnd, &client_rect);
window_hidth = client_rect.right - client_rect.left;
window_height = client_rect.bottom - client_rect.top;
```
It works fine with the Vulkan backend (image 1). But when I switch to the D3D12 backend, the client area is smaller (it's the width - the border, and the height - title bar and border) - Image 2. 

Note this is the case regardless of whether I do the swapchain recreation using the new with / height in WM_WINDOWPOSCHANGING/CHANGED or WM_SIZING/WM_SIZE.

Not sure at this point whether the issue is coming from me not understanding well enough how windows work, but since the difference here comes from switching from one backend to another, I am thinking that Vulkan or D312 down the Dawn pipeline may be setting or not setting something, hence the difference between the 2 backends.

Thought bringing this to your attention could be worthwhile.


vulkan.png
d3d12.png

j...@jean-colas.com

unread,
Apr 2, 2023, 6:06:49 PM4/2/23
to Mark Sibly, Dawn Graphics
I didn’t try with GLFW. Will do.

I could very well do something wrong in the Windows native API calls, yet I wonder why this would work with Vulkan and not D3D12. I will post the code later for anyone interested to try.

Which leads me to ask (but it’s a different question so I might post another thread one day): has anyone tried to use Dawn and the Direct Composition API on Windows (or Visual Layer I believe which is the now recommended way)? It seems that I’d need to get the swap chain texture view as a directx compatible texture, and that seems possible using external textures? But I have not seen any example of that.

On 2 Apr 2023, at 23:40, Mark Sibly <mark...@gmail.com> wrote:

Hi,

In glfw, I use glfwGetWindowSize to get swapchain size from glfw which actually just ends up just returning clientRect.right and clientRect.bottom, left and top are apparently ignored (news to me) Source code here:


But one slightly surprising thing I've found while messing around with this is that I can't actually NOT draw to the entire client rect. If I create a swapchain of window width/2, height/2 or something, it just gets stretched to fill the entire client window area. Same in D3D12 and Vulkan.

I do vaguely remember reading something about this though so I'm not too surprised, but then why isn't yours doing that? Perhaps some window HWND flags are different?

It does also mean that my width/height could actually be off left / top too I guess, I just can't notice it because it's been stretched to fit the client area exactly - will do some more research...

Bye!
Mark


--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dawn-graphics/4c186fae-5106-4720-a484-6ab18f19f924n%40googlegroups.com.

Corentin Wallez

unread,
Apr 3, 2023, 3:21:26 AM4/3/23
to j...@jean-colas.com, Mark Sibly, Dawn Graphics
Hey all,

I haven't double checked recently but the swapchain on Windows should automatically stretch to cover the whole window. This used to work with the windows set up by GLFW at least. The stretching over the whole client area is done on purpose (it matches Web semantics better and avoids missing pixels if applications forget to handle a resize) although it could be worth having an option to choose the behavior in the future. It's weird that the DXGI_STRETCH_MODE_SCALING I linked doesn't apply to your D3D12 window. I'm not sure what's going on. Do you see any difference between your setup code and the one GLFW?

It is possible to use Dawn with DirectComposition because that's what Chromium does in some cases, but that's using a backdoor API that's not in the main webgpu.h header. If you have an idea for how this could be added as a surface descriptor then I think we could easily add it to webgpu.h

Cheers,

Corentin



Jean-Colas Prunier

unread,
Apr 3, 2023, 4:50:52 AM4/3/23
to Dawn Graphics
Thanks Mark and Corentin for looking into that.

I am putting a simple reproducible example.

Can be compiled with:

clang++ -std=c++20 -I$DAWN_PATH/dawn/include -I $DAWN_PATH/dawn/out/Release/gen/include -I $DAWN_PATH/dawn/src/dawn/ -L$DAWN_PATH/dawn/out/Release -ldawn_native.dll -ldawn_proc.dll -ldawn_platform.dll webgpu_cpp.o MultiThreadedArchi.cpp -DMULTITHREADED -lUser32 -lGdi32 -DUNICODE

@Corentin. I don't see a different with GLFW implementation. I made a version using GLFW and I see the problem with this version as well. Switch to D3D12 and you will get the images I posted.

Regarding Direct Composition I will try to make some progress with this, but I find it rather painful). So not sure when I will get a chance to get to that but I will definitely give it a go at some point. Do you have an example somewhere (or can point to one) that shows the use of ExternalTexture?

Many thanks for your swift and open-minded answers).
MultiThreadedArchi.cpp

Jean-Colas Prunier

unread,
Apr 3, 2023, 9:37:53 AM4/3/23
to Dawn Graphics
The plot thickens)

Vulkan: currently the app I am running is about 1.5K microseconds with no problem when I resize the window.

D3D12: the app starts to run at the same speed for the first fractions of a second and then drops to 15K microseconds, x10 slower (no need to resize the windowfor that - it just drops while doing nothing essentially). In addition to the positioning/sizing issue that I indicated before. Note: the dimensions returned by client rect are correct (with respect to what's supposed to be the client area size). 

I will try to adapt the test code later to see if I can reproduce this with this code (you don't even need to render geometry to see this problem - at least in my tests - but haven't tested with the example I provided you with).

Jean-Colas Prunier

unread,
Apr 3, 2023, 10:06:36 AM4/3/23
to Dawn Graphics
Here is the file with a timer (and somehow corrected tabs to make it easier to read )) sorry about that put this together quickly today).

You can switch between D3D12 and Vulkan and see if you can reproduce the problem (the client area not refreshed as expected with DX and the timing issue which is likely related).

Also, this test is using Mailbox / Immediate (timing of course changes with Fifo).

MultiThreadedArchi.cpp

Mark Sibly

unread,
Apr 3, 2023, 5:33:48 PM4/3/23
to Jean-Colas Prunier, Dawn Graphics
Hi Jean-Colas,

I tried the first MultiThreadedArch.cpp you posted and it appeared to work fine with my game/dawn framework. The window was completely filled by the flashing 'clear' rectangle in both D3D12/Vulkan modes, no gaps on any of the edges, even after resizes. I also disabled the assignments to window_width and window_height in WndProc and everything behaved the same, so clear is always clearing the entire client rect.

I had to de-c++20-ify your code as my framework is c++17, but that won't have anything to do with it so I'm guessing the problem could lie in the dawn dlls you are using - when/how were they built?

I use a single static lib which contains a few custom tweaks which I keep pretty up to date, eg: I merged with upstream/main and rebuilt it just yesterday. I'd be happy to share it although it's pretty massive on Windows (365M for the 'Release' build!) although apps that link with it are smaller, eg: yours is 'just' 21M. I haven't done any work trying to reduce the size of anything as yet. I am still kind of hoping someone comes along and fixes/implements better library builds in cmake than the bodge I'm using, as random people keep threatening to do. It's still kind of a major issue IMO...

Bye,
Mark

j...@jean-colas.com

unread,
Apr 3, 2023, 6:01:17 PM4/3/23
to Mark Sibly, Dawn Graphics
Ok thanks Mark,

That’s strange. I have pulled the code recently but I believe my latest build if from February (I will check tomorrow). I have been using the standard ninja built option. I will try to rebuild sometime later after updating.

I guess it could be various other things, drivers, windows dlls version. I agree that a better building solution would be great but my understanding was that the team was working hard towards releasing a v1 somehow this year, so I’d think everybody is busy with that, and yes hopefully a make guru can come along and help (sadly that’s the last of my abilities)).

Regading this issue, well if it’s in the code somewhere, someone will probably stumble on it again at some point. We are am mostly interested in the Vulkan backend at this point in time, so I will try this on a different machine as well to see of that’s dependent as we will also need to make it work with DirectX.

Thanks again for spending time on this).

--
You received this message because you are subscribed to a topic in the Google Groups "Dawn Graphics" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dawn-graphics/0x4F4UScn90/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dawn-graphic...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dawn-graphics/CAK32ozgWoiCOpKAQhuhK3te7Y2fVHjjD9tXeptHv2NZnCuEg_w%40mail.gmail.com.

Mark Sibly

unread,
Apr 3, 2023, 6:09:38 PM4/3/23
to j...@jean-colas.com, Dawn Graphics
If you want to send me a zip of your build including all the dawn dlls I'd be happy to give it a test on my (Windows 10 Pro) machine.

Mark Sibly

unread,
Apr 4, 2023, 2:01:46 AM4/4/23
to Jean-Colas Prunier, Dawn Graphics
Hi,

In glfw, I use glfwGetWindowSize to get swapchain size from glfw which actually just ends up just returning clientRect.right and clientRect.bottom, left and top are apparently ignored (news to me) Source code here:


But one slightly surprising thing I've found while messing around with this is that I can't actually NOT draw to the entire client rect. If I create a swapchain of window width/2, height/2 or something, it just gets stretched to fill the entire client window area. Same in D3D12 and Vulkan.

I do vaguely remember reading something about this though so I'm not too surprised, but then why isn't yours doing that? Perhaps some window HWND flags are different?

It does also mean that my width/height could actually be off left / top too I guess, I just can't notice it because it's been stretched to fit the client area exactly - will do some more research...

Bye!
Mark


On Sun, Apr 2, 2023 at 10:33 PM Jean-Colas Prunier <j...@jean-colas.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dawn-graphics/4c186fae-5106-4720-a484-6ab18f19f924n%40googlegroups.com.

Jean-Colas Prunier

unread,
Apr 4, 2023, 3:58:22 AM4/4/23
to Dawn Graphics
Hum, as Corentin mentioned, the stretch is expected indeed, but it can't be the cause of the problem in this case. I have been checking the result of Dawn / real-time API with CPU renders, and they match. No stretch. The geometry is where it's supposed to be in the frame. 

Let me do further tests on different computers, rebuild Dawn and see. I will also add some geometry to check where it is drawn on the screen.

Reply all
Reply to author
Forward
0 new messages