ifcviewer-wgpu: wire Windows HWND surface creation

Without a Windows branch in `WgpuViewportWindow::createSurface()` we
were falling through to the `qWarning() << "wgpu surface creation not
yet wired for this platform"` else clause on Windows runs, causing
`init() -> createSurface()` to return false and the viewport to render
nothing (the user sees the Qt window's background fill — a white
viewport — and the log says "wgpu init failed; viewport will not
render in DebugView").

Add a `#elif defined(Q_OS_WIN)` branch that fills a
`WGPUSurfaceSourceWindowsHWND` chained-struct from
`GetModuleHandleW(nullptr)` (HINSTANCE) and `winId()` (HWND, as a Win32
window handle on the Qt Windows platform plugin), then passes it as
`surface_desc.nextInChain` to `wgpuInstanceCreateSurface`.

`<windows.h>` is pulled in inside the gated block with NOMINMAX and
WIN32_LEAN_AND_MEAN defined first so the preprocessor pollution
(`min`, `max`, etc.) doesn't leak into Eigen / `std::min`,`std::max`
elsewhere in the TU.

Note on the unrelated DXC log line the user also sees:

    [wgpu err] DxcCreateInstance failed:
    No such interface supported (0x80004002)

That is wgpu-native's DX12 backend probing for a modern
`dxcompiler.dll`. `E_NOINTERFACE` means a *too-old* dxcompiler.dll was
found on the system DLL search path (typical: a stale copy in
System32 / Visual Studio install). wgpu-native then falls back to its
Vulkan backend, so this log line is recoverable on its own — the
fatal failure was the missing surface branch above. If we hit shader
compilation issues after this lands, we can ship a known-good
dxcompiler.dll + dxil.dll alongside wgpu_native.dll separately.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-06-02 13:32:01 +10:00
parent 1b920e502f
commit d4d0c934b1
+22 -2
View File
@@ -1808,6 +1808,16 @@ bool WgpuViewportWindow::probeAndCreatePool() {
# if __has_include(<wayland-client-core.h>) # if __has_include(<wayland-client-core.h>)
# include <wayland-client-core.h> # include <wayland-client-core.h>
# endif # endif
#elif defined(Q_OS_WIN)
// HINSTANCE for the surface descriptor. NOMINMAX + LEAN_AND_MEAN keep
// <windows.h>'s preprocessor pollution out of Eigen / std::min,max.
# ifndef NOMINMAX
# define NOMINMAX
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
#endif #endif
bool WgpuViewportWindow::createSurface() { bool WgpuViewportWindow::createSurface() {
@@ -1852,9 +1862,19 @@ bool WgpuViewportWindow::createSurface() {
qWarning().noquote() << "Unsupported Qt platform for wgpu surface:" << platform; qWarning().noquote() << "Unsupported Qt platform for wgpu surface:" << platform;
return false; return false;
} }
#elif defined(Q_OS_WIN)
// wgpu-native maps WGPUSurfaceSourceWindowsHWND.hwnd to a Win32 HWND
// it never dereferences directly (it only hands the handle to D3D12 /
// Vulkan WSI). winId() is the HWND for top-level Qt windows on the
// Windows platform plugin, returned as WId (== quintptr).
WGPUSurfaceSourceWindowsHWND hwndsrc = {};
hwndsrc.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
hwndsrc.hinstance = ::GetModuleHandleW(nullptr);
hwndsrc.hwnd = reinterpret_cast<void*>(static_cast<uintptr_t>(winId()));
surface_desc.nextInChain = &hwndsrc.chain;
surface_ = wgpuInstanceCreateSurface(instance_, &surface_desc);
#else #else
// macOS / Windows native-handle wiring lands when those targets become // macOS Metal surface wiring lands with task #32.
// active. Stage-1 development happens on Linux.
qWarning() << "wgpu surface creation not yet wired for this platform"; qWarning() << "wgpu surface creation not yet wired for this platform";
return false; return false;
#endif #endif