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

Add and document many synchronous error statuses #377

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
42 changes: 42 additions & 0 deletions doc/articles/Errors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Errors {#Errors}

Errors are surfaced in several ways.

Most errors only result from incorrect use of the API and should not need to be handled at runtime.
However, a few (@ref WGPUErrorType_OutOfMemory, @ref WGPUErrorType_Internal) are potentially useful to handle.

## Device Error {#DeviceError}

These behave the same way as [in the WebGPU JavaScript API specification](https://www.w3.org/TR/webgpu/#errors-and-debugging).
They are receivable via @ref wgpuDevicePopErrorScope() and @ref WGPUDeviceDescriptor::uncapturedErrorCallbackInfo.

These errors include:

- All device-timeline errors in the WebGPU specification.
- Enum values which are numerically invalid (this is not possible in JavaScript).
- 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.
- Other content-timeline errors where specified.

## Callback Errors {#CallbackErrors}

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.

## Synchronous Errors {#SynchronousErrors}

These errors include:

- @ref StructChainingError cases.
- [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.

Generally these will return some kind of failure status (like \ref WGPUStatus_Error), or `NULL`.

### Struct-Chaining Error {#StructChainingError}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't these piggy-back on device errors when possible? There's a lot of call that take extensible structs and that return void.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically they are validation errors.


A struct-chaining error happens when the `SType` of a struct in a struct chain is not valid for that chain.
The API returns a failure status or `NULL` and produces an @ref ImplementationDefinedLogging message.

### Implementation-Defined Logging {#ImplementationDefinedLogging}

Entry points may also specify that they produce "implementation-defined logging".
These messages are logged in an implementation defined way (e.g. to an implementation-specific callback, or to a logging runtime).
They are intended to be intended to be read by humans, useful primarily for development and crash reporting.
1 change: 1 addition & 0 deletions doc/articles/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
\page articles Articles

- \subpage Asynchronous-Operations
- \subpage Errors
- \subpage Ownership
- \subpage Surfaces
- \subpage SentinelValues
Expand Down
105 changes: 82 additions & 23 deletions webgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,8 @@ typedef enum WGPUSamplerBindingType {

/**
* Status code returned (synchronously) from many operations. Generally
* indicates an invalid input like an unknown enum value or struct chaining
* error. Read the function's documentation for specific error conditions.
* indicates an invalid input like an unknown enum value or @ref StructChainingError.
* Read the function's documentation for specific error conditions.
*/
typedef enum WGPUStatus {
WGPUStatus_Success = 0x00000001,
Expand Down Expand Up @@ -832,6 +832,11 @@ typedef enum WGPUSurfaceGetCurrentTextureStatus {
* The @ref WGPUDevice configured on the @ref WGPUSurface was lost.
*/
WGPUSurfaceGetCurrentTextureStatus_DeviceLost = 0x00000007,
/**
* `0x00000008`.
* The surface is not configured, or there was a @ref StructChainingError.
*/
WGPUSurfaceGetCurrentTextureStatus_Error = 0x00000008,
WGPUSurfaceGetCurrentTextureStatus_Force32 = 0x7FFFFFFF
} WGPUSurfaceGetCurrentTextureStatus WGPU_ENUM_ATTRIBUTE;

Expand Down Expand Up @@ -2137,7 +2142,7 @@ typedef WGPUInstance (*WGPUProcCreateInstance)(WGPU_NULLABLE WGPUInstanceDescrip
* Proc pointer type for @ref wgpuGetInstanceFeatures:
* > @copydoc wgpuGetInstanceFeatures
*/
typedef void (*WGPUProcGetInstanceFeatures)(WGPUInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcGetInstanceFeatures)(WGPUInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuGetProcAddress:
* > @copydoc wgpuGetProcAddress
Expand All @@ -2154,12 +2159,12 @@ typedef WGPUStatus (*WGPUProcAdapterGetFeatures)(WGPUAdapter adapter, WGPUSuppor
* Proc pointer type for @ref wgpuAdapterGetInfo:
* > @copydoc wgpuAdapterGetInfo
*/
typedef void (*WGPUProcAdapterGetInfo)(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcAdapterGetInfo)(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuAdapterGetLimits:
* > @copydoc wgpuAdapterGetLimits
*/
typedef WGPUBool (*WGPUProcAdapterGetLimits)(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcAdapterGetLimits)(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuAdapterHasFeature:
* > @copydoc wgpuAdapterHasFeature
Expand Down Expand Up @@ -2542,7 +2547,7 @@ typedef WGPUStatus (*WGPUProcDeviceGetFeatures)(WGPUDevice device, WGPUSupported
* Proc pointer type for @ref wgpuDeviceGetLimits:
* > @copydoc wgpuDeviceGetLimits
*/
typedef WGPUBool (*WGPUProcDeviceGetLimits)(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcDeviceGetLimits)(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuDeviceGetQueue:
* > @copydoc wgpuDeviceGetQueue
Expand Down Expand Up @@ -2981,12 +2986,12 @@ typedef void (*WGPUProcSupportedFeaturesFreeMembers)(WGPUSupportedFeatures suppo
* Proc pointer type for @ref wgpuSurfaceConfigure:
* > @copydoc wgpuSurfaceConfigure
*/
typedef void (*WGPUProcSurfaceConfigure)(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcSurfaceConfigure)(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuSurfaceGetCapabilities:
* > @copydoc wgpuSurfaceGetCapabilities
*/
typedef WGPUBool (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuSurfaceGetCurrentTexture:
* > @copydoc wgpuSurfaceGetCurrentTexture
Expand All @@ -2996,7 +3001,7 @@ typedef void (*WGPUProcSurfaceGetCurrentTexture)(WGPUSurface surface, WGPUSurfac
* Proc pointer type for @ref wgpuSurfacePresent:
* > @copydoc wgpuSurfacePresent
*/
typedef void (*WGPUProcSurfacePresent)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE;
typedef WGPUStatus (*WGPUProcSurfacePresent)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE;
/**
* Proc pointer type for @ref wgpuSurfaceSetLabel:
* > @copydoc wgpuSurfaceSetLabel
Expand Down Expand Up @@ -3127,8 +3132,11 @@ WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPU_NULLABLE WGPUInstanceDescriptor
*
* @param features
* The supported instance features
*
* @returns
* Returns @ref WGPUStatus_Error (and leaves `features` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT void wgpuGetInstanceFeatures(WGPUInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUStatus wgpuGetInstanceFeatures(WGPUInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
/**
* Returns the "procedure address" (function pointer) of the named function.
* The result must be cast to the appropriate proc pointer type.
Expand Down Expand Up @@ -3158,17 +3166,22 @@ WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUStringView procName) WGPU_FUNCTION_A
* This parameter is @ref ReturnedWithOwnership.
*
* @returns
* Return @ref WGPUStatus_Error (and leaves `features` uninitialized) if:
*
* - `features` has an invalid struct chain.
* Returns @ref WGPUStatus_Error (and leaves `features` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT WGPUStatus wgpuAdapterGetFeatures(WGPUAdapter adapter, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
/**
* @param info
* This parameter is @ref ReturnedWithOwnership.
*
* @returns
* Returns @ref WGPUStatus_Error (and leaves `info` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT void wgpuAdapterGetInfo(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUStatus wgpuAdapterGetInfo(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE;
/**
* @returns
* Returns @ref WGPUStatus_Error (and leaves `limits` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT WGPUStatus wgpuAdapterGetLimits(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUFuture wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT void wgpuAdapterAddRef(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE;
Expand Down Expand Up @@ -3224,8 +3237,37 @@ WGPU_EXPORT void wgpuBindGroupLayoutRelease(WGPUBindGroupLayout bindGroupLayout)
* @{
*/
WGPU_EXPORT void wgpuBufferDestroy(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE;
/**
* @param offset
* Byte offset relative to the beginning of the buffer.
*
* @param size
* Byte size of the range to get. The returned pointer is valid for exactly this many bytes.
*
* @returns
* Returns a const pointer to beginning of the mapped range.
* It must not be written; writing to this range causes undefined behavior.
* Returns `NULL` with @ref ImplementationDefinedLogging if:
*
* - There is any content-timeline error as defined in the WebGPU specification for `getMappedRange()` (alignments, overlaps, etc.)
*/
WGPU_EXPORT void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBufferMapState wgpuBufferGetMapState(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE;
/**
* @param offset
* Byte offset relative to the beginning of the buffer.
*
* @param size
* Byte size of the range to get. The returned pointer is valid for exactly this many bytes.
*
* @returns
* Returns a mutable pointer to beginning of the mapped range.
* It may be written, but reading is undefined behavior unless the buffer was also mapped with @ref WGPUMapMode_Read.
* Returns `NULL` with @ref ImplementationDefinedLogging if:
*
* - There is any content-timeline error as defined in the WebGPU specification for `getMappedRange()` (alignments, overlaps, etc.)
* - The buffer is not mapped with @ref WGPUMapMode_Write.
*/
WGPU_EXPORT void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT uint64_t wgpuBufferGetSize(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBufferUsage wgpuBufferGetUsage(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE;
Expand Down Expand Up @@ -3340,12 +3382,14 @@ WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE;
* This parameter is @ref ReturnedWithOwnership.
*
* @returns
* Return @ref WGPUStatus_Error (and leaves `features` uninitialized) if:
*
* - `features` has an invalid struct chain.
* Returns @ref WGPUStatus_Error (and leaves `features` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT WGPUStatus wgpuDeviceGetFeatures(WGPUDevice device, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBool wgpuDeviceGetLimits(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
/**
* @returns
* Returns @ref WGPUStatus_Error (and leaves `limits` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT WGPUStatus wgpuDeviceGetLimits(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUQueue wgpuDeviceGetQueue(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUBool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUFuture wgpuDevicePopErrorScope(WGPUDevice device, WGPUPopErrorScopeCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE;
Expand Down Expand Up @@ -3431,6 +3475,10 @@ WGPU_EXPORT void wgpuQuerySetRelease(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIB
WGPU_EXPORT WGPUFuture wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, WGPUQueueWorkDoneCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT void wgpuQueueSetLabel(WGPUQueue queue, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE;
/**
* Produces a @ref DeviceError if `size` is not a multiple of 4
* (in addition to device-timeline errors defined by the WebGPU specification).
*/
WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT void wgpuQueueAddRef(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE;
Expand Down Expand Up @@ -3572,12 +3620,18 @@ WGPU_EXPORT void wgpuSupportedFeaturesFreeMembers(WGPUSupportedFeatures supporte
*/
/**
* Configures parameters for rendering to `surface`.
* Produces a @ref DeviceError for all content-timeline errors defined by the WebGPU specification
* (formats that are not supported by the surface or not enabled on the device).
*
* See @ref Surface-Configuration for more details.
*
* @param config
* The new configuration to use.
*
* @returns
* Returns @ref WGPUStatus_Error if there was a @ref StructChainingError.
*/
WGPU_EXPORT void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUStatus wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE;
/**
* Provides information on how `adapter` is able to use `surface`.
* See @ref Surface-Capabilities for more details.
Expand All @@ -3591,11 +3645,13 @@ WGPU_EXPORT void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfigurat
* This parameter is @ref ReturnedWithOwnership.
*
* @returns
* TODO make this WGPUStatus instead of a boolean.
* Returns @ref WGPUStatus_Error (and leaves `capabilities` unchanged) if there was a @ref StructChainingError.
*/
WGPU_EXPORT WGPUBool wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUStatus wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE;
/**
* Returns the @ref WGPUTexture to render to `surface` this frame along with metadata on the frame.
* Returns `NULL` and @ref WGPUSurfaceGetCurrentTextureStatus_Error if the surface is not configured.
*
* See @ref Surface-Presenting for more details.
*
* @param surfaceTexture
Expand All @@ -3605,8 +3661,11 @@ WGPU_EXPORT void wgpuSurfaceGetCurrentTexture(WGPUSurface surface, WGPUSurfaceTe
/**
* Shows `surface`'s current texture to the user.
* See @ref Surface-Presenting for more details.
*
* @returns
* Returns @ref WGPUStatus_Error if the surface doesn't have a current texture.
*/
WGPU_EXPORT void wgpuSurfacePresent(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE;
WGPU_EXPORT WGPUStatus wgpuSurfacePresent(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE;
/**
* Modifies the label used to refer to `surface`.
*
Expand Down
Loading
Loading