Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: implementation-allocated struct chains, and FreeMembers traversal #476

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions doc/articles/Ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ The application must `Release` this ref before losing the pointer.
(The returned object may _also_ have other refs, either API-owned refs or existing application-owned refs, but this should not be relied upon.)

Variable-sized outputs returned from the API (e.g. the strings in \ref WGPUAdapterInfo, from \ref wgpuAdapterGetInfo) are application-owned.
The application must call the appropriate `FreeMembers` function (e.g. \ref wgpuAdapterInfoFreeMembers) before losing the pointers.
The application must call the appropriate `FreeMembers` function (e.g. \ref wgpuAdapterInfoFreeMembers) before losing the member pointers.
`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.

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.:

- Overwriting the strings in \ref WGPUAdapterInfo with \ref wgpuAdapterGetInfo without first calling \ref wgpuAdapterInfoFreeMembers.
- Overwriting the `texture` in \ref WGPUSurfaceTexture with \ref wgpuSurfaceGetCurrentTexture without first calling \ref wgpuTextureRelease.

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 applcation (as an input).
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).

## Callback Arguments {#CallbackArgs}

Expand All @@ -35,5 +36,16 @@ A.k.a. "pass by reference".

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.

Variable-sized outputs passed from the API to callbacks (such as message strings in most callbacks) are always owned by the API and guaranteed to be valid only during the callback's execution, after which the pointers passed to the callback are no longer valid.
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.

### Implementation-Allocated Struct Chain {#ImplementationAllocatedStructChain}

Some callback arguments contain [chained structs](@ref StructChaining).
These are allocated by the implementation. They:

- May be chained in any order.
- May contain chain members not known to the application (e.g. implementation-specific extensions or extensions added in a later version of `webgpu.h`).

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.

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.
7 changes: 6 additions & 1 deletion doc/articles/StructChaining.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ Operations which take out-struct-chains (e.g. @ref WGPULimits, in @ref wgpuAdapt

## Ownership

TODO(#264): Document whether `FreeMembers` functions traverse the chain (see @ref ReturnedWithOwnership).
`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.
See @ref ReturnedWithOwnership.

## Callbacks

See @ref PassedWithoutOwnership.
12 changes: 12 additions & 0 deletions webgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,8 @@ typedef void (*WGPUBufferMapCallback)(WGPUMapAsyncStatus status, WGPUStringView
* See also @ref CallbackError.
*
* @param compilationInfo
* This argument contains multiple @ref ImplementationAllocatedStructChain roots.
* Arbitrary chains must be handled gracefully by the application!
* This parameter is @ref PassedWithoutOwnership.
*/
typedef void (*WGPUCompilationInfoCallback)(WGPUCompilationInfoRequestStatus status, struct WGPUCompilationInfo const * compilationInfo, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE;
Expand Down Expand Up @@ -1862,6 +1864,11 @@ typedef struct WGPUCommandEncoderDescriptor {
})

/**
* TODO
*
* This is an @ref ImplementationAllocatedStructChain root.
* Arbitrary chains must be handled gracefully by the application!
*
* Default values can be set using @ref WGPU_COMPILATION_MESSAGE_INIT as initializer.
*/
typedef struct WGPUCompilationMessage {
Expand Down Expand Up @@ -3608,6 +3615,11 @@ typedef struct WGPUBlendState {
})

/**
* TODO
*
* This is an @ref ImplementationAllocatedStructChain root.
* Arbitrary chains must be handled gracefully by the application!
*
* Default values can be set using @ref WGPU_COMPILATION_INFO_INIT as initializer.
*/
typedef struct WGPUCompilationInfo {
Expand Down
9 changes: 8 additions & 1 deletion webgpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,9 @@ structs:
- name: compilation_info
doc: |
TODO

This is an @ref ImplementationAllocatedStructChain root.
Arbitrary chains must be handled gracefully by the application!
type: extensible
members:
- name: messages
Expand All @@ -1825,6 +1828,9 @@ structs:
- name: compilation_message
doc: |
TODO

This is an @ref ImplementationAllocatedStructChain root.
Arbitrary chains must be handled gracefully by the application!
type: extensible
members:
- name: message
Expand Down Expand Up @@ -3251,7 +3257,8 @@ callbacks:
type: enum.compilation_info_request_status
- name: compilation_info
doc: |
TODO
This argument contains multiple @ref ImplementationAllocatedStructChain roots.
Arbitrary chains must be handled gracefully by the application!
type: struct.compilation_info
pointer: immutable
passed_with_ownership: false
Expand Down
Loading