Under modern versions of Windows, it is possible for a process to have a global DPI_AWARENESS context but also for specific threads within that process to have their own DPI_AWARENESS set. This comes up, for example, when a host application is DPI aware but it allows user DLL plugins running in sub-threads that may or may not be DPI-aware.
Furthermore, a window receives a DPI_AWARENESS context when it is created, based on the DPI_AWARENESS of the calling thread. Microsoft says this very clearly in [1], “When a window is created, its DPI awareness is defined as the DPI awareness of the calling thread at that time.”
I have found that using NVIDIA driver 561.09 on Windows 11 (fully updated) that the vkGetPhysicalDeviceSurfaceCapabilitiesKHR() function is NOT correctly honoring the DPI_AWARENESS of the HWND window attached to the Vulkan swap chain. It is applying the DPI_AWARENESS of the current thread, not of the window, which is incorrect behavior: it should respect the window’s DPI_AWARENESS regardless of the calling thread/process.
This can be reproduced by creating a process and calling:
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE)
Then, creating a new thread and in that thread calling:
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
And then creating an HWND via CreateWindowEx(). This window will have the per-monitor-aware DPI context. Set its position/size with MoveWindow().
Then, back on the main thread, or another subthread with the process-wide DPI unawareness, create a Vulkan swap chain and then call vkGetPhysicalDeviceSurfaceCapabilitiesKHR() to get its extent.
Examining the Vulkan surface extent, you’ll find that it is in logical coordinates, instead of physical pixel coordinates, which is incorrect because the window is DPI-aware.
It seems like this perhaps also affects the OpenGL api [2]. (?)
[1] Mixed-Mode DPI Scaling and DPI-aware APIs - Win32 apps | Microsoft Learn
[2] High-DPI scaling bug with NVIDIA drivers and OpenGL on Windows 10 - #4 by emezeske