Skip to documentation
SLOP

tiny.gpu.webgpu

Reference tiny.gpu webgpu

Defined in tiny.gpu.

API (5)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.gpuwebgpu
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callstest sourcelib.gpu.src.webgputest: webgpu backend creates owned wg...test sourcelib.gpu.src.webgputest: webgpu backend rejects non-wgsl...test sourcelib.gpu.src.webgputest: webgpu backend reports wgsl cap...test sourcelib.gpu.src.webgputest: webgpu backend runtime entry po...webgpu.Statedeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.gpu.src.webgputest: webgpu backend creates owned wg...test sourcelib.gpu.src.webgputest: webgpu backend rejects non-wgsl...test sourcelib.gpu.src.webgputest: webgpu backend reports wgsl cap...test sourcelib.gpu.src.webgputest: webgpu backend runtime entry po...webgpu.Statehandle
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.gpu.src.webgputest: webgpu backend creates owned wg...test sourcelib.gpu.src.webgputest: webgpu backend rejects non-wgsl...test sourcelib.gpu.src.webgputest: webgpu backend reports wgsl cap...test sourcelib.gpu.src.webgputest: webgpu backend runtime entry po...webgpu.Stateinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.gpu.src.webgpuqueryCapabilitieswebgpustaticCapabilities
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/gpu/src/root.zig:11

zig
pub const webgpu = @import("webgpu.zig");

Source: lib/gpu/src/webgpu.zig

zig
const std = @import("std");const builtin = @import("builtin");const backend = @import("root.zig");const host = @import("host.zig");const Allocator = std.mem.Allocator;const browserish = builtin.target.cpu.arch.isWasm() and builtin.target.os.tag == .freestanding;pub const State = struct {    allocator: Allocator,    pub fn init(allocator: Allocator) State {        return .{            .allocator = allocator,        };    }    pub fn deinit(_: *State) void {}    pub fn handle(self: *State) backend.BackendHandle {        return .{            .ptr = self,            .vtable = &vtable,            .kind = .webgpu,        };    }};pub fn staticCapabilities() backend.BackendCapabilities {    return .{        .identity = .{            .backend = .webgpu,            .family = .webgpu,            .name = "webgpu",        },        .memory = .{            .shared_memory_per_threadgroup_bytes = 16 * 1024,            .min_buffer_alignment = 4,        },        .threadgroup = .{            .max_threads = 256,            .max_blocks = .{ 65_535, 65_535, 65_535 },            .max_threads_per_dim = .{ 256, 256, 64 },            .max_grid_per_dim = .{ 65_535, 65_535, 65_535 },            .shared_memory_bytes = 16 * 1024,        },        .dtypes = backend.DTypeSet.init(&.{ .i1, .i32, .u32, .f32, .key }),        .layouts = .{            .row_major = true,            .compact_strides = true,            .broadcast_strides = true,            .tiled = true,            .opaque_backend_layouts = true,        },        .runtime = .{            .driver_loaded = browserish,            .device_context = browserish,        },        .artifact_formats = backend.ArtifactFormatSet.init(&.{.webgpu_wgsl}),    };}fn queryCapabilities(_: *anyopaque) backend.BackendError!backend.BackendCapabilities {    return staticCapabilities();}fn createArtifact(ptr: *anyopaque, request: backend.CompileRequest) backend.BackendError!backend.KernelArtifact {    if (request.requested_format != .webgpu_wgsl) return error.UnsupportedOperation;    const state: *State = @ptrCast(@alignCast(ptr));    return switch (request.payload) {        .text => |source| createWgslArtifact(state, request, source),        .bytes => |source| createWgslArtifact(state, request, source),        .none => error.UnsupportedOperation,        .words_u32 => error.UnsupportedArtifactFormat,    };}fn createWgslArtifact(    state: *State,    request: backend.CompileRequest,    source: []const u8,) backend.BackendError!backend.KernelArtifact {    if (request.kernel_name.len == 0) return error.InvalidArtifact;    if (source.len == 0) return error.InvalidArtifact;    var artifact = backend.KernelArtifact.init(state.allocator, .{        .backend = .webgpu,        .format = .webgpu_wgsl,        .entry_name = request.kernel_name,        .argument_count = request.argument_count,        .scalar_argument_count = request.scalar_argument_count,        .diagnostic_id = request.diagnostic_id,    }) catch return error.OutOfMemory;    errdefer artifact.deinit();    try artifact.setOwnedText(source);    return artifact;}fn loadArtifact(_: *anyopaque, artifact: *const backend.KernelArtifact) backend.BackendError!backend.LoadedArtifact {    if (artifact.backend != .webgpu or artifact.format != .webgpu_wgsl) return error.InvalidArtifact;    if (artifact.entry_name.len == 0) return error.InvalidArtifact;    const source = switch (artifact.payload) {        .text => |payload| payload,        else => return error.InvalidArtifact,    };    if (source.len == 0) return error.InvalidArtifact;    if (comptime !browserish) return error.RuntimeUnavailable;    const id = Host.artifactLoad(        host.pointer(source),        source.len,        host.pointer(artifact.entry_name),        artifact.entry_name.len,        artifact.argument_count,    );    if (id == 0) return error.RuntimeUnavailable;    return .{        .id = id,        .backend = .webgpu,        .format = .webgpu_wgsl,    };}fn allocateBuffer(_: *anyopaque, request: backend.BufferAllocation) backend.BackendError!backend.BufferHandle {    if (comptime !browserish) return error.RuntimeUnavailable;    const id = Host.bufferAlloc(request.byte_size, request.alignment);    if (id == 0) return error.OutOfMemory;    return .{        .id = id,        .backend = .webgpu,        .byte_size = request.byte_size,        .ownership = .backend,    };}fn writeBuffer(_: *anyopaque, request: backend.BufferWriteRequest) backend.BackendError!void {    if (comptime !browserish) return error.RuntimeUnavailable;    try host.status(Host.bufferWrite(request.handle.id, host.pointer(request.bytes), request.bytes.len));}fn readBuffer(_: *anyopaque, request: backend.BufferReadRequest) backend.BackendError!void {    if (comptime !browserish) return error.RuntimeUnavailable;    try host.status(Host.bufferRead(request.handle.id, host.pointer(request.bytes), request.bytes.len));}fn launch(ptr: *anyopaque, request: backend.LaunchRequest) backend.BackendError!void {    if (comptime !browserish) return error.RuntimeUnavailable;    const state: *State = @ptrCast(@alignCast(ptr));    const loaded = request.loaded_artifact orelse return error.InvalidArtifact;    if (loaded.backend != .webgpu or loaded.format != .webgpu_wgsl) return error.InvalidArtifact;    const bindings = state.allocator.alloc(host.Binding, request.buffers.len) catch return error.OutOfMemory;    defer state.allocator.free(bindings);    for (request.buffers, bindings) |source, *dest| dest.* = try host.binding(source);    const scalars = state.allocator.alloc(host.Scalar, request.scalar_arguments.len) catch return error.OutOfMemory;    defer state.allocator.free(scalars);    for (request.scalar_arguments, scalars) |source, *dest| dest.* = host.scalar(source);    try host.status(Host.launch(        loaded.id,        host.pointer(bindings),        bindings.len,        host.pointer(scalars),        scalars.len,        request.geometry.grid[0],        request.geometry.grid[1],        request.geometry.grid[2],        request.geometry.threadgroup[0],        request.geometry.threadgroup[1],        request.geometry.threadgroup[2],        request.geometry.dynamic_shared_memory_bytes,    ));}fn synchronize(_: *anyopaque, _: backend.SyncRequest) backend.BackendError!void {}fn destroyObject(_: *anyopaque, id: backend.BackendObjectId) void {    if (comptime browserish) Host.objectDestroy(id);}const BrowserHost = struct {    extern "accy" fn accy_webgpu_artifact_load(        source_ptr: usize,        source_len: usize,        entry_ptr: usize,        entry_len: usize,        argument_count: u32,    ) callconv(.c) u64;    extern "accy" fn accy_webgpu_buffer_alloc(byte_size: usize, alignment: u32) callconv(.c) u64;    extern "accy" fn accy_webgpu_buffer_write(id: u64, bytes_ptr: usize, byte_count: usize) callconv(.c) i32;    extern "accy" fn accy_webgpu_buffer_read(id: u64, bytes_ptr: usize, byte_count: usize) callconv(.c) i32;    extern "accy" fn accy_webgpu_object_destroy(id: u64) callconv(.c) void;    extern "accy" fn accy_webgpu_launch(        artifact_id: u64,        bindings_ptr: usize,        binding_count: usize,        scalars_ptr: usize,        scalar_count: usize,        grid_x: u32,        grid_y: u32,        grid_z: u32,        threadgroup_x: u32,        threadgroup_y: u32,        threadgroup_z: u32,        dynamic_shared_memory_bytes: u32,    ) callconv(.c) i32;    fn artifactLoad(source_ptr: usize, source_len: usize, entry_ptr: usize, entry_len: usize, argument_count: u32) u64 {        return accy_webgpu_artifact_load(source_ptr, source_len, entry_ptr, entry_len, argument_count);    }    fn bufferAlloc(byte_size: usize, alignment: u32) u64 {        return accy_webgpu_buffer_alloc(byte_size, alignment);    }    fn bufferWrite(id: u64, bytes_ptr: usize, byte_count: usize) i32 {        return accy_webgpu_buffer_write(id, bytes_ptr, byte_count);    }    fn bufferRead(id: u64, bytes_ptr: usize, byte_count: usize) i32 {        return accy_webgpu_buffer_read(id, bytes_ptr, byte_count);    }    fn launch(        artifact_id: u64,        bindings_ptr: usize,        binding_count: usize,        scalars_ptr: usize,        scalar_count: usize,        grid_x: u32,        grid_y: u32,        grid_z: u32,        threadgroup_x: u32,        threadgroup_y: u32,        threadgroup_z: u32,        dynamic_shared_memory_bytes: u32,    ) i32 {        return accy_webgpu_launch(            artifact_id,            bindings_ptr,            binding_count,            scalars_ptr,            scalar_count,            grid_x,            grid_y,            grid_z,            threadgroup_x,            threadgroup_y,            threadgroup_z,            dynamic_shared_memory_bytes,        );    }    fn objectDestroy(id: u64) void {        accy_webgpu_object_destroy(id);    }};const Host = if (browserish) BrowserHost else struct {};const vtable = backend.BackendVTable{    .query_capabilities = queryCapabilities,    .create_artifact = createArtifact,    .load_artifact = loadArtifact,    .allocate_buffer = allocateBuffer,    .write_buffer = writeBuffer,    .read_buffer = readBuffer,    .launch = launch,    .synchronize = synchronize,    .destroy_object = destroyObject,};test "webgpu backend reports wgsl capabilities" {    const testing = std.testing;    var state = State.init(testing.allocator);    defer state.deinit();    const caps = try state.handle().queryCapabilities();    try testing.expectEqual(backend.BackendKind.webgpu, caps.identity.backend);    try testing.expectEqual(backend.DeviceFamily.webgpu, caps.identity.family);    try testing.expect(caps.supportsArtifactFormat(.webgpu_wgsl));    try testing.expect(caps.supportsDType(.f32));    try testing.expect(caps.supportsDType(.i32));    try testing.expect(caps.supportsDType(.key));    try testing.expect(!caps.supportsDType(.f16));    try testing.expect(!caps.subgroup.supported);    try testing.expectEqual(@as(u32, 256), caps.threadgroup.max_threads);    try testing.expect(!caps.runtime.driver_loaded);}test "webgpu backend creates owned wgsl artifacts" {    const testing = std.testing;    var state = State.init(testing.allocator);    defer state.deinit();    var artifact = try state.handle().createArtifact(.{        .kernel_name = "accy_test",        .requested_format = .webgpu_wgsl,        .argument_count = 2,        .required_dtypes = backend.DTypeSet.init(&.{.f32}),        .payload = .{ .text = "@compute fn accy_test() {}" },    });    defer artifact.deinit();    try testing.expectEqual(backend.BackendKind.webgpu, artifact.backend);    try testing.expectEqual(backend.ArtifactFormat.webgpu_wgsl, artifact.format);    try testing.expectEqual(@as(u32, 2), artifact.argument_count);    try testing.expectEqual(backend.PayloadOwnership.owned, artifact.payload_ownership);    try testing.expectEqualStrings("@compute fn accy_test() {}", artifact.payload.text);}test "webgpu backend rejects non-wgsl payloads" {    const testing = std.testing;    var state = State.init(testing.allocator);    defer state.deinit();    try testing.expectError(error.UnsupportedArtifactFormat, state.handle().createArtifact(.{        .kernel_name = "accy_test",        .requested_format = .webgpu_wgsl,        .payload = .{ .words_u32 = &.{ 0x07230203, 0 } },    }));    try testing.expectError(error.UnsupportedArtifactFormat, state.handle().createArtifact(.{        .kernel_name = "accy_test",        .requested_format = .vulkan_spirv,        .payload = .{ .text = "@compute fn accy_test() {}" },    }));}test "webgpu backend runtime entry points are unavailable off the browser host" {    const testing = std.testing;    var state = State.init(testing.allocator);    defer state.deinit();    const handle = state.handle();    var artifact = try handle.createArtifact(.{        .kernel_name = "accy_test",        .requested_format = .webgpu_wgsl,        .argument_count = 1,        .payload = .{ .text = "@compute fn accy_test() {}" },    });    defer artifact.deinit();    try testing.expectError(error.RuntimeUnavailable, handle.loadArtifact(&artifact));    try testing.expectError(error.RuntimeUnavailable, handle.allocateBuffer(.{        .byte_size = 16,        .alignment = 4,        .dtype = .f32,        .element_count = 4,    }));    var bytes = @as([16]u8, @splat(0));    const buffer = backend.BufferHandle{ .id = 1, .backend = .webgpu, .byte_size = 16, .ownership = .backend };    try testing.expectError(error.RuntimeUnavailable, handle.writeBuffer(.{ .handle = buffer, .bytes = bytes[0..] }));    try testing.expectError(error.RuntimeUnavailable, handle.readBuffer(.{ .handle = buffer, .bytes = bytes[0..] }));    const launch_bindings = [_]backend.BufferBinding{.{        .handle = buffer,        .access = .read_write,        .ownership = .backend,        .byte_size = buffer.byte_size,    }};    try testing.expectError(error.RuntimeUnavailable, handle.launch(.{        .artifact = &artifact,        .loaded_artifact = .{ .id = 1, .backend = .webgpu, .format = .webgpu_wgsl },        .buffers = launch_bindings[0..],        .scalar_arguments = &.{},        .geometry = .{ .grid = .{ 1, 1, 1 }, .threadgroup = .{ 1, 1, 1 } },    }));}

Audit

Definitions6
Public names6
Members1
Version26.7.0
Revisiondaab053ee433