wgpu Graphics API

repository·trunk·Indexed 12 days ago

https://github.com/gfx-rs/wgpu

A cross-platform, safe, pure-Rust graphics API based on the WebGPU standard. It provides a unified interface for Vulkan, Metal, D3D12, and OpenGL, and can run in web browsers via WebAssembly.

Tokens
44.5K
Snippets
141
Records
214
Agent score
96%

What's inside wgpu

  1. Platform-specific dependencies for Linux, Android, and FreeBSD

    trunk
    The wgpu-core/platform-deps/linux-android-bsd crate provides platform-specific features required for wgpu to function correctly on certain operating systems. These features are conditionally enabled only when the target operating system is linux, android, or freebsd. For a detailed list of the specific features provided by this crate, refer to the wgpu-hal Cargo.toml file.
  2. Identify supported wgpu_hal backends

    trunk

    wgpu_hal provides implementations for several graphics APIs, categorized into primary and secondary backends.

    • Vulkan: Available on Linux, Android, and Windows (via ash). On macOS, it requires [MoltenVK].
    • Metal: Available on macOS (via metal).
    • Direct3D 12: Available on Windows (via windows).

    Secondary Backends (Partial implementation)

    • GL: Available wherever OpenGL, OpenGL ES, or WebGL are available. See the gles module for details. Note that secondary backends may impose more overhead than primary backends.

    To check for specific feature support or missing capabilities on an adapter, inspect ExposedAdapter::capabilities which returns DownlevelCapabilities.

  3. Explore framework-based wgpu examples

    trunk
    Framework examples use a common infrastructure to handle wgpu initialization, window creation, and event handling. This allows the code to focus on specific graphics or compute logic. They are categorized into Graphics, Compute, and Combined workflows.
  4. Supported platforms and APIs for wgpu

    trunk

    wgpu is a cross-platform API that runs natively on several backends. Support levels vary by platform:

    APIWindowsLinux/AndroidmacOS/iOSWeb (wasm)
    Vulkan🌋
    Metal
    DX12
    OpenGL🆗 (GL 3.3+)🆗 (GL ES 3.0+)📐🆗 (WebGL2)
    WebGPU

    Legend:

    • ✅: First Class Support
    • 🆗: Downlevel/Best Effort Support
    • 🌋: Requires MoltenVK translation layer (macOS)
    • 📐: Requires ANGLE translation layer. On macOS/iOS, use the angle feature. On Windows, gles uses WGL by default; build with cfg(windows_angle) to use ANGLE instead.
  5. What is naga-types and when to use it

    trunk
    naga-types is a shared crate containing type definitions used by both naga and wgpu. It exists to resolve a circular dependency: naga is an independent crate that cannot depend on wgpu, and wgpu may eventually treat naga as an optional dependency. By using naga-types, both crates can access a common set of types without creating a dependency loop.
  6. Understand the purpose of wgpu-core-deps-apple

    trunk

    The wgpu-core-deps-apple crate is a platform-specific dependency used to ensure that platform-specific and feature-specific logic works correctly on Apple platforms. The features enabled in this crate are only active when the compilation target vendor is apple (target_vendor = "apple").

    For a detailed list of which features are enabled and how they interact with the hardware abstraction layer, refer to the wgpu-hal Cargo.toml file.

  7. Use conservative rasterization for voxelization

    trunk

    Conservative rasterization is a native extension with limited support that ensures any pixel touched by a triangle primitive is rasterized. This is particularly useful for advanced techniques like real-time voxelization where standard rasterization might miss thin triangles or small features.

    In the provided example, the technique is demonstrated by:

    1. Rendering a triangle to a low-resolution target.
    2. Upscaling that target using nearest-neighbor filtering.
    3. Rendering the outlines in the original resolution using the same vertex shader, specifically enabling conservative rasterization for those pixels (depicted as red in the demo).
  8. How Ray Queries work in Naga

    trunk

    Ray queries (inline raytracing) allow you to perform ray-scene intersections directly within a shader. The process follows a specific lifecycle:

    1. Initialize: Call rayQueryInitialize with a RayDesc and an acceleration structure. This sets up the query state.
    2. Traverse: Call rayQueryProceed to step through the scene. This function returns true if it finds a Candidate intersection (a hit in a non-opaque Blas) and false if it finds a Committed intersection or no more hits.
    3. Handle Intersections:
      • Candidate Intersections: These are non-guaranteed closest hits. Use rayQueryGetCandidateIntersection to inspect them. They are useful for custom intersection logic.
      • Committed Intersections: These are the closest valid hits found so far. Use rayQueryGetCommittedIntersection to retrieve details.
    4. Terminate: Use rayQueryTerminate to abort the query. The next rayQueryProceed will return false, and subsequent calls to rayQueryGetCommittedIntersection will return the closest committed result found up to that point.

    Note on Candidate vs Committed:

    • A Candidate intersection interrupts traversal but might not be the closest hit.
    • A Committed intersection is a confirmed hit that the user has decided is valid (or the closest one found).
    // Example lifecycle sketch
    rayQueryInitialize(rq, accel_struct, ray_desc);
    while (rayQueryProceed(rq)) {
        // Handle candidate intersections if needed
    }
    let hit = rayQueryGetCommittedIntersection(rq);
    if (hit.kind != RAY_QUERY_INTERSECTION_NONE) {
        // Use hit data
    }
  9. Accessing Mesh Shader data in Fragment Shaders

    trunk

    Fragment shaders can access both vertex and primitive data from a mesh shader pipeline:

    1. Vertex Data: Accessed normally as if from a standard vertex shader.
    2. Primitive Data: Can be accessed if the input is decorated with @per_primitive.

    Constraints:

    • The @per_primitive decoration can only be applied to inputs or struct members decorated with @location.
    • The locations of vertex and primitive inputs must not overlap.
    • Using @per_primitive requires the wgpu_mesh_shader extension to be enabled.
    • If the mesh shader outputs primitive_index (a builtin), the fragment shader must explicitly input it if it intends to use it.
  10. Understand Cooperative Matrix Types and Roles

    trunk

    A cooperative matrix is a value type parameterized by tile size (M×N), scalar element type T, and a role R. The role determines how the matrix participates in a multiply-accumulate operation (A * B + C):

    • A: Left operand. Shape is M×K.
    • B: Right operand. Shape is K×N.
    • C: Accumulator/result. Shape is M×N.

    Important: Roles are part of the type and are not interchangeable. You must use combinations of (M, N, T, R) that are explicitly supported by the hardware, which can be queried via Adapter::cooperative_matrix_properties.

    // Example: 8x8 single-precision tiles
    alias CoopMatA = coop_mat8x8<f32, A>;
    alias CoopMatB = coop_mat8x8<f32, B>;
    alias CoopMatC = coop_mat8x8<f32, C>;
    
    // Example: 16x16 mixed precision (f16 inputs, f32 accumulator)
    alias CoopMat16x16A = coop_mat16x16<f16, A>;
    alias CoopMat16x16B = coop_mat16x16<f16, B>;
    alias CoopMat16x16C = coop_mat16x16<f32, C>;
  11. How Mesh Shaders work in WGSL

    trunk

    Mesh shaders are the primary stage for generating geometry. They are invoked in a grid of workgroups.

    Key Requirements:

    • Attribute: Must use the @mesh(VAR) attribute, where VAR is a workgroup variable storing the output information.
    • Payload: If a task shader is present in the pipeline, the mesh shader must also have a @payload(G) attribute with matching variable sizes. Mesh shaders can read from this payload but cannot write to it.
    • Output Structure: The workgroup variable VAR must be a struct with exactly 4 fields:
      1. @builtin(vertex_count): u32 (number of vertices to draw).
      2. @builtin(primitive_count): u32 (number of primitives to draw).
      3. @builtin(vertices): An array of vertex output types V.
      4. @builtin(primitives): An array of primitive output types P.

    Primitive Output (P) Details:

    • Must be a struct.
    • Must contain exactly one member with one of these attributes:
      • @builtin(triangle_indices), @builtin(line_indices), or @builtin(point_index): Type vec3<u32>, vec2<u32>, or u32. These act as indices into the generated vertex array.
      • @builtin(cull_primitive): Type bool. If true, the primitive is skipped.
    • All members decorated with @location must also be decorated with @per_primitive.

    Capabilities:

    • Can use compute and mesh shader builtin inputs.
    • Can use view_index and (if no task shader is present) draw_id.
    struct MeshOutput {
        @builtin(vertices) vertices: array<VertexOutput, 64>,
        @builtin(primitives) primitives: array<PrimitiveOutput, 128>,
        @builtin(vertex_count) vertex_count: u32,
        @builtin(primitive_count) primitive_count: u32,
    }
    
    var<workgroup> mesh_output: MeshOutput;
    
    @mesh(mesh_output)
    @workgroup_size(64)
    fn my_mesh_main() {
        // ... populate mesh_output ...
    }