webgpu-headers

repository·main·Indexed 20 days ago

https://github.com/webgpu-native/webgpu-headers

Provides the stable C header webgpu.h, serving as a native C API equivalent to the WebGPU JavaScript API. It acts as a portable interface for implementations such as Dawn, wgpu-native, and Emdawnwebgpu. The repository includes the machine-readable sources of truth (webgpu.yml and webgpu.json) used to generate the header and official documentation.

Tokens
9.9K
Snippets
12
Records
51
Agent score
69%

What's inside webgpu-headers

  1. Handle Callback Errors

    main

    Callback-based APIs in webgpu-native behave similarly to Promise-returning APIs in JavaScript. Instead of separate resolve/reject callbacks, a single callback is used which receives a status code.

    • Success: A valid result is returned with an empty message string (represented as {NULL, 0}).
    • Failure: An invalid result is returned with a non-empty message string.
  2. Understand the machine-readable source of truth: webgpu.yml and webgpu.json

    main

    The C API and its documentation are driven by two machine-readable files: webgpu.yml and webgpu.json (which contain the same data in different formats).

    These files serve as the single source of truth for:

    1. Generating the official webgpu.h header.
    2. Generating the official documentation.
    3. Providing data for third-party tools and language bindings (e.g., creating wrappers for other programming languages).

    If you are building language bindings and require additional high-level or semantic information to be available in these files, you can contribute to the project to include that data in webgpu.yml.

  3. Understand Device destruction and the DeviceLost event

    main

    Releasing the last external reference to a WGPUDevice triggers automatic destruction if the device is not already lost or destroyed.

    Effects of releasing the last ref:

    1. It sets a flag on the DeviceLost future to pass a null WGPUDevice to the callback.
    2. It calls wgpuDeviceDestroy(), which triggers the DeviceLost event.
    3. It decrements the refcount to 0.

    Destruction side-effects: Even if you release the last ref instead of calling wgpuDeviceDestroy() explicitly, the following will occur:

    • All buffers on the device are destroyed (unmapped and pending map requests aborted).
    • The device is lost, triggering the DeviceLost event.

    Note on Callbacks: Because the last ref is gone, any DeviceLost callback triggered this way will receive a null pointer for the device.

  4. How double is used as a supertype for numeric values

    main

    Following the JavaScript API specification, the double type (equivalent to JS Number) is used as a supertype for various numeric subtypes. The actual numeric type used is determined by the context of the operation.

    Key usage patterns include:

    • WGPUColor: Acts as a supertype for f32, u32, or i32. For example, in WGPURenderPassColorAttachment::clearValue, the specific type depends on the texture format. In wgpuRenderPassEncoderSetBlendConstant, the type is f32.
    • WGPUConstantEntry::value: Acts as a supertype for all overrideable WGSL types (such as bool, f32, u32, i32, f16, etc.). The specific type depends on the WGSL type of the constant being overridden.
  5. Handle Output Strings

    main

    An Output String is always explicitly sized and is never null.

    Key characteristics:

    • There is no guaranteed null terminator inside the string (there may or may not be one after the end).
    • If the string is empty, the data pointer may or may not be null.

    Formatting with printf: Because these strings are explicitly sized and may lack a null terminator, you must use the %.*s format specifier. This requires providing a 'precision' argument (.*) to specify the maximum number of bytes to read from the pointer.

    // Example of formatting an explicitly-sized output string with printf
    // Assuming 'ptr' is the data pointer and 'size' is the length
    printf("%.*s\n", size, ptr);
  6. Understand Mapped Range Behavior and Error Conditions

    main

    When using buffer mapping methods like wgpuBufferGetMappedRange, wgpuBufferGetConstMappedRange, wgpuBufferReadMappedRange, or wgpuBufferWriteMappedRange, calls will fail (returning NULL or WGPUStatus_Error) if they violate WebGPU specification rules for getMappedRange().

    Common failure reasons include:

    • The buffer is not currently mapped.
    • The requested offset or size violates alignment constraints.
    • The requested range overlaps with another active range (except for overlaps between const ranges in C on non-Wasm targets).
    • wgpuBufferGetMappedRange or wgpuBufferWriteMappedRange is called on a buffer that was not mapped with WGPUMapMode_Write.
  7. Handle Synchronous Errors

    main

    Synchronous errors occur immediately during an API call. These include:

    • OutStructChainError cases.
    • Certain content-timeline errors (check specific documentation for how they are exposed).

    When a synchronous error occurs, the API will generally return a failure status (such as WGPUStatus_Error) or NULL, and the implementation may produce an implementation-defined logging message.

  8. Handle Device Errors

    main

    Device errors in webgpu-native follow the WebGPU JavaScript specification. They include device-timeline errors, numerically invalid enum values, enum values requiring unenabled features (content-timeline errors), and NonFiniteFloatValueError.

    You can capture these errors using:

    1. wgpuDevicePopErrorScope() to retrieve errors from the current error scope stack.
    2. The uncapturedErrorCallbackInfo field in WGPUDeviceDescriptor to handle errors that were not caught by a scope.
  9. Representing null values in nullable floating-point types

    main

    When working with nullable or optional floating-point types (float or double), the value NaN is used to represent a null value.

    Important Implementation Note: To check if a value represents a null, you must use isnan(value) != 0. Do not use an equality check with a NaN constant (e.g., if (value == NaN)), because NaN == NaN is always false in floating-point logic.

  10. Understand WebGPU extension naming conventions and registries

    main

    To ensure compatibility, implementation-specific extensions follow a strict naming and numbering convention.

    Prefix and Enum Block Registry

    Implementations use specific prefixes for new functions/objects and assigned blocks for new enum values. If an implementation is not listed below, it should be added to this registry.

    ImplementationPrefixEnum BlockDescription
    Standard(none)0x0000_????Extensions standardized in webgpu.h
    (Reserved)-0x0001_????Reserved for future use
    (Not used)-0x0002_????Do not use this block (historical)
    wgpu-nativeWgpu0x0003_????-
    EmscriptenEmscripten0x0004_????-
    DawnDawn0x0005_????-
    WagyuWagyu0x0006_????-

    Note: All negative values (MSB set to 1) are reserved for future use.

    Extension Design Principles

    When working with or implementing extensions, adhere to these rules:

    • Enums: Must include a Force32 = 0x7FFFFFFF value to ensure a stable 32-bit ABI.
    • Bitflags: Must always be 64-bit.
    • Structures: Should be extensible using nextInChain, or associated with an extensible struct (child, sibling, or parent).