├── .github ├── FUNDING.yml └── workflows │ └── cmake.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── examples ├── .gitignore ├── CMakeLists.txt ├── hello-sdl2webgpu.c └── utils.cmake ├── sdl2webgpu.c └── sdl2webgpu.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: eliemichel 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=DNEEF8GDX2EV6¤cy_code=EUR&source=url'] 15 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | 12 | jobs: 13 | build: 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | system: [ Linux-x64, Windows-MSVC-x64, Windows-MSYS-x64, MacOS-x64, MacOS-ARM ] 18 | webgpu-backend: [ DAWN, WGPU ] 19 | link-type: [ SHARED, STATIC ] 20 | build-type: [ Debug, Release ] 21 | 22 | include: 23 | - system: Linux-x64 24 | runner: ubuntu-latest 25 | install-deps: | 26 | sudo apt-get update -y 27 | sudo apt-get install -y libwayland-dev libxkbcommon-dev xorg-dev 28 | 29 | - system: Windows-MSVC-x64 30 | runner: windows-latest 31 | exe-extension: .exe 32 | is-multiconfig: true 33 | 34 | - system: Windows-MSYS-x64 35 | runner: windows-latest 36 | msystem: ucrt64 37 | exe-extension: .exe 38 | 39 | - system: MacOS-ARM 40 | runner: macos-latest 41 | 42 | - system: MacOS-x64 43 | runner: macos-13 44 | 45 | - system: emscripten 46 | runner: ubuntu-latest 47 | webgpu-backend: EMSCRIPTEN 48 | link-type: STATIC 49 | build-type: Release 50 | cmake-wrapper: emcmake 51 | emsdk-version: 4.0.5 52 | 53 | # Latest version of Dawn to not support static linking 54 | exclude: 55 | - webgpu-backend: DAWN 56 | link-type: STATIC 57 | 58 | runs-on: ${{ matrix.runner }} 59 | 60 | steps: 61 | - uses: actions/checkout@v4 62 | 63 | - name: Install dependencies 64 | if: ${{ matrix.install-deps }} 65 | run: ${{ matrix.install-deps }} 66 | 67 | - name: Setup MSYS 68 | if: ${{ matrix.msystem }} 69 | uses: msys2/setup-msys2@v2 70 | with: 71 | msystem: ${{ matrix.msystem }} 72 | pacboy: >- 73 | toolchain:p 74 | cmake:p 75 | ninja:p 76 | 77 | - name: Setup emscripten 78 | if: ${{ matrix.emsdk-version }} 79 | uses: mymindstorm/setup-emsdk@v14 80 | with: 81 | version: ${{ matrix.emsdk-version }} 82 | 83 | - name: Configure CMake 84 | if: ${{ ! matrix.msystem }} 85 | run: > 86 | ${{ matrix.cmake-wrapper }} cmake 87 | -S examples 88 | -B build 89 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }} 90 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }} 91 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} 92 | 93 | - name: Build 94 | if: ${{ ! matrix.msystem }} 95 | run: > 96 | cmake 97 | --build build 98 | --config ${{ matrix.build-type }} 99 | 100 | # This is a hack to work around the lack of ${{ variables }} in 'shell' parameter 101 | # We use the SHELL env variable as the value of 'shell' 102 | - name: Configure CMake (MSYS) 103 | if: ${{ matrix.msystem }} 104 | shell: msys2 {0} 105 | run: > 106 | ${{ matrix.cmake-wrapper }} cmake 107 | -S examples 108 | -B build 109 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }} 110 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }} 111 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} 112 | 113 | - name: Build (MSYS) 114 | if: ${{ matrix.msystem }} 115 | shell: msys2 {0} 116 | run: > 117 | cmake 118 | --build build 119 | --config ${{ matrix.build-type }} 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | releases/ 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This is only meant to be included as a subdirectory in another project. 2 | # It assumes that targets 'SDL2' and 'webgpu' exist. 3 | # Look at examples/CMakeLists.txt to see how to use it in a project. 4 | 5 | # The sdl2webgpu target 6 | add_library(sdl2webgpu STATIC sdl2webgpu.c) 7 | target_include_directories(sdl2webgpu PUBLIC .) 8 | target_link_libraries(sdl2webgpu PUBLIC SDL2::SDL2 webgpu) 9 | 10 | if (APPLE) 11 | target_compile_options(sdl2webgpu PRIVATE -x objective-c) 12 | target_link_libraries(sdl2webgpu PRIVATE "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore") 13 | 14 | if (IOS) 15 | target_link_libraries(sdl2webgpu PRIVATE "-framework UIKit") 16 | else() 17 | target_link_libraries(sdl2webgpu PRIVATE "-framework Cocoa") 18 | endif() 19 | endif() 20 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2022-2024 Élie Michel 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CMake Badge 2 | 3 |
4 | 5 | 6 | 7 | Learn WebGPU Logo 8 | 9 | 10 | LearnWebGPU  |  WebGPU-C++  |  WebGPU-distribution
11 | glfw3webgpu  |  sdl2webgpu  |  sdl3webgpu 12 | 13 | Discord | Join us! 14 |
15 | 16 | 17 | SDL2 WebGPU Extension 18 | ===================== 19 | 20 | This is an extension for the great [SDL2](https://wiki.libsdl.org/SDL2/FrontPage) library for using it with **WebGPU native**. It was written as part of the [Learn WebGPU for native C++](https://eliemichel.github.io/LearnWebGPU) tutorial series. 21 | 22 | Table of Contents 23 | ----------------- 24 | 25 | - [Overview](#overview) 26 | - [Usage](#usage) 27 | - [Example](#example) 28 | - [License](#license) 29 | 30 | Overview 31 | -------- 32 | 33 | This extension simply provides the following function: 34 | 35 | ```C 36 | WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window); 37 | ``` 38 | 39 | Given an SDL window, `SDL_GetWGPUSurface` returns a WebGPU *surface* that corresponds to the window's backend. This is a process that is highly platform-specific, which is why I believe it belongs to SDL. 40 | 41 | Usage 42 | ----- 43 | 44 | Your project must link to an implementation of WebGPU (providing `webgpu.h`) and of course to SDL. Then: 45 | 46 | **Option A** If you use CMake, you can simply include this project as a subdirectory with `add_subdirectory(sdl2webgpu)` (see the content of [`CMakeLists.txt`](CMakeLists.txt)). 47 | 48 | **Option B** Just copy [`sdl2webgpu.h`](sdl2webgpu.h) and [`sdl2webgpu.c`](sdl2webgpu.c) to your project's source tree. On MacOS, you must add the compile option `-x objective-c` and the link libraries `-framework Cocoa`, `-framework CoreVideo`, `-framework IOKit`, and `-framework QuartzCore`. For iOS, do similarly but use `-framework UIKit` instead of `-framework Cocoa`. 49 | 50 | Example 51 | ------- 52 | 53 | Thanks to this extension it is possible to simply write a fully cross-platform WebGPU hello world: 54 | 55 | ```C 56 | #define SDL_MAIN_HANDLED 57 | #include "sdl2webgpu.h" 58 | #include 59 | #include 60 | #include 61 | 62 | int main(int argc, char* argv[]) { 63 | // Init WebGPU 64 | WGPUInstanceDescriptor desc; 65 | desc.nextInChain = NULL; 66 | WGPUInstance instance = wgpuCreateInstance(&desc); 67 | 68 | // Init SDL 69 | SDL_Init(SDL_INIT_VIDEO); 70 | SDL_Window *window = SDL_CreateWindow("Learn WebGPU", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); 71 | 72 | // Here we create our WebGPU surface from the window! 73 | WGPUSurface surface = SDL_GetWGPUSurface(instance, window); 74 | printf("surface = %p", surface); 75 | 76 | // Wait for close 77 | SDL_Event event; 78 | while (1) 79 | while (SDL_PollEvent(&event)) 80 | if (event.type == SDL_QUIT) 81 | break; 82 | // Terminate SDL 83 | SDL_DestroyWindow(window); 84 | SDL_Quit(); 85 | 86 | return 0; 87 | } 88 | ``` 89 | 90 | **NB** The linking process depends on the implementation of WebGPU that you are using. You can find detailed instructions for the `wgpu-native` implementation in [this Hello WebGPU chapter](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html). You may also check out [`examples/CMakeLists.txt`](examples/CMakeLists.txt). 91 | 92 | License 93 | ------- 94 | 95 | See [LICENSE.txt](LICENSE.txt). 96 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | webgpu/ 3 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This example comes from https://eliemichel.github.io/LearnWebGPU 2 | cmake_minimum_required(VERSION 3.11.0...3.25.0) 3 | project(sdl2webgpu-examples VERSION 1.0.0 LANGUAGES C) 4 | 5 | include(FetchContent) 6 | include(utils.cmake) 7 | 8 | # Dependencies 9 | if (EMSCRIPTEN) 10 | 11 | add_library(SDL2_SDL2 INTERFACE) 12 | target_compile_options(SDL2_SDL2 INTERFACE --use-port=sdl2) 13 | target_link_options(SDL2_SDL2 INTERFACE --use-port=sdl2) 14 | add_library(SDL2::SDL2 ALIAS SDL2_SDL2) 15 | function(target_copy_sdl2_binaries) 16 | endfunction() 17 | 18 | add_library(webgpu INTERFACE) 19 | target_link_options(webgpu INTERFACE -sUSE_WEBGPU=1) 20 | function(target_copy_webgpu_binaries) 21 | endfunction() 22 | 23 | else() 24 | 25 | FetchContent_Declare( 26 | sdl2 27 | URL https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.32.2.zip 28 | URL_HASH MD5=c38041ed63bdc9be67982adb746b8635 29 | ) 30 | FetchContent_Declare( 31 | webgpu 32 | URL https://github.com/eliemichel/WebGPU-distribution/archive/refs/tags/main-v0.3.0-alpha.zip 33 | URL_HASH MD5=ea1195dc6c7661c36aa13ea5b734b86e 34 | ) 35 | FetchContent_MakeAvailable(sdl2 webgpu) 36 | 37 | function(target_copy_sdl2_binaries Target) 38 | add_custom_command( 39 | TARGET ${Target} 40 | POST_BUILD 41 | COMMAND 42 | ${CMAKE_COMMAND} 43 | -E copy_if_different 44 | $ 45 | $ 46 | ) 47 | endfunction() 48 | 49 | endif() 50 | 51 | # The sdl2webgpu target 52 | # NB: We specify a second argument only because this is an out-of-tree 53 | # directory, no need to do this in your case. 54 | add_subdirectory(.. sdl2webgpu) 55 | 56 | # Example 57 | add_executable(hello-sdl2webgpu hello-sdl2webgpu.c) 58 | target_link_libraries(hello-sdl2webgpu PRIVATE SDL2::SDL2 webgpu sdl2webgpu) 59 | set_target_properties(hello-sdl2webgpu PROPERTIES CXX_STANDARD 17) 60 | target_treat_all_warnings_as_errors(hello-sdl2webgpu) 61 | 62 | # Copy wgpu-native or Dawn dll/so/dylib next to the executable 63 | target_copy_webgpu_binaries(hello-sdl2webgpu) 64 | # Copy SDL2.dll/so/dylib next to the executable 65 | target_copy_sdl2_binaries(hello-sdl2webgpu) 66 | -------------------------------------------------------------------------------- /examples/hello-sdl2webgpu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL2 for WebGPU, abstracting away the details of 3 | * OS-specific operations. 4 | * 5 | * This file is part of the "Learn WebGPU for C++" book. 6 | * https://eliemichel.github.io/LearnWebGPU 7 | * 8 | * MIT License 9 | * Copyright (c) 2022-2024 Elie Michel 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in all 19 | * copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | * SOFTWARE. 28 | */ 29 | 30 | #define SDL_MAIN_HANDLED 31 | #include "sdl2webgpu.h" 32 | #include 33 | #include 34 | #include 35 | 36 | int main(int argc, char* argv[]) { 37 | (void)argc; 38 | (void)argv; 39 | 40 | // Init WebGPU 41 | WGPUInstanceDescriptor desc; 42 | desc.nextInChain = NULL; 43 | WGPUInstance instance = wgpuCreateInstance(&desc); 44 | 45 | // Init SDL 46 | SDL_Init(SDL_INIT_VIDEO); 47 | SDL_Window *window = SDL_CreateWindow("Learn WebGPU", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); 48 | 49 | // Here we create our WebGPU surface from the window! 50 | WGPUSurface surface = SDL_GetWGPUSurface(instance, window); 51 | printf("surface = %p", (void*)surface); 52 | 53 | // Wait for close 54 | SDL_Event event; 55 | int running = 1; 56 | while (running) 57 | while (SDL_PollEvent(&event)) 58 | if (event.type == SDL_QUIT) 59 | running = 0; 60 | // Terminate SDL 61 | SDL_DestroyWindow(window); 62 | SDL_Quit(); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /examples/utils.cmake: -------------------------------------------------------------------------------- 1 | function(target_treat_all_warnings_as_errors Target) 2 | # Treat warnings as errors 3 | set_target_properties(${Target} PROPERTIES COMPILE_WARNING_AS_ERROR ON) 4 | 5 | # Turn all warnings on 6 | if (MSVC) 7 | target_compile_options(${Target} PRIVATE /W4) 8 | else() 9 | target_compile_options(${Target} PRIVATE -Wall -Wextra -pedantic) 10 | endif() 11 | endfunction() 12 | -------------------------------------------------------------------------------- /sdl2webgpu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL2 for WebGPU, abstracting away the details of 3 | * OS-specific operations. 4 | * 5 | * This file is part of the "Learn WebGPU for C++" book. 6 | * https://eliemichel.github.io/LearnWebGPU 7 | * 8 | * Most of this code comes from the wgpu-native triangle example: 9 | * https://github.com/gfx-rs/wgpu-native/blob/master/examples/triangle/main.c 10 | * 11 | * MIT License 12 | * Copyright (c) 2022-2025 Elie Michel and the wgpu-native authors 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | * SOFTWARE. 31 | */ 32 | 33 | #include "sdl2webgpu.h" 34 | 35 | #include 36 | 37 | #if defined(SDL_VIDEO_DRIVER_COCOA) 38 | # include 39 | # include 40 | # include 41 | #elif defined(SDL_VIDEO_DRIVER_UIKIT) 42 | # include 43 | # include 44 | # include 45 | # include 46 | #endif 47 | 48 | #include 49 | #include 50 | 51 | WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window) { 52 | SDL_SysWMinfo windowWMInfo; 53 | SDL_VERSION(&windowWMInfo.version); 54 | SDL_GetWindowWMInfo(window, &windowWMInfo); 55 | 56 | #if defined(SDL_VIDEO_DRIVER_COCOA) 57 | { 58 | id metal_layer = NULL; 59 | NSWindow* ns_window = windowWMInfo.info.cocoa.window; 60 | [ns_window.contentView setWantsLayer : YES]; 61 | metal_layer = [CAMetalLayer layer]; 62 | [ns_window.contentView setLayer : metal_layer]; 63 | 64 | WGPUSurfaceSourceMetalLayer fromMetalLayer; 65 | fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer; 66 | fromMetalLayer.chain.next = NULL; 67 | fromMetalLayer.layer = metal_layer; 68 | 69 | WGPUSurfaceDescriptor surfaceDescriptor; 70 | surfaceDescriptor.nextInChain = &fromMetalLayer.chain; 71 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 72 | 73 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 74 | } 75 | #elif defined(SDL_VIDEO_DRIVER_UIKIT) 76 | { 77 | UIWindow* ui_window = windowWMInfo.info.uikit.window; 78 | UIView* ui_view = ui_window.rootViewController.view; 79 | CAMetalLayer* metal_layer = [CAMetalLayer new]; 80 | metal_layer.opaque = true; 81 | metal_layer.frame = ui_view.frame; 82 | metal_layer.drawableSize = ui_view.frame.size; 83 | 84 | [ui_view.layer addSublayer: metal_layer]; 85 | 86 | WGPUSurfaceSourceMetalLayer fromMetalLayer; 87 | fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer; 88 | fromMetalLayer.chain.next = NULL; 89 | fromMetalLayer.layer = metal_layer; 90 | 91 | WGPUSurfaceDescriptor surfaceDescriptor; 92 | surfaceDescriptor.nextInChain = &fromMetalLayer.chain; 93 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 94 | 95 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 96 | } 97 | #elif defined(SDL_VIDEO_DRIVER_X11) 98 | { 99 | Display* x11_display = windowWMInfo.info.x11.display; 100 | Window x11_window = windowWMInfo.info.x11.window; 101 | 102 | WGPUSurfaceSourceXlibWindow fromXlibWindow; 103 | fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow; 104 | fromXlibWindow.chain.next = NULL; 105 | fromXlibWindow.display = x11_display; 106 | fromXlibWindow.window = x11_window; 107 | 108 | WGPUSurfaceDescriptor surfaceDescriptor; 109 | surfaceDescriptor.nextInChain = &fromXlibWindow.chain; 110 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 111 | 112 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 113 | } 114 | #elif defined(SDL_VIDEO_DRIVER_WAYLAND) 115 | { 116 | struct wl_display* wayland_display = windowWMInfo.info.wl.display; 117 | struct wl_surface* wayland_surface = windowWMInfo.info.wl.surface; 118 | 119 | WGPUSurfaceSourceWaylandSurface fromWaylandSurface; 120 | fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface; 121 | fromWaylandSurface.chain.next = NULL; 122 | fromWaylandSurface.display = wayland_display; 123 | fromWaylandSurface.surface = wayland_surface; 124 | 125 | WGPUSurfaceDescriptor surfaceDescriptor; 126 | surfaceDescriptor.nextInChain = &fromWaylandSurface.chain; 127 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 128 | 129 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 130 | } 131 | #elif defined(SDL_VIDEO_DRIVER_WINDOWS) 132 | { 133 | HWND hwnd = windowWMInfo.info.win.window; 134 | HINSTANCE hinstance = GetModuleHandle(NULL); 135 | 136 | WGPUSurfaceSourceWindowsHWND fromWindowsHWND; 137 | fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND; 138 | fromWindowsHWND.chain.next = NULL; 139 | fromWindowsHWND.hinstance = hinstance; 140 | fromWindowsHWND.hwnd = hwnd; 141 | 142 | WGPUSurfaceDescriptor surfaceDescriptor; 143 | surfaceDescriptor.nextInChain = &fromWindowsHWND.chain; 144 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 145 | 146 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 147 | } 148 | #elif defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) 149 | { 150 | # ifdef WEBGPU_BACKEND_EMDAWNWEBGPU 151 | WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector; 152 | fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector; 153 | # else 154 | WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector; 155 | fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector; 156 | # endif 157 | fromCanvasHTMLSelector.chain.next = NULL; 158 | fromCanvasHTMLSelector.selector = "canvas"; 159 | 160 | WGPUSurfaceDescriptor surfaceDescriptor; 161 | surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain; 162 | surfaceDescriptor.label = NULL; 163 | 164 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 165 | } 166 | #else 167 | // TODO: See SDL_syswm.h for other possible enum values! 168 | #error "Unsupported WGPU_TARGET" 169 | #endif 170 | } 171 | 172 | -------------------------------------------------------------------------------- /sdl2webgpu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL2 for WebGPU, abstracting away the details of 3 | * OS-specific operations. 4 | * 5 | * This file is part of the "Learn WebGPU for C++" book. 6 | * https://eliemichel.github.io/LearnWebGPU 7 | * 8 | * MIT License 9 | * Copyright (c) 2022-2023 Elie Michel and the wgpu-native authors 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in all 19 | * copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | * SOFTWARE. 28 | */ 29 | 30 | #ifndef _sdl2_webgpu_h_ 31 | #define _sdl2_webgpu_h_ 32 | 33 | #include 34 | #include 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** 41 | * Get a WGPUSurface from a SDL2 window. 42 | */ 43 | WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif // _sdl2_webgpu_h_ 50 | --------------------------------------------------------------------------------