├── .gitattributes
├── .github
└── workflows
│ ├── compile.yml
│ ├── gen-check.yml
│ └── gen-docs.yml
├── .gitignore
├── Doxyfile
├── LICENSE
├── Makefile
├── README.md
├── doc
├── .gitignore
└── articles
│ ├── Asynchronous Operations.md
│ ├── BufferMapping.md
│ ├── Errors.md
│ ├── Extensions.md
│ ├── FloatingPointNumbers.md
│ ├── Multithreading.md
│ ├── Ownership.md
│ ├── SentinelValues.md
│ ├── Strings.md
│ ├── StructChaining.md
│ ├── Surfaces.md
│ └── index.md
├── fix
└── main.go
├── gen
├── README.md
├── cheader.tmpl
├── gen.go
├── main.go
├── utils.go
├── validator.go
└── yml.go
├── go.mod
├── go.sum
├── schema.json
├── tests
├── compile
│ ├── .gitignore
│ ├── Makefile
│ ├── main.c
│ ├── main.cpp
│ ├── main.inl
│ └── windows
│ │ └── makefile
└── extensions
│ ├── extension.yml
│ └── webgpu_extension.h
├── webgpu.h
└── webgpu.yml
/.gitattributes:
--------------------------------------------------------------------------------
1 | gen/** -linguist-detectable
2 |
--------------------------------------------------------------------------------
/.github/workflows/compile.yml:
--------------------------------------------------------------------------------
1 | name: compile
2 | on:
3 | pull_request:
4 | jobs:
5 | compile-gcc-clang:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v4
9 | - run: |
10 | cd "${{ github.workspace }}/tests/compile"
11 | make
12 | compile-msvc:
13 | runs-on: windows-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: ilammy/msvc-dev-cmd@v1
17 | - name: Build something requiring CL.EXE
18 | run: |
19 | cd "${{ github.workspace }}/tests/compile/windows"
20 | nmake
21 |
--------------------------------------------------------------------------------
/.github/workflows/gen-check.yml:
--------------------------------------------------------------------------------
1 | name: gen-check
2 | on:
3 | pull_request:
4 | jobs:
5 | gen-check:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v3
9 | - uses: actions/setup-go@v4
10 | with:
11 | go-version: '>=1.21.0'
12 | - run: |
13 | cd "${{ github.workspace }}"
14 | make gen-check
15 |
--------------------------------------------------------------------------------
/.github/workflows/gen-docs.yml:
--------------------------------------------------------------------------------
1 | name: gen-docs
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 | workflow_dispatch:
7 | pull_request:
8 |
9 | # Allow only one concurrent deployment
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.ref }}
12 | cancel-in-progress: true
13 |
14 | jobs:
15 | # Generate and build docs
16 | gen-docs:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - uses: actions/checkout@v4
20 | - uses: actions/setup-go@v4
21 | with:
22 | go-version: '>=1.21.0'
23 | - uses: ssciwr/doxygen-install@v1
24 | with:
25 | version: '1.10.0'
26 | - run: make doc
27 | - uses: actions/upload-pages-artifact@v3
28 | with:
29 | path: doc/generated/html
30 |
31 | # Deployment job
32 | deploy:
33 | if: ${{ success() && github.ref == 'refs/heads/main' }}
34 | needs: gen-docs
35 |
36 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
37 | permissions:
38 | pages: write # to deploy to Pages
39 | id-token: write # to verify the deployment originates from an appropriate source
40 |
41 | environment:
42 | name: github-pages
43 | url: ${{ steps.deployment.outputs.page_url }}
44 |
45 | runs-on: ubuntu-latest
46 | steps:
47 | - name: Deploy to GitHub Pages
48 | id: deployment
49 | uses: actions/deploy-pages@v4
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 |
--------------------------------------------------------------------------------
/Doxyfile:
--------------------------------------------------------------------------------
1 | # This file was initially generated by Doxyfile 1.10.0 and all entries left
2 | # to their default value have been removed for the sake of clarity.
3 |
4 | #---------------------------------------------------------------------------
5 | # Project related configuration options
6 | #---------------------------------------------------------------------------
7 |
8 | PROJECT_NAME = "WebGPU Headers"
9 |
10 | # This is the version of webgpu.h. Currently we don't have release versions.
11 |
12 | PROJECT_NUMBER =
13 |
14 | # This appears at the top of each page and should give viewer a quick idea
15 | # about the purpose of the project. Keep the description short.
16 |
17 | PROJECT_BRIEF = "The WebGPU C API"
18 |
19 | # The Doxygen-generated documentation is written in doc/generated. Make sure
20 | # to keep this in sync with the deployment workflow file
21 | # (.github/workflows/gen-docs.yml).
22 |
23 | OUTPUT_DIRECTORY = doc/generated
24 |
25 | # Since webgpu.h is a C API, we set the OPTIMIZE_OUTPUT_FOR_C tag to YES so
26 | # that Doxygen generates an output that is more tailored for C.
27 |
28 | OPTIMIZE_OUTPUT_FOR_C = YES
29 |
30 | EXTRACT_ALL = YES
31 | EXTRACT_STATIC = YES
32 | WARN_AS_ERROR = FAIL_ON_WARNINGS
33 | WARN_IF_INCOMPLETE_DOC = NO
34 | # Note EXTRACT_ALL bypasses these, but keep them in case we disable it.
35 | WARN_IF_UNDOC_ENUM_VAL = YES
36 | WARN_NO_PARAMDOC = NO
37 | WARN_IF_UNDOCUMENTED = YES
38 |
39 | #---------------------------------------------------------------------------
40 | # Build related configuration options
41 | #---------------------------------------------------------------------------
42 |
43 | # The WebGPU C API does not have cases of symbols only differing by case, so
44 | # we can afford to turn this to YES even on non-case sensitive file systems.
45 | # This options helps getting slightly better path names, although it is still
46 | # overall not satisfying so as soon as we have a proper way to generate good
47 | # human-memorable URLs we could turn this back to NO or SYSTEM.
48 |
49 | CASE_SENSE_NAMES = YES
50 |
51 | # No need to show header file, since there is only webgpu.h. When using this
52 | # Doxyfile with implementation-specific extensions (e.g., wgpu.h), it could
53 | # be useful to turn this back to YES.
54 |
55 | SHOW_HEADERFILE = NO
56 |
57 | # Instead of letting Doxygen sort definition alphabetically, we have it rely
58 | # on the order from webgpu.h. Since the latter is auto-generated, we can
59 | # expect the order there to be sound and consistent.
60 |
61 | SORT_MEMBER_DOCS = NO
62 |
63 | # No need to show used files as there is only webgpu.h
64 |
65 | SHOW_USED_FILES = NO
66 |
67 | # And no need for the Files page neither.
68 |
69 | SHOW_FILES = NO
70 |
71 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
72 | # by doxygen. The layout file controls the global structure of the generated
73 | # output files in an output format independent way. To create the layout file
74 | # that represents doxygen's defaults, run doxygen with the -l option. You can
75 | # optionally specify a file name after the option, if omitted DoxygenLayout.xml
76 | # will be used as the name of the layout file. See also section "Changing the
77 | # layout of pages" for information.
78 | #
79 | # Note that if you run doxygen from a directory containing a file called
80 | # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
81 | # tag is left empty.
82 |
83 | LAYOUT_FILE =
84 |
85 | #---------------------------------------------------------------------------
86 | # Configuration options related to the input files
87 | #---------------------------------------------------------------------------
88 |
89 | # When adding extra files, separate them with spaces.
90 |
91 | INPUT = webgpu.h doc/articles/
92 |
93 | #---------------------------------------------------------------------------
94 | # Configuration options related to source browsing
95 | #---------------------------------------------------------------------------
96 |
97 | # The header file itself is often a good source of information, so we have
98 | # documented entries be cross-referenced with their source.
99 |
100 | SOURCE_BROWSER = YES
101 |
102 | #---------------------------------------------------------------------------
103 | # Configuration options related to the alphabetical class index
104 | #---------------------------------------------------------------------------
105 |
106 | # Make sure the WGPU/wgpu prefix of type/function names are ignored while
107 | # sorting member names in the alphabetical index.
108 |
109 | IGNORE_PREFIX = WGPU,wgpu
110 |
111 | #---------------------------------------------------------------------------
112 | # Configuration options related to the HTML output
113 | #---------------------------------------------------------------------------
114 |
115 | # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
116 | # The default value is: YES.
117 |
118 | GENERATE_HTML = YES
119 |
120 | # Sidebar-based page layout (https://www.doxygen.nl/manual/customize.html)
121 |
122 | DISABLE_INDEX = YES
123 | GENERATE_TREEVIEW = YES
124 | FULL_SIDEBAR = YES
125 |
126 | # Enum values look weird in Doxygen output in general, but a bit less weird
127 | # when only allowing 1 value per line.
128 |
129 | ENUM_VALUES_PER_LINE = 1
130 |
131 | #---------------------------------------------------------------------------
132 | # Configuration options related to the LaTeX output
133 | #---------------------------------------------------------------------------
134 |
135 | # We do not need a LaTeX documentation
136 |
137 | GENERATE_LATEX = NO
138 |
139 | #---------------------------------------------------------------------------
140 | # Configuration options related to the preprocessor
141 | #---------------------------------------------------------------------------
142 |
143 | # We need to expand macros to prevent the empty defines used as tags like
144 | # WGPU_ENUM_ATTRIBUTE to be treated by Doxygen and mess up with the whole
145 | # documentation.
146 |
147 | MACRO_EXPANSION = YES
148 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2019, "WebGPU native" developers
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all all-help-message help check-schema fix gen gen-check doc
2 |
3 | # default target if you just type `make`
4 | all: all-help-message fix gen doc
5 |
6 | # help message before starting `make all`
7 | all-help-message: help
8 | @echo 'Running default targets: fix gen doc'
9 |
10 | help:
11 | @echo 'Targets are: all, help, check-schema, fix, gen, gen-check, doc'
12 |
13 | check-schema: schema.json
14 | go run ./gen -schema schema.json -yaml webgpu.yml -header webgpu.h -yaml tests/extensions/extension.yml -header tests/extensions/webgpu_extension.h
15 |
16 | fix: check-schema webgpu.yml tests/extensions/extension.yml
17 | go run ./fix -yaml webgpu.yml
18 | go run ./fix -yaml tests/extensions/extension.yml
19 |
20 | gen: check-schema webgpu.yml tests/extensions/extension.yml
21 |
22 | gen-check: fix gen
23 | @git diff --quiet -- webgpu.h || { \
24 | echo "error: The re-generated header from yml doesn't match the checked-in header"; \
25 | git diff -- webgpu.h; \
26 | exit 1; \
27 | }
28 | @git diff --quiet -- webgpu.yml || { \
29 | echo "error: Please re-run 'make fix' to format the yml"; \
30 | git diff -- webgpu.yml; \
31 | exit 1; \
32 | }
33 | @git diff --quiet -- tests/extensions/webgpu_extension.h || { \
34 | echo "error: The re-generated extensions header from yml doesn't match the checked-in header"; \
35 | git diff -- tests/extensions/webgpu_extension.h; \
36 | exit 1; \
37 | }
38 | @git diff --quiet -- tests/extensions/extension.yml || { \
39 | echo "error: Please re-run 'make fix' to format the extension yml"; \
40 | git diff -- tests/extensions/extension.yml; \
41 | exit 1; \
42 | }
43 |
44 | doc: webgpu.h Doxyfile
45 | doxygen Doxyfile
46 | # Verify that no ` or :: made it through into the final docs
47 | ! grep -RE '`|>::' doc/generated/**/*.html
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WebGPU Headers
2 |
3 | This repository contains C headers equivalent to the [WebGPU](https://gpuweb.github.io/gpuweb/) API and documentation on the native specificities of the headers.
4 |
5 | **This header is NOT STABLE yet, and the documentation is very much a work in progress!**
6 |
7 | All of the API is defined in the [webgpu.h](./webgpu.h) header file.
8 | **[Read the documentation here!](https://webgpu-native.github.io/webgpu-headers/)**
9 |
10 | ## Why?
11 |
12 | While WebGPU is a JavaScript API made for the Web, it is a good tradeoff of ergonomic, efficient and portable graphics API.
13 | Almost all of its concepts are not specific to the Web platform and the headers replicate them exactly, while adding capabilities to interact with native concepts (like windows).
14 |
15 | Implementations of this header include:
16 |
17 | - [Dawn](https://dawn.googlesource.com/dawn), the C++ WebGPU implementation used in Chromium
18 | - [wgpu-native](https://github.com/gfx-rs/wgpu-native), C bindings to [wgpu](https://github.com/gfx-rs/wgpu), the Rust WebGPU implementation used in Firefox
19 | - [Emscripten](https://github.com/emscripten-core/emscripten/blob/main/src/library_webgpu.js) translates [webgpu.h](./webgpu.h) calls to JavaScript WebGPU calls when compiling to WASM
20 |
21 | ## Details
22 |
23 | Here are some details about the structure of this repository.
24 |
25 | ### Main files
26 |
27 | - `webgpu.h` is the one and only header file that defines the WebGPU C API. Only this needs to be integrated in a C project that links against a WebGPU implementation.
28 |
29 | - `webgpu.yml` is the main machine-readable source of truth for the C API and its documentation (in [YAML](https://yaml.org/) format). It is used to generate the official `webgpu.h` header present in this repository, (will be used) to generate the official documentation, and may be used by any other third party to design tools and wrappers around WebGPU-Native.
30 |
31 | - `schema.json` is the [JSON schema](https://json-schema.org/) that formally specifies the structure of `webgpu.yml`.
32 |
33 | ### Generator
34 |
35 | - `Makefile` defines the rules to automatically generate `webgpu.h` from `webgpu.yml` and check the result.
36 |
37 | - `gen/` and the `go.*` files are the source code of the generator called by the `Makefile`.
38 |
39 | - `tests/compile` is used to check that the generated C header is indeed valid C/C++ code.
40 |
41 | ### Workflows
42 |
43 | - `.github/workflows` defines the automated processes that run upon new commits/PR, to check that changes in `webgpu.yml` and `webgpu.h` are consistent.
44 |
45 | ## Contributing
46 |
47 | **Important** When submitting a change, one must modify both the `webgpu.yml` and `webgpu.h` files in a consistent way. One should first edit `webgpu.yml` (the source of truth), then run `make gen` to update `webgpu.h` and finally commit both changes together.
48 |
--------------------------------------------------------------------------------
/doc/.gitignore:
--------------------------------------------------------------------------------
1 | /generated/
2 |
--------------------------------------------------------------------------------
/doc/articles/Asynchronous Operations.md:
--------------------------------------------------------------------------------
1 | # Asynchronous Operations {#Asynchronous-Operations}
2 |
3 | Asynchronous operations in webgpu.h return a @ref WGPUFuture. This is an opaque handle which applications may use to poll or wait for completion of the asynchronous operation.
4 |
5 | On all implementations of webgpu.h, it must be possible to react to async operations without undue latency or spin-waiting.
6 |
7 | ## Creation
8 |
9 | All asynchronous operations start when the application calls an asynchronous webgpu.h function. These functions return `WGPUFuture`, and take in their arguments a `CallbackInfo` struct like @ref WGPURequestDeviceCallbackInfo or @ref WGPUBufferMapCallbackInfo. `CallbackInfo` structs have the following members:
10 | - a `WGPUChainedStruct const * nextInChain` pointer, for extensions.
11 | - a @ref WGPUCallbackMode `mode` enum.
12 | - a `callback` function pointer. For example:
13 | ```c
14 | typedef void (*WGPUBufferMapCallback)(
15 | WGPUMapAsyncStatus status,
16 | WGPUStringView message,
17 | WGPU_NULLABLE void* userdata1,
18 | WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE;
19 | ```
20 | - Two application-owned userdata members.
21 | `void* userdata1`
22 | `void* userdata2`
23 |
24 | The `callback` function pointer is called when the application _observes completion_ of the asynchronous operation. The `userdata1` and `userdata2` members are passed back to the application as the last two arguments in the callback function. Callbacks **might not** be called unless the application explicitly flushes them in order to _observe completion_. The point in time a callback is called depends on the @ref WGPUCallbackMode of the operation. webgpu.h provides three callback modes: @ref WGPUCallbackMode_WaitAnyOnly, @ref WGPUCallbackMode_AllowProcessEvents, and @ref WGPUCallbackMode_AllowSpontaneous.
25 |
26 | @ref WGPUCallbackMode_WaitAnyOnly
27 |
28 | > @copydoc ::WGPUCallbackMode_WaitAnyOnly
29 |
30 | @ref WGPUCallbackMode_AllowProcessEvents
31 |
32 | > @copydoc ::WGPUCallbackMode_AllowProcessEvents
33 |
34 | @ref WGPUCallbackMode_AllowSpontaneous
35 |
36 | > @copydoc ::WGPUCallbackMode_AllowSpontaneous
37 |
38 | ## Callback Statuses {#CallbackStatuses}
39 |
40 | Each event's callback has its own status enum. Generally, there will be one
41 | success case, and several failure cases.
42 |
43 | Every callback status enum has a `CallbackCancelled` status. This indicates that the callback was cancelled, though any background processing related to the event, like pipeline compilation, may not be complete.
44 |
45 | `CallbackCancelled` happens when the last (external) reference to the @ref WGPUInstance is dropped.
46 | At this point it becomes impossible to call @ref wgpuInstanceWaitAny or @ref wgpuInstanceProcessEvents.
47 |
48 | ## wgpuInstanceWaitAny {#Wait-Any}
49 |
50 | `WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance, size_t futureCount, WGPUFutureWaitInfo * futures, uint64_t timeoutNS)`
51 |
52 | Waits on any WGPUFuture in the list of `futures` to complete for `timeoutNS` nanoseconds. Returns when at least one `WGPUFuture` is completed or `timeoutNS` elapses, whichever is first. If `timeoutNS` is zero, all `futures` are polled once, without blocking.
53 |
54 | - Returns @ref WGPUWaitStatus_Success if at least one `WGPUFuture` completes. Each future which _just_ completed has its respective callback fired. Each future which _is_ complete has its corresponding @ref WGPUFutureWaitInfo::completed set to true.
55 | - Note that the timeout applies only to the "wait" phase, and does not affect the callback firing phase.
56 | - Returns @ref WGPUWaitStatus_TimedOut if the timeout passed without any futures completing.
57 | - Returns @ref WGPUWaitStatus_Error if the call was invalid for any of the following reasons:
58 | - A @ref Timed-Wait was performed when WGPUInstanceFeatures::timedWaitAnyEnable is not enabled.
59 | - The number of futures waited on in a @ref Timed-Wait is greater than the enabled WGPUInstanceFeatures::timedWaitAnyMaxCount.
60 | - A wait was attempted with @ref Mixed-Sources.
61 |
62 | ### Timed Wait {#Timed-Wait}
63 |
64 | Use of _timed waits_ (`timeoutNS > 0`), must be enabled on the WGPUInstance in @ref wgpuCreateInstance() with @ref WGPUInstanceFeatureName_TimedWaitAnyEnable, and the number of futures waited on must be less than or equal to @ref WGPUInstanceLimits::timedWaitAnyMaxCount.
65 |
66 | ### Mixed Sources {#Mixed-Sources}
67 |
68 | Asynchronous operations may originate from different sources. There are CPU-timeline operations and there are Queue-timeline operations. Within a _timed wait_, it is only valid to wait on `WGPUFuture`s originating from a single `WGPUQueue`. Waiting on two futures from different queues, or waiting on a Queue-timeline future and some other CPU-timeline future is an error.
69 |
70 | #### CPU-Timeline Operations
71 |
72 | - ::wgpuInstanceRequestAdapter
73 | - ::wgpuAdapterRequestDevice
74 | - ::wgpuShaderModuleGetCompilationInfo
75 | - ::wgpuDeviceCreateRenderPipelineAsync
76 | - ::wgpuDeviceCreateComputePipelineAsync
77 | - ::wgpuDevicePopErrorScope
78 |
79 | #### Queue-Timeline Operations
80 |
81 | - ::wgpuBufferMapAsync
82 | - ::wgpuQueueOnSubmittedWorkDone
83 |
84 | ## wgpuInstanceProcessEvents {#Process-Events}
85 | `void wgpuInstanceProcessEvents(WGPUInstance)`
86 |
87 | Processes asynchronous events on this `WGPUInstance`, calling any callbacks for asynchronous operations created with @ref WGPUCallbackMode_AllowProcessEvents that have completed. This is a non-blocking operation.
88 |
89 | ## Device Events
90 |
91 | Device events are slightly different in that their callback info are passed on the `WGPUDeviceDescriptor`, instead of in a function argument.
92 |
93 | - The DeviceLost callback is set via @ref WGPUDeviceDescriptor::deviceLostCallbackInfo.
94 | The Future for that event is @ref wgpuDeviceGetLostFuture.
95 | - The UncapturedError callback is set via @ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo.
96 | It is a repeating event, not a future, and it does not have a callback mode (see docs).
97 |
98 | The uncaptured error callback is guaranteed not to fire after the device becomes lost. When the device is lost, it is an appropriate time for the application to free userdata variables for the uncaptured error callback. Note that the device becomes lost _before_ the actual device lost callback fires. First the device state transitions to lost, then the device lost callback fires. The timing of the callback depends on the device lost callback mode.
99 |
100 | ## Callback Reentrancy {#CallbackReentrancy}
101 |
102 | There are three cases of async/callback re-entrancy:
103 |
104 | - Calls to the API are nested inside non-spontaneous callbacks (those with @ref WGPUCallbackMode_WaitAnyOnly or @ref WGPUCallbackMode_AllowProcessEvents). Such callbacks always happen in @ref wgpuInstanceWaitAny() or @ref wgpuInstanceProcessEvents().
105 | - This does not introduce any unsafety. Implementations are required to exit critical sections before invoking callbacks.
106 | - This includes making nested calls to @ref wgpuInstanceWaitAny() and @ref wgpuInstanceProcessEvents(). (However, beware of overflowing the call stack!)
107 | - Calls to the API are nested inside @ref WGPUCallbackMode_AllowSpontaneous callbacks, which may happen at any time (during a `webgpu.h` function call or on an arbitrary thread).
108 | - Therefore, calls to the API should never be made in @ref WGPUCallbackMode_AllowSpontaneous callbacks, except where otherwise noted (e.g. @ref wgpuBufferGetMappedRange), due to the possibility of self-deadlock.
109 | Additionally, applications should take extra care even when accessing their *own* state (and locks) inside the callback.
110 | - This includes @ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo, which is always allowed to fire spontaneously.
111 | - Two threads are doing things in parallel, so calls to the API are made while callbacks (or API functions in general) are running on another thread.
112 | - In general, most API calls are thread-safe (see @ref ThreadSafety).
113 |
--------------------------------------------------------------------------------
/doc/articles/BufferMapping.md:
--------------------------------------------------------------------------------
1 | # Buffer Mapping {#BufferMapping}
2 |
3 | ## Mapped Range Behavior {#MappedRangeBehavior}
4 |
5 | The @ref wgpuBufferGetMappedRange, @ref wgpuBufferGetConstMappedRange, @ref wgpuBufferReadMappedRange, and @ref wgpuBufferWriteMappedRange methods:
6 |
7 | - Fail (return `NULL` or `WGPUStatus_Error`) with @ref ImplementationDefinedLogging if:
8 | - There is any content-timeline error, as defined in the WebGPU specification for `getMappedRange()`, given the same buffer, offset, and size (buffer is not mapped, alignment constraints, overlaps, etc.)
9 | - **Except** for overlaps between *const* ranges, which are allowed in C *in non-Wasm targets only*.
10 | (Wasm does not allow this because const ranges do not exist in JS.
11 | All of these calls are implemented on top of `getMappedRange()`.)
12 | - @ref wgpuBufferGetMappedRange or @ref wgpuBufferWriteMappedRange is called, but the buffer is not mapped with @ref WGPUMapMode_Write.
13 |
14 | @ref wgpuBufferGetMappedRange, @ref wgpuBufferGetConstMappedRange additionally:
15 |
16 | - Do not guarantee they will return any particular address value relative to another GetMappedRange call.
17 | - Guarantee that the mapped pointer will be aligned to 16 bytes if the `MapAsync` and `GetMappedRange` offsets are also aligned to 16 bytes.
18 |
19 | More specifically: `GetMappedRange pointer` and `MapAsync offset + GetMappedRange offset` must be _congruent modulo_ `16`.
20 |
21 | - Implementations **should** try to guarantee better alignments (as large as 256 bytes), if they can do so without significant runtime overhead (i.e. without allocating new memory and copying data).
22 |
--------------------------------------------------------------------------------
/doc/articles/Errors.md:
--------------------------------------------------------------------------------
1 | # Errors {#Errors}
2 |
3 | Errors are surfaced in several ways.
4 |
5 | Most errors only result from incorrect use of the API and should not need to be handled at runtime.
6 | However, a few (@ref WGPUErrorType_OutOfMemory, @ref WGPUErrorType_Internal) are potentially useful to handle.
7 |
8 | ## Device Error {#DeviceError}
9 |
10 | These behave the same way as [in the WebGPU JavaScript API specification](https://www.w3.org/TR/webgpu/#errors-and-debugging).
11 | They are receivable via @ref wgpuDevicePopErrorScope() and @ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo.
12 |
13 | These errors include:
14 |
15 | - All device-timeline errors in the WebGPU specification.
16 | - Enum values which are numerically invalid (this is not possible in JavaScript).
17 | - Enum values which are require features not enabled on the device (a [content-timeline](https://www.w3.org/TR/webgpu/#content-timeline) error in JavaScript), for example compressed texture formats.
18 | - Other content-timeline errors where specified.
19 | - @ref NonFiniteFloatValueError (except when they interrupt Wasm execution)
20 |
21 | ### Error Scopes {#ErrorScopes}
22 |
23 | Error scopes are used via @ref wgpuDevicePushErrorScope, @ref wgpuDevicePopErrorScope, and @ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo. These behave the same as in the JavaScript API, except for considerations around multi-threading (which JavaScript doesn't have at the time of this writing):
24 |
25 | - The error scope stack state is **thread-local**: each thread has a separate stack, which is initially empty. The error scope that captures an error depends on which thread made the API call that generated the error.
26 | Note in particular:
27 | - Async callbacks run on various threads and with unpredictable timing (see @ref Asynchronous-Operations), except when using @ref wgpuInstanceWaitAny. To avoid race conditions, if error scopes are used, applications generally should avoid having device errors escape from an async function, and/or should not keep scopes open when callbacks that could produce errors may run.
28 | - Runtimes with async task support (I/O runtimes, language async/coroutines/futures, etc.) may use "green threads" style systems to schedule tasks on different OS threads. Error scope stack state is OS-thread-local, not green-thread-local.
29 | - The UncapturedError callback (@ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo) is called for uncaptured errors on all threads. It **may** be called inline inside of a call to the API.
30 |
31 | ## Callback Error {#CallbackError}
32 |
33 | These behave similarly to the Promise-returning JavaScript APIs. Instead of there being two callbacks like in JavaScript (one for resolve and one for reject), there is a single callback which receives a status code, and depending on the status, _either_ a valid result with an empty message string (`{NULL, 0}`), _or_ an invalid result with a non-empty message string.
34 |
35 | ## Synchronous Error {#SynchronousError}
36 |
37 | These errors include:
38 |
39 | - @ref OutStructChainError cases.
40 | - [Content-timeline](https://www.w3.org/TR/webgpu/#content-timeline) errors other than those which are surfaced as @ref DeviceError in `webgpu.h`. See specific documentation to determine how each error is exposed.
41 |
42 | Generally these will return some kind of failure status (like \ref WGPUStatus_Error) or `NULL`, and produce an @ref ImplementationDefinedLogging message.
43 |
44 | ### Implementation-Defined Logging {#ImplementationDefinedLogging}
45 |
46 | Entry points may also specify that they produce "implementation-defined logging".
47 | These messages are logged in an implementation defined way (e.g. to an implementation-specific callback, or to a logging runtime).
48 | They are intended to be intended to be read by humans, useful primarily for development and crash reporting.
49 |
--------------------------------------------------------------------------------
/doc/articles/Extensions.md:
--------------------------------------------------------------------------------
1 | # Extensions {#Extensions}
2 |
3 | `webgpu.h` is designed to be an extensible and forward-compatible API.
4 | The following types of extensions are supported:
5 |
6 | ```
7 | wgpuPrefixNewFunction
8 |
9 | WGPUPrefixNewObject
10 | wgpuPrefixNewObjectNewMethod
11 | wgpuOldObjectPrefixNewMethod
12 |
13 | WGPUPrefixNewEnum
14 | WGPUPrefixNewEnum_NewValue
15 | WGPUOldEnum_PrefixNewValue
16 |
17 | WGPUPrefixNewStruct
18 |
19 | WGPUPrefixNewBitflagType
20 | WGPUPrefixNewBitflagType_NewValue
21 | WGPUOldBitflagType_PrefixNewValue
22 |
23 | WGPUPrefixNewCallback
24 |
25 | WGPU_PREFIX_NEW_CONSTANT
26 | ```
27 |
28 | ("Prefix" is the name of the implementation that owns the extension, if any; see below.)
29 |
30 | When an application is running against an unknown `webgpu.h` implementation, extension support may be detected at runtime as follows:
31 |
32 | - New functions/methods may be runtime-detected by loading them dynamically, and checking whether loading succeeds. (@ref wgpuGetProcAddress() returns `NULL` for unknown function names.)
33 | - New objects may be detected by the presence of the methods that create them.
34 | - New (root) structs, enum/bitflag types, and callback types are always supported if the methods that accept them exist.
35 | - New enum/bitflag values and [chained structs](@ref StructChaining) are available iff the corresponding "feature" was already explicitly enabled for the context where they're used:
36 | - Device features are detected via @ref wgpuAdapterGetFeatures() and enabled via @ref WGPUDeviceDescriptor::requiredFeatures.
37 | - Instance features are detected via @ref wgpuHasInstanceFeature() and @ref wgpuGetInstanceFeatures(), and enabled via @ref WGPUInstanceDescriptor::requiredFeatures.
38 | - Instance limits are detected via @ref wgpuGetInstanceLimits(), and enabled via @ref WGPUInstanceDescriptor::requiredLimits.
39 |
40 | The following design principles should be followed to ensure future extensibility:
41 |
42 | - Enums always have a `Force32 = 0x7FFFFFFF` value to force them to be 32-bit (and have a stable ABI representation).
43 | - Bitflag types are always 64-bit.
44 | - Structures should be extensible (have a `nextInChain`), or at least be associated with some struct (e.g. child, sibling, or parent) that is extensible.
45 |
46 | Note also:
47 |
48 | - Whenever necessary a version `2` or implementation-specific version of an existing method or type can be added.
49 |
50 | ## Registry of prefixes and enum blocks
51 |
52 | Implementation-specific extensions **should** use the naming conventions listed above, with the name prefixes listed here.
53 |
54 | Implementation-specific extensions **must** use their assigned block when adding new values to existing enum types. (Implementation-specific enum types do not need to use these blocks since they are exclusive to one implementation.)
55 |
56 | If an implementation does not have an assigned prefix and block, it **should** be added to this registry.
57 |
58 | | | Prefix | Enum Block | Description
59 | |----------------------|--------------|---------------|------------
60 | | Standard | (none) | `0x0000_????` | Extensions standardized in webgpu.h
61 | | Compatibility Mode | *TBD* | `0x0002_????` | **Special:** implementations that don't support Compatibility Mode must ignore any chained structs with @ref WGPUSType values in this block, instead of erroring. This block must only be used for Compat additions that can be ignored without affecting the semantics of a non-erroring program.
62 | | wgpu-native | `Wgpu` | `0x0003_????` | -
63 | | Emscripten | `Emscripten` | `0x0004_????` | -
64 | | Dawn | `Dawn` | `0x0005_????` | -
65 | | Wagyu | `Wagyu` | `0x0006_????` | -
66 |
67 | Note all negative values (values with the most-significant bit set to 1) are reserved for future use.
68 |
69 | ## Bitflag Registry {#BitflagRegistry}
70 |
71 | Implementation-specific extensions **must** choose one of the following options when adding new bitflag values:
72 | - Register their reserved bitflag values in this document.
73 | - Add a new bitflag type, and use it via an extension struct.
74 |
75 | Core and Compatibility Mode bits will always be in the least-significant 53 bits, because the JS API can only represent 53 bits.
76 | Therefore, extended bitflag values **should** be in the most-significant 11 bits, overflowing into the most-significant end of the least-significant 53 bits if necessary (or avoiding doing so by adding a new bitflag type entirely).
77 |
78 | - (None have been registered yet!)
79 |
--------------------------------------------------------------------------------
/doc/articles/FloatingPointNumbers.md:
--------------------------------------------------------------------------------
1 | # Floating-Point Numbers {#FloatingPointNumbers}
2 |
3 | ## Double-as-Supertype {#DoubleAsSupertype}
4 |
5 | Like in the JS API, `double` (aka JavaScript's native `Number` type) is used in several places as a supertype of various numeric values.
6 | Such a value will be numerically downcast to the appropriate subtype depending how it is used,
7 | as specified in the JS API spec.
8 |
9 | - In @ref WGPUColor, as a supertype of `f32`/`u32`/`i32`
10 | - In @ref WGPURenderPassColorAttachment::clearValue, the type depends on the texture format.
11 | - In @ref wgpuRenderPassEncoderSetBlendConstant, the type is `f32`.
12 | - In @ref WGPUConstantEntry::value, as a supertype of all of the overrideable WGSL types
13 | (`bool`/`f32`/`u32`/`i32`/`f16` and possibly more).
14 | - The type depends on the WGSL type of the constant being overridden.
15 |
16 | ## Nullable Floating-Point Type {#NullableFloatingPointType}
17 |
18 | Floating-point-typed (`float`/`double`) values which are nullable or optional use `NaN` to
19 | represent the null value. A value `value` represents the null value iff `isnan(value) != 0`.
20 | (Do not use an equality check with a `NaN` constant, because `NaN == NaN` is false.)
21 |
22 | Infinities are invalid. See @ref NonFiniteFloatValueError.
23 |
24 | ## Non-Finite Float Value Errors {#NonFiniteFloatValueError}
25 |
26 | The JavaScript API does not allow non-finite floating-point values (it throws a `TypeError`).
27 |
28 | In `webgpu.h`, a value is finite iff `isfinite(value) != 0`.
29 | Using a non-finite value (aside from `NaN` for a @ref NullableFloatingPointType)
30 | results in a validation @ref DeviceError, except on Wasm-on-JS targets where a `TypeError`
31 | thrown by JS **may** be passed unhandled, interrupting Wasm execution.
32 |
--------------------------------------------------------------------------------
/doc/articles/Multithreading.md:
--------------------------------------------------------------------------------
1 | # Multithreading {#Multithreading}
2 |
3 | `webgpu.h` implementations are allowed to require that all returned objects, except for `WGPUInstance`, can only be used from the thread they were created on, causing undefined behavior otherwise.
4 |
5 | Where multithreading is supported:
6 |
7 | - The implementation must provide the documented @ref ThreadSafety guarantees.
8 | - All objects must be freely usable on any thread at any time, except:
9 | - Where APIs are specified as being non-thread-safe, they must mutexed.
10 | - The exceptions for Wasm, below: @ref MultithreadingInWasm.
11 | - State must be thread-global, except where otherwise defined.
12 | - For example, buffer map state is thread-global, and mapped memory ranges may be used from any thread.
13 | - Note: Error scope state is thread-local. See @ref ErrorScopes.
14 |
15 | Native (non-Wasm) implementations **should** support multithreading.
16 |
17 | ## Multithreading In WebAssembly {#MultithreadingInWasm}
18 |
19 | At the time of this writing, the JS WebGPU API is not multithreading-capable.
20 | Initial `webgpu.h` implementations will not be multithreading-capable.
21 |
22 | Wasm-on-JS implementations *may* implement multithreading by proxying calls to a single JS "thread", as long as the C API behavior is conformant.
23 |
24 | Once the JS API is multithreading-capable, there are still expected to be some thread-local behaviors:
25 |
26 | - Buffer mapping state may be thread-local.
27 | - Implementations *should* make this state thread-global if feasible (e.g. by proxying all mapping calls to a single JS thread).
28 | - Any object which is non-shareable or non-transferable in JS may also be fully or partially non-shareable or non-transferable in Wasm (e.g. encoder objects may be thread-locked, similar to how they are not thread safe in `webgpu.h` in general). (In Rust terms, shareable = `Send`+`Sync`, transferable = `Send`.)
29 | - Implementations *may* make them shareable. (For example, proxying all encoder methods to a single thread would make them fully shareable but be inefficient; alternatively, encoder commands can be buffered, which might enable some multithreaded use-cases even if `Finish()` still must happen on the thread that created the encoder.)
30 |
31 | ## Thread Safety {#ThreadSafety}
32 |
33 | The `webgpu.h` API is thread-safe (when multithreading is supported). That is, its functions are reentrant and may be called during the execution of other functions, with the following exceptions:
34 |
35 | - Encoder objects (@ref WGPUCommandEncoder, @ref WGPUComputePassEncoder, @ref WGPURenderPassEncoder, and @ref WGPURenderBundleEncoder) are not thread-safe. Note these objects appear only in their own methods.
36 | - Additionally, in Wasm, these objects may be thread-locked, as discussed above.
37 | - API calls may not be made during @ref WGPUCallbackMode_AllowSpontaneous callbacks. See @ref CallbackReentrancy.
38 |
39 | The following _are_ thread safe:
40 |
41 | - @ref wgpuInstanceWaitAny() and @ref wgpuInstanceProcessEvents
42 | - @ref wgpuDeviceDestroy()
43 | - @ref wgpuBufferDestroy(), @ref wgpuTextureDestroy(), and @ref wgpuQuerySetDestroy()
44 |
--------------------------------------------------------------------------------
/doc/articles/Ownership.md:
--------------------------------------------------------------------------------
1 | # Ownership {#Ownership}
2 |
3 | Objects in `webgpu.h` are refcounted via the `AddRef` and `Release` functions.
4 | The refcount only changes when these methods are called explicitly (not, for example, in \ref wgpuCommandEncoderFinish or \ref wgpuQueueSubmit).
5 |
6 | Applications are *not* required to maintain refs to WebGPU objects which are internally used by other WebGPU objects (CommandBuffer→BindGroup, BindGroup→TextureView, TextureView→Texture, etc.); `webgpu.h` implementations must maintain internal references, as needed, to be internally memory safe. These *internal* references do *not* make it safe to use objects that have ever reached an *external* refcount of 0.
7 |
8 | Memory for variable-sized outputs from the API (message strings, capability arrays, etc.) is managed in different ways depending on whether they are returned values or callback arguments.
9 |
10 | ## Returned with Ownership {#ReturnedWithOwnership}
11 |
12 | Objects returned directly from the API (e.g. \ref WGPUBuffer from \ref wgpuDeviceCreateBuffer and \ref WGPUTexture via \ref WGPUSurfaceTexture from \ref wgpuSurfaceGetCurrentTexture) start with one application-owned ref.
13 | The application must `Release` this ref before losing the pointer.
14 | (The returned object may _also_ have other refs, either API-owned refs or existing application-owned refs, but this should not be relied upon.)
15 |
16 | Variable-sized outputs returned from the API (e.g. the strings in \ref WGPUAdapterInfo, from \ref wgpuAdapterGetInfo) are application-owned.
17 | The application must call the appropriate `FreeMembers` function (e.g. \ref wgpuAdapterInfoFreeMembers) before losing the member pointers.
18 | `FreeMembers` functions do not traverse the [struct chain](@ref StructChaining) and must be called separately on each struct (that has a `FreeMembers` function) in the chain.
19 |
20 | Note that such functions will *not* free any previously-allocated data: overwriting an output structure without first releasing ownership will leak the allocations; e.g.:
21 |
22 | - Overwriting the strings in \ref WGPUAdapterInfo with \ref wgpuAdapterGetInfo without first calling \ref wgpuAdapterInfoFreeMembers.
23 | - Overwriting the `texture` in \ref WGPUSurfaceTexture with \ref wgpuSurfaceGetCurrentTexture without first calling \ref wgpuTextureRelease.
24 |
25 | Note also that some structs with `FreeMembers` functions may be used as both inputs and outputs. In this case `FreeMembers` must only be used if the member allocations were made by the `webgpu.h` implementation (as an output), not if they were made by the application (as an input).
26 |
27 | ## Releasing a Device object {#DeviceRelease}
28 |
29 | Unlike other destroyable objects, releasing the last (external) ref to a device causes it to be automatically destroyed, if it isn't already lost or destroyed. Though the device object is no longer valid to use after releasing the last ref, the direct effects of @ref wgpuDeviceDestroy() still take effect:
30 |
31 | - It destroys all buffers on the device, which will unmap them and abort any pending map requests.
32 | - It loses the device and triggers the DeviceLost event.
33 |
34 | Because the device's last ref has already been released, DeviceLost callbacks triggered in this way will *not* receive a pointer to the device object. More specifically, freeing the last ref:
35 |
36 | 1. Sets a flag on the DeviceLost future (if it is uncompleted, even if it is already ready) indicating it should pass a null @ref WGPUDevice to the callback.
37 | 1. Calls @ref wgpuDeviceDestroy(), readying the DeviceLost future.
38 | - This may call the DeviceLost callback, if it is @ref WGPUCallbackMode_AllowSpontaneous.
39 | 1. Decrements the refcount, bringing it to 0.
40 |
41 | ## Callback Arguments {#CallbackArgs}
42 |
43 | Output arguments passed from the API to application callbacks include objects and message strings, which are passed to most callbacks.
44 |
45 | ### Passed with Ownership {#PassedWithOwnership}
46 |
47 | Usually, object arguments passed to callbacks start with one application-owned ref, which the application must free before losing the pointer.
48 |
49 | ### Passed without Ownership {#PassedWithoutOwnership}
50 |
51 | A.k.a. "pass by reference".
52 |
53 | Sometimes, object arguments passed to callbacks are non-owning (such as the \ref WGPUDevice in \ref WGPUDeviceLostCallback) - the application doesn't need to free them.
54 |
55 | Variable-sized and [struct-chained](@ref StructChaining) outputs passed from the API to callbacks (such as message strings in most callbacks) are always owned by the API and passed without ownership. They are guaranteed to be valid only during the callback's execution, after which the pointers passed to the callback are no longer valid.
56 |
57 | ### Implementation-Allocated Struct Chain {#ImplementationAllocatedStructChain}
58 |
59 | Some callback arguments contain [chained structs](@ref StructChaining).
60 | These are allocated by the implementation. They:
61 |
62 | - May be chained in any order.
63 | - May contain chain members not known to the application (e.g. implementation-specific extensions or extensions added in a later version of `webgpu.h`).
64 |
65 | Applications must handle these cases gracefully, by traversing the struct chain and ignoring any structs in the chain that have @ref WGPUChainedStruct::sType values other than the ones they're interested in.
66 |
67 | Implementations may consider injecting bogus structs into such chains, e.g. `{.sType=0xDEADBEEF}` in debug builds, to help developers catch invalid assumptions in their applications.
68 |
--------------------------------------------------------------------------------
/doc/articles/SentinelValues.md:
--------------------------------------------------------------------------------
1 | # Sentinel Values {#SentinelValues}
2 |
3 | ## Undefined and Null
4 |
5 | Since WebGPU is defined first as a JavaScript API, it uses the JavaScript value
6 | `undefined` in many places to indicate the lack of a value.
7 |
8 | This is usually used in dictionaries, where, for example, `{}` and
9 | `{ powerPreference: undefined }` are equivalent, and distinct from both
10 | `{ powerPreference: "high-performance" }` and `{ powerPreference: "low-power" }`.
11 |
12 | It may also be used in functions/methods. For example, `GPUBuffer`'s
13 | `getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size)`
14 | can be called equivalently as `b.getMappedRange()`, `b.getMappedRange(0)`,
15 | `b.getMappedRange(undefined)`, or `b.getMappedRange(undefined, undefined)`.
16 |
17 | To represent `undefined` in C, `webgpu.h` uses `NULL` where possible (anything
18 | behind a pointer, including objects), `*_UNDEFINED` sentinel numeric values
19 | (usually `UINT32_MAX` or similar), `*_Undefined` enum values (usually `0`),
20 | or other semantic-specific names (like `WGPU_WHOLE_SIZE`).
21 |
22 | The place that uses the type will define what to do with an undefined or
23 | other sentinel value. It may be:
24 |
25 | - Required, in which case an error is produced.
26 | - Defaulting, in which case it trivially defaults to some other value.
27 | - Optional, in which case the API accepts the sentinel value and handles it
28 | (usually this is either a special value or it has more complex defaulting,
29 | for example depending on other values).
30 |
31 | ## C-Specific Sentinel Values
32 |
33 | Undefined and null values are also used in C-specific ways in place of
34 | WebIDL's more flexible typing:
35 |
36 | - \ref WGPUStringView has a special null value
37 | - \ref WGPUFuture has a special null value
38 | - Special cases to indicate the parent struct is null, avoiding extra layers of
39 | pointers just for nullability:
40 | - \ref WGPUVertexBufferLayout::stepMode = \ref WGPUVertexStepMode_Undefined with \ref WGPUVertexBufferLayout::attributeCount
41 | - \ref WGPUBufferBindingLayout::type = \ref WGPUBufferBindingType_BindingNotUsed
42 | - \ref WGPUSamplerBindingLayout::type = \ref WGPUSamplerBindingType_BindingNotUsed
43 | - \ref WGPUTextureBindingLayout::sampleType = \ref WGPUTextureSampleType_BindingNotUsed
44 | - \ref WGPUStorageTextureBindingLayout::access = \ref WGPUStorageTextureAccess_BindingNotUsed
45 | - \ref WGPURenderPassColorAttachment::view = `NULL`
46 | - \ref WGPUColorTargetState::format = \ref WGPUTextureFormat_Undefined
47 | - \ref NullableFloatingPointType
48 |
--------------------------------------------------------------------------------
/doc/articles/Strings.md:
--------------------------------------------------------------------------------
1 | # Strings {#Strings}
2 |
3 | Strings are represented in UTF-8, using the \ref WGPUStringView struct:
4 |
5 | > \copydoc WGPUStringView
6 |
7 | ## Nullable Input String {#NullableInputString}
8 |
9 | An input string where the null value may be treated separately from the empty string (e.g. to indicate the absence of a string, or to run some non-trivial defaulting algorithm).
10 |
11 | ## Non-Null Input String {#NonNullInputString}
12 |
13 | This input string is non-nullable.
14 | If the null value is passed, it is treated as the empty string.
15 |
16 | ## Output String {#OutputString}
17 |
18 | This output string is always explicitly sized and never the null value. There is no null terminator inside the string; there may or may not be one after the end. If empty, the data pointer may or may not be null.
19 |
20 | To format explicitly-sized strings with `printf`, use `%.*s` (`%s` with a "precision" argument `.*` specifying the max number of bytes to read from the pointer).
21 |
22 | ### Localizable Human-Readable Message String {#LocalizableHumanReadableMessageString}
23 |
24 | This is a @ref OutputString which is human-readable and implementation-dependent, and may be locale-dependent.
25 | It should not be parsed or otherwise treated as machine-readable.
26 |
--------------------------------------------------------------------------------
/doc/articles/StructChaining.md:
--------------------------------------------------------------------------------
1 | # Struct-Chaining {#StructChaining}
2 |
3 | Struct-chaining is a C API pattern using linked lists and dynamic typing to extend existing structs with new members, while maintaining API and ABI compatibility. For example:
4 |
5 | An extensible struct is statically typed. It is the root of a linked list, containing a pointer to the next struct in the chain:
6 |
7 | ```c
8 | typedef struct WGPUMyStructBase {
9 | WGPUChainedStruct * nextInChain;
10 | uint32_t x;
11 | } WGPUMyBaseStruct;
12 | ```
13 |
14 | Each extension struct is a "subtype" of @ref WGPUChainedStruct; that is, its first member is a @ref WGPUChainedStruct, so that it can be safely cast to @ref WGPUChainedStruct. This allows the implementation to read its @ref WGPUChainedStruct::sType, which is some value of @ref WGPUSType ("Struct Type") that dynamically identifies the struct's type. (The `sType` may come from an implementation-specific extension; @ref WGPUSType is an "open" enum.)
15 |
16 | Once the implementation identifies the struct by its `sType`, it casts the pointer back to the appropriate struct type in order to access its contents. Setting `sType` incorrectly (or pointing to any type that isn't a subtype of @ref WGPUChainedStruct) causes undefined behavior.
17 |
18 | ```c
19 | typedef enum WGPUSType {
20 | // ...
21 | WGPUSType_MyStructExtension1 = /* ... */,
22 | WGPUSType_MyStructExtension2 = /* ... */,
23 | // ...
24 | } WGPUStype;
25 |
26 | typedef struct WGPUMyStructExtension1 {
27 | WGPUChainedStruct chain; // .chain.sType must be WGPUSType_MyStructExtension1
28 | uint32_t y;
29 | } WGPUMyStructExtension1;
30 |
31 | typedef struct WGPUMyStructExtension2 {
32 | WGPUChainedStruct chain; // .chain.sType must be WGPUSType_MyStructExtension2
33 | uint32_t z;
34 | } WGPUMyStructExtension2;
35 | ```
36 |
37 | This is used like so:
38 |
39 | ```c
40 | WGPUMyStructExtension2 ext2 = WGPU_MY_STRUCT_EXTENSION2_INIT;
41 | // .chain.sType is already set correctly by the INIT macro.
42 | // .chain.next is set to NULL indicating the end of the chain.
43 | ext2.z = 2;
44 |
45 | WGPUMyStructExtension1 ext1 = WGPU_MY_STRUCT_EXTENSION1_INIT;
46 | // .chain.sType is already set correctly by the INIT macro.
47 | // .chain.next may be set in either of two ways, equivalently:
48 | ext1.chain.next = &ext2.chain;
49 | ext1.chain.next = (WGPUChainedStruct*) &ext2;
50 | ext1.y = 1;
51 |
52 | WGPUMyStructBase base = WGPU_MY_STRUCT_BASE_INIT;
53 | // Note: base structs do not have STypes (they are statically typed).
54 | base.nextInChain = &ext1.chain;
55 | base.x = 0;
56 | ```
57 |
58 | The pointer links in a struct chain are all mutable pointers. Whether the structs in the chain are actually mutated depends on the function they are passed to (whether the struct chain is passed as an input or an output). Some structs (e.g. @ref WGPULimits) may be either an input or an output depending on the function being called.
59 |
60 | ## Struct-Chaining Error {#StructChainingError}
61 |
62 | A struct-chaining error occurs if a struct chain is incorrectly constructed (in a detectable way).
63 | They occur if and only if:
64 |
65 | - The `sType` of a struct in the chain is not valid _in the context of the chain root's static type_.
66 | - If this happens, the implementation must not downcast the pointer to access the rest of the struct (even if it would know how to downcast it in other contexts).
67 | - Multiple instances of the same `sType` value are seen in the same struct chain. (Note this also detects and disallows cycles.)
68 | - Implementation-specific extensions also _should_ avoid designs that use unbounded recursion (such as linked lists) in favor of iterative designs (arrays or arrays-of-pointers). This is to avoid stack overflows in struct handling and serialization/deserialization.
69 |
70 | Struct chains which are used in device-timeline validation/operations (e.g. @ref WGPUBufferDescriptor in @ref wgpuDeviceCreateBuffer) have their chain errors surfaced asynchronously, like any other validation error.
71 |
72 | Struct chains which are used in content-timeline operations (e.g. @ref OutStructChainError) have their chain errors surfaced synchronously, like other content-timeline validation errors.
73 |
74 | ### Out-Struct-Chain Error {#OutStructChainError}
75 |
76 | Operations which take out-struct-chains (e.g. @ref WGPULimits, in @ref wgpuAdapterGetLimits and @ref wgpuDeviceGetLimits, but not in @ref WGPUDeviceDescriptor) handle struct-chaining errors as follows:
77 |
78 | - The output struct and struct chain is not modified.
79 | - The operation produces a @ref SynchronousError (return value and log message).
80 |
81 | ## Ownership
82 |
83 | `FreeMembers` functions do not traverse the [struct chain](@ref StructChaining) and must be called separately on each struct (that has a `FreeMembers` function) in the chain.
84 | See @ref ReturnedWithOwnership.
85 |
86 | ## Callbacks
87 |
88 | See @ref PassedWithoutOwnership.
89 |
--------------------------------------------------------------------------------
/doc/articles/Surfaces.md:
--------------------------------------------------------------------------------
1 | # Surfaces {#Surfaces}
2 |
3 | Surfaces are used to continuously present color texture data to users in an OS Window, HTML `