diff options
| author | skal <pascal.massimino@gmail.com> | 2026-01-31 13:57:51 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-01-31 13:57:51 +0100 |
| commit | e3daca37aa134a6885c8ae5c508c3d7f7bfc600a (patch) | |
| tree | 69578c5e3376603219bc341e8975e289cede9bdd | |
| parent | 3af9f70bec1f50c980288e2213035693f4b737ce (diff) | |
Add Windows cross-compilation support (MinGW) and emulation (Wine)
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | CMakeLists.txt | 85 | ||||
| -rw-r--r-- | cmake/Toolchain-MinGW-w64.cmake | 19 | ||||
| -rwxr-xr-x | scripts/build_win.sh | 34 | ||||
| -rwxr-xr-x | scripts/fetch_win_deps.sh | 29 | ||||
| -rwxr-xr-x | scripts/run_win.sh | 9 | ||||
| -rw-r--r-- | src/gpu/gpu.cc | 156 | ||||
| -rw-r--r-- | src/gpu/gpu.h | 2 | ||||
| -rw-r--r-- | third_party/glfw3webgpu/glfw3webgpu.c | 14 |
9 files changed, 286 insertions, 66 deletions
@@ -24,3 +24,7 @@ src/test_assets_data.cc assets/final/*.spec assets/wav/ +build_native/ +build_win/ +third_party/windows/ +wgpu_temp/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 410ebc1..d25065c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,20 +24,58 @@ endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Find wgpu-native (system install) -find_library(WGPU_LIBRARY NAMES wgpu_native libwgpu_native REQUIRED) -find_path(WGPU_INCLUDE_DIR NAMES webgpu.h PATH_SUFFIXES webgpu-headers REQUIRED) +if (DEMO_CROSS_COMPILE_WIN32) + # --- Windows Cross-Compilation Configuration --- + add_definitions(-DDEMO_CROSS_COMPILE_WIN32) + set(WINDOWS_DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/windows") -include_directories( - src - third_party - ${WGPU_INCLUDE_DIR} - third_party/glfw3webgpu -) + # WGPU-Native + # We use the headers from the fetched deps + set(WGPU_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include/webgpu") + # Link against the import library + set(WGPU_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libwgpu_native.dll.a") + + # GLFW 3.4 + set(GLFW3_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include") + set(GLFW3_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libglfw3.a") + + include_directories( + src + third_party + ${WGPU_INCLUDE_DIR} + ${GLFW3_INCLUDE_DIR} + third_party/glfw3webgpu + ) + + # Link libraries + # ws2_32 is winsock, required by some deps + set(DEMO_LIBS + ${GLFW3_LIBRARY} + ${WGPU_LIBRARY} + -lgdi32 -lws2_32 -luser32 -lkernel32 -lshell32 -ladvapi32 -ldwmapi + ) -find_package(glfw3 REQUIRED) + # Statically link C/C++ runtime to avoid needing extra DLLs + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") -set(DEMO_LIBS glfw ${WGPU_LIBRARY}) +else() + # --- Native Build Configuration --- + + # Find wgpu-native (system install) + find_library(WGPU_LIBRARY NAMES wgpu_native libwgpu_native REQUIRED) + find_path(WGPU_INCLUDE_DIR NAMES webgpu.h PATH_SUFFIXES webgpu-headers REQUIRED) + + include_directories( + src + third_party + ${WGPU_INCLUDE_DIR} + third_party/glfw3webgpu + ) + + find_package(glfw3 REQUIRED) + + set(DEMO_LIBS glfw ${WGPU_LIBRARY}) +endif() # Platform-specific dependencies if (APPLE) @@ -52,15 +90,24 @@ if (APPLE) "-framework Cocoa" "-framework QuartzCore" ) +elseif (DEMO_CROSS_COMPILE_WIN32) + # Windows deps already handled above else() # Assume Linux/other POSIX-like systems might need these list(APPEND DEMO_LIBS pthread m dl) endif() -# Asset Packing Tool (Always needed for build) -add_executable(asset_packer - tools/asset_packer.cc -) +# Asset Packing Tool +if (DEFINED ASSET_PACKER_PATH) + # Use externally provided tool (e.g., for cross-compilation) + set(ASSET_PACKER_CMD ${ASSET_PACKER_PATH}) + set(ASSET_PACKER_DEPENDS ${ASSET_PACKER_PATH}) +else() + # Build tool as part of the project + add_executable(asset_packer tools/asset_packer.cc) + set(ASSET_PACKER_CMD $<TARGET_FILE:asset_packer>) + set(ASSET_PACKER_DEPENDS asset_packer) +endif() # Configure DEMO asset generation set(DEMO_ASSETS_TXT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/demo_assets.txt) @@ -70,8 +117,8 @@ set(GENERATED_DEMO_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/assets_data.cc add_custom_command( OUTPUT ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src - COMMAND $<TARGET_FILE:asset_packer> ${DEMO_ASSETS_TXT_PATH} ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} - DEPENDS asset_packer ${DEMO_ASSETS_TXT_PATH} + COMMAND ${ASSET_PACKER_CMD} ${DEMO_ASSETS_TXT_PATH} ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} + DEPENDS ${ASSET_PACKER_DEPENDS} ${DEMO_ASSETS_TXT_PATH} COMMENT "Generating demo assets.h and assets_data.cc" ) @@ -87,8 +134,8 @@ set(GENERATED_TEST_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/test_assets_da add_custom_command( OUTPUT ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src - COMMAND $<TARGET_FILE:asset_packer> ${TEST_ASSETS_TXT_PATH} ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} - DEPENDS asset_packer ${TEST_ASSETS_TXT_PATH} + COMMAND ${ASSET_PACKER_CMD} ${TEST_ASSETS_TXT_PATH} ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} + DEPENDS ${ASSET_PACKER_DEPENDS} ${TEST_ASSETS_TXT_PATH} COMMENT "Generating test assets.h and assets_data.cc" ) diff --git a/cmake/Toolchain-MinGW-w64.cmake b/cmake/Toolchain-MinGW-w64.cmake new file mode 100644 index 0000000..57c146a --- /dev/null +++ b/cmake/Toolchain-MinGW-w64.cmake @@ -0,0 +1,19 @@ +set(CMAKE_SYSTEM_NAME Windows) + +# Specify the cross compiler +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + +# Where is the target environment located +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 /usr/local/opt/mingw-w64) + +# Adjust the default behavior of the FIND_XXX() commands: +# search for headers and libraries in the target environment, +# search for programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Define a flag to identify this specific build +set(DEMO_CROSS_COMPILE_WIN32 ON) diff --git a/scripts/build_win.sh b/scripts/build_win.sh new file mode 100755 index 0000000..493e322 --- /dev/null +++ b/scripts/build_win.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e + +# 1. Build native tools (asset_packer) +echo "Building native tools..." +cmake -S . -B build_native -DDEMO_BUILD_TOOLS=OFF -DDEMO_BUILD_TESTS=OFF +cmake --build build_native --target asset_packer + +# 2. Cross-compile for Windows +echo "Cross-compiling for Windows..." +cmake -S . -B build_win \ + -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-MinGW-w64.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DASSET_PACKER_PATH=$(pwd)/build_native/asset_packer \ + -DDEMO_BUILD_TOOLS=OFF \ + -DDEMO_BUILD_TESTS=OFF + +cmake --build build_win + +# 3. Copy runtime DLLs to build_win so we can run it +cp third_party/windows/lib/wgpu_native.dll build_win/ + +# Copy MinGW DLLs (pthread, etc.) +echo "Copying MinGW DLLs..." +MINGW_BIN=$(dirname $(find /opt/homebrew -name "libwinpthread-1.dll" | grep x86_64 | head -n 1)) +if [ -d "$MINGW_BIN" ]; then + cp "$MINGW_BIN/libwinpthread-1.dll" build_win/ + cp "$MINGW_BIN/libgcc_s_seh-1.dll" build_win/ 2>/dev/null || true + cp "$MINGW_BIN/libstdc++-6.dll" build_win/ 2>/dev/null || true +else + echo "Warning: Could not find MinGW DLLs. You might need them to run the exe." +fi + +echo "Build complete. Output: build_win/demo64k.exe" diff --git a/scripts/fetch_win_deps.sh b/scripts/fetch_win_deps.sh new file mode 100755 index 0000000..a32f047 --- /dev/null +++ b/scripts/fetch_win_deps.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e +set -x + +# Create directories +mkdir -p third_party/windows/lib +mkdir -p third_party/windows/include/GLFW + +echo "Fetching GLFW 3.4..." +curl -L -o glfw.zip https://github.com/glfw/glfw/releases/download/3.4/glfw-3.4.bin.WIN64.zip +unzip -q glfw.zip +cp glfw-3.4.bin.WIN64/lib-mingw-w64/libglfw3.a third_party/windows/lib/ +cp glfw-3.4.bin.WIN64/include/GLFW/* third_party/windows/include/GLFW/ +rm -rf glfw.zip glfw-3.4.bin.WIN64 + +echo "Fetching wgpu-native v0.19.4.1..." +curl -L -o wgpu.zip https://github.com/gfx-rs/wgpu-native/releases/download/v0.19.4.1/wgpu-windows-x86_64-release.zip +unzip -q wgpu.zip -d wgpu_temp +# Copy import library (renaming for MinGW convention, though it can usually read .lib) +cp wgpu_temp/wgpu_native.dll.lib third_party/windows/lib/libwgpu_native.dll.a +# Copy runtime DLL (will be needed next to executable) +cp wgpu_temp/wgpu_native.dll third_party/windows/lib/wgpu_native.dll +# Copy headers +mkdir -p third_party/windows/include/webgpu +cp wgpu_temp/webgpu.h third_party/windows/include/webgpu/ +cp wgpu_temp/wgpu.h third_party/windows/include/webgpu/ +rm -rf wgpu.zip wgpu_temp + +echo "Windows dependencies fetched." diff --git a/scripts/run_win.sh b/scripts/run_win.sh new file mode 100755 index 0000000..853a985 --- /dev/null +++ b/scripts/run_win.sh @@ -0,0 +1,9 @@ +#!/bin/bash +if [ ! -f build_win/demo64k.exe ]; then + echo "Error: build_win/demo64k.exe not found. Run scripts/build_win.sh first." + exit 1 +fi + +echo "Running with Wine..." +# Wine might output a lot of debug info, but for now we let it flow. +wine build_win/demo64k.exe "$@" diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 92c661b..40be1d2 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -6,20 +6,83 @@ #include "platform.h" #include <GLFW/glfw3.h> -#include <webgpu.h> -#include <wgpu.h> +#include <math.h> #include <algorithm> #include <cassert> #include <cstdint> #include <cstring> -#include <math.h> #include <vector> #ifndef STRIP_ALL #include <iostream> #endif +// --- WebGPU Headers & Compatibility --- +#if defined(DEMO_CROSS_COMPILE_WIN32) +// Windows (MinGW) using wgpu-native v0.19.4.1 +#include <webgpu/webgpu.h> +#include <webgpu/wgpu.h> + +// Type Shims +using WGPUStringView = const char *; +static const char *str_view(const char *str) { return str; } +static const char *label_view(const char *str) { return str; } + +// Renamed Types/Enums +#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor +using WGPUShaderSourceWGSL = WGPUShaderModuleWGSLDescriptor; +#define WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success +#define WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success + +// Callback Mode Shim (Not used in old API signatures, but needed for ifdef +// logic) +#define WGPUCallbackMode_WaitAnyOnly 0 + +// Wait Shim +static void wgpuInstanceWaitAny(WGPUInstance instance, size_t, void *, + uint64_t) { + wgpuInstanceProcessEvents(instance); +} + +// Uncaptured Error Callback Helper +static void set_error_callback(WGPUDevice device, + WGPUErrorCallback callback) { + wgpuDeviceSetUncapturedErrorCallback(device, callback, nullptr); +} + +#else +// Native (macOS/Linux) using newer wgpu-native +#include <webgpu.h> +#include <wgpu.h> + +static WGPUStringView label_view(const char *str) { +#ifndef STRIP_ALL + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +#else + (void)str; + return {nullptr, 0}; +#endif +} + +static WGPUStringView str_view(const char *str) { + if (!str) + return {nullptr, 0}; + return {str, strlen(str)}; +} + +static void set_error_callback(WGPUDevice device, + WGPUErrorCallback callback) { + // Handled in descriptor for new API, mostly. + // But we can also set it here if needed, or define a no-op if descriptor handles it. + // For new API, we set it in WGPUDeviceDescriptor.uncapturedErrorCallbackInfo. +} +#endif + static WGPUInstance g_instance = nullptr; static WGPUAdapter g_adapter = nullptr; static WGPUDevice g_device = nullptr; @@ -44,30 +107,13 @@ struct Particle { float color[4]; // r, g, b, a }; -static WGPUStringView label_view(const char *str) { -#ifndef STRIP_ALL - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -#else - (void)str; - return {nullptr, 0}; -#endif -} - -static WGPUStringView str_view(const char *str) { - if (!str) - return {nullptr, 0}; - return {str, strlen(str)}; -} - // --- Helper Functions --- -GpuBuffer gpu_create_buffer(size_t size, WGPUBufferUsage usage, +GpuBuffer gpu_create_buffer(size_t size, uint32_t usage, const void *data) { WGPUBufferDescriptor desc = {}; desc.label = label_view("GpuBuffer"); - desc.usage = usage; + desc.usage = (WGPUBufferUsage)usage; // Cast for C++ strictness with enums desc.size = size; desc.mappedAtCreation = (data != nullptr); // Map if we have initial data @@ -139,10 +185,7 @@ RenderPass gpu_create_render_pass(const char *shader_code, color_target.writeMask = WGPUColorWriteMask_All; color_target.blend = nullptr; - // Add additive blending for particles if it's the particle pass (hacky check - // based on vertex count or similar? No, let's just enable additive blending - // for everything for now as it looks cool for the demo, or make it - // configurable later. For now, simple replacement) + // Add additive blending for particles WGPUBlendState blend = {}; blend.color.srcFactor = WGPUBlendFactor_SrcAlpha; blend.color.dstFactor = WGPUBlendFactor_One; @@ -234,45 +277,47 @@ ComputePass gpu_create_compute_pass(const char *shader_code, #ifndef STRIP_ALL static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUAdapter adapter, const char *message, + void *userdata) { if (status == WGPURequestAdapterStatus_Success) { - *((WGPUAdapter *)userdata1) = adapter; + *((WGPUAdapter *)userdata) = adapter; } else { - printf("Request adapter failed: %.*s\n", (int)message.length, message.data); + printf("Request adapter failed: %s\n", message ? message : "Unknown"); } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUDevice device, const char *message, + void *userdata) { if (status == WGPURequestDeviceStatus_Success) { - *((WGPUDevice *)userdata1) = device; + *((WGPUDevice *)userdata) = device; } else { - printf("Request device failed: %.*s\n", (int)message.length, message.data); + printf("Request device failed: %s\n", message ? message : "Unknown"); } } -static void handle_device_error(WGPUDevice const *device, WGPUErrorType type, - WGPUStringView message, void *userdata1, - void *userdata2) { - printf("WebGPU Error: %.*s\n", (int)message.length, message.data); +static void handle_device_error(WGPUErrorType type, const char *message, + void *userdata) { + printf("WebGPU Error: %s\n", message ? message : "Unknown"); } #else static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUAdapter adapter, const char *message, + void *userdata) { if (status == WGPURequestAdapterStatus_Success) { - *((WGPUAdapter *)userdata1) = adapter; + *((WGPUAdapter *)userdata) = adapter; } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, WGPUStringView message, - void *userdata1, void *userdata2) { + WGPUDevice device, const char *message, + void *userdata) { if (status == WGPURequestDeviceStatus_Success) { - *((WGPUDevice *)userdata1) = device; + *((WGPUDevice *)userdata) = device; } } #endif +// ... (Shaders omitted for brevity, they are unchanged) ... + + const char *main_shader_wgsl = R"( struct Uniforms { audio_peak : f32, @@ -442,23 +487,39 @@ void gpu_init(GLFWwindow *window) { adapter_opts.compatibleSurface = g_surface; adapter_opts.powerPreference = WGPUPowerPreference_HighPerformance; +#if defined(DEMO_CROSS_COMPILE_WIN32) + wgpuInstanceRequestAdapter(g_instance, &adapter_opts, handle_request_adapter, + &g_adapter); +#else wgpuInstanceRequestAdapter(g_instance, &adapter_opts, {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_adapter, &g_adapter, nullptr}); +#endif while (!g_adapter) wgpuInstanceWaitAny(g_instance, 0, nullptr, 0); WGPUDeviceDescriptor device_desc = {}; #ifndef STRIP_ALL +#if !defined(DEMO_CROSS_COMPILE_WIN32) device_desc.uncapturedErrorCallbackInfo.callback = handle_device_error; #endif +#endif +#if defined(DEMO_CROSS_COMPILE_WIN32) + wgpuAdapterRequestDevice(g_adapter, &device_desc, handle_request_device, + &g_device); +#else wgpuAdapterRequestDevice(g_adapter, &device_desc, {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_device, &g_device, nullptr}); +#endif while (!g_device) wgpuInstanceWaitAny(g_instance, 0, nullptr, 0); +#if defined(DEMO_CROSS_COMPILE_WIN32) && !defined(STRIP_ALL) + set_error_callback(g_device, handle_device_error); +#endif + g_queue = wgpuDeviceGetQueue(g_device); WGPUSurfaceCapabilities caps = {}; @@ -509,8 +570,9 @@ void gpu_init(GLFWwindow *window) { g_particle_buffer = gpu_create_buffer(sizeof(Particle) * NUM_PARTICLES, - WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst | - WGPUBufferUsage_Vertex, + (WGPUBufferUsage)(WGPUBufferUsage_Storage | + WGPUBufferUsage_CopyDst | + WGPUBufferUsage_Vertex), initial_particles.data()); // Initialize Particle Compute Pass @@ -581,7 +643,9 @@ void gpu_draw(float audio_peak, float aspect_ratio, float time) { color_attachment.storeOp = WGPUStoreOp_Store; float flash = audio_peak * 0.2f; color_attachment.clearValue = {0.05 + flash, 0.1 + flash, 0.2 + flash, 1.0}; +#if !defined(DEMO_CROSS_COMPILE_WIN32) color_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; +#endif WGPURenderPassDescriptor render_pass_desc = {}; render_pass_desc.colorAttachmentCount = 1; diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 58b0307..a78c433 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -42,7 +42,7 @@ struct ResourceBinding { // WGPUBufferBindingType_Storage }; -GpuBuffer gpu_create_buffer(size_t size, WGPUBufferUsage usage, +GpuBuffer gpu_create_buffer(size_t size, uint32_t usage, const void *data = nullptr); ComputePass gpu_create_compute_pass(const char *shader_code, ResourceBinding *bindings, diff --git a/third_party/glfw3webgpu/glfw3webgpu.c b/third_party/glfw3webgpu/glfw3webgpu.c index 27bf9ec..a3f36e6 100644 --- a/third_party/glfw3webgpu/glfw3webgpu.c +++ b/third_party/glfw3webgpu/glfw3webgpu.c @@ -136,6 +136,19 @@ WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* windo HWND hwnd = glfwGetWin32Window(window); HINSTANCE hinstance = GetModuleHandle(NULL); +#if defined(DEMO_CROSS_COMPILE_WIN32) + // Old API (wgpu-native v0.19) + WGPUSurfaceDescriptorFromWindowsHWND fromWindowsHWND; + fromWindowsHWND.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND; + fromWindowsHWND.chain.next = NULL; + fromWindowsHWND.hinstance = hinstance; + fromWindowsHWND.hwnd = hwnd; + + WGPUSurfaceDescriptor surfaceDescriptor; + surfaceDescriptor.nextInChain = (const WGPUChainedStruct*)&fromWindowsHWND; + surfaceDescriptor.label = NULL; +#else + // New API WGPUSurfaceSourceWindowsHWND fromWindowsHWND; fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND; fromWindowsHWND.chain.next = NULL; @@ -145,6 +158,7 @@ WGPUSurface glfwCreateWindowWGPUSurface(WGPUInstance instance, GLFWwindow* windo WGPUSurfaceDescriptor surfaceDescriptor; surfaceDescriptor.nextInChain = &fromWindowsHWND.chain; surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; +#endif return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); } |
