WebGPU-C++

repository·main·Indexed 19 days ago

https://github.com/eliemichel/webgpu-cpp

A single-file, zero-overhead syntactic sugar wrapper for the WebGPU native C API. It provides an idiomatic C++ experience featuring the wgpu namespace, object notation, scoped enums, and capturing closures for asynchronous callbacks without altering the underlying memory layout. Supports Dawn, wgpu-native, and Emscripten backends.

Tokens
1.2K
Snippets
6
Records
7
Agent score
17%

What's inside webgpu-cpp

  1. Use the wgpu namespace and object notation

    main

    WebGPU-C++ wraps the C API into a wgpu namespace and converts procedural functions into object-oriented methods. This makes the API more idiomatic for C++.

    • Namespaces: Instead of WGPUInstance, use wgpu::Instance.
    • Object Notation: Functions that take an object as their first argument are exposed as methods of that object. For example, wgpuDeviceCreateBuffer(device, ...) becomes device.createBuffer(...).
    • References: Descriptors are passed by reference (const Descriptor&) rather than by pointer (const Descriptor*).
    // C++ style usage
    wgpu::InstanceDescriptor desc = {};
    wgpu::Instance instance = wgpu::createInstance(desc);
    
    // Object notation example
    auto buffer = device.createBuffer(bufferDescriptor);
  2. Use capturing closures for asynchronous callbacks

    main

    Instead of passing a void* userdata pointer to asynchronous operations (the C way), WebGPU-C++ allows you to use C++ capturing lambdas. This allows you to capture local context directly into the callback.

    // C++ style with capturing lambda
    buffer.mapAsync(wgpu::MapMode::Read, 0, 16, [&context](wgpu::BufferMapAsyncStatus status) {
        std::cout << "Buffer mapped with status " << status << std::endl;
        unsigned char* bufferData = (unsigned char*)context.buffer.getMappedRange(0, 16);
        context.buffer.unmap();
    });
  3. Use scoped enumerations

    main
    WebGPU-C++ converts unscoped C enums into C++ enum class types. This provides stronger typing and cleaner syntax. Instead of long prefixes like WGPURequestAdapterStatus_Success, you use the scoped syntax: wgpu::RequestAdapterStatus::Success.
  4. Setup WebGPU-C++ in your project

    main

    To use the WebGPU-C++ wrapper, follow these steps:

    1. Copy the header: Copy the appropriate webgpu.hpp file from the repository to your project based on your backend:

      • dawn/webgpu.hpp for Dawn
      • wgpu-native/webgpu.hpp for wgpu-native
      • emscripten/webgpu.hpp for Emscripten Note: Ensure the version matches your backend's git tag.
    2. Include the header: Replace #include <webgpu/webgpu.h> with #include "webgpu/webgpu.hpp" in your source files.

    3. Implement the header: In exactly one of your source files, define WEBGPU_CPP_IMPLEMENTATION before including the header to generate the implementation.

    #define WEBGPU_CPP_IMPLEMENTATION
    #include "webgpu/webgpu.hpp"
  5. Set default values for descriptors

    main

    To avoid manually initializing every field in a descriptor, WebGPU-C++ provides a way to synchronize fields with the official WebGPU specification defaults.

    • setDefault(): Recursively sets all fields of a descriptor to their default values.
    • Default constant: A compact way to initialize a descriptor with default values.

    Note: nextInChain is automatically set to nullptr by default to reduce overhead.

    // Using setDefault()
    BindGroupLayoutEntry bindGroupLayoutEntry;
    bindGroupLayoutEntry.setDefault();
    
    // Using the Default constant
    BindGroupLayoutEntry bindGroupLayoutEntry = Default;
  6. Fetch default values from the WebGPU specification

    main

    The fetch_default_values.py script scrapes the official WebGPU specification to create a defaults.txt file used during header generation. This ensures descriptors are initialized according to the spec.

    python fetch_default_values.py -u <URL_TO_SPEC> -d output_defaults.txt
  7. Generate the webgpu.hpp binding with generate.py

    main

    If you have a custom or newer version of webgpu.h, you can generate a new webgpu.hpp using the provided Python script.

    Requirements: Python 3.10+

    Common Options:

    • -o OUTPUT: Path to output the generated webgpu.hpp.
    • -u HEADER_URL: URL of the official webgpu.h (can be used multiple times for extensions).
    • -d DEFAULTS: File listing default values for descriptor fields.
    • --no-scoped-enums: Disable C++ scoped enums.
    • --use-non-member-procedures: Include methods that are not members of any object.
    python generate.py -u wgpu-native/webgpu.h -u wgpu-native/wgpu.h -t webgpu.template.hpp -o wgpu-native/webgpu.hpp -d defaults.txt -d extra-defaults.txt