(Apologies for the sending two questions in a row).
I have a Vulkan app running on Windows. I have noticed for a while that when I was resizing the window I would generally get a gutter effect like so
This problem obviously is more visible when the app uses the FIFO present mode which it needs to be. I don’t think this is strictly a Vulkan problem as a I have seen devs on Windows + DirectX having the same problem but I am hoping some people on the forum may have some insights into this. It’s impossible to find information on this on the net though I found by playing with applications like Blender that these app don’t suffer from that issue. Though Chrome does.
After going down the rabbit hole I found that it could have something to do with the Windows DWM. On windows it uses two possible modes the redirection surface / BitBlt model or the Flip model. This is well documented. To my knowledge you don’t control this directly through Vulkan as this is driver specific though you can switch between different models using the NV control panel (I am using a NV card here).
The two modes are:
- Native
- Layered DXGI
I understand Native would using the BitBlt mode while Layered would use the DX swapchain for flip. There is a godot post on this matter: Use DXGI to present frames rendered by Vulkan on Windows
The interesting thing is that I would think if I understand what I find on the net properly, that using the Layered path would be better. In fact people playing video games reported faster framerates with this mode. Though these are my observations regarding the gutter effect:
- Native. PresentMon reports Copy with GPU GDI so I assume this is the BitBlt mode (redirection surface) → no gutter
- Layered: PresentMon reports Independant Flip → gutter visible
When I tried to understand why I had the gutter effect it made no sense:
- first the gutter shows up the most when you resize the window down. So it’s almost like the DWM lags behind by showing the window with an old size while the image rendered by VK is already smaller? It’s a guess.
- It’s worth noting that I have been playing with
VkSwapchainPresentScalingCreateInfoEXT scaling_info = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT,
.pNext = NULL,
.scalingBehavior = VK_PRESENT_SCALING_STRETCH_BIT_EXT,
.presentGravityX = VK_PRESENT_GRAVITY_CENTERED_BIT_EXT ,
.presentGravityY = VK_PRESENT_GRAVITY_CENTERED_BIT_EXT ,
};
If I don’t do this, even in the native mode I get the gutter effect. I guess this is why VkSwapchainPresentScalingCreateInfoEXT is made in the first place, stretch the image when the surface held by the DWM has a different size, but then why does it work in Native mode and not in the Layered mode?
- Generally speaking I was told that the Native mode implying a redirection surface was slower than the DXGI path which is why Vulkan/OpenGL app feels sluggish compared to DX apps on Windows. That’s why Godot considered using a DXGI swapchain approach as well but that leaves me puzzled since when I loop at PresentMon numbers when running the DXGI mode through the NV control panel my framerate is effectively lower (report 60 fps in Mailbox) than when using the Native mode (4K in mailbox)? DXGI limits the fps to 60 even in Mailbox present mode. Rather strange. Something feels broken there.
If anyone has experience which this matter, I’d love with they could share their knowledge on this. I will also try to post something on the NV forums as I don’t know what these two modes really do other what I have described, and try to ask them to explain the numbers I see (slower with DXGI and gutter even when I use VkSwapchainPresentScalingCreateInfoEXT ). Also I found this gutter effect really annoying and would think this is something there should be 1) a good / solid explanation for 2) a good robust solution to fix it?
