gpu: prepare for full-scale rewrite of library

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2022-07-10 18:02:19 -07:00 committed by Stephen Gutekanst
parent 9d05e7c656
commit 2174936469
30 changed files with 0 additions and 5865 deletions

View file

@ -1,208 +0,0 @@
//! A GPUAdapter which identifies an implementation of WebGPU on the system.
//!
//! An adapter is both an instance of compute/rendering functionality on the platform, and an
//! instance of the WebGPU implementation on top of that functionality.
//!
//! Adapters do not uniquely represent underlying implementations: calling `requestAdapter()`
//! multiple times returns a different adapter object each time.
//!
//! An adapter object may become invalid at any time. This happens inside "lose the device" and
//! "mark adapters stale". An invalid adapter is unable to vend new devices.
//!
//! Note: This mechanism ensures that various adapter-creation scenarios look similar to
//! applications, so they can easily be robust to more scenarios with less testing: first
//! initialization, reinitialization due to an unplugged adapter, reinitialization due to a test
//! GPUDevice.destroy() call, etc. It also ensures applications use the latest system state to make
//! decisions about which adapter to use.
//!
//! https://gpuweb.github.io/gpuweb/#adapters
//! https://gpuweb.github.io/gpuweb/#gpuadapter
const std = @import("std");
const Feature = @import("enums.zig").Feature;
const Limits = @import("data.zig").Limits;
const Device = @import("Device.zig");
const Adapter = @This();
/// The features which can be used to create devices on this adapter.
features: []Feature,
_features: [std.enums.values(Feature).len]Feature = undefined,
/// The best limits which can be used to create devices on this adapter.
///
/// Each adapter limit will be the same or better than its default value in supported limits.
limits: Limits,
/// If set to true indicates that the adapter is a fallback adapter.
///
/// An adapter may be considered a fallback adapter if it has significant performance caveats in
/// exchange for some combination of wider compatibility, more predictable behavior, or improved
/// privacy. It is not guaranteed that a fallback adapter is available on every system.
///
/// Always false on native implementations of WebGPU (TODO: why is this not queryable in Dawn?)
fallback: bool,
properties: Properties,
/// The type erased pointer to the Adapter implementation
/// Equal to c.WGPUAdapter for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
requestDevice: fn requestDevice(
ptr: *anyopaque,
descriptor: *const Device.Descriptor,
callback: *RequestDeviceCallback,
) void,
};
pub inline fn reference(adapter: Adapter) void {
adapter.vtable.reference(adapter.ptr);
}
pub inline fn release(adapter: Adapter) void {
adapter.vtable.release(adapter.ptr);
}
/// Tests of the given feature can be used to create devices on this adapter.
pub fn hasFeature(adapter: Adapter, feature: Feature) bool {
for (adapter.features) |f| {
if (f == feature) return true;
}
return false;
}
pub const Properties = struct {
vendor_id: u32,
device_id: u32,
name: []const u8,
driver_description: []const u8,
adapter_type: Type,
backend_type: BackendType,
};
pub const Type = enum(u32) {
discrete_gpu,
integrated_gpu,
cpu,
unknown,
};
pub fn typeName(t: Type) []const u8 {
return switch (t) {
.discrete_gpu => "Discrete GPU",
.integrated_gpu => "Integrated GPU",
.cpu => "CPU",
.unknown => "Unknown",
};
}
pub const BackendType = enum(u32) {
nul,
webgpu,
d3d11,
d3d12,
metal,
vulkan,
opengl,
opengles,
};
pub fn backendTypeName(t: BackendType) []const u8 {
return switch (t) {
.nul => "Null",
.webgpu => "WebGPU",
.d3d11 => "D3D11",
.d3d12 => "D3D12",
.metal => "Metal",
.vulkan => "Vulkan",
.opengl => "OpenGL",
.opengles => "OpenGLES",
};
}
pub const RequestDeviceErrorCode = error{
Error,
Unknown,
};
pub const RequestDeviceError = struct {
message: []const u8,
code: RequestDeviceErrorCode,
};
pub const RequestDeviceResponseTag = enum {
device,
err,
};
pub const RequestDeviceResponse = union(RequestDeviceResponseTag) {
device: Device,
err: RequestDeviceError,
};
pub fn requestDevice(
adapter: Adapter,
descriptor: *const Device.Descriptor,
callback: *RequestDeviceCallback,
) void {
adapter.vtable.requestDevice(adapter.ptr, descriptor, callback);
}
pub const RequestDeviceCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, response: RequestDeviceResponse) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, response: RequestDeviceResponse) void,
) RequestDeviceCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, response: RequestDeviceResponse) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), response);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
/// A helper which invokes requestDevice and blocks until the device is recieved.
pub fn waitForDevice(adapter: Adapter, descriptor: *const Device.Descriptor) RequestDeviceResponse {
var response: RequestDeviceResponse = undefined;
var callback = RequestDeviceCallback.init(*RequestDeviceResponse, &response, (struct {
pub fn callback(ctx: *RequestDeviceResponse, callback_response: RequestDeviceResponse) void {
ctx.* = callback_response;
}
}).callback);
adapter.requestDevice(descriptor, &callback);
// TODO: FUTURE: Once crbug.com/dawn/1122 is fixed, we should process events here otherwise our
// callback would not be invoked:
//c.wgpuInstanceProcessEvents(adapter.instance)
return response;
}
test {
_ = VTable;
_ = hasFeature;
_ = Properties;
_ = Type;
_ = BackendType;
_ = RequestDeviceErrorCode;
_ = RequestDeviceError;
_ = RequestDeviceResponse;
_ = RequestDeviceCallback;
_ = requestDevice;
_ = waitForDevice;
}

View file

@ -1,81 +0,0 @@
const Buffer = @import("Buffer.zig");
const Sampler = @import("Sampler.zig");
const TextureView = @import("TextureView.zig");
const BindGroupLayout = @import("BindGroupLayout.zig");
const BindGroup = @This();
/// The type erased pointer to the BindGroup implementation
/// Equal to c.WGPUBindGroup for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(group: BindGroup) void {
group.vtable.reference(group.ptr);
}
pub inline fn release(group: BindGroup) void {
group.vtable.release(group.ptr);
}
pub inline fn setLabel(group: BindGroup, label: [:0]const u8) void {
group.vtable.setLabel(group.ptr, label);
}
pub const Entry = struct {
binding: u32,
buffer: ?Buffer = null,
offset: u64 = 0,
size: u64,
sampler: ?Sampler = null,
texture_view: ?TextureView = null,
/// Helper to create a buffer BindGroup.Entry.
pub fn buffer(binding: u32, buf: Buffer, offset: u64, size: u64) Entry {
return .{
.binding = binding,
.buffer = buf,
.offset = offset,
.size = size,
};
}
/// Helper to create a sampler BindGroup.Entry.
pub fn sampler(binding: u32, sam: Sampler) Entry {
return .{
.binding = binding,
.sampler = sam,
.size = 0,
};
}
/// Helper to create a texture view BindGroup.Entry.
pub fn textureView(binding: u32, texview: TextureView) Entry {
return .{
.binding = binding,
.texture_view = texview,
.size = 0,
};
}
};
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
layout: BindGroupLayout,
entries: []const Entry,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = setLabel;
_ = Entry;
_ = Descriptor;
}

View file

@ -1,132 +0,0 @@
const Buffer = @import("Buffer.zig");
const Sampler = @import("Sampler.zig");
const Texture = @import("Texture.zig");
const TextureView = @import("TextureView.zig");
const StorageTextureBindingLayout = @import("structs.zig").StorageTextureBindingLayout;
const StorageTextureAccess = @import("enums.zig").StorageTextureAccess;
const ShaderStage = @import("enums.zig").ShaderStage;
const BindGroupLayout = @This();
/// The type erased pointer to the BindGroupLayout implementation
/// Equal to c.WGPUBindGroupLayout for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(layout: BindGroupLayout) void {
layout.vtable.reference(layout.ptr);
}
pub inline fn release(layout: BindGroupLayout) void {
layout.vtable.release(layout.ptr);
}
pub inline fn setLabel(group: BindGroupLayout, label: [:0]const u8) void {
group.vtable.setLabel(group.ptr, label);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
entries: []const Entry,
};
pub const Entry = extern struct {
reserved: ?*anyopaque = null,
binding: u32,
visibility: ShaderStage,
buffer: Buffer.BindingLayout = .{ .type = .none },
sampler: Sampler.BindingLayout = .{ .type = .none },
texture: Texture.BindingLayout = .{ .sample_type = .none },
storage_texture: StorageTextureBindingLayout = .{ .access = .none, .format = .none },
/// Helper to create a buffer BindGroupLayout.Entry.
pub fn buffer(
binding: u32,
visibility: ShaderStage,
binding_type: Buffer.BindingType,
has_dynamic_offset: bool,
min_binding_size: u64,
) Entry {
return .{
.binding = binding,
.visibility = visibility,
.buffer = .{
.type = binding_type,
.has_dynamic_offset = has_dynamic_offset,
.min_binding_size = min_binding_size,
},
};
}
/// Helper to create a sampler BindGroupLayout.Entry.
pub fn sampler(binding: u32, visibility: ShaderStage, binding_type: Sampler.BindingType) Entry {
return .{
.binding = binding,
.visibility = visibility,
.sampler = .{ .type = binding_type },
};
}
/// Helper to create a texture BindGroupLayout.Entry.
pub fn texture(
binding: u32,
visibility: ShaderStage,
sample_type: Texture.SampleType,
view_dimension: TextureView.Dimension,
multisampled: bool,
) Entry {
return .{
.binding = binding,
.visibility = visibility,
.texture = .{
.sample_type = sample_type,
.view_dimension = view_dimension,
.multisampled = multisampled,
},
};
}
/// Helper to create a storage texture BindGroupLayout.Entry.
pub fn storageTexture(
binding: u32,
visibility: ShaderStage,
access: StorageTextureAccess,
format: Texture.Format,
view_dimension: TextureView.Dimension,
) Entry {
return .{
.binding = binding,
.visibility = visibility,
.storage_texture = .{
.access = access,
.format = format,
.view_dimension = view_dimension,
},
};
}
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = setLabel;
_ = Descriptor;
_ = Entry;
const desc = BindGroupLayout.Descriptor{
.entries = &.{
BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0),
BindGroupLayout.Entry.sampler(1, .{ .vertex = true }, .filtering),
BindGroupLayout.Entry.texture(2, .{ .fragment = true }, .float, .dimension_2d, false),
BindGroupLayout.Entry.storageTexture(3, .{ .fragment = true }, .none, .rgba32_float, .dimension_2d),
},
};
_ = desc;
}

View file

@ -1,142 +0,0 @@
const std = @import("std");
const BufferUsage = @import("enums.zig").BufferUsage;
const Buffer = @This();
/// The type erased pointer to the Buffer implementation
/// Equal to c.WGPUBuffer for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
destroy: fn (ptr: *anyopaque) void,
getConstMappedRange: fn (ptr: *anyopaque, offset: usize, size: usize) []const u8,
getMappedRange: fn (ptr: *anyopaque, offset: usize, size: usize) []u8,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
mapAsync: fn (
ptr: *anyopaque,
mode: MapMode,
offset: usize,
size: usize,
callback: *MapCallback,
) void,
unmap: fn (ptr: *anyopaque) void,
};
pub inline fn reference(buf: Buffer) void {
buf.vtable.reference(buf.ptr);
}
pub inline fn release(buf: Buffer) void {
buf.vtable.release(buf.ptr);
}
pub inline fn destroy(buf: Buffer) void {
buf.vtable.destroy(buf.ptr);
}
pub inline fn getConstMappedRange(buf: Buffer, comptime T: type, offset: usize, len: usize) []const T {
const size = @sizeOf(T) * len;
const data = buf.vtable.getConstMappedRange(buf.ptr, offset, size + size % 4);
return @ptrCast([*]const T, @alignCast(@alignOf(T), data.ptr))[0..len];
}
pub inline fn getMappedRange(buf: Buffer, comptime T: type, offset: usize, len: usize) []T {
const size = @sizeOf(T) * len;
const data = buf.vtable.getMappedRange(buf.ptr, offset, size + size % 4);
return @ptrCast([*]T, @alignCast(@alignOf(T), data.ptr))[0..len];
}
pub inline fn setLabel(buf: Buffer, label: [:0]const u8) void {
buf.vtable.setLabel(buf.ptr, label);
}
pub inline fn mapAsync(
buf: Buffer,
mode: MapMode,
offset: usize,
size: usize,
callback: *MapCallback,
) void {
buf.vtable.mapAsync(buf.ptr, mode, offset, size, callback);
}
pub const MapCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, status: MapAsyncStatus) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, status: MapAsyncStatus) void,
) MapCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, status: MapAsyncStatus) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), status);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
pub inline fn unmap(buf: Buffer) void {
buf.vtable.unmap(buf.ptr);
}
pub const Descriptor = extern struct {
reserved: ?*anyopaque = null,
label: ?[*:0]const u8 = null,
usage: BufferUsage,
size: usize,
mapped_at_creation: bool = false,
};
pub const BindingType = enum(u32) {
none = 0x00000000,
uniform = 0x00000001,
storage = 0x00000002,
read_only_storage = 0x00000003,
};
pub const BindingLayout = extern struct {
reserved: ?*anyopaque = null,
type: BindingType = .uniform,
has_dynamic_offset: bool = false,
min_binding_size: u64 = 0,
};
pub const MapAsyncStatus = enum(u32) {
success = 0x00000000,
err = 0x00000001,
unknown = 0x00000002,
device_lost = 0x00000003,
destroyed_before_callback = 0x00000004,
unmapped_before_callback = 0x00000005,
};
pub const MapMode = enum(u32) {
none = 0x00000000,
read = 0x00000001,
write = 0x00000002,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = destroy;
_ = getConstMappedRange;
_ = getMappedRange;
_ = setLabel;
_ = Descriptor;
_ = BindingType;
_ = BindingLayout;
_ = MapAsyncStatus;
_ = MapMode;
}

View file

@ -1,36 +0,0 @@
const CommandBuffer = @This();
/// The type erased pointer to the CommandBuffer implementation
/// Equal to c.WGPUCommandBuffer for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(buf: CommandBuffer) void {
buf.vtable.reference(buf.ptr);
}
pub inline fn release(buf: CommandBuffer) void {
buf.vtable.release(buf.ptr);
}
pub inline fn setLabel(buf: CommandBuffer, label: [:0]const u8) void {
buf.vtable.setLabel(buf.ptr, label);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = setLabel;
_ = Descriptor;
}

View file

@ -1,172 +0,0 @@
const std = @import("std");
const ComputePassEncoder = @import("ComputePassEncoder.zig");
const RenderPassEncoder = @import("RenderPassEncoder.zig");
const CommandBuffer = @import("CommandBuffer.zig");
const QuerySet = @import("QuerySet.zig");
const Buffer = @import("Buffer.zig");
const ImageCopyBuffer = @import("structs.zig").ImageCopyBuffer;
const ImageCopyTexture = @import("structs.zig").ImageCopyTexture;
const Extent3D = @import("data.zig").Extent3D;
const CommandEncoder = @This();
/// The type erased pointer to the CommandEncoder implementation
/// Equal to c.WGPUCommandEncoder for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
beginComputePass: fn (ptr: *anyopaque, descriptor: ?*const ComputePassEncoder.Descriptor) ComputePassEncoder,
beginRenderPass: fn (ptr: *anyopaque, descriptor: *const RenderPassEncoder.Descriptor) RenderPassEncoder,
clearBuffer: fn (ptr: *anyopaque, buffer: Buffer, offset: u64, size: u64) void,
copyBufferToBuffer: fn (ptr: *anyopaque, source: Buffer, source_offset: u64, destination: Buffer, destination_offset: u64, size: u64) void,
copyBufferToTexture: fn (ptr: *anyopaque, source: *const ImageCopyBuffer, destination: *const ImageCopyTexture, copy_size: *const Extent3D) void,
copyTextureToBuffer: fn (ptr: *anyopaque, source: *const ImageCopyTexture, destination: *const ImageCopyBuffer, copy_size: *const Extent3D) void,
copyTextureToTexture: fn (ptr: *anyopaque, source: *const ImageCopyTexture, destination: *const ImageCopyTexture, copy_size: *const Extent3D) void,
finish: fn (ptr: *anyopaque, descriptor: ?*const CommandBuffer.Descriptor) CommandBuffer,
injectValidationError: fn (ptr: *anyopaque, message: [*:0]const u8) void,
insertDebugMarker: fn (ptr: *anyopaque, marker_label: [*:0]const u8) void,
popDebugGroup: fn (ptr: *anyopaque) void,
pushDebugGroup: fn (ptr: *anyopaque, group_label: [*:0]const u8) void,
resolveQuerySet: fn (ptr: *anyopaque, query_set: QuerySet, first_query: u32, query_count: u32, destination: Buffer, destination_offset: u64) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
writeBuffer: fn (ptr: *anyopaque, buffer: Buffer, buffer_offset: u64, data: [*]const u8, size: u64) void,
writeTimestamp: fn (ptr: *anyopaque, query_set: QuerySet, query_index: u32) void,
};
pub inline fn reference(enc: CommandEncoder) void {
enc.vtable.reference(enc.ptr);
}
pub inline fn release(enc: CommandEncoder) void {
enc.vtable.release(enc.ptr);
}
pub inline fn beginComputePass(enc: CommandEncoder, descriptor: ?*const ComputePassEncoder.Descriptor) ComputePassEncoder {
return enc.vtable.beginComputePass(enc.ptr, descriptor);
}
pub inline fn beginRenderPass(enc: CommandEncoder, descriptor: *const RenderPassEncoder.Descriptor) RenderPassEncoder {
return enc.vtable.beginRenderPass(enc.ptr, descriptor);
}
pub inline fn clearBuffer(enc: CommandEncoder, buffer: Buffer, offset: u64, size: u64) void {
enc.vtable.clearBuffer(enc.ptr, buffer, offset, size);
}
pub inline fn copyBufferToBuffer(
enc: CommandEncoder,
source: Buffer,
source_offset: u64,
destination: Buffer,
destination_offset: u64,
size: u64,
) void {
enc.vtable.copyBufferToBuffer(enc.ptr, source, source_offset, destination, destination_offset, size);
}
pub inline fn copyBufferToTexture(
enc: CommandEncoder,
source: *const ImageCopyBuffer,
destination: *const ImageCopyTexture,
copy_size: *const Extent3D,
) void {
enc.vtable.copyBufferToTexture(enc.ptr, source, destination, copy_size);
}
pub inline fn copyTextureToBuffer(
enc: CommandEncoder,
source: *const ImageCopyTexture,
destination: *const ImageCopyBuffer,
copy_size: *const Extent3D,
) void {
enc.vtable.copyTextureToBuffer(enc.ptr, source, destination, copy_size);
}
pub inline fn copyTextureToTexture(
enc: CommandEncoder,
source: *const ImageCopyTexture,
destination: *const ImageCopyTexture,
copy_size: *const Extent3D,
) void {
enc.vtable.copyTextureToTexture(enc.ptr, source, destination, copy_size);
}
pub inline fn finish(enc: CommandEncoder, descriptor: ?*const CommandBuffer.Descriptor) CommandBuffer {
return enc.vtable.finish(enc.ptr, descriptor);
}
pub inline fn injectValidationError(enc: CommandEncoder, message: [*:0]const u8) void {
enc.vtable.injectValidationError(enc.ptr, message);
}
pub inline fn insertDebugMarker(enc: CommandEncoder, marker_label: [*:0]const u8) void {
enc.vtable.insertDebugMarker(enc.ptr, marker_label);
}
pub inline fn popDebugGroup(enc: CommandEncoder) void {
enc.vtable.popDebugGroup(enc.ptr);
}
pub inline fn pushDebugGroup(enc: CommandEncoder, group_label: [*:0]const u8) void {
enc.vtable.pushDebugGroup(enc.ptr, group_label);
}
pub inline fn resolveQuerySet(
enc: CommandEncoder,
query_set: QuerySet,
first_query: u32,
query_count: u32,
destination: Buffer,
destination_offset: u64,
) void {
enc.vtable.resolveQuerySet(enc.ptr, query_set, first_query, query_count, destination, destination_offset);
}
pub inline fn setLabel(enc: CommandEncoder, label: [:0]const u8) void {
enc.vtable.setLabel(enc.ptr, label);
}
pub inline fn writeBuffer(enc: CommandEncoder, buffer: Buffer, buffer_offset: u64, comptime T: type, data: []const T) void {
enc.vtable.writeBuffer(
enc.ptr,
buffer,
buffer_offset,
@ptrCast([*]const u8, data.ptr),
@intCast(u64, data.len) * @sizeOf(T),
);
}
pub inline fn writeTimestamp(pass: RenderPassEncoder, query_set: QuerySet, query_index: u32) void {
pass.vtable.writeTimestamp(pass.ptr, query_set, query_index);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = beginComputePass;
_ = beginRenderPass;
_ = clearBuffer;
_ = copyBufferToBuffer;
_ = copyBufferToTexture;
_ = copyTextureToBuffer;
_ = copyTextureToTexture;
_ = finish;
_ = injectValidationError;
_ = insertDebugMarker;
_ = popDebugGroup;
_ = pushDebugGroup;
_ = resolveQuerySet;
_ = setLabel;
_ = writeBuffer;
_ = writeTimestamp;
_ = Descriptor;
}

View file

@ -1,111 +0,0 @@
const ComputePassTimestampWrite = @import("structs.zig").ComputePassTimestampWrite;
const ComputePipeline = @import("ComputePipeline.zig");
const QuerySet = @import("QuerySet.zig");
const BindGroup = @import("BindGroup.zig");
const Buffer = @import("Buffer.zig");
const ComputePassEncoder = @This();
/// The type erased pointer to the ComputePassEncoder implementation
/// Equal to c.WGPUComputePassEncoder for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
dispatch: fn (ptr: *anyopaque, workgroup_count_x: u32, workgroup_count_y: u32, workgroup_count_z: u32) void,
dispatchIndirect: fn (ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void,
end: fn (ptr: *anyopaque) void,
insertDebugMarker: fn (ptr: *anyopaque, marker_label: [*:0]const u8) void,
popDebugGroup: fn (ptr: *anyopaque) void,
pushDebugGroup: fn (ptr: *anyopaque, group_label: [*:0]const u8) void,
setBindGroup: fn (ptr: *anyopaque, group_index: u32, group: BindGroup, dynamic_offsets: ?[]const u32) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
setPipeline: fn (ptr: *anyopaque, pipeline: ComputePipeline) void,
writeTimestamp: fn (ptr: *anyopaque, query_set: QuerySet, query_index: u32) void,
};
pub inline fn reference(enc: ComputePassEncoder) void {
enc.vtable.reference(enc.ptr);
}
pub inline fn release(enc: ComputePassEncoder) void {
enc.vtable.release(enc.ptr);
}
pub inline fn dispatch(
enc: ComputePassEncoder,
workgroup_count_x: u32,
workgroup_count_y: u32,
workgroup_count_z: u32,
) void {
enc.vtable.dispatch(enc.ptr, workgroup_count_x, workgroup_count_y, workgroup_count_z);
}
pub inline fn dispatchIndirect(
enc: ComputePassEncoder,
indirect_buffer: Buffer,
indirect_offset: u64,
) void {
enc.vtable.dispatchIndirect(enc.ptr, indirect_buffer, indirect_offset);
}
pub inline fn end(enc: ComputePassEncoder) void {
enc.vtable.end(enc.ptr);
}
pub inline fn insertDebugMarker(enc: ComputePassEncoder, marker_label: [*:0]const u8) void {
enc.vtable.insertDebugMarker(enc.ptr, marker_label);
}
pub inline fn popDebugGroup(enc: ComputePassEncoder) void {
enc.vtable.popDebugGroup(enc.ptr);
}
pub inline fn pushDebugGroup(enc: ComputePassEncoder, group_label: [*:0]const u8) void {
enc.vtable.pushDebugGroup(enc.ptr, group_label);
}
pub inline fn setBindGroup(
enc: ComputePassEncoder,
group_index: u32,
group: BindGroup,
dynamic_offsets: ?[]const u32,
) void {
enc.vtable.setBindGroup(enc.ptr, group_index, group, dynamic_offsets);
}
pub inline fn setLabel(enc: ComputePassEncoder, label: [:0]const u8) void {
enc.vtable.setLabel(enc.ptr, label);
}
pub inline fn setPipeline(enc: ComputePassEncoder, pipeline: ComputePipeline) void {
enc.vtable.setPipeline(enc.ptr, pipeline);
}
pub inline fn writeTimestamp(enc: ComputePassEncoder, query_set: QuerySet, query_index: u32) void {
enc.vtable.writeTimestamp(enc.ptr, query_set, query_index);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
timestamp_writes: []const ComputePassTimestampWrite,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = dispatch;
_ = dispatchIndirect;
_ = end;
_ = insertDebugMarker;
_ = popDebugGroup;
_ = pushDebugGroup;
_ = setBindGroup;
_ = setLabel;
_ = setPipeline;
_ = writeTimestamp;
_ = Descriptor;
}

View file

@ -1,101 +0,0 @@
const std = @import("std");
const PipelineLayout = @import("PipelineLayout.zig");
const ProgrammableStageDescriptor = @import("structs.zig").ProgrammableStageDescriptor;
const BindGroupLayout = @import("BindGroupLayout.zig");
const ComputePipeline = @This();
/// The type erased pointer to the ComputePipeline implementation
/// Equal to c.WGPUComputePipeline for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
getBindGroupLayout: fn (ptr: *anyopaque, group_index: u32) BindGroupLayout,
};
pub inline fn reference(pipeline: ComputePipeline) void {
pipeline.vtable.reference(pipeline.ptr);
}
pub inline fn release(pipeline: ComputePipeline) void {
pipeline.vtable.release(pipeline.ptr);
}
pub inline fn setLabel(pipeline: ComputePipeline, label: [:0]const u8) void {
pipeline.vtable.setLabel(pipeline.ptr, label);
}
pub inline fn getBindGroupLayout(pipeline: ComputePipeline, group_index: u32) BindGroupLayout {
return pipeline.vtable.getBindGroupLayout(pipeline.ptr, group_index);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
layout: ?PipelineLayout = null,
compute: ProgrammableStageDescriptor,
};
pub const CreateStatus = enum(u32) {
success = 0x00000000,
err = 0x00000001,
device_lost = 0x00000002,
device_destroyed = 0x00000003,
unknown = 0x00000004,
};
pub const CreateCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (
ctx: *anyopaque,
status: CreateStatus,
pipeline: ComputePipeline,
message: [:0]const u8,
) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (
ctx: Context,
status: CreateStatus,
pipeline: ComputePipeline,
message: [:0]const u8,
) void,
) CreateCallback {
const erased = (struct {
pub inline fn erased(
type_erased_ctx: *anyopaque,
status: CreateStatus,
pipeline: ComputePipeline,
message: [:0]const u8,
) void {
callback(
if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)),
status,
pipeline,
message,
);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = setLabel;
_ = getBindGroupLayout;
_ = Descriptor;
_ = CreateStatus;
_ = CreateCallback;
}

View file

@ -1,293 +0,0 @@
//! A GPUDevice / logical instantiation of an adapter.
//!
//! A device is the exclusive owner of all internal objects created from it: when the device is
//! lost or destroyed, it and all objects created on it (directly, e.g. createTexture(), or
//! indirectly, e.g. createView()) become implicitly unusable.
//!
//! https://gpuweb.github.io/gpuweb/#devices
//! https://gpuweb.github.io/gpuweb/#gpuadapter
const std = @import("std");
const Feature = @import("enums.zig").Feature;
const ErrorType = @import("enums.zig").ErrorType;
const ErrorFilter = @import("enums.zig").ErrorFilter;
const Limits = @import("data.zig").Limits;
const LoggingType = @import("enums.zig").LoggingType;
const ErrorCallback = @import("structs.zig").ErrorCallback;
const LoggingCallback = @import("structs.zig").LoggingCallback;
const Queue = @import("Queue.zig");
const ShaderModule = @import("ShaderModule.zig");
const Surface = @import("Surface.zig");
const SwapChain = @import("SwapChain.zig");
const RenderPipeline = @import("RenderPipeline.zig");
const CommandEncoder = @import("CommandEncoder.zig");
const ComputePipeline = @import("ComputePipeline.zig");
const BindGroup = @import("BindGroup.zig");
const BindGroupLayout = @import("BindGroupLayout.zig");
const Buffer = @import("Buffer.zig");
const ExternalTexture = @import("ExternalTexture.zig");
const PipelineLayout = @import("PipelineLayout.zig");
const QuerySet = @import("QuerySet.zig");
const RenderBundleEncoder = @import("RenderBundleEncoder.zig");
const Sampler = @import("Sampler.zig");
const Texture = @import("Texture.zig");
const Device = @This();
/// The features supported by the device (i.e. the ones with which it was created).
features: []Feature,
_features: [std.enums.values(Feature).len]Feature = undefined,
/// The limits supported by the device (which are exactly the ones with which it was created).
limits: Limits,
/// The type erased pointer to the Device implementation
/// Equal to c.WGPUDevice for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
createBindGroup: fn (ptr: *anyopaque, descriptor: *const BindGroup.Descriptor) BindGroup,
createBindGroupLayout: fn (ptr: *anyopaque, descriptor: *const BindGroupLayout.Descriptor) BindGroupLayout,
createBuffer: fn (ptr: *anyopaque, descriptor: *const Buffer.Descriptor) Buffer,
createCommandEncoder: fn (ptr: *anyopaque, descriptor: ?*const CommandEncoder.Descriptor) CommandEncoder,
createComputePipeline: fn (ptr: *anyopaque, descriptor: *const ComputePipeline.Descriptor) ComputePipeline,
createComputePipelineAsync: fn (
ptr: *anyopaque,
descriptor: *const ComputePipeline.Descriptor,
callback: *ComputePipeline.CreateCallback,
) void,
createErrorBuffer: fn (ptr: *anyopaque) Buffer,
createExternalTexture: fn (ptr: *anyopaque, descriptor: *const ExternalTexture.Descriptor) ExternalTexture,
createPipelineLayout: fn (ptr: *anyopaque, descriptor: *const PipelineLayout.Descriptor) PipelineLayout,
createQuerySet: fn (ptr: *anyopaque, descriptor: *const QuerySet.Descriptor) QuerySet,
createRenderBundleEncoder: fn (ptr: *anyopaque, descriptor: *const RenderBundleEncoder.Descriptor) RenderBundleEncoder,
createRenderPipeline: fn (ptr: *anyopaque, descriptor: *const RenderPipeline.Descriptor) RenderPipeline,
createRenderPipelineAsync: fn (
ptr: *anyopaque,
descriptor: *const RenderPipeline.Descriptor,
callback: *RenderPipeline.CreateCallback,
) void,
createSampler: fn (ptr: *anyopaque, descriptor: *const Sampler.Descriptor) Sampler,
createShaderModule: fn (ptr: *anyopaque, descriptor: *const ShaderModule.Descriptor) ShaderModule,
nativeCreateSwapChain: fn (ptr: *anyopaque, surface: ?Surface, descriptor: *const SwapChain.Descriptor) SwapChain,
createTexture: fn (ptr: *anyopaque, descriptor: *const Texture.Descriptor) Texture,
destroy: fn (ptr: *anyopaque) void,
getQueue: fn (ptr: *anyopaque) Queue,
injectError: fn (ptr: *anyopaque, type: ErrorType, message: [*:0]const u8) void,
loseForTesting: fn (ptr: *anyopaque) void,
popErrorScope: fn (ptr: *anyopaque, callback: *ErrorCallback) bool,
pushErrorScope: fn (ptr: *anyopaque, filter: ErrorFilter) void,
setLostCallback: fn (ptr: *anyopaque, callback: *LostCallback) void,
setLoggingCallback: fn (ptr: *anyopaque, callback: *LoggingCallback) void,
setUncapturedErrorCallback: fn (ptr: *anyopaque, callback: *ErrorCallback) void,
tick: fn (ptr: *anyopaque) void,
};
pub inline fn reference(device: Device) void {
device.vtable.reference(device.ptr);
}
pub inline fn release(device: Device) void {
device.vtable.release(device.ptr);
}
/// Tests of the device has this feature & was created with it.
pub fn hasFeature(device: Device, feature: Feature) bool {
for (device.features) |f| {
if (f == feature) return true;
}
return false;
}
pub inline fn getQueue(device: Device) Queue {
return device.vtable.getQueue(device.ptr);
}
pub inline fn injectError(device: Device, typ: ErrorType, message: [*:0]const u8) void {
device.vtable.injectError(device.ptr, typ, message);
}
pub inline fn loseForTesting(device: Device) void {
device.vtable.loseForTesting(device.ptr);
}
pub inline fn popErrorScope(device: Device, callback: *ErrorCallback) bool {
return device.vtable.popErrorScope(device.ptr, callback);
}
pub inline fn pushErrorScope(device: Device, filter: ErrorFilter) void {
device.vtable.pushErrorScope(device.ptr, filter);
}
pub inline fn setLostCallback(device: Device, callback: *LostCallback) void {
device.vtable.setLostCallback(device.ptr, callback);
}
pub const LostCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, reason: LostReason, message: [*:0]const u8) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, reason: LostReason, message: [*:0]const u8) void,
) LostCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, reason: LostReason, message: [*:0]const u8) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), reason, message);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
pub inline fn createBindGroup(device: Device, descriptor: *const BindGroup.Descriptor) BindGroup {
return device.vtable.createBindGroup(device.ptr, descriptor);
}
pub inline fn createBindGroupLayout(device: Device, descriptor: *const BindGroupLayout.Descriptor) BindGroupLayout {
return device.vtable.createBindGroupLayout(device.ptr, descriptor);
}
pub inline fn createSampler(device: Device, descriptor: *const Sampler.Descriptor) Sampler {
return device.vtable.createSampler(device.ptr, descriptor);
}
pub inline fn createShaderModule(device: Device, descriptor: *const ShaderModule.Descriptor) ShaderModule {
return device.vtable.createShaderModule(device.ptr, descriptor);
}
pub inline fn nativeCreateSwapChain(device: Device, surface: ?Surface, descriptor: *const SwapChain.Descriptor) SwapChain {
return device.vtable.nativeCreateSwapChain(device.ptr, surface, descriptor);
}
pub inline fn createTexture(device: Device, descriptor: *const Texture.Descriptor) Texture {
return device.vtable.createTexture(device.ptr, descriptor);
}
pub inline fn destroy(device: Device) void {
device.vtable.destroy(device.ptr);
}
pub inline fn createBuffer(device: Device, descriptor: *const Buffer.Descriptor) Buffer {
var local_descriptor = descriptor.*;
local_descriptor.size += local_descriptor.size % 4;
return device.vtable.createBuffer(device.ptr, &local_descriptor);
}
pub inline fn createCommandEncoder(device: Device, descriptor: ?*const CommandEncoder.Descriptor) CommandEncoder {
return device.vtable.createCommandEncoder(device.ptr, descriptor);
}
pub inline fn createComputePipeline(
device: Device,
descriptor: *const ComputePipeline.Descriptor,
) ComputePipeline {
return device.vtable.createComputePipeline(device.ptr, descriptor);
}
pub inline fn createComputePipelineAsync(
device: Device,
descriptor: *const ComputePipeline.Descriptor,
callback: *ComputePipeline.CreateCallback,
) void {
device.vtable.createComputePipelineAsync(device.ptr, descriptor, callback);
}
pub inline fn createErrorBuffer(device: Device) Buffer {
return device.vtable.createErrorBuffer(device.ptr);
}
pub inline fn createExternalTexture(device: Device, descriptor: *const ExternalTexture.Descriptor) ExternalTexture {
return device.vtable.createExternalTexture(device.ptr, descriptor);
}
pub inline fn createPipelineLayout(device: Device, descriptor: *const PipelineLayout.Descriptor) PipelineLayout {
return device.vtable.createPipelineLayout(device.ptr, descriptor);
}
pub inline fn createQuerySet(device: Device, descriptor: *const QuerySet.Descriptor) QuerySet {
return device.vtable.createQuerySet(device.ptr, descriptor);
}
pub inline fn createRenderBundleEncoder(device: Device, descriptor: *const RenderBundleEncoder.Descriptor) RenderBundleEncoder {
return device.vtable.createRenderBundleEncoder(device.ptr, descriptor);
}
pub inline fn createRenderPipeline(device: Device, descriptor: *const RenderPipeline.Descriptor) RenderPipeline {
return device.vtable.createRenderPipeline(device.ptr, descriptor);
}
pub inline fn createRenderPipelineAsync(
device: Device,
descriptor: *const RenderPipeline.Descriptor,
callback: *RenderPipeline.CreateCallback,
) void {
device.vtable.createRenderPipelineAsync(device.ptr, descriptor, callback);
}
pub inline fn setLoggingCallback(device: Device, callback: *LoggingCallback) void {
device.vtable.setLoggingCallback(device.ptr, callback);
}
pub inline fn setUncapturedErrorCallback(device: Device, callback: *ErrorCallback) void {
device.vtable.setUncapturedErrorCallback(device.ptr, callback);
}
pub inline fn tick(device: Device) void {
device.vtable.tick(device.ptr);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
required_features: ?[]Feature = null,
required_limits: ?Limits = null,
default_queue: ?Queue.Descriptor = null,
};
pub const LostReason = enum(u32) {
none = 0x00000000,
destroyed = 0x00000001,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = getQueue;
_ = injectError;
_ = loseForTesting;
_ = popErrorScope;
_ = setLostCallback;
_ = createBindGroup;
_ = pushErrorScope;
_ = createBindGroupLayout;
_ = createSampler;
_ = createShaderModule;
_ = nativeCreateSwapChain;
_ = createTexture;
_ = destroy;
_ = createBuffer;
_ = createCommandEncoder;
_ = createComputePipeline;
_ = createComputePipelineAsync;
_ = createErrorBuffer;
_ = createExternalTexture;
_ = createPipelineLayout;
_ = createQuerySet;
_ = createRenderBundleEncoder;
_ = createRenderPipeline;
_ = createRenderPipelineAsync;
_ = setLoggingCallback;
_ = setUncapturedErrorCallback;
_ = tick;
_ = Descriptor;
_ = LostReason;
}

View file

@ -1,48 +0,0 @@
const Texture = @import("Texture.zig");
const TextureView = @import("TextureView.zig");
const PredefinedColorSpace = @import("enums.zig").PredefinedColorSpace;
const ExternalTexture = @This();
/// The type erased pointer to the ExternalTexture implementation
/// Equal to c.WGPUExternalTexture for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
destroy: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(texture: ExternalTexture) void {
texture.vtable.reference(texture.ptr);
}
pub inline fn release(texture: ExternalTexture) void {
texture.vtable.release(texture.ptr);
}
pub inline fn setLabel(texture: ExternalTexture, label: [:0]const u8) void {
texture.vtable.setLabel(texture.ptr, label);
}
pub inline fn destroy(texture: ExternalTexture) void {
texture.vtable.destroy(texture.ptr);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
plane0: TextureView,
plane1: TextureView,
color_space: PredefinedColorSpace,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = destroy;
_ = Descriptor;
}

View file

@ -1,121 +0,0 @@
//! 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 PowerPreference = @import("enums.zig").PowerPreference;
const Interface = @This();
/// The type erased pointer to the Interface implementation
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
requestAdapter: fn requestAdapter(
ptr: *anyopaque,
options: *const RequestAdapterOptions,
callback: *RequestAdapterCallback,
) void,
};
pub inline fn reference(interface: Interface) void {
interface.vtable.reference(interface.ptr);
}
pub inline fn release(interface: Interface) void {
interface.vtable.release(interface.ptr);
}
pub const RequestAdapterOptions = struct {
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,
};
pub const RequestAdapterError = struct {
message: []const u8,
code: RequestAdapterErrorCode,
};
pub const RequestAdapterResponseTag = enum {
adapter,
err,
};
pub const RequestAdapterResponse = union(RequestAdapterResponseTag) {
adapter: Adapter,
err: RequestAdapterError,
};
pub fn requestAdapter(
interface: Interface,
options: *const RequestAdapterOptions,
callback: *RequestAdapterCallback,
) void {
interface.vtable.requestAdapter(interface.ptr, options, callback);
}
pub const RequestAdapterCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, response: RequestAdapterResponse) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, response: RequestAdapterResponse) void,
) RequestAdapterCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, response: RequestAdapterResponse) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), response);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
/// A helper which invokes requestAdapter and blocks until the adapter is recieved.
pub fn waitForAdapter(interface: Interface, options: *const RequestAdapterOptions) RequestAdapterResponse {
var response: RequestAdapterResponse = undefined;
var callback = RequestAdapterCallback.init(*RequestAdapterResponse, &response, (struct {
pub fn callback(ctx: *RequestAdapterResponse, callback_response: RequestAdapterResponse) void {
ctx.* = callback_response;
}
}).callback);
interface.requestAdapter(options, &callback);
// TODO: FUTURE: Once crbug.com/dawn/1122 is fixed, we should process events here otherwise our
// callback would not be invoked:
//c.wgpuInstanceProcessEvents(interface.instance)
return response;
}
test {
_ = VTable;
_ = reference;
_ = release;
_ = RequestAdapterOptions;
_ = RequestAdapterErrorCode;
_ = RequestAdapterError;
_ = RequestAdapterResponse;
_ = requestAdapter;
_ = waitForAdapter;
}

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
const BindGroupLayout = @import("BindGroupLayout.zig");
const BindGroup = @import("BindGroup.zig");
const PipelineLayout = @This();
/// The type erased pointer to the PipelineLayout implementation
/// Equal to c.WGPUPipelineLayout for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(qset: PipelineLayout) void {
qset.vtable.reference(qset.ptr);
}
pub inline fn release(qset: PipelineLayout) void {
qset.vtable.release(qset.ptr);
}
pub inline fn setLabel(qset: PipelineLayout, label: [:0]const u8) void {
qset.vtable.setLabel(qset.ptr, label);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
bind_group_layouts: []const BindGroupLayout,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = Descriptor;
}

View file

@ -1,48 +0,0 @@
const QueryType = @import("enums.zig").QueryType;
const PipelineStatistic = @import("enums.zig").PipelineStatistic;
const QuerySet = @This();
/// The type erased pointer to the QuerySet implementation
/// Equal to c.WGPUQuerySet for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
destroy: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(qset: QuerySet) void {
qset.vtable.reference(qset.ptr);
}
pub inline fn release(qset: QuerySet) void {
qset.vtable.release(qset.ptr);
}
pub inline fn setLabel(qset: QuerySet, label: [:0]const u8) void {
qset.vtable.setLabel(qset.ptr, label);
}
pub inline fn destroy(qset: QuerySet) void {
qset.vtable.destroy(qset.ptr);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
type: QueryType,
count: u32,
pipeline_statistics: []PipelineStatistic,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = destroy;
_ = Descriptor;
}

View file

@ -1,126 +0,0 @@
const std = @import("std");
const ImageCopyTexture = @import("structs.zig").ImageCopyTexture;
const Extent3D = @import("data.zig").Extent3D;
const CommandBuffer = @import("CommandBuffer.zig");
const Buffer = @import("Buffer.zig");
const Texture = @import("Texture.zig");
const Queue = @This();
/// Callback to executed when all work has been done
/// This field must be set before calling `submit()` on the commands the callback waits for.
/// Note that the address stored must be valid when the callback is executed.
on_submitted_work_done: ?*WorkDoneCallback = null,
/// The type erased pointer to the Queue implementation
/// Equal to c.WGPUQueue for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
// TODO: dawn specific?
// copyTextureForBrowser: fn (ptr: *anyopaque, source: *const ImageCopyTexture, destination: *const ImageCopyTexture, copy_size: *const Extent3D, options: *const CopyTextureForBrowserOptions) void,
submit: fn (queue: *Queue, commands: []const CommandBuffer) void,
writeBuffer: fn (
ptr: *anyopaque,
buffer: Buffer,
buffer_offset: u64,
data: *const anyopaque,
size: u64,
) void,
writeTexture: fn (
ptr: *anyopaque,
destination: *const ImageCopyTexture,
data: *const anyopaque,
data_size: usize,
data_layout: *const Texture.DataLayout,
write_size: *const Extent3D,
) void,
};
pub inline fn reference(queue: Queue) void {
queue.vtable.reference(queue.ptr);
}
pub inline fn release(queue: Queue) void {
queue.vtable.release(queue.ptr);
}
pub inline fn submit(queue: *Queue, commands: []const CommandBuffer) void {
queue.vtable.submit(queue, commands);
}
pub inline fn writeBuffer(queue: Queue, buffer: Buffer, buffer_offset: u64, comptime T: type, data: []const T) void {
queue.vtable.writeBuffer(
queue.ptr,
buffer,
buffer_offset,
@ptrCast(*const anyopaque, data.ptr),
@intCast(u64, data.len) * @sizeOf(T),
);
}
pub inline fn writeTexture(
queue: Queue,
destination: *const ImageCopyTexture,
data_layout: *const Texture.DataLayout,
write_size: *const Extent3D,
comptime T: type,
data: []const T,
) void {
queue.vtable.writeTexture(
queue.ptr,
destination,
@ptrCast(*const anyopaque, data.ptr),
@intCast(usize, data.len) * @sizeOf(std.meta.Elem(@TypeOf(data))),
data_layout,
write_size,
);
}
pub const WorkDoneCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, status: WorkDoneStatus) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, status: WorkDoneStatus) void,
) WorkDoneCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, status: WorkDoneStatus) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), status);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
};
pub const WorkDoneStatus = enum(u32) {
success = 0x00000000,
err = 0x00000001,
unknown = 0x00000002,
device_lost = 0x00000003,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = submit;
_ = writeBuffer;
_ = writeTexture;
_ = WorkDoneCallback;
_ = WorkDoneStatus;
}

View file

@ -1,30 +0,0 @@
const RenderBundle = @This();
/// The type erased pointer to the RenderBundle implementation
/// Equal to c.WGPURenderBundle for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
};
pub inline fn reference(bundle: RenderBundle) void {
bundle.vtable.reference(bundle.ptr);
}
pub inline fn release(bundle: RenderBundle) void {
bundle.vtable.release(bundle.ptr);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = Descriptor;
}

View file

@ -1,163 +0,0 @@
const Texture = @import("Texture.zig");
const Buffer = @import("Buffer.zig");
const RenderBundle = @import("RenderBundle.zig");
const BindGroup = @import("BindGroup.zig");
const RenderPipeline = @import("RenderPipeline.zig");
const IndexFormat = @import("enums.zig").IndexFormat;
const RenderBundleEncoder = @This();
/// The type erased pointer to the RenderBundleEncoder implementation
/// Equal to c.WGPURenderBundleEncoder for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
draw: fn (
ptr: *anyopaque,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
) void,
drawIndexed: fn (
ptr: *anyopaque,
index_count: u32,
instance_count: u32,
first_index: u32,
base_vertex: i32,
first_instance: u32,
) void,
drawIndexedIndirect: fn (ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void,
drawIndirect: fn (ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void,
finish: fn (ptr: *anyopaque, descriptor: *const RenderBundle.Descriptor) RenderBundle,
insertDebugMarker: fn (ptr: *anyopaque, marker_label: [*:0]const u8) void,
popDebugGroup: fn (ptr: *anyopaque) void,
pushDebugGroup: fn (ptr: *anyopaque, group_label: [*:0]const u8) void,
setBindGroup: fn (ptr: *anyopaque, group_index: u32, group: BindGroup, dynamic_offsets: ?[]const u32) void,
setIndexBuffer: fn (ptr: *anyopaque, buffer: Buffer, format: IndexFormat, offset: u64, size: u64) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
setPipeline: fn (ptr: *anyopaque, pipeline: RenderPipeline) void,
setVertexBuffer: fn (ptr: *anyopaque, slot: u32, buffer: Buffer, offset: u64, size: u64) void,
};
pub inline fn reference(enc: RenderBundleEncoder) void {
enc.vtable.reference(enc.ptr);
}
pub inline fn release(enc: RenderBundleEncoder) void {
enc.vtable.release(enc.ptr);
}
pub inline fn draw(
enc: RenderBundleEncoder,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
) void {
enc.vtable.draw(enc.ptr, vertex_count, instance_count, first_vertex, first_instance);
}
pub inline fn drawIndexed(
enc: RenderBundleEncoder,
index_count: u32,
instance_count: u32,
first_index: u32,
base_vertex: i32,
first_instance: u32,
) void {
enc.vtable.drawIndexed(enc.ptr, index_count, instance_count, first_index, base_vertex, first_instance);
}
pub inline fn drawIndexedIndirect(enc: RenderBundleEncoder, indirect_buffer: Buffer, indirect_offset: u64) void {
enc.vtable.drawIndexedIndirect(enc.ptr, indirect_buffer, indirect_offset);
}
pub inline fn drawIndirect(enc: RenderBundleEncoder, indirect_buffer: Buffer, indirect_offset: u64) void {
enc.vtable.drawIndirect(enc.ptr, indirect_buffer, indirect_offset);
}
pub inline fn finish(enc: RenderBundleEncoder, descriptor: *const RenderBundle.Descriptor) RenderBundle {
return enc.vtable.finish(enc.ptr, descriptor);
}
pub inline fn insertDebugMarker(enc: RenderBundleEncoder, marker_label: [*:0]const u8) void {
enc.vtable.insertDebugMarker(enc.ptr, marker_label);
}
pub inline fn popDebugGroup(enc: RenderBundleEncoder) void {
enc.vtable.popDebugGroup(enc.ptr);
}
pub inline fn pushDebugGroup(enc: RenderBundleEncoder, group_label: [*:0]const u8) void {
enc.vtable.pushDebugGroup(enc.ptr, group_label);
}
pub inline fn setBindGroup(
enc: RenderBundleEncoder,
group_index: u32,
group: BindGroup,
dynamic_offsets: ?[]const u32,
) void {
enc.vtable.setBindGroup(enc.ptr, group_index, group, dynamic_offsets);
}
pub inline fn setIndexBuffer(
enc: RenderBundleEncoder,
buffer: Buffer,
format: IndexFormat,
offset: u64,
size: u64,
) void {
enc.vtable.setIndexBuffer(enc.ptr, buffer, format, offset, size);
}
pub inline fn setLabel(enc: RenderBundleEncoder, label: [:0]const u8) void {
enc.vtable.setLabel(enc.ptr, label);
}
pub inline fn setPipeline(enc: RenderBundleEncoder, pipeline: RenderPipeline) void {
enc.vtable.setPipeline(enc.ptr, pipeline);
}
pub inline fn setVertexBuffer(
enc: RenderBundleEncoder,
slot: u32,
buffer: Buffer,
offset: u64,
size: u64,
) void {
enc.vtable.setVertexBuffer(enc.ptr, slot, buffer, offset, size);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
color_formats: []Texture.Format,
depth_stencil_format: Texture.Format,
sample_count: u32,
depth_read_only: bool,
stencil_read_only: bool,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = draw;
_ = drawIndexed;
_ = drawIndexedIndirect;
_ = drawIndirect;
_ = finish;
_ = insertDebugMarker;
_ = popDebugGroup;
_ = pushDebugGroup;
_ = setBindGroup;
_ = setIndexBuffer;
_ = setLabel;
_ = setPipeline;
_ = setVertexBuffer;
_ = Descriptor;
}

View file

@ -1,216 +0,0 @@
const QuerySet = @import("QuerySet.zig");
const RenderPassColorAttachment = @import("structs.zig").RenderPassColorAttachment;
const RenderPassDepthStencilAttachment = @import("structs.zig").RenderPassDepthStencilAttachment;
const RenderPassTimestampWrite = @import("structs.zig").RenderPassTimestampWrite;
const RenderPipeline = @import("RenderPipeline.zig");
const Buffer = @import("Buffer.zig");
const RenderBundle = @import("RenderBundle.zig");
const BindGroup = @import("BindGroup.zig");
const Color = @import("data.zig").Color;
const IndexFormat = @import("enums.zig").IndexFormat;
const RenderPassEncoder = @This();
/// The type erased pointer to the RenderPassEncoder implementation
/// Equal to c.WGPURenderPassEncoder for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
draw: fn (ptr: *anyopaque, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void,
drawIndexed: fn (
ptr: *anyopaque,
index_count: u32,
instance_count: u32,
first_index: u32,
base_vertex: i32,
first_instance: u32,
) void,
drawIndexedIndirect: fn (ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void,
drawIndirect: fn (ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void,
beginOcclusionQuery: fn (ptr: *anyopaque, query_index: u32) void,
endOcclusionQuery: fn (ptr: *anyopaque) void,
end: fn (ptr: *anyopaque) void,
executeBundles: fn (ptr: *anyopaque, bundles: []RenderBundle) void,
insertDebugMarker: fn (ptr: *anyopaque, marker_label: [*:0]const u8) void,
popDebugGroup: fn (ptr: *anyopaque) void,
pushDebugGroup: fn (ptr: *anyopaque, group_label: [*:0]const u8) void,
setBindGroup: fn (ptr: *anyopaque, group_index: u32, group: BindGroup, dynamic_offsets: ?[]const u32) void,
setBlendConstant: fn (ptr: *anyopaque, color: *const Color) void,
setIndexBuffer: fn (ptr: *anyopaque, buffer: Buffer, format: IndexFormat, offset: u64, size: u64) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
setPipeline: fn (ptr: *anyopaque, pipeline: RenderPipeline) void,
setScissorRect: fn (ptr: *anyopaque, x: u32, y: u32, width: u32, height: u32) void,
setStencilReference: fn (ptr: *anyopaque, reference: u32) void,
setVertexBuffer: fn (ptr: *anyopaque, slot: u32, buffer: Buffer, offset: u64, size: u64) void,
setViewport: fn (ptr: *anyopaque, x: f32, y: f32, width: f32, height: f32, min_depth: f32, max_depth: f32) void,
writeTimestamp: fn (ptr: *anyopaque, query_set: QuerySet, query_index: u32) void,
};
pub inline fn reference(pass: RenderPassEncoder) void {
pass.vtable.reference(pass.ptr);
}
pub inline fn release(pass: RenderPassEncoder) void {
pass.vtable.release(pass.ptr);
}
pub inline fn draw(
pass: RenderPassEncoder,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
first_instance: u32,
) void {
pass.vtable.draw(pass.ptr, vertex_count, instance_count, first_vertex, first_instance);
}
pub inline fn drawIndexed(
pass: RenderPassEncoder,
index_count: u32,
instance_count: u32,
first_index: u32,
base_vertex: i32,
first_instance: u32,
) void {
pass.vtable.drawIndexed(pass.ptr, index_count, instance_count, first_index, base_vertex, first_instance);
}
pub inline fn drawIndexedIndirect(pass: RenderPassEncoder, indirect_buffer: Buffer, indirect_offset: u64) void {
pass.vtable.drawIndexedIndirect(pass.ptr, indirect_buffer, indirect_offset);
}
pub inline fn drawIndirect(pass: RenderPassEncoder, indirect_buffer: Buffer, indirect_offset: u64) void {
pass.vtable.drawIndirect(pass.ptr, indirect_buffer, indirect_offset);
}
pub inline fn beginOcclusionQuery(pass: RenderPassEncoder, query_index: u32) void {
pass.vtable.beginOcclusionQuery(pass.ptr, query_index);
}
pub inline fn endOcclusionQuery(pass: RenderPassEncoder) void {
pass.vtable.endOcclusionQuery(pass.ptr);
}
pub inline fn end(pass: RenderPassEncoder) void {
pass.vtable.end(pass.ptr);
}
pub inline fn executeBundles(pass: RenderPassEncoder, bundles: []RenderBundle) void {
pass.vtable.executeBundles(pass.ptr, bundles);
}
pub inline fn insertDebugMarker(pass: RenderPassEncoder, marker_label: [*:0]const u8) void {
pass.vtable.insertDebugMarker(pass.ptr, marker_label);
}
pub inline fn popDebugGroup(pass: RenderPassEncoder) void {
pass.vtable.popDebugGroup(pass.ptr);
}
pub inline fn pushDebugGroup(pass: RenderPassEncoder, group_label: [*:0]const u8) void {
pass.vtable.pushDebugGroup(pass.ptr, group_label);
}
pub inline fn setBindGroup(
pass: RenderPassEncoder,
group_index: u32,
group: BindGroup,
dynamic_offsets: ?[]const u32,
) void {
pass.vtable.setBindGroup(pass.ptr, group_index, group, dynamic_offsets);
}
pub inline fn setBlendConstant(pass: RenderPassEncoder, color: *const Color) void {
pass.vtable.setBlendConstant(pass.ptr, color);
}
pub inline fn setIndexBuffer(
pass: RenderPassEncoder,
buffer: Buffer,
format: IndexFormat,
offset: u64,
size: u64,
) void {
pass.vtable.setIndexBuffer(pass.ptr, buffer, format, offset, size);
}
pub inline fn setLabel(pass: RenderPassEncoder, label: [:0]const u8) void {
pass.vtable.setLabel(pass.ptr, label);
}
pub inline fn setPipeline(pass: RenderPassEncoder, pipeline: RenderPipeline) void {
pass.vtable.setPipeline(pass.ptr, pipeline);
}
pub inline fn setScissorRect(pass: RenderPassEncoder, x: u32, y: u32, width: u32, height: u32) void {
pass.vtable.setScissorRect(pass.ptr, x, y, width, height);
}
pub inline fn setStencilReference(pass: RenderPassEncoder, ref: u32) void {
pass.vtable.setStencilReference(pass.ptr, ref);
}
pub inline fn setVertexBuffer(
pass: RenderPassEncoder,
slot: u32,
buffer: Buffer,
offset: u64,
size: u64,
) void {
pass.vtable.setVertexBuffer(pass.ptr, slot, buffer, offset, size);
}
pub inline fn setViewport(
pass: RenderPassEncoder,
x: f32,
y: f32,
width: f32,
height: f32,
min_depth: f32,
max_depth: f32,
) void {
pass.vtable.setViewport(pass.ptr, x, y, width, height, min_depth, max_depth);
}
pub inline fn writeTimestamp(pass: RenderPassEncoder, query_set: QuerySet, query_index: u32) void {
pass.vtable.writeTimestamp(pass.ptr, query_set, query_index);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
color_attachments: []const RenderPassColorAttachment,
depth_stencil_attachment: ?*const RenderPassDepthStencilAttachment = null,
occlusion_query_set: ?QuerySet = null,
timestamp_writes: ?[]RenderPassTimestampWrite = null,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = draw;
_ = drawIndexed;
_ = drawIndexedIndirect;
_ = drawIndirect;
_ = beginOcclusionQuery;
_ = endOcclusionQuery;
_ = end;
_ = executeBundles;
_ = insertDebugMarker;
_ = popDebugGroup;
_ = pushDebugGroup;
_ = setBindGroup;
_ = setBlendConstant;
_ = setIndexBuffer;
_ = setLabel;
_ = setPipeline;
_ = setPipeline;
_ = setStencilReference;
_ = setVertexBuffer;
_ = setViewport;
_ = writeTimestamp;
_ = Descriptor;
}

View file

@ -1,109 +0,0 @@
const std = @import("std");
const PipelineLayout = @import("PipelineLayout.zig");
const VertexState = @import("structs.zig").VertexState;
const PrimitiveState = @import("structs.zig").PrimitiveState;
const DepthStencilState = @import("structs.zig").DepthStencilState;
const MultisampleState = @import("structs.zig").MultisampleState;
const FragmentState = @import("structs.zig").FragmentState;
const BindGroupLayout = @import("BindGroupLayout.zig");
const RenderPipeline = @This();
/// The type erased pointer to the RenderPipeline implementation
/// Equal to c.WGPURenderPipeline for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
getBindGroupLayout: fn (ptr: *anyopaque, group_index: u32) BindGroupLayout,
};
pub inline fn reference(pipeline: RenderPipeline) void {
pipeline.vtable.reference(pipeline.ptr);
}
pub inline fn release(pipeline: RenderPipeline) void {
pipeline.vtable.release(pipeline.ptr);
}
pub inline fn setLabel(pipeline: RenderPipeline, label: [:0]const u8) void {
pipeline.vtable.setLabel(pipeline.ptr, label);
}
pub inline fn getBindGroupLayout(pipeline: RenderPipeline, group_index: u32) BindGroupLayout {
return pipeline.vtable.getBindGroupLayout(pipeline.ptr, group_index);
}
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
layout: ?PipelineLayout = null,
vertex: VertexState,
primitive: PrimitiveState = .{},
depth_stencil: ?*const DepthStencilState = null,
multisample: MultisampleState = .{},
fragment: ?*const FragmentState = null,
};
pub const CreateStatus = enum(u32) {
success = 0x00000000,
err = 0x00000001,
device_lost = 0x00000002,
device_destroyed = 0x00000003,
unknown = 0x00000004,
};
pub const CreateCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (
ctx: *anyopaque,
status: CreateStatus,
pipeline: RenderPipeline,
message: [:0]const u8,
) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (
ctx: Context,
status: CreateStatus,
pipeline: RenderPipeline,
message: [:0]const u8,
) void,
) CreateCallback {
const erased = (struct {
pub inline fn erased(
type_erased_ctx: *anyopaque,
status: CreateStatus,
pipeline: RenderPipeline,
message: [:0]const u8,
) void {
callback(
if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)),
status,
pipeline,
message,
);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = setLabel;
_ = getBindGroupLayout;
_ = Descriptor;
_ = CreateStatus;
_ = CreateCallback;
}

View file

@ -1,64 +0,0 @@
const AddressMode = @import("enums.zig").AddressMode;
const FilterMode = @import("enums.zig").FilterMode;
const CompareFunction = @import("enums.zig").CompareFunction;
const Sampler = @This();
/// The type erased pointer to the Sampler implementation
/// Equal to c.WGPUSampler for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(sampler: Sampler) void {
sampler.vtable.reference(sampler.ptr);
}
pub inline fn release(sampler: Sampler) void {
sampler.vtable.release(sampler.ptr);
}
pub inline fn setLabel(sampler: Sampler, label: [:0]const u8) void {
sampler.vtable.setLabel(sampler.ptr, label);
}
pub const BindingType = enum(u32) {
none = 0x00000000,
filtering = 0x00000001,
non_filtering = 0x00000002,
comparison = 0x00000003,
};
pub const BindingLayout = extern struct {
reserved: ?*anyopaque = null,
type: BindingType = .filtering,
};
pub const Descriptor = extern struct {
reserved: ?*anyopaque = null,
label: ?[*:0]const u8 = null,
address_mode_u: AddressMode = .clamp_to_edge,
address_mode_v: AddressMode = .clamp_to_edge,
address_mode_w: AddressMode = .clamp_to_edge,
mag_filter: FilterMode = .nearest,
min_filter: FilterMode = .nearest,
mipmap_filter: FilterMode = .nearest,
lod_min_clamp: f32 = 0,
lod_max_clamp: f32 = 32,
compare: CompareFunction = .none,
max_anisotropy: u16 = 1,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = BindingType;
_ = BindingLayout;
_ = Descriptor;
}

View file

@ -1,104 +0,0 @@
const std = @import("std");
const ShaderModule = @This();
/// The type erased pointer to the ShaderModule implementation
/// Equal to c.WGPUShaderModule for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
getCompilationInfo: fn (ptr: *anyopaque, callback: *CompilationInfoCallback) void,
};
pub inline fn reference(shader: ShaderModule) void {
shader.vtable.reference(shader.ptr);
}
pub inline fn release(shader: ShaderModule) void {
shader.vtable.release(shader.ptr);
}
pub inline fn setLabel(shader: ShaderModule, label: [:0]const u8) void {
shader.vtable.setLabel(shader.ptr, label);
}
pub inline fn getCompilationInfo(shader: ShaderModule, callback: *CompilationInfoCallback) void {
shader.vtable.getCompilationInfo(shader.ptr, callback);
}
pub const CompilationInfoCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, status: CompilationInfoRequestStatus, info: *const CompilationInfo) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, status: CompilationInfoRequestStatus, info: *const CompilationInfo) void,
) CompilationInfoCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, status: CompilationInfoRequestStatus) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), status);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
pub const CompilationInfoRequestStatus = enum(u32) {
success = 0x00000000,
err = 0x00000001,
device_lost = 0x00000002,
unknown = 0x00000003,
};
pub const CompilationInfo = struct {
messages: []const CompilationMessage,
};
pub const CompilationMessageType = enum(u32) {
err = 0x00000000,
warning = 0x00000001,
info = 0x00000002,
};
pub const CompilationMessage = extern struct {
reserved: ?*anyopaque = null,
message: [*:0]const u8,
type: CompilationMessageType,
line_num: u64,
line_pos: u64,
offset: u64,
length: u64,
};
pub const CodeTag = enum {
spirv,
wgsl,
};
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
code: union(CodeTag) {
wgsl: [*:0]const u8,
spirv: []const u32,
},
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = CompilationInfoRequestStatus;
_ = CompilationInfo;
_ = CompilationMessageType;
_ = CompilationMessage;
_ = CodeTag;
_ = Descriptor;
}

View file

@ -1,67 +0,0 @@
//! A native WebGPU surface
const Surface = @This();
/// The type erased pointer to the Surface implementation
/// Equal to c.WGPUSurface for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
};
pub inline fn reference(surface: Surface) void {
surface.vtable.reference(surface.ptr);
}
pub inline fn release(surface: Surface) void {
surface.vtable.release(surface.ptr);
}
pub const DescriptorTag = enum {
metal_layer,
windows_hwnd,
windows_core_window,
windows_swap_chain_panel,
xlib,
canvas_html_selector,
};
pub const Descriptor = union(DescriptorTag) {
metal_layer: struct {
label: ?[*:0]const u8 = null,
layer: *anyopaque,
},
windows_hwnd: struct {
label: ?[*:0]const u8 = null,
hinstance: *anyopaque,
hwnd: *anyopaque,
},
windows_core_window: struct {
label: ?[*:0]const u8 = null,
core_window: *anyopaque,
},
windows_swap_chain_panel: struct {
label: ?[*:0]const u8 = null,
swap_chain_panel: *anyopaque,
},
xlib: struct {
label: ?[*:0]const u8 = null,
display: *anyopaque,
window: u32,
},
canvas_html_selector: struct {
label: ?[*:0]const u8 = null,
selector: ?[*:0]const u8,
},
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = DescriptorTag;
_ = Descriptor;
}

View file

@ -1,78 +0,0 @@
const std = @import("std");
const Texture = @import("Texture.zig");
const TextureView = @import("TextureView.zig");
const PresentMode = @import("enums.zig").PresentMode;
const SwapChain = @This();
/// The type erased pointer to the SwapChain implementation
/// Equal to c.WGPUSwapChain for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
configure: fn (ptr: *anyopaque, format: Texture.Format, allowed_usage: Texture.Usage, width: u32, height: u32) void,
getCurrentTextureView: fn (ptr: *anyopaque) TextureView,
present: fn (ptr: *anyopaque) void,
};
pub inline fn reference(swap_chain: SwapChain) void {
swap_chain.vtable.reference(swap_chain.ptr);
}
pub inline fn release(swap_chain: SwapChain) void {
swap_chain.vtable.release(swap_chain.ptr);
}
// TODO: remove this and/or prefix with dawn? Seems to be deprecated / not in upstream webgpu.h
pub inline fn configure(
swap_chain: SwapChain,
format: Texture.Format,
allowed_usage: Texture.Usage,
width: u32,
height: u32,
) void {
swap_chain.vtable.configure(swap_chain.ptr, format, allowed_usage, width, height);
}
pub inline fn getCurrentTextureView(swap_chain: SwapChain) TextureView {
return swap_chain.vtable.getCurrentTextureView(swap_chain.ptr);
}
pub inline fn present(swap_chain: SwapChain) void {
swap_chain.vtable.present(swap_chain.ptr);
}
pub const Descriptor = struct {
label: ?[:0]const u8 = null,
usage: Texture.Usage,
format: Texture.Format,
width: u32,
height: u32,
present_mode: PresentMode,
implementation: u64,
pub fn equal(a: *const Descriptor, b: *const Descriptor) bool {
if ((a.label == null) != (b.label == null)) return false;
if (a.label != null and !std.mem.eql(u8, a.label.?, b.label.?)) return false;
if (!a.usage.equal(b.usage)) return false;
if (a.format != b.format) return false;
if (a.width != b.width) return false;
if (a.height != b.height) return false;
if (a.present_mode != b.present_mode) return false;
if (a.implementation != b.implementation) return false;
return true;
}
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = configure;
_ = getCurrentTextureView;
_ = present;
_ = Descriptor;
}

View file

@ -1,241 +0,0 @@
const std = @import("std");
const Extent3D = @import("data.zig").Extent3D;
const TextureView = @import("TextureView.zig");
const Texture = @This();
/// The type erased pointer to the Texture implementation
/// Equal to c.WGPUTexture for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
destroy: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
createView: fn (ptr: *anyopaque, descriptor: *const TextureView.Descriptor) TextureView,
};
pub inline fn reference(texture: Texture) void {
texture.vtable.reference(texture.ptr);
}
pub inline fn release(texture: Texture) void {
texture.vtable.release(texture.ptr);
}
pub inline fn setLabel(texture: Texture, label: [:0]const u8) void {
texture.vtable.setLabel(texture.ptr, label);
}
pub inline fn destroy(texture: Texture) void {
texture.vtable.destroy(texture.ptr);
}
pub inline fn createView(texture: Texture, descriptor: *const TextureView.Descriptor) TextureView {
return texture.vtable.createView(texture.ptr, descriptor);
}
pub const Descriptor = struct {
reserved: ?*anyopaque = null,
label: ?[*:0]const u8 = null,
usage: Usage,
dimension: Dimension = .dimension_2d,
size: Extent3D,
format: Format,
mip_level_count: u32 = 1,
sample_count: u32 = 1,
view_formats: ?[]const Format = null,
};
pub const Usage = packed struct {
copy_src: bool = false,
copy_dst: bool = false,
texture_binding: bool = false,
storage_binding: bool = false,
render_attachment: bool = false,
present: bool = false,
_pad0: u2 = 0,
_pad1: u8 = 0,
_pad2: u16 = 0,
comptime {
std.debug.assert(
@sizeOf(@This()) == @sizeOf(u32) and
@bitSizeOf(@This()) == @bitSizeOf(u32),
);
}
pub fn equal(a: Usage, b: Usage) bool {
return a.copy_src == b.copy_src and
a.copy_dst == b.copy_dst and
a.texture_binding == b.texture_binding and
a.storage_binding == b.storage_binding and
a.render_attachment == b.render_attachment and
a.present == b.present;
}
};
pub const Format = enum(u32) {
none = 0x00000000,
r8_unorm = 0x00000001,
r8_snorm = 0x00000002,
r8_uint = 0x00000003,
r8_sint = 0x00000004,
r16_uint = 0x00000005,
r16_sint = 0x00000006,
r16_float = 0x00000007,
rg8_unorm = 0x00000008,
rg8_snorm = 0x00000009,
rg8_uint = 0x0000000a,
rg8_sint = 0x0000000b,
r32_float = 0x0000000c,
r32_uint = 0x0000000d,
r32_sint = 0x0000000e,
rg16_uint = 0x0000000f,
rg16_sint = 0x00000010,
rg16_float = 0x00000011,
rgba8_unorm = 0x00000012,
rgba8_unorm_srgb = 0x00000013,
rgba8_snorm = 0x00000014,
rgba8_uint = 0x00000015,
rgba8_sint = 0x00000016,
bgra8_unorm = 0x00000017,
bgra8_unorm_srgb = 0x00000018,
rgb10a2_unorm = 0x00000019,
rg11b10u_float = 0x0000001a,
rgb9e5u_float = 0x0000001b,
rg32_float = 0x0000001c,
rg32_uint = 0x0000001d,
rg32_sint = 0x0000001e,
rgba16_uint = 0x0000001f,
rgba16_sint = 0x00000020,
rgba16_float = 0x00000021,
rgba32_float = 0x00000022,
rgba32_uint = 0x00000023,
rgba32_sint = 0x00000024,
stencil8 = 0x00000025,
depth16_unorm = 0x00000026,
depth24_plus = 0x00000027,
depth24_plus_stencil8 = 0x00000028,
depth24_unorm_stencil8 = 0x00000029,
depth32_float = 0x0000002a,
depth32_float_stencil8 = 0x0000002b,
bc1rgba_unorm = 0x0000002c,
bc1rgba_unorm_srgb = 0x0000002d,
bc2rgba_unorm = 0x0000002e,
bc2rgba_unorm_srgb = 0x0000002f,
bc3rgba_unorm = 0x00000030,
bc3rgba_unorm_srgb = 0x00000031,
bc4r_unorm = 0x00000032,
bc4r_snorm = 0x00000033,
bc5rg_unorm = 0x00000034,
bc5rg_snorm = 0x00000035,
bc6hrgbu_float = 0x00000036,
bc6hrgb_float = 0x00000037,
bc7rgba_unorm = 0x00000038,
bc7rgba_unorm_srgb = 0x00000039,
etc2rgb8_unorm = 0x0000003a,
etc2rgb8_unorm_srgb = 0x0000003b,
etc2rgb8a1_unorm = 0x0000003c,
etc2rgb8a1_unorm_srgb = 0x0000003d,
etc2rgba8_unorm = 0x0000003e,
etc2rgba8_unorm_srgb = 0x0000003f,
eacr11_unorm = 0x00000040,
eacr11_snorm = 0x00000041,
eacrg11_unorm = 0x00000042,
eacrg11_snorm = 0x00000043,
astc4x4_unorm = 0x00000044,
astc4x4_unorm_srgb = 0x00000045,
astc5x4_unorm = 0x00000046,
astc5x4_unorm_srgb = 0x00000047,
astc5x5_unorm = 0x00000048,
astc5x5_unorm_srgb = 0x00000049,
astc6x5_unorm = 0x0000004a,
astc6x5_unorm_srgb = 0x0000004b,
astc6x6_unorm = 0x0000004c,
astc6x6_unorm_srgb = 0x0000004d,
astc8x5_unorm = 0x0000004e,
astc8x5_unorm_srgb = 0x0000004f,
astc8x6_unorm = 0x00000050,
astc8x6_unorm_srgb = 0x00000051,
astc8x8_unorm = 0x00000052,
astc8x8_unorm_srgb = 0x00000053,
astc10x5_unorm = 0x00000054,
astc10x5_unorm_srgb = 0x00000055,
astc10x6_unorm = 0x00000056,
astc10x6_unorm_srgb = 0x00000057,
astc10x8_unorm = 0x00000058,
astc10x8_unorm_srgb = 0x00000059,
astc10x10_unorm = 0x0000005a,
astc10x10_unorm_srgb = 0x0000005b,
astc12x10_unorm = 0x0000005c,
astc12x10_unorm_srgb = 0x0000005d,
astc12x12_unorm = 0x0000005e,
astc12x12_unorm_srgb = 0x0000005f,
r8bg8biplanar420_unorm = 0x00000060,
};
pub const Aspect = enum(u32) {
all = 0x00000000,
stencil_only = 0x00000001,
depth_only = 0x00000002,
plane0_only = 0x00000003,
plane1_only = 0x00000004,
};
pub const ComponentType = enum(u32) {
float = 0x00000000,
sint = 0x00000001,
uint = 0x00000002,
depth_comparison = 0x00000003,
};
pub const Dimension = enum(u32) {
dimension_1d = 0x00000000,
dimension_2d = 0x00000001,
dimension_3d = 0x00000002,
};
pub const SampleType = enum(u32) {
none = 0x00000000,
float = 0x00000001,
unfilterable_float = 0x00000002,
depth = 0x00000003,
sint = 0x00000004,
uint = 0x00000005,
};
pub const BindingLayout = extern struct {
reserved: ?*anyopaque = null,
sample_type: SampleType = .float,
view_dimension: TextureView.Dimension = .dimension_2d,
multisampled: bool = false,
};
pub const DataLayout = extern struct {
reserved: ?*anyopaque = null,
offset: u64 = 0,
bytes_per_row: u32,
rows_per_image: u32,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = destroy;
_ = Descriptor;
_ = Usage;
_ = Format;
_ = Aspect;
_ = ComponentType;
_ = Dimension;
_ = SampleType;
_ = BindingLayout;
_ = DataLayout;
}

View file

@ -1,58 +0,0 @@
const Texture = @import("Texture.zig");
const TextureView = @This();
/// The type erased pointer to the TextureView implementation
/// Equal to c.WGPUTextureView for NativeInstance.
ptr: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
reference: fn (ptr: *anyopaque) void,
release: fn (ptr: *anyopaque) void,
setLabel: fn (ptr: *anyopaque, label: [:0]const u8) void,
};
pub inline fn reference(texture_view: TextureView) void {
texture_view.vtable.reference(texture_view.ptr);
}
pub inline fn release(texture_view: TextureView) void {
texture_view.vtable.release(texture_view.ptr);
}
pub inline fn setLabel(texture_view: TextureView, label: [:0]const u8) void {
texture_view.vtable.setLabel(texture_view.ptr, label);
}
const mip_level_count_undefined: u32 = 0xffffffff;
const array_layer_count_undefined: u32 = 0xffffffff;
pub const Descriptor = struct {
label: ?[*:0]const u8 = null,
format: Texture.Format = .none,
dimension: TextureView.Dimension = .dimension_none,
base_mip_level: u32 = 0,
mip_level_count: u32 = mip_level_count_undefined,
base_array_layer: u32 = 0,
array_layer_count: u32 = array_layer_count_undefined,
aspect: Texture.Aspect = .all,
};
pub const Dimension = enum(u32) {
dimension_none = 0x00000000,
dimension_1d = 0x00000001,
dimension_2d = 0x00000002,
dimension_2d_array = 0x00000003,
dimension_cube = 0x00000004,
dimension_cube_array = 0x00000005,
dimension_3d = 0x00000006,
};
test {
_ = VTable;
_ = reference;
_ = release;
_ = Descriptor;
_ = Dimension;
}

View file

@ -1,3 +0,0 @@
pub const c = @cImport({
@cInclude("webgpu/webgpu.h");
});

View file

@ -1,99 +0,0 @@
//! Data structures that are ABI-compatible with webgpu.h
const BlendOperation = @import("enums.zig").BlendOperation;
const BlendFactor = @import("enums.zig").BlendFactor;
const CompareFunction = @import("enums.zig").CompareFunction;
const StencilOperation = @import("enums.zig").StencilOperation;
const VertexFormat = @import("enums.zig").VertexFormat;
const VertexStepMode = @import("enums.zig").VertexStepMode;
pub const Limits = extern struct {
max_texture_dimension_1d: u32,
max_texture_dimension_2d: u32,
max_texture_dimension_3d: u32,
max_texture_array_layers: u32,
max_bind_groups: u32,
max_dynamic_uniform_buffers_per_pipeline_layout: u32,
max_dynamic_storage_buffers_per_pipeline_layout: u32,
max_sampled_textures_per_shader_stage: u32,
max_samplers_per_shader_stage: u32,
max_storage_buffers_per_shader_stage: u32,
max_storage_textures_per_shader_stage: u32,
max_uniform_buffers_per_shader_stage: u32,
max_uniform_buffer_binding_size: u64,
max_storage_buffer_binding_size: u64,
min_uniform_buffer_offset_alignment: u32,
min_storage_buffer_offset_alignment: u32,
max_vertex_buffers: u32,
max_vertex_attributes: u32,
max_vertex_buffer_array_stride: u32,
max_inter_stage_shader_components: u32,
max_compute_workgroup_storage_size: u32,
max_compute_invocations_per_workgroup: u32,
max_compute_workgroup_size_x: u32,
max_compute_workgroup_size_y: u32,
max_compute_workgroup_size_z: u32,
max_compute_workgroups_per_dimension: u32,
};
pub const Color = extern struct {
r: f64,
g: f64,
b: f64,
a: f64,
};
pub const Extent3D = extern struct {
width: u32,
height: u32 = 1,
depth_or_array_layers: u32 = 1,
};
pub const Origin3D = extern struct {
x: u32 = 0,
y: u32 = 0,
z: u32 = 0,
};
pub const StencilFaceState = extern struct {
compare: CompareFunction = .always,
fail_op: StencilOperation = .keep,
depth_fail_op: StencilOperation = .keep,
pass_op: StencilOperation = .keep,
};
pub const VertexAttribute = extern struct {
format: VertexFormat,
offset: u64,
shader_location: u32,
};
pub const BlendComponent = extern struct {
operation: BlendOperation = .add,
src_factor: BlendFactor = .one,
dst_factor: BlendFactor = .zero,
};
pub const BlendState = extern struct {
color: BlendComponent,
alpha: BlendComponent,
};
pub const VertexBufferLayout = extern struct {
array_stride: u64,
step_mode: VertexStepMode = .vertex,
attribute_count: u32,
attributes: [*]const VertexAttribute,
};
test {
_ = Limits;
_ = Color;
_ = Extent3D;
_ = Origin3D;
_ = StencilFaceState;
_ = VertexAttribute;
_ = BlendComponent;
_ = BlendState;
_ = VertexBufferLayout;
}

View file

@ -1,324 +0,0 @@
const std = @import("std");
pub const Feature = enum(u32) {
depth24_unorm_stencil8 = 0x00000002,
depth32_float_stencil8 = 0x00000003,
timestamp_query = 0x00000004,
pipeline_statistics_query = 0x00000005,
texture_compression_bc = 0x00000006,
texture_compression_etc2 = 0x00000007,
texture_compression_astc = 0x00000008,
indirect_first_instance = 0x00000009,
depth_clamping = 0x000003e8,
dawn_shader_float16 = 0x000003e9,
dawn_internal_usages = 0x000003ea,
dawn_multi_planar_formats = 0x000003eb,
dawn_native = 0x000003ec,
};
pub const AddressMode = enum(u32) {
repeat = 0x00000000,
mirror_repeat = 0x00000001,
clamp_to_edge = 0x00000002,
};
pub const PresentMode = enum(u32) {
immediate = 0x00000000,
mailbox = 0x00000001,
fifo = 0x00000002,
};
pub const AlphaMode = enum(u32) {
premultiplied = 0x00000000,
unpremultiplied = 0x00000001,
};
pub const BlendFactor = enum(u32) {
zero = 0x00000000,
one = 0x00000001,
src = 0x00000002,
one_minus_src = 0x00000003,
src_alpha = 0x00000004,
one_minus_src_alpha = 0x00000005,
dst = 0x00000006,
one_minus_dst = 0x00000007,
dst_alpha = 0x00000008,
one_minus_dst_alpha = 0x00000009,
src_alpha_saturated = 0x0000000A,
constant = 0x0000000B,
one_minus_constant = 0x0000000C,
};
pub const BlendOperation = enum(u32) {
add = 0x00000000,
subtract = 0x00000001,
reverse_subtract = 0x00000002,
min = 0x00000003,
max = 0x00000004,
};
pub const CompareFunction = enum(u32) {
none = 0x00000000,
never = 0x00000001,
less = 0x00000002,
less_equal = 0x00000003,
greater = 0x00000004,
greater_equal = 0x00000005,
equal = 0x00000006,
not_equal = 0x00000007,
always = 0x00000008,
};
pub const ComputePassTimestampLocation = enum(u32) {
beginning = 0x00000000,
end = 0x00000001,
};
pub const CullMode = enum(u32) {
none = 0x00000000,
front = 0x00000001,
back = 0x00000002,
};
pub const ErrorFilter = enum(u32) {
validation = 0x00000000,
out_of_memory = 0x00000001,
};
pub const ErrorType = enum(u32) {
noError = 0x00000000,
validation = 0x00000001,
out_of_memory = 0x00000002,
unknown = 0x00000003,
device_lost = 0x00000004,
};
pub const FilterMode = enum(u32) {
nearest = 0x00000000,
linear = 0x00000001,
};
pub const FrontFace = enum(u32) {
ccw = 0x00000000,
cw = 0x00000001,
};
pub const IndexFormat = enum(u32) {
none = 0x00000000,
uint16 = 0x00000001,
uint32 = 0x00000002,
};
pub const LoadOp = enum(u32) {
none = 0x00000000,
clear = 0x00000001,
load = 0x00000002,
};
pub const LoggingType = enum(u32) {
verbose = 0x00000000,
info = 0x00000001,
warning = 0x00000002,
err = 0x00000003,
};
pub const PipelineStatistic = enum(u32) {
vertex_shader_invocations = 0x00000000,
clipper_invocations = 0x00000001,
clipper_primitives_out = 0x00000002,
fragment_shader_invocations = 0x00000003,
compute_shader_invocations = 0x00000004,
};
pub const PowerPreference = enum(u32) {
none = 0x00000000,
low_power = 0x00000001,
high_performance = 0x00000002,
};
pub const PredefinedColorSpace = enum(u32) {
none = 0x00000000,
srgb = 0x00000001,
};
pub const PrimitiveTopology = enum(u32) {
point_list = 0x00000000,
line_list = 0x00000001,
line_strip = 0x00000002,
triangle_list = 0x00000003,
triangle_strip = 0x00000004,
};
pub const QueryType = enum(u32) {
occlusion = 0x00000000,
pipeline_statistics = 0x00000001,
timestamp = 0x00000002,
};
pub const RenderPassTimestampLocation = enum(u32) {
beginning = 0x00000000,
end = 0x00000001,
};
pub const StencilOperation = enum(u32) {
keep = 0x00000000,
zero = 0x00000001,
replace = 0x00000002,
invert = 0x00000003,
increment_clamp = 0x00000004,
decrement_clamp = 0x00000005,
increment_wrap = 0x00000006,
decrement_wrap = 0x00000007,
};
pub const StorageTextureAccess = enum(u32) {
none = 0x00000000,
write_only = 0x00000001,
};
pub const StoreOp = enum(u32) {
none = 0x00000000,
store = 0x00000001,
discard = 0x00000002,
};
pub const VertexFormat = enum(u32) {
none = 0x00000000,
uint8x2 = 0x00000001,
uint8x4 = 0x00000002,
sint8x2 = 0x00000003,
sint8x4 = 0x00000004,
unorm8x2 = 0x00000005,
unorm8x4 = 0x00000006,
snorm8x2 = 0x00000007,
snorm8x4 = 0x00000008,
uint16x2 = 0x00000009,
uint16x4 = 0x0000000A,
sint16x2 = 0x0000000B,
sint16x4 = 0x0000000C,
unorm16x2 = 0x0000000D,
unorm16x4 = 0x0000000E,
snorm16x2 = 0x0000000F,
snorm16x4 = 0x00000010,
float16x2 = 0x00000011,
float16x4 = 0x00000012,
float32 = 0x00000013,
float32x2 = 0x00000014,
float32x3 = 0x00000015,
float32x4 = 0x00000016,
uint32 = 0x00000017,
uint32x2 = 0x00000018,
uint32x3 = 0x00000019,
uint32x4 = 0x0000001A,
sint32 = 0x0000001B,
sint32x2 = 0x0000001C,
sint32x3 = 0x0000001D,
sint32x4 = 0x0000001E,
};
pub const VertexStepMode = enum(u32) {
vertex = 0x00000000,
instance = 0x00000001,
};
pub const BufferUsage = packed struct {
map_read: bool = false,
map_write: bool = false,
copy_src: bool = false,
copy_dst: bool = false,
index: bool = false,
vertex: bool = false,
uniform: bool = false,
storage: bool = false,
indirect: bool = false,
query_resolve: bool = false,
_pad0: u6 = 0,
_pad1: u16 = 0,
comptime {
std.debug.assert(
@sizeOf(@This()) == @sizeOf(u32) and
@bitSizeOf(@This()) == @bitSizeOf(u32),
);
}
};
pub const ColorWriteMask = packed struct {
red: bool = false,
green: bool = false,
blue: bool = false,
alpha: bool = false,
_pad0: u4 = 0,
_pad1: u8 = 0,
_pad2: u16 = 0,
comptime {
std.debug.assert(
@sizeOf(@This()) == @sizeOf(u32) and
@bitSizeOf(@This()) == @bitSizeOf(u32),
);
}
pub const all = ColorWriteMask{
.red = true,
.green = true,
.blue = true,
.alpha = true,
};
};
pub const ShaderStage = packed struct {
vertex: bool = false,
fragment: bool = false,
compute: bool = false,
_pad0: u5 = 0,
_pad1: u8 = 0,
_pad2: u16 = 0,
comptime {
std.debug.assert(
@sizeOf(@This()) == @sizeOf(u32) and
@bitSizeOf(@This()) == @bitSizeOf(u32),
);
}
};
test "name" {
try std.testing.expect(std.mem.eql(u8, @tagName(Feature.timestamp_query), "timestamp_query"));
}
test {
_ = Feature;
_ = AddressMode;
_ = PresentMode;
_ = AlphaMode;
_ = BlendFactor;
_ = BlendOperation;
_ = CompareFunction;
_ = ComputePassTimestampLocation;
_ = CullMode;
_ = ErrorFilter;
_ = ErrorType;
_ = FilterMode;
_ = FrontFace;
_ = IndexFormat;
_ = LoadOp;
_ = LoggingType;
_ = PipelineStatistic;
_ = PowerPreference;
_ = PredefinedColorSpace;
_ = PrimitiveTopology;
_ = QueryType;
_ = RenderPassTimestampLocation;
_ = StencilOperation;
_ = StorageTextureAccess;
_ = StoreOp;
_ = VertexFormat;
_ = VertexStepMode;
_ = BufferUsage;
_ = ColorWriteMask;
_ = ShaderStage;
}

View file

@ -1,159 +0,0 @@
//! WebGPU interface for Zig
//!
//! # Coordinate Systems
//!
//! * Y-axis is up in normalized device coordinate (NDC): point(-1.0, -1.0) in NDC is located at
//! the bottom-left corner of NDC. In addition, x and y in NDC should be between -1.0 and 1.0
//! inclusive, while z in NDC should be between 0.0 and 1.0 inclusive. Vertices out of this range
//! in NDC will not introduce any errors, but they will be clipped.
//! * Y-axis is down in framebuffer coordinate, viewport coordinate and fragment/pixel coordinate:
//! origin(0, 0) is located at the top-left corner in these coordinate systems.
//! * Window/present coordinate matches framebuffer coordinate.
//! * UV of origin(0, 0) in texture coordinate represents the first texel (the lowest byte) in
//! texture memory.
//!
//! Note: WebGPUs coordinate systems match DirectXs coordinate systems in a graphics pipeline.
//!
//! # Releasing resources
//!
//! WebGPU objects such as textures provide two APIs to release resources:
//!
//! * Reference counting: `reference` / `release`
//! * Manual destruction: `destroy`
//!
//! Where possible, using `destroy` is preferred as it more explicitly communicates the intent to
//! the implementation.
//!
//! When an object is `destroy`d, it is merely marked as destroyed. If the object is used past that
//! point, it is not unsafe nor does it access undefined memory. Instead, you will merely recieve
//! errors. The actual memory is released at the discretion of the implementation, possibly after a
//! few frames but it should be relatively soon (e.g. if the GPU is still using the resource, then
//! the implementation has to wait until it's safe to free.)
//!
//! Native implementations generally implement reference/release via referencing counting and invoke
//! destroy when zero is reached, but a browser implementation may choose to utilize these as
//! signals into an imprecise GC that may not even be aware of GPU-allocated memory (and so a 2MB
//! texture may appear as just a ~40b texture handle which is not important to free.)
//!
//! Implementations keep track of which objects are dead (so that errors, not undefined memory
//! accesses, occur) without truly keeping memory reserved for them by e.g. using a unique ID/handle
//! to represent a texture, and e.g. a hashmap from that handle to the memory. Thus, if the handle
//! doesn't exist in the map then it is dead.
//!
const std = @import("std");
// Root interface/implementations
pub const Interface = @import("Interface.zig");
pub const RequestAdapterOptions = Interface.RequestAdapterOptions;
pub const RequestAdapterErrorCode = Interface.RequestAdapterErrorCode;
pub const RequestAdapterError = Interface.RequestAdapterError;
pub const RequestAdapterCallback = Interface.RequestAdapterCallback;
pub const RequestAdapterResponse = Interface.RequestAdapterResponse;
pub const Adapter = @import("Adapter.zig");
pub const RequestDeviceErrorCode = Adapter.RequestDeviceErrorCode;
pub const RequestDeviceError = Adapter.RequestDeviceError;
pub const RequestDeviceCallback = Adapter.RequestDeviceCallback;
pub const RequestDeviceResponse = Adapter.RequestDeviceResponse;
pub const NativeInstance = @import("NativeInstance.zig");
// Interfaces
pub const Device = @import("Device.zig");
pub const Surface = @import("Surface.zig");
pub const Queue = @import("Queue.zig");
pub const CommandBuffer = @import("CommandBuffer.zig");
pub const ShaderModule = @import("ShaderModule.zig");
pub const SwapChain = @import("SwapChain.zig");
pub const TextureView = @import("TextureView.zig");
pub const Texture = @import("Texture.zig");
pub const Sampler = @import("Sampler.zig");
pub const RenderPipeline = @import("RenderPipeline.zig");
pub const RenderPassEncoder = @import("RenderPassEncoder.zig");
pub const RenderBundleEncoder = @import("RenderBundleEncoder.zig");
pub const RenderBundle = @import("RenderBundle.zig");
pub const QuerySet = @import("QuerySet.zig");
pub const PipelineLayout = @import("PipelineLayout.zig");
pub const ExternalTexture = @import("ExternalTexture.zig");
pub const BindGroup = @import("BindGroup.zig");
pub const BindGroupLayout = @import("BindGroupLayout.zig");
pub const Buffer = @import("Buffer.zig");
pub const CommandEncoder = @import("CommandEncoder.zig");
pub const ComputePassEncoder = @import("ComputePassEncoder.zig");
pub const ComputePipeline = @import("ComputePipeline.zig");
// Data structures ABI-compatible with webgpu.h
pub const Limits = @import("data.zig").Limits;
pub const Color = @import("data.zig").Color;
pub const Extent3D = @import("data.zig").Extent3D;
pub const Origin3D = @import("data.zig").Origin3D;
pub const StencilFaceState = @import("data.zig").StencilFaceState;
pub const VertexAttribute = @import("data.zig").VertexAttribute;
pub const BlendComponent = @import("data.zig").BlendComponent;
pub const BlendState = @import("data.zig").BlendState;
pub const VertexBufferLayout = @import("data.zig").VertexBufferLayout;
// Data structures not ABI-compatible with webgpu.h
pub const MultisampleState = @import("structs.zig").MultisampleState;
pub const PrimitiveState = @import("structs.zig").PrimitiveState;
pub const StorageTextureBindingLayout = @import("structs.zig").StorageTextureBindingLayout;
pub const DepthStencilState = @import("structs.zig").DepthStencilState;
pub const ConstantEntry = @import("structs.zig").ConstantEntry;
pub const ProgrammableStageDescriptor = @import("structs.zig").ProgrammableStageDescriptor;
// TODO: should these be moved into ComputePassEncoder / RenderPassEncoder? If not, should
// WGPURenderPassDescriptor really be RenderPassEncoder.Descriptor?
pub const ComputePassTimestampWrite = @import("structs.zig").ComputePassTimestampWrite;
pub const RenderPassTimestampWrite = @import("structs.zig").RenderPassTimestampWrite;
pub const RenderPassDepthStencilAttachment = @import("structs.zig").RenderPassDepthStencilAttachment;
pub const RenderPassColorAttachment = @import("structs.zig").RenderPassColorAttachment;
pub const VertexState = @import("structs.zig").VertexState;
pub const FragmentState = @import("structs.zig").FragmentState;
pub const ColorTargetState = @import("structs.zig").ColorTargetState;
pub const ImageCopyBuffer = @import("structs.zig").ImageCopyBuffer;
pub const ImageCopyTexture = @import("structs.zig").ImageCopyTexture;
pub const ErrorCallback = @import("structs.zig").ErrorCallback;
pub const LoggingCallback = @import("structs.zig").LoggingCallback;
// Enumerations
pub const Feature = @import("enums.zig").Feature;
pub const PresentMode = @import("enums.zig").PresentMode;
pub const AddressMode = @import("enums.zig").AddressMode;
pub const AlphaMode = @import("enums.zig").AlphaMode;
pub const BlendFactor = @import("enums.zig").BlendFactor;
pub const BlendOperation = @import("enums.zig").BlendOperation;
pub const CompareFunction = @import("enums.zig").CompareFunction;
pub const ComputePassTimestampLocation = @import("enums.zig").ComputePassTimestampLocation;
pub const CullMode = @import("enums.zig").CullMode;
pub const ErrorFilter = @import("enums.zig").ErrorFilter;
pub const ErrorType = @import("enums.zig").ErrorType;
pub const FilterMode = @import("enums.zig").FilterMode;
pub const FrontFace = @import("enums.zig").FrontFace;
pub const IndexFormat = @import("enums.zig").IndexFormat;
pub const LoadOp = @import("enums.zig").LoadOp;
pub const LoggingType = @import("enums.zig").LoggingType;
pub const PipelineStatistic = @import("enums.zig").PipelineStatistic;
pub const PowerPreference = @import("enums.zig").PowerPreference;
pub const PredefinedColorSpace = @import("enums.zig").PredefinedColorSpace;
pub const PrimitiveTopology = @import("enums.zig").PrimitiveTopology;
pub const QueryType = @import("enums.zig").QueryType;
pub const RenderPassTimestampLocation = @import("enums.zig").RenderPassTimestampLocation;
pub const StencilOperation = @import("enums.zig").StencilOperation;
pub const StorageTextureAccess = @import("enums.zig").StorageTextureAccess;
pub const StoreOp = @import("enums.zig").StoreOp;
pub const VertexFormat = @import("enums.zig").VertexFormat;
pub const VertexStepMode = @import("enums.zig").VertexStepMode;
pub const BufferUsage = @import("enums.zig").BufferUsage;
pub const ColorWriteMask = @import("enums.zig").ColorWriteMask;
pub const ShaderStage = @import("enums.zig").ShaderStage;
// Constants
const copy_stride_undefined: u32 = 0xffffffff;
const limit_u32_undefined: u32 = 0xffffffff;
const limit_u64_undefined: u64 = 0xffffffffffffffff;
const stride_undefined: u32 = 0xffffffff;
const whole_map_size: u32 = std.math.maxInt(c_int);
const whole_size: u64 = 0xffffffffffffffff;
test {
std.testing.refAllDeclsRecursive(@This());
}

View file

@ -1,204 +0,0 @@
//! Structures which are not ABI compatible with webgpu.h
const std = @import("std");
const math = @import("std").math;
const Buffer = @import("Buffer.zig");
const Sampler = @import("Sampler.zig");
const Texture = @import("Texture.zig");
const TextureView = @import("TextureView.zig");
const ShaderModule = @import("ShaderModule.zig");
const QuerySet = @import("QuerySet.zig");
const StencilFaceState = @import("data.zig").StencilFaceState;
const Color = @import("data.zig").Color;
const VertexBufferLayout = @import("data.zig").VertexBufferLayout;
const BlendState = @import("data.zig").BlendState;
const Origin3D = @import("data.zig").Origin3D;
const PrimitiveTopology = @import("enums.zig").PrimitiveTopology;
const IndexFormat = @import("enums.zig").IndexFormat;
const FrontFace = @import("enums.zig").FrontFace;
const CullMode = @import("enums.zig").CullMode;
const StorageTextureAccess = @import("enums.zig").StorageTextureAccess;
const CompareFunction = @import("enums.zig").CompareFunction;
const ComputePassTimestampLocation = @import("enums.zig").ComputePassTimestampLocation;
const RenderPassTimestampLocation = @import("enums.zig").RenderPassTimestampLocation;
const LoadOp = @import("enums.zig").LoadOp;
const StoreOp = @import("enums.zig").StoreOp;
const ColorWriteMask = @import("enums.zig").ColorWriteMask;
const ErrorType = @import("enums.zig").ErrorType;
const LoggingType = @import("enums.zig").LoggingType;
pub const MultisampleState = struct {
count: u32 = 1,
mask: u32 = 0xffff_ffff,
alpha_to_coverage_enabled: bool = false,
};
pub const PrimitiveState = struct {
topology: PrimitiveTopology = .triangle_list,
strip_index_format: IndexFormat = .none,
front_face: FrontFace = .ccw,
cull_mode: CullMode = .none,
};
pub const StorageTextureBindingLayout = extern struct {
reserved: ?*anyopaque = null,
access: StorageTextureAccess = .write_only,
format: Texture.Format,
view_dimension: TextureView.Dimension = .dimension_2d,
};
pub const DepthStencilState = struct {
format: Texture.Format,
depth_write_enabled: bool = false,
depth_compare: CompareFunction = .always,
stencil_front: StencilFaceState = .{},
stencil_back: StencilFaceState = .{},
stencil_read_mask: u32 = 0xffff_ffff,
stencil_write_mask: u32 = 0xffff_ffff,
depth_bias: i32 = 0,
depth_bias_slope_scale: f32 = 0.0,
depth_bias_clamp: f32 = 0.0,
};
// TODO: how does this map to browser API?
pub const ConstantEntry = extern struct {
reserved: ?*anyopaque = null,
key: [*:0]const u8,
value: f64,
};
pub const ProgrammableStageDescriptor = struct {
label: ?[*:0]const u8 = null,
module: ShaderModule,
entry_point: [*:0]const u8,
constants: ?[]const ConstantEntry = null,
};
pub const ComputePassTimestampWrite = struct {
query_set: QuerySet,
query_index: u32,
location: ComputePassTimestampLocation,
};
pub const RenderPassTimestampWrite = struct {
query_set: QuerySet,
query_index: u32,
location: RenderPassTimestampLocation,
};
pub const RenderPassDepthStencilAttachment = struct {
view: TextureView,
depth_load_op: LoadOp = .none,
depth_store_op: StoreOp = .none,
clear_depth: f32 = math.nan_f32,
depth_clear_value: f32 = 0.0,
depth_read_only: bool = false,
stencil_load_op: LoadOp = .none,
stencil_store_op: StoreOp = .none,
clear_stencil: u32 = 0,
stencil_clear_value: u32 = 0.0,
stencil_read_only: bool = false,
};
pub const RenderPassColorAttachment = struct {
view: TextureView,
resolve_target: ?TextureView = null,
load_op: LoadOp,
store_op: StoreOp,
clear_value: Color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 },
};
pub const VertexState = struct {
module: ShaderModule,
entry_point: [*:0]const u8,
constants: ?[]const ConstantEntry = null,
buffers: ?[]const VertexBufferLayout = null,
};
pub const FragmentState = struct {
module: ShaderModule,
entry_point: [*:0]const u8,
constants: ?[]const ConstantEntry = null,
targets: ?[]const ColorTargetState = null,
};
pub const ColorTargetState = extern struct {
reserved: ?*anyopaque = null,
format: Texture.Format,
blend: ?*const BlendState = null,
write_mask: ColorWriteMask = ColorWriteMask.all,
};
pub const ImageCopyBuffer = struct {
layout: Texture.DataLayout,
buffer: Buffer,
};
pub const ImageCopyTexture = struct {
texture: Texture,
mip_level: u32 = 0,
origin: Origin3D = .{},
aspect: Texture.Aspect = .all,
};
pub const ErrorCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, typ: ErrorType, message: [*:0]const u8) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, typ: ErrorType, message: [*:0]const u8) void,
) ErrorCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, typ: ErrorType, message: [*:0]const u8) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), typ, message);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
pub const LoggingCallback = struct {
type_erased_ctx: *anyopaque,
type_erased_callback: fn (ctx: *anyopaque, typ: LoggingType, message: [*:0]const u8) callconv(.Inline) void,
pub fn init(
comptime Context: type,
ctx: Context,
comptime callback: fn (ctx: Context, typ: LoggingType, message: [*:0]const u8) void,
) LoggingCallback {
const erased = (struct {
pub inline fn erased(type_erased_ctx: *anyopaque, typ: LoggingType, message: [*:0]const u8) void {
callback(if (Context == void) {} else @ptrCast(Context, @alignCast(std.meta.alignment(Context), type_erased_ctx)), typ, message);
}
}).erased;
return .{
.type_erased_ctx = if (Context == void) undefined else ctx,
.type_erased_callback = erased,
};
}
};
test {
_ = MultisampleState;
_ = PrimitiveState;
_ = StorageTextureBindingLayout;
_ = DepthStencilState;
_ = ConstantEntry;
_ = ProgrammableStageDescriptor;
_ = ComputePassTimestampWrite;
_ = RenderPassTimestampWrite;
_ = RenderPassDepthStencilAttachment;
_ = RenderPassColorAttachment;
_ = VertexState;
_ = FragmentState;
_ = ImageCopyBuffer;
_ = ImageCopyTexture;
_ = ErrorCallback;
_ = LoggingCallback;
}