├── .github ├── FUNDING.yml └── workflows │ └── cmake.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── examples ├── .gitignore ├── CMakeLists.txt ├── hello-sdl3webgpu.c └── utils.cmake ├── sdl3webgpu.c └── sdl3webgpu.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 xorg-dev 28 | 29 | - system: Windows-MSVC-x64 30 | runner: windows-2025 31 | exe-extension: .exe 32 | is-multiconfig: true 33 | 34 | - system: Windows-MSYS-x64 35 | runner: windows-2025 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 | exclude: 46 | - webgpu-backend: DAWN 47 | link-type: STATIC 48 | 49 | runs-on: ${{ matrix.runner }} 50 | 51 | steps: 52 | - uses: actions/checkout@v4 53 | 54 | - name: Install dependencies 55 | if: ${{ matrix.install-deps }} 56 | run: ${{ matrix.install-deps }} 57 | 58 | - name: Setup MSYS 59 | if: ${{ matrix.msystem }} 60 | uses: msys2/setup-msys2@v2 61 | with: 62 | msystem: ${{ matrix.msystem }} 63 | pacboy: >- 64 | toolchain:p 65 | egl-headers:p 66 | cmake:p 67 | ninja:p 68 | 69 | - name: Configure CMake 70 | if: ${{ ! matrix.msystem }} 71 | run: > 72 | cmake 73 | -S examples 74 | -B build 75 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }} 76 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }} 77 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} 78 | 79 | - name: Build 80 | if: ${{ ! matrix.msystem }} 81 | run: > 82 | cmake 83 | --build build 84 | --config ${{ matrix.build-type }} 85 | 86 | # This is a hack to work around the lack of ${{ variables }} in 'shell' parameter 87 | # We use the SHELL env variable as the value of 'shell' 88 | - name: Configure CMake (MSYS) 89 | if: ${{ matrix.msystem }} 90 | shell: msys2 {0} 91 | run: > 92 | cmake 93 | -S examples 94 | -B build 95 | -DWEBGPU_BACKEND=${{ matrix.webgpu-backend }} 96 | -D${{ matrix.webgpu-backend }}_LINK_TYPE=${{ matrix.link-type }} 97 | -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} 98 | 99 | - name: Build (MSYS) 100 | if: ${{ matrix.msystem }} 101 | shell: msys2 {0} 102 | run: > 103 | cmake 104 | --build build 105 | --config ${{ matrix.build-type }} 106 | -------------------------------------------------------------------------------- /.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 'SDL3' and 'webgpu' exist. 3 | # Look at examples/CMakeLists.txt to see how to use it in a project. 4 | 5 | # The sdl3webgpu target 6 | add_library(sdl3webgpu STATIC sdl3webgpu.c) 7 | target_include_directories(sdl3webgpu PUBLIC .) 8 | target_link_libraries(sdl3webgpu PUBLIC SDL3::SDL3 webgpu) 9 | 10 | if (APPLE) 11 | target_compile_options(sdl3webgpu PRIVATE -x objective-c) 12 | target_link_libraries(sdl3webgpu PRIVATE "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore") 13 | 14 | if (IOS) 15 | target_link_libraries(sdl3webgpu PRIVATE "-framework UIKit") 16 | else() 17 | target_link_libraries(sdl3webgpu 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 | SDL3 WebGPU Extension 18 | ===================== 19 | 20 | This is an extension for the great [SDL3](https://wiki.libsdl.org/SDL3/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(sdl3webgpu)` (see the content of [`CMakeLists.txt`](CMakeLists.txt)). 47 | 48 | **Option B** Just copy [`sdl3webgpu.h`](sdl3webgpu.h) and [`sdl3webgpu.c`](sdl3webgpu.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 "sdl3webgpu.h" 58 | #include 59 | #include 60 | #include 61 | 62 | int main(int argc, char* argv[]) { 63 | (void)argc; 64 | (void)argv; 65 | 66 | // Init WebGPU 67 | WGPUInstance instance = wgpuCreateInstance(NULL); 68 | 69 | // Init SDL 70 | SDL_Init(SDL_INIT_VIDEO); 71 | SDL_Window *window = SDL_CreateWindow("Learn WebGPU", 640, 480, 0); 72 | 73 | // Here we create our WebGPU surface from the window! 74 | WGPUSurface surface = SDL_GetWGPUSurface(instance, window); 75 | printf("surface = %p", (void*)surface); 76 | 77 | // Wait for close 78 | SDL_Event event; 79 | int running = 1; 80 | while (running) 81 | while (SDL_PollEvent(&event)) 82 | if (event.type == SDL_EVENT_QUIT) 83 | running = 0; 84 | // Terminate SDL 85 | SDL_DestroyWindow(window); 86 | SDL_Quit(); 87 | 88 | return 0; 89 | } 90 | ``` 91 | 92 | **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). 93 | 94 | License 95 | ------- 96 | 97 | See [LICENSE.txt](LICENSE.txt). 98 | -------------------------------------------------------------------------------- /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(sdl3webgpu-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(SDL3_SDL3 INTERFACE) 12 | target_compile_options(SDL3_SDL3 INTERFACE --use-port=sdl3) # NB: This port does not exist yet, emscripten is not supported 13 | target_link_options(SDL3_SDL3 INTERFACE --use-port=sdl3) # NB: This port does not exist yet, emscripten is not supported 14 | add_library(SDL3::SDL3 ALIAS SDL3_SDL3) 15 | function(target_copy_sdl3_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 | sdl3 27 | URL https://github.com/libsdl-org/SDL/archive/refs/tags/release-3.2.8.zip 28 | URL_HASH MD5=1a4affbf987808da38a0d6c8aa802a5e 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(sdl3 webgpu) 36 | 37 | function(target_copy_sdl3_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 sdl3webgpu 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(.. sdl3webgpu) 55 | 56 | # Example 57 | add_executable(hello-sdl3webgpu hello-sdl3webgpu.c) 58 | target_link_libraries(hello-sdl3webgpu PRIVATE SDL3::SDL3 webgpu sdl3webgpu) 59 | set_target_properties(hello-sdl3webgpu PROPERTIES CXX_STANDARD 17) 60 | target_treat_all_warnings_as_errors(hello-sdl3webgpu) 61 | 62 | # Copy wgpu-native or Dawn dll/so/dylib next to the executable 63 | target_copy_webgpu_binaries(hello-sdl3webgpu) 64 | # Copy SDL3.dll/so/dylib next to the executable 65 | target_copy_sdl3_binaries(hello-sdl3webgpu) 66 | 67 | -------------------------------------------------------------------------------- /examples/hello-sdl3webgpu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL3 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 "sdl3webgpu.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 | WGPUInstance instance = wgpuCreateInstance(NULL); 42 | 43 | // Init SDL 44 | SDL_Init(SDL_INIT_VIDEO); 45 | SDL_Window *window = SDL_CreateWindow("Learn WebGPU", 640, 480, 0); 46 | 47 | // Here we create our WebGPU surface from the window! 48 | WGPUSurface surface = SDL_GetWGPUSurface(instance, window); 49 | printf("surface = %p", (void*)surface); 50 | 51 | // Wait for close 52 | SDL_Event event; 53 | int running = 1; 54 | while (running) 55 | while (SDL_PollEvent(&event)) 56 | if (event.type == SDL_EVENT_QUIT) 57 | running = 0; 58 | // Terminate SDL 59 | SDL_DestroyWindow(window); 60 | SDL_Quit(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /sdl3webgpu.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL3 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-2024 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 "sdl3webgpu.h" 34 | 35 | #include 36 | 37 | #if defined(SDL_PLATFORM_MACOS) 38 | # include 39 | # include 40 | # include 41 | #elif defined(SDL_PLATFORM_IOS) 42 | # include 43 | # include 44 | # include 45 | # include 46 | #elif defined(SDL_PLATFORM_WIN32) 47 | # include 48 | #endif 49 | 50 | #include 51 | 52 | WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window) { 53 | SDL_PropertiesID props = SDL_GetWindowProperties(window); 54 | 55 | #if defined(SDL_PLATFORM_MACOS) 56 | { 57 | id metal_layer = NULL; 58 | NSWindow *ns_window = (__bridge NSWindow *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL); 59 | if (!ns_window) return NULL; 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_PLATFORM_IOS) 76 | { 77 | UIWindow *ui_window = (__bridge UIWindow *)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, NULL); 78 | if (!uiwindow) return NULL; 79 | 80 | UIView* ui_view = ui_window.rootViewController.view; 81 | CAMetalLayer* metal_layer = [CAMetalLayer new]; 82 | metal_layer.opaque = true; 83 | metal_layer.frame = ui_view.frame; 84 | metal_layer.drawableSize = ui_view.frame.size; 85 | 86 | [ui_view.layer addSublayer: metal_layer]; 87 | 88 | WGPUSurfaceSourceMetalLayer fromMetalLayer; 89 | fromMetalLayer.chain.sType = WGPUSType_SurfaceSourceMetalLayer; 90 | fromMetalLayer.chain.next = NULL; 91 | fromMetalLayer.layer = metal_layer; 92 | 93 | WGPUSurfaceDescriptor surfaceDescriptor; 94 | surfaceDescriptor.nextInChain = &fromMetalLayer.chain; 95 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 96 | 97 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 98 | } 99 | #elif defined(SDL_PLATFORM_LINUX) 100 | if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) { 101 | void *x11_display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); 102 | uint64_t x11_window = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); 103 | if (!x11_display || !x11_window) return NULL; 104 | 105 | WGPUSurfaceSourceXlibWindow fromXlibWindow; 106 | fromXlibWindow.chain.sType = WGPUSType_SurfaceSourceXlibWindow; 107 | fromXlibWindow.chain.next = NULL; 108 | fromXlibWindow.display = x11_display; 109 | fromXlibWindow.window = x11_window; 110 | 111 | WGPUSurfaceDescriptor surfaceDescriptor; 112 | surfaceDescriptor.nextInChain = &fromXlibWindow.chain; 113 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 114 | 115 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 116 | } 117 | else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) { 118 | void *wayland_display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL); 119 | void *wayland_surface = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL); 120 | if (!wayland_display || !wayland_surface) return NULL; 121 | 122 | WGPUSurfaceSourceWaylandSurface fromWaylandSurface; 123 | fromWaylandSurface.chain.sType = WGPUSType_SurfaceSourceWaylandSurface; 124 | fromWaylandSurface.chain.next = NULL; 125 | fromWaylandSurface.display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL); 126 | fromWaylandSurface.surface = wayland_surface; 127 | 128 | WGPUSurfaceDescriptor surfaceDescriptor; 129 | surfaceDescriptor.nextInChain = &fromWaylandSurface.chain; 130 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 131 | 132 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 133 | } 134 | #elif defined(SDL_PLATFORM_WIN32) 135 | { 136 | HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); 137 | if (!hwnd) return NULL; 138 | HINSTANCE hinstance = GetModuleHandle(NULL); 139 | 140 | WGPUSurfaceSourceWindowsHWND fromWindowsHWND; 141 | fromWindowsHWND.chain.sType = WGPUSType_SurfaceSourceWindowsHWND; 142 | fromWindowsHWND.chain.next = NULL; 143 | fromWindowsHWND.hinstance = hinstance; 144 | fromWindowsHWND.hwnd = hwnd; 145 | 146 | WGPUSurfaceDescriptor surfaceDescriptor; 147 | surfaceDescriptor.nextInChain = &fromWindowsHWND.chain; 148 | surfaceDescriptor.label = (WGPUStringView){ NULL, WGPU_STRLEN }; 149 | 150 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 151 | } 152 | #elif defined(__EMSCRIPTEN__) 153 | { 154 | # ifdef WEBGPU_BACKEND_EMDAWNWEBGPU 155 | WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector; 156 | fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector; 157 | # else 158 | WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector; 159 | fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector; 160 | # endif 161 | fromCanvasHTMLSelector.chain.next = NULL; 162 | fromCanvasHTMLSelector.selector = "canvas"; 163 | 164 | WGPUSurfaceDescriptor surfaceDescriptor; 165 | surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain; 166 | surfaceDescriptor.label = NULL; 167 | 168 | return wgpuInstanceCreateSurface(instance, &surfaceDescriptor); 169 | } 170 | #else 171 | // TODO: See SDL_syswm.h for other possible enum values! 172 | #error "Unsupported WGPU_TARGET" 173 | #endif 174 | } 175 | 176 | -------------------------------------------------------------------------------- /sdl3webgpu.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This is an extension of SDL3 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 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 _sdl3_webgpu_h_ 31 | #define _sdl3_webgpu_h_ 32 | 33 | #include 34 | #include 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** 41 | * Get a WGPUSurface from a SDL3 window. 42 | */ 43 | WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif // _sdl3_webgpu_h_ 50 | --------------------------------------------------------------------------------