From e72c915a56856e59507cb15ad34c5c74fcb5cc57 Mon Sep 17 00:00:00 2001 From: Elie Michel Date: Mon, 22 Apr 2024 21:58:51 +0200 Subject: [PATCH 1/2] Adapt example_glfw_wgpu to wgpu-native --- backends/imgui_impl_wgpu.h | 2 +- examples/example_glfw_wgpu/CMakeLists.txt | 52 ++--- examples/example_glfw_wgpu/FetchGLFW.cmake | 27 +++ .../example_glfw_wgpu/FetchGLFW3WebGPU.cmake | 16 ++ .../example_glfw_wgpu/FetchWgpuNative.cmake | 211 ++++++++++++++++++ examples/example_glfw_wgpu/main.cpp | 112 ++++++---- 6 files changed, 336 insertions(+), 84 deletions(-) create mode 100644 examples/example_glfw_wgpu/FetchGLFW.cmake create mode 100644 examples/example_glfw_wgpu/FetchGLFW3WebGPU.cmake create mode 100644 examples/example_glfw_wgpu/FetchWgpuNative.cmake diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index 2e19ea36ea9f..a3a4fca7394f 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -23,7 +23,7 @@ // Initialization data, for ImGui_ImplWGPU_Init() struct ImGui_ImplWGPU_InitInfo { - WGPUDevice Device; + WGPUDevice Device = nullptr; int NumFramesInFlight = 3; WGPUTextureFormat RenderTargetFormat = WGPUTextureFormat_Undefined; WGPUTextureFormat DepthStencilFormat = WGPUTextureFormat_Undefined; diff --git a/examples/example_glfw_wgpu/CMakeLists.txt b/examples/example_glfw_wgpu/CMakeLists.txt index e682836ddb58..fa5048135473 100644 --- a/examples/example_glfw_wgpu/CMakeLists.txt +++ b/examples/example_glfw_wgpu/CMakeLists.txt @@ -26,40 +26,9 @@ set(CMAKE_CXX_STANDARD 17) # Dawn requires C++17 set(IMGUI_DIR ../../) # Libraries -if(EMSCRIPTEN) - set(LIBRARIES glfw) - add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1) -else() - # Dawn wgpu desktop - set(DAWN_FETCH_DEPENDENCIES ON) - set(IMGUI_DAWN_DIR CACHE PATH "Path to Dawn repository") - if (NOT IMGUI_DAWN_DIR) - message(FATAL_ERROR "Please specify the Dawn repository by setting IMGUI_DAWN_DIR") - endif() - - option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" ON) - - # Dawn builds many things by default - disable things we don't need - option(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" OFF) - option(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" OFF) - option(TINT_BUILD_DOCS "Build documentation" OFF) - option(TINT_BUILD_TESTS "Build tests" OFF) - if (NOT APPLE) - option(TINT_BUILD_MSL_WRITER "Build the MSL output writer" OFF) - endif() - if(WIN32) - option(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" OFF) - option(TINT_BUILD_WGSL_READER "Build the WGSL input reader" ON) - option(TINT_BUILD_GLSL_WRITER "Build the GLSL output writer" OFF) - option(TINT_BUILD_GLSL_VALIDATOR "Build the GLSL output validator" OFF) - option(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" OFF) - option(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON) - endif() - - add_subdirectory("${IMGUI_DAWN_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/dawn" EXCLUDE_FROM_ALL) - - set(LIBRARIES webgpu_dawn webgpu_cpp webgpu_glfw glfw) -endif() +include(FetchGLFW3WebGPU.cmake) +include(FetchWgpuNative.cmake) +include(FetchGLFW.cmake) add_executable(example_glfw_wgpu main.cpp @@ -73,15 +42,26 @@ add_executable(example_glfw_wgpu ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp ) -target_include_directories(example_glfw_wgpu PUBLIC +target_include_directories(example_glfw_wgpu PRIVATE ${IMGUI_DIR} ${IMGUI_DIR}/backends ) -target_link_libraries(example_glfw_wgpu PUBLIC ${LIBRARIES}) +target_link_libraries(example_glfw_wgpu PRIVATE + webgpu + glfw + glfw3webgpu +) + +target_copy_webgpu_binaries(example_glfw_wgpu) # Emscripten settings if(EMSCRIPTEN) + target_compile_options(example_glfw_wgpu PRIVATE + -sDISABLE_EXCEPTION_CATCHING=1 + -DIMGUI_DISABLE_FILE_FUNCTIONS=1 + ) + target_link_options(example_glfw_wgpu PRIVATE "-sUSE_WEBGPU=1" "-sUSE_GLFW=3" diff --git a/examples/example_glfw_wgpu/FetchGLFW.cmake b/examples/example_glfw_wgpu/FetchGLFW.cmake new file mode 100644 index 000000000000..54146d94d332 --- /dev/null +++ b/examples/example_glfw_wgpu/FetchGLFW.cmake @@ -0,0 +1,27 @@ +include(FetchContent) + +if (TARGET glfw) + return() +endif() + +set(GLFW_VERSION "3.4" CACHE STRING "Version of GLFW to use. Must correspond to the tag name of an existing release on https://github.com/glfw/glfw") + +if (EMSCRIPTEN) + + add_library(glfw INTERFACE) + target_link_options(glfw INTERFACE + -sUSE_GLFW=3 + ) + +else (EMSCRIPTEN) + + set(URL "https://github.com/glfw/glfw/releases/download/${GLFW_VERSION}/glfw-${GLFW_VERSION}.zip") + FetchContent_Declare(glfw + URL "${URL}" + DOWNLOAD_EXTRACT_TIMESTAMP ON + ) + + message(STATUS "Downloading GLFW from '${URL}'") + FetchContent_MakeAvailable(glfw) + +endif (EMSCRIPTEN) diff --git a/examples/example_glfw_wgpu/FetchGLFW3WebGPU.cmake b/examples/example_glfw_wgpu/FetchGLFW3WebGPU.cmake new file mode 100644 index 000000000000..398ec871fa81 --- /dev/null +++ b/examples/example_glfw_wgpu/FetchGLFW3WebGPU.cmake @@ -0,0 +1,16 @@ +include(FetchContent) + +if (TARGET glfw3webgpu) + return() +endif() + +set(GLFW3WEBGPU_VERSION "v1.2.0" CACHE STRING "Version of GLFW to use. Must correspond to the tag name of an existing release on https://github.com/eliemichel/glfw3webgpu") + +set(URL "https://github.com/eliemichel/glfw3webgpu/releases/download/${GLFW3WEBGPU_VERSION}/glfw3webgpu-${GLFW3WEBGPU_VERSION}.zip") +FetchContent_Declare(glfw3webgpu + URL "${URL}" + DOWNLOAD_EXTRACT_TIMESTAMP ON +) + +message(STATUS "Downloading glfw3webgpu from '${URL}'") +FetchContent_MakeAvailable(glfw3webgpu) diff --git a/examples/example_glfw_wgpu/FetchWgpuNative.cmake b/examples/example_glfw_wgpu/FetchWgpuNative.cmake new file mode 100644 index 000000000000..fd9b042b122b --- /dev/null +++ b/examples/example_glfw_wgpu/FetchWgpuNative.cmake @@ -0,0 +1,211 @@ +# This file is part of the "Learn WebGPU for C++" book. +# https://eliemichel.github.io/LearnWebGPU +# https://github.com/eliemichel/WebGPU-distribution/blob/dev-fetch-wgpu/cmake/FetchWgpuNative.cmake +# +# MIT License +# Copyright (c) 2023-2024 Elie Michel and the wgpu-native authors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +include(FetchContent) + +if (TARGET webgpu) + return() +endif() + +set(WGPU_LINK_TYPE "DYNAMIC" CACHE STRING "Whether the wgpu-native WebGPU implementation must be statically or dynamically linked. Possible values are STATIC and DYNAMIC") +set(WGPU_VERSION "v0.19.4.1" CACHE STRING "Version of the wgpu-native WebGPU implementation to use. Must correspond to the tag name of an existing release on https://github.com/gfx-rs/wgpu-native/releases") + +if (EMSCRIPTEN) + + add_library(webgpu INTERFACE) + + target_include_directories(webgpu INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include-emscripten" + ) + + # This is used to advertise the flavor of WebGPU that this zip provides + target_compile_definitions(webgpu INTERFACE WEBGPU_BACKEND_EMSCRIPTEN) + + target_link_options(webgpu INTERFACE + -sUSE_WEBGPU # Handle WebGPU symbols + ) + + function(target_copy_webgpu_binaries Target) + endfunction() + +else (EMSCRIPTEN) + + if (NOT ARCH) + set(ARCH ${CMAKE_SYSTEM_PROCESSOR}) + if (ARCH STREQUAL "AMD64") + set(ARCH "x86_64") + endif() + endif() + + set(USE_DYNAMIC_LIB) + if (WGPU_LINK_TYPE STREQUAL "DYNAMIC") + set(USE_DYNAMIC_LIB TRUE) + elseif (WGPU_LINK_TYPE STREQUAL "STATIC") + set(USE_DYNAMIC_LIB FALSE) + else() + message(FATAL_ERROR "Link type '${WGPU_LINK_TYPE}'is not valid. Possible values for WGPU_LINK_TYPE are DYNAMIC and STATIC.") + endif() + + set(URL_OS) + set(BINARY_FILENAME) + if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + + set(URL_OS windows) + if (USE_DYNAMIC_LIB) + set(BINARY_FILENAME "wgpu_native.dll") + else() + set(BINARY_FILENAME "wgpu_native.lib") + endif() + + elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") + + set(URL_OS linux) + if (USE_DYNAMIC_LIB) + set(BINARY_FILENAME "libwgpu_native.so") + else() + set(BINARY_FILENAME "libwgpu_native.a") + endif() + + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + + set(URL_OS macos) + if (USE_DYNAMIC_LIB) + set(BINARY_FILENAME "libwgpu_native.dylib") + else() + set(BINARY_FILENAME "libwgpu_native.a") + endif() + + else() + + message(FATAL_ERROR "Platform system ${CMAKE_SYSTEM_NAME} not supported by this release of WebGPU. You may consider building it yourself from its source (see https://github.com/gfx-rs/wgpu-native)") + + endif() + + set(URL_ARCH) + if (ARCH STREQUAL "x86_64") + set(URL_ARCH "x86_64") + elseif (ARCH STREQUAL "aarch64" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(URL_ARCH "aarch64") + elseif (ARCH STREQUAL "i686" AND CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(URL_ARCH "i686") + else() + message(FATAL_ERROR "Platform architecture ${ARCH} not supported by this release of WebGPU. You may consider building it yourself from its source (see https://github.com/gfx-rs/wgpu-native)") + endif() + + set(URL_CONFIG release) + set(URL_NAME "wgpu-${URL_OS}-${URL_ARCH}-${URL_CONFIG}") + set(URL "https://github.com/gfx-rs/wgpu-native/releases/download/${WGPU_VERSION}/${URL_NAME}.zip") + + FetchContent_Declare(${URL_NAME} + URL ${URL} + DOWNLOAD_EXTRACT_TIMESTAMP ON + ) + message(STATUS "Downloading WebGPU runtime from '${URL}'") + FetchContent_MakeAvailable(${URL_NAME}) + set(ZIP_DIR "${${URL_NAME}_SOURCE_DIR}") + + # Fix folder layout + file(MAKE_DIRECTORY "${ZIP_DIR}/include/webgpu") + if (EXISTS "${ZIP_DIR}/webgpu.h") + file(RENAME "${ZIP_DIR}/webgpu.h" "${ZIP_DIR}/include/webgpu/webgpu.h") + endif() + if (EXISTS "${ZIP_DIR}/wgpu.h") + file(RENAME "${ZIP_DIR}/wgpu.h" "${ZIP_DIR}/include/webgpu/wgpu.h") + endif() + + # A pre-compiled target (IMPORTED) that is a dynamically + # linked library (SHARED, meaning .dll, .so or .dylib). + add_library(webgpu SHARED IMPORTED GLOBAL) + + # This is used to advertise the flavor of WebGPU that this zip provides + target_compile_definitions(webgpu INTERFACE WEBGPU_BACKEND_WGPU) + + set(WGPU_RUNTIME_LIB "${ZIP_DIR}/${BINARY_FILENAME}") + set_target_properties( + webgpu + PROPERTIES + IMPORTED_LOCATION "${WGPU_RUNTIME_LIB}" + INTERFACE_INCLUDE_DIRECTORIES "${ZIP_DIR}/include" + ) + + if (CMAKE_SYSTEM_NAME STREQUAL "Windows") + + set_target_properties( + webgpu + PROPERTIES + IMPORTED_IMPLIB "${WGPU_RUNTIME_LIB}.lib" + ) + + elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") + + set_target_properties( + webgpu + PROPERTIES + IMPORTED_NO_SONAME TRUE + ) + + endif() + + message(STATUS "Using WebGPU runtime from '${WGPU_RUNTIME_LIB}'") + #set(WGPU_RUNTIME_LIB ${WGPU_RUNTIME_LIB} PARENT_SCOPE) + set(WGPU_RUNTIME_LIB ${WGPU_RUNTIME_LIB} CACHE INTERNAL "Path to the WebGPU library binary") + + # The application's binary must find wgpu.dll or libwgpu.so at runtime, + # so we automatically copy it (it's called WGPU_RUNTIME_LIB in general) + # next to the binary. + # Also make sure that the binary's RPATH is set to find this shared library. + function(target_copy_webgpu_binaries Target) + add_custom_command( + TARGET ${Target} POST_BUILD + COMMAND + ${CMAKE_COMMAND} -E copy_if_different + ${WGPU_RUNTIME_LIB} + $ + COMMENT + "Copying '${WGPU_RUNTIME_LIB}' to '$'..." + ) + + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # Bug fix, there might be a cleaner way to do this but no INSTALL_RPATH + # or related target properties seem to be a solution. + set_target_properties(${Target} PROPERTIES INSTALL_RPATH "./") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(ARCH_DIR aarch64) + else() + set(ARCH_DIR ${CMAKE_SYSTEM_PROCESSOR}) + endif() + add_custom_command( + TARGET ${Target} POST_BUILD + COMMAND + ${CMAKE_INSTALL_NAME_TOOL} "-change" + "/Users/runner/work/wgpu-native/wgpu-native/target/${ARCH_DIR}-apple-darwin/release/deps/libwgpu_native.dylib" + "@executable_path/libwgpu_native.dylib" + "$" + VERBATIM + ) + endif() + endfunction() + +endif (EMSCRIPTEN) diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index 4e47b8323bd6..ade25850fc35 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -17,13 +17,15 @@ #include #include #include -#else -#include #endif #include #include -#include +#include + +#ifdef WEBGPU_BACKEND_WGPU +#include // for wgpuDevicePoll +#endif // This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details. #ifdef __EMSCRIPTEN__ @@ -35,13 +37,13 @@ static WGPUInstance wgpu_instance = nullptr; static WGPUDevice wgpu_device = nullptr; static WGPUSurface wgpu_surface = nullptr; static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm; -static WGPUSwapChain wgpu_swap_chain = nullptr; -static int wgpu_swap_chain_width = 1280; -static int wgpu_swap_chain_height = 720; +static int wgpu_surface_width = 1280; +static int wgpu_surface_height = 720; // Forward declarations static bool InitWGPU(GLFWwindow* window); -static void CreateSwapChain(int width, int height); +static void ConfigureSurface(int width, int height); +static WGPUTextureView GetCurrentSurfaceTextureView(); static void glfw_error_callback(int error, const char* description) { @@ -72,7 +74,7 @@ int main(int, char**) // Make sure GLFW does not initialize any graphics context. // This needs to be done explicitly later. glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* window = glfwCreateWindow(wgpu_swap_chain_width, wgpu_swap_chain_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr); + GLFWwindow* window = glfwCreateWindow(wgpu_surface_width, wgpu_surface_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr); if (window == nullptr) return 1; @@ -84,7 +86,7 @@ int main(int, char**) glfwTerminate(); return 1; } - CreateSwapChain(wgpu_swap_chain_width, wgpu_swap_chain_height); + ConfigureSurface(wgpu_surface_width, wgpu_surface_height); glfwShowWindow(window); // Setup Dear ImGui context @@ -155,10 +157,10 @@ int main(int, char**) // React to changes in screen size int width, height; glfwGetFramebufferSize((GLFWwindow*)window, &width, &height); - if (width != wgpu_swap_chain_width || height != wgpu_swap_chain_height) + if (width != wgpu_surface_width || height != wgpu_surface_height) { ImGui_ImplWGPU_InvalidateDeviceObjects(); - CreateSwapChain(width, height); + ConfigureSurface(width, height); ImGui_ImplWGPU_CreateDeviceObjects(); } @@ -207,17 +209,23 @@ int main(int, char**) // Rendering ImGui::Render(); -#ifndef __EMSCRIPTEN__ +#if defined(WEBGPU_BACKEND_DAWN) // Tick needs to be called in Dawn to display validation errors wgpuDeviceTick(wgpu_device); +#elif defined(WEBGPU_BACKEND_WGPU) + wgpuDevicePoll(wgpu_device, false, nullptr); +#elif defined(__EMSCRIPTEN__) + // Nothing to do #endif WGPURenderPassColorAttachment color_attachments = {}; +#ifndef WEBGPU_BACKEND_WGPU // not supported yet by wgpu-native color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; +#endif color_attachments.loadOp = WGPULoadOp_Clear; color_attachments.storeOp = WGPUStoreOp_Store; color_attachments.clearValue = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; - color_attachments.view = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain); + color_attachments.view = GetCurrentSurfaceTextureView(); WGPURenderPassDescriptor render_pass_desc = {}; render_pass_desc.colorAttachmentCount = 1; @@ -237,7 +245,7 @@ int main(int, char**) wgpuQueueSubmit(queue, 1, &cmd_buffer); #ifndef __EMSCRIPTEN__ - wgpuSwapChainPresent(wgpu_swap_chain); + wgpuSurfacePresent(wgpu_surface); #endif wgpuTextureViewRelease(color_attachments.view); @@ -292,54 +300,64 @@ static WGPUDevice RequestDevice(WGPUAdapter& adapter) static bool InitWGPU(GLFWwindow* window) { - wgpu::Instance instance = wgpuCreateInstance(nullptr); + WGPUInstance instance = wgpuCreateInstance(nullptr); #ifdef __EMSCRIPTEN__ + WGPUAdapter adapter = nullptr; wgpu_device = emscripten_webgpu_get_device(); - if (!wgpu_device) - return false; #else - WGPUAdapter adapter = RequestAdapter(instance.Get()); + WGPUAdapter adapter = RequestAdapter(instance); if (!adapter) return false; wgpu_device = RequestDevice(adapter); + wgpuAdapterRelease(adapter); #endif - -#ifdef __EMSCRIPTEN__ - wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {}; - html_surface_desc.selector = "#canvas"; - wgpu::SurfaceDescriptor surface_desc = {}; - surface_desc.nextInChain = &html_surface_desc; - wgpu::Surface surface = instance.CreateSurface(&surface_desc); - - wgpu::Adapter adapter = {}; - wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter); -#else - wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window); - if (!surface) + if (!wgpu_device) return false; - wgpu_preferred_fmt = WGPUTextureFormat_BGRA8Unorm; -#endif - wgpu_instance = instance.MoveToCHandle(); - wgpu_surface = surface.MoveToCHandle(); + wgpu_surface = glfwGetWGPUSurface(instance, window); + if (!wgpu_surface) + return false; + wgpu_preferred_fmt = wgpuSurfaceGetPreferredFormat(wgpu_surface, adapter); wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr); + wgpuInstanceRelease(instance); return true; } -static void CreateSwapChain(int width, int height) +static void ConfigureSurface(int width, int height) { - if (wgpu_swap_chain) - wgpuSwapChainRelease(wgpu_swap_chain); - wgpu_swap_chain_width = width; - wgpu_swap_chain_height = height; - WGPUSwapChainDescriptor swap_chain_desc = {}; - swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment; - swap_chain_desc.format = wgpu_preferred_fmt; - swap_chain_desc.width = width; - swap_chain_desc.height = height; - swap_chain_desc.presentMode = WGPUPresentMode_Fifo; - wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc); + wgpu_surface_width = width; + wgpu_surface_height = height; + WGPUSurfaceConfiguration surface_config = {}; + surface_config.device = wgpu_device; + surface_config.usage = WGPUTextureUsage_RenderAttachment; + surface_config.format = wgpu_preferred_fmt; + surface_config.width = width; + surface_config.height = height; + surface_config.viewFormatCount = 0; + surface_config.viewFormats = nullptr; + surface_config.presentMode = WGPUPresentMode_Fifo; + surface_config.alphaMode = WGPUCompositeAlphaMode_Auto; + wgpuSurfaceConfigure(wgpu_surface, &surface_config); +} + +static WGPUTextureView GetCurrentSurfaceTextureView() { + WGPUSurfaceTexture surfaceTexture; + wgpuSurfaceGetCurrentTexture(wgpu_surface, &surfaceTexture); + if (surfaceTexture.status != WGPUSurfaceGetCurrentTextureStatus_Success) { + return nullptr; + } + WGPUTextureViewDescriptor viewDescriptor; + viewDescriptor.nextInChain = nullptr; + viewDescriptor.label = "Surface texture view"; + viewDescriptor.format = wgpuTextureGetFormat(surfaceTexture.texture); + viewDescriptor.dimension = WGPUTextureViewDimension_2D; + viewDescriptor.baseMipLevel = 0; + viewDescriptor.mipLevelCount = 1; + viewDescriptor.baseArrayLayer = 0; + viewDescriptor.arrayLayerCount = 1; + viewDescriptor.aspect = WGPUTextureAspect_All; + return wgpuTextureCreateView(surfaceTexture.texture, &viewDescriptor); } From eee847e5f5c4899aa52e005002060d51821fce2b Mon Sep 17 00:00:00 2001 From: Elie Michel Date: Mon, 22 Apr 2024 22:13:19 +0200 Subject: [PATCH 2/2] Move device ticking to the beginning of main loop --- examples/example_glfw_wgpu/main.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index ade25850fc35..bcd03b0de25d 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -154,6 +154,16 @@ int main(int, char**) // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); + // Poll WebGPU events +#if defined(WEBGPU_BACKEND_DAWN) + // Tick needs to be called in Dawn to display validation errors + wgpuDeviceTick(wgpu_device); +#elif defined(WEBGPU_BACKEND_WGPU) + wgpuDevicePoll(wgpu_device, false, nullptr); +#elif defined(__EMSCRIPTEN__) + // Nothing to do +#endif + // React to changes in screen size int width, height; glfwGetFramebufferSize((GLFWwindow*)window, &width, &height); @@ -209,15 +219,6 @@ int main(int, char**) // Rendering ImGui::Render(); -#if defined(WEBGPU_BACKEND_DAWN) - // Tick needs to be called in Dawn to display validation errors - wgpuDeviceTick(wgpu_device); -#elif defined(WEBGPU_BACKEND_WGPU) - wgpuDevicePoll(wgpu_device, false, nullptr); -#elif defined(__EMSCRIPTEN__) - // Nothing to do -#endif - WGPURenderPassColorAttachment color_attachments = {}; #ifndef WEBGPU_BACKEND_WGPU // not supported yet by wgpu-native color_attachments.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;