mach/gpu/src/Interface.zig
Stephen Gutekanst 60702eb9e6 gpu: fix requestAdapter implementation
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
2022-03-19 00:51:48 -07:00

95 lines
2.5 KiB
Zig

//! A standard interface to a WebGPU implementation.
//!
//! Like std.mem.Allocator, but representing a WebGPU implementation.
const std = @import("std");
const Surface = @import("Surface.zig");
const Adapter = @import("Adapter.zig");
const Interface = @This();
/// The type erased pointer to the Interface implementation
ptr: *anyopaque,
vtable: *const VTable,
// The @frameSize(func) of the implementations requestAdapter async function
request_adapter_frame_size: usize,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
requestAdapter: fn requestAdapter(ptr: *anyopaque, options: *const RequestAdapterOptions) callconv(.Async) RequestAdapterResponse,
};
pub inline fn reference(interface: Interface) void {
interface.vtable.reference(interface.ptr);
}
pub inline fn release(interface: Interface) void {
interface.vtable.release(interface.ptr);
}
// TODO: docs
pub const RequestAdapterOptions = struct {
// TODO:
//power_preference: PowerPreference,
force_fallback_adapter: bool = false,
/// Only respected by native WebGPU implementations.
compatible_surface: ?Surface = null,
};
pub const RequestAdapterErrorCode = error{
Unavailable,
Error,
Unknown,
};
// TODO: docs
pub const RequestAdapterError = struct {
message: []const u8,
code: RequestAdapterErrorCode,
};
pub const RequestAdapterResponseTag = enum {
adapter,
err,
};
pub const RequestAdapterResponse = union(RequestAdapterResponseTag) {
// TODO: docs
adapter: Adapter,
err: RequestAdapterError,
};
// TODO: docs
pub fn requestAdapter(interface: Interface, options: *const RequestAdapterOptions) callconv(.Async) RequestAdapterResponse {
var frame_buffer = std.heap.page_allocator.allocAdvanced(
u8,
16,
interface.request_adapter_frame_size,
std.mem.Allocator.Exact.at_least,
) catch {
return .{ .err = .{
.message = "Out of memory",
.code = RequestAdapterErrorCode.Error,
} };
};
defer std.heap.page_allocator.free(frame_buffer);
var result: RequestAdapterResponse = undefined;
const f = @asyncCall(frame_buffer, &result, interface.vtable.requestAdapter, .{ interface.ptr, options });
resume f;
return result;
}
test "syntax" {
_ = VTable;
_ = reference;
_ = release;
_ = RequestAdapterOptions;
_ = RequestAdapterErrorCode;
_ = RequestAdapterError;
_ = RequestAdapterResponse;
_ = requestAdapter;
}