diff --git a/gpu/src/Adapter.zig b/gpu/src/Adapter.zig deleted file mode 100644 index fe98c6f7..00000000 --- a/gpu/src/Adapter.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/BindGroup.zig b/gpu/src/BindGroup.zig deleted file mode 100644 index 63278fde..00000000 --- a/gpu/src/BindGroup.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/BindGroupLayout.zig b/gpu/src/BindGroupLayout.zig deleted file mode 100644 index d06fc148..00000000 --- a/gpu/src/BindGroupLayout.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Buffer.zig b/gpu/src/Buffer.zig deleted file mode 100644 index 37a2ced6..00000000 --- a/gpu/src/Buffer.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/CommandBuffer.zig b/gpu/src/CommandBuffer.zig deleted file mode 100644 index 2cd4497d..00000000 --- a/gpu/src/CommandBuffer.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/CommandEncoder.zig b/gpu/src/CommandEncoder.zig deleted file mode 100644 index 843fa017..00000000 --- a/gpu/src/CommandEncoder.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/ComputePassEncoder.zig b/gpu/src/ComputePassEncoder.zig deleted file mode 100644 index c24329a6..00000000 --- a/gpu/src/ComputePassEncoder.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/ComputePipeline.zig b/gpu/src/ComputePipeline.zig deleted file mode 100644 index e81d88fb..00000000 --- a/gpu/src/ComputePipeline.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig deleted file mode 100644 index 267dc38a..00000000 --- a/gpu/src/Device.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/ExternalTexture.zig b/gpu/src/ExternalTexture.zig deleted file mode 100644 index a3c37f15..00000000 --- a/gpu/src/ExternalTexture.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Interface.zig b/gpu/src/Interface.zig deleted file mode 100644 index e8420392..00000000 --- a/gpu/src/Interface.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig deleted file mode 100644 index d8f1ed7d..00000000 --- a/gpu/src/NativeInstance.zig +++ /dev/null @@ -1,2287 +0,0 @@ -//! A native webgpu.h implementation of the gpu.Interface -const std = @import("std"); -const c = @import("c.zig").c; - -const Interface = @import("Interface.zig"); -const RequestAdapterOptions = Interface.RequestAdapterOptions; -const RequestAdapterErrorCode = Interface.RequestAdapterErrorCode; -const RequestAdapterError = Interface.RequestAdapterError; -const RequestAdapterCallback = Interface.RequestAdapterCallback; -const RequestAdapterResponse = Interface.RequestAdapterResponse; - -const Adapter = @import("Adapter.zig"); -const RequestDeviceErrorCode = Adapter.RequestDeviceErrorCode; -const RequestDeviceError = Adapter.RequestDeviceError; -const RequestDeviceCallback = Adapter.RequestDeviceCallback; -const RequestDeviceResponse = Adapter.RequestDeviceResponse; - -const Limits = @import("data.zig").Limits; -const Color = @import("data.zig").Color; -const Extent3D = @import("data.zig").Extent3D; - -const Device = @import("Device.zig"); -const Surface = @import("Surface.zig"); -const Queue = @import("Queue.zig"); -const CommandBuffer = @import("CommandBuffer.zig"); -const ShaderModule = @import("ShaderModule.zig"); -const SwapChain = @import("SwapChain.zig"); -const TextureView = @import("TextureView.zig"); -const Texture = @import("Texture.zig"); -const Sampler = @import("Sampler.zig"); -const RenderPipeline = @import("RenderPipeline.zig"); -const RenderPassEncoder = @import("RenderPassEncoder.zig"); -const RenderBundleEncoder = @import("RenderBundleEncoder.zig"); -const RenderBundle = @import("RenderBundle.zig"); -const QuerySet = @import("QuerySet.zig"); -const PipelineLayout = @import("PipelineLayout.zig"); -const ExternalTexture = @import("ExternalTexture.zig"); -const BindGroup = @import("BindGroup.zig"); -const BindGroupLayout = @import("BindGroupLayout.zig"); -const Buffer = @import("Buffer.zig"); -const CommandEncoder = @import("CommandEncoder.zig"); -const ComputePassEncoder = @import("ComputePassEncoder.zig"); -const ComputePipeline = @import("ComputePipeline.zig"); - -const PresentMode = @import("enums.zig").PresentMode; -const IndexFormat = @import("enums.zig").IndexFormat; -const ErrorType = @import("enums.zig").ErrorType; -const ErrorFilter = @import("enums.zig").ErrorFilter; -const LoggingType = @import("enums.zig").LoggingType; -const Feature = @import("enums.zig").Feature; - -const ImageCopyBuffer = @import("structs.zig").ImageCopyBuffer; -const ImageCopyTexture = @import("structs.zig").ImageCopyTexture; -const ErrorCallback = @import("structs.zig").ErrorCallback; -const LoggingCallback = @import("structs.zig").LoggingCallback; - -const NativeInstance = @This(); - -/// The WGPUInstance that is wrapped by this native instance. -instance: c.WGPUInstance, - -/// Wraps a native WGPUInstance to provide an implementation of the gpu.Interface. -pub fn wrap(instance: *anyopaque) NativeInstance { - return .{ .instance = @ptrCast(c.WGPUInstance, instance) }; -} - -const interface_vtable = Interface.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - const native = @ptrCast(*NativeInstance, @alignCast(std.meta.alignment(*NativeInstance), ptr)); - c.wgpuInstanceReference(native.instance); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - const native = @ptrCast(*NativeInstance, @alignCast(std.meta.alignment(*NativeInstance), ptr)); - c.wgpuInstanceRelease(native.instance); - } - }).release, - .requestAdapter = (struct { - pub fn requestAdapter( - ptr: *anyopaque, - options: *const RequestAdapterOptions, - callback: *RequestAdapterCallback, - ) void { - const native = @ptrCast(*NativeInstance, @alignCast(std.meta.alignment(*NativeInstance), ptr)); - - const opt = c.WGPURequestAdapterOptions{ - .nextInChain = null, - .compatibleSurface = if (options.compatible_surface) |surface| @ptrCast(c.WGPUSurface, surface.ptr) else null, - .powerPreference = @enumToInt(options.power_preference), - .forceFallbackAdapter = options.force_fallback_adapter, - }; - - const cCallback = (struct { - pub fn cCallback(status: c.WGPURequestAdapterStatus, adapter: c.WGPUAdapter, message: [*c]const u8, userdata: ?*anyopaque) callconv(.C) void { - const callback_info = @ptrCast(*RequestAdapterCallback, @alignCast(std.meta.alignment(*RequestAdapterCallback), userdata.?)); - - // Store the response into a field on the native instance for later reading. - const response = if (status == c.WGPURequestAdapterStatus_Success) RequestAdapterResponse{ - .adapter = wrapAdapter(adapter.?), - } else RequestAdapterResponse{ - .err = Interface.RequestAdapterError{ - .message = std.mem.span(message), - .code = switch (status) { - c.WGPURequestAdapterStatus_Unavailable => RequestAdapterErrorCode.Unavailable, - c.WGPURequestAdapterStatus_Error => RequestAdapterErrorCode.Error, - c.WGPURequestAdapterStatus_Unknown => RequestAdapterErrorCode.Unknown, - else => unreachable, - }, - }, - }; - - callback_info.type_erased_callback(callback_info.type_erased_ctx, response); - } - }).cCallback; - - c.wgpuInstanceRequestAdapter(native.instance, &opt, cCallback, callback); - } - }).requestAdapter, -}; - -/// Returns the gpu.Interface for interacting with this native instance. -pub fn interface(native: *NativeInstance) Interface { - return .{ - .ptr = native, - .vtable = &interface_vtable, - }; -} - -pub fn createSurface(native: *const NativeInstance, descriptor: *const Surface.Descriptor) Surface { - const surface = switch (descriptor.*) { - .metal_layer => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromMetalLayer = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromMetalLayer; - desc.layer = src.layer; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - .windows_hwnd => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromWindowsHWND = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsHWND; - desc.hinstance = src.hinstance; - desc.hwnd = src.hwnd; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - .windows_core_window => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromWindowsCoreWindow = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsCoreWindow; - desc.coreWindow = src.core_window; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - .windows_swap_chain_panel => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromWindowsSwapChainPanel = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsSwapChainPanel; - desc.swapChainPanel = src.swap_chain_panel; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - .xlib => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromXlibWindow = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromXlibWindow; - desc.display = src.display; - desc.window = src.window; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - .canvas_html_selector => |src| blk: { - var desc: c.WGPUSurfaceDescriptorFromCanvasHTMLSelector = undefined; - desc.chain.next = null; - desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector; - desc.selector = src.selector; - break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ - .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), - .label = if (src.label) |l| l else null, - }); - }, - }; - - return Surface{ - .ptr = surface.?, - .vtable = &surface_vtable, - }; -} - -const surface_vtable = Surface.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuSurfaceReference(@ptrCast(c.WGPUSurface, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuSurfaceRelease(@ptrCast(c.WGPUSurface, ptr)); - } - }).release, -}; - -pub inline fn fromWGPUAdapter(adapter: *anyopaque) Adapter { - return wrapAdapter(@ptrCast(c.WGPUAdapter, adapter)); -} - -pub fn wrapAdapter(adapter: c.WGPUAdapter) Adapter { - var c_props: c.WGPUAdapterProperties = undefined; - c.wgpuAdapterGetProperties(adapter, &c_props); - const properties = Adapter.Properties{ - .vendor_id = c_props.vendorID, - .device_id = c_props.deviceID, - .name = std.mem.span(c_props.name), - .driver_description = std.mem.span(c_props.driverDescription), - .adapter_type = @intToEnum(Adapter.Type, c_props.adapterType), - .backend_type = @intToEnum(Adapter.BackendType, c_props.backendType), - }; - - var supported_limits: c.WGPUSupportedLimits = undefined; - supported_limits.nextInChain = null; - if (!c.wgpuAdapterGetLimits(adapter.?, &supported_limits)) @panic("failed to get adapter limits (this is a bug in mach/gpu)"); - - var wrapped = Adapter{ - .features = undefined, - .limits = @bitCast(Limits, supported_limits.limits), - .properties = properties, - - // TODO: why is fallback not queryable on Dawn? - .fallback = false, - - .ptr = adapter.?, - .vtable = &adapter_vtable, - }; - - const features_len = c.wgpuAdapterEnumerateFeatures(adapter.?, @ptrCast([*]c.WGPUFeatureName, &wrapped._features)); - wrapped.features = wrapped._features[0..features_len]; - return wrapped; -} - -const adapter_vtable = Adapter.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuAdapterReference(@ptrCast(c.WGPUAdapter, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuAdapterRelease(@ptrCast(c.WGPUAdapter, ptr)); - } - }).release, - .requestDevice = (struct { - pub fn requestDevice( - ptr: *anyopaque, - descriptor: *const Device.Descriptor, - callback: *RequestDeviceCallback, - ) void { - const adapter = @ptrCast(c.WGPUAdapter, @alignCast(@alignOf(c.WGPUAdapter), ptr)); - - const required_limits = if (descriptor.required_limits) |l| c.WGPURequiredLimits{ - .nextInChain = null, - .limits = @bitCast(c.WGPULimits, l), - } else null; - - const desc = c.WGPUDeviceDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .requiredFeaturesCount = if (descriptor.required_features) |f| @intCast(u32, f.len) else 0, - .requiredFeatures = if (descriptor.required_features) |f| @ptrCast([*]const c_uint, f.ptr) else null, - .requiredLimits = if (required_limits) |*l| l else null, - .defaultQueue = if (descriptor.default_queue) |q| .{ .nextInChain = null, .label = q.label } else .{ .nextInChain = null, .label = null }, - }; - - const cCallback = (struct { - pub fn cCallback(status: c.WGPURequestDeviceStatus, device: c.WGPUDevice, message: [*c]const u8, userdata: ?*anyopaque) callconv(.C) void { - const callback_info = @ptrCast(*RequestDeviceCallback, @alignCast(std.meta.alignment(*RequestDeviceCallback), userdata.?)); - - const response = if (status == c.WGPURequestDeviceStatus_Success) RequestDeviceResponse{ - .device = wrapDevice(device.?), - } else RequestDeviceResponse{ - .err = Adapter.RequestDeviceError{ - .message = std.mem.span(message), - .code = switch (status) { - c.WGPURequestDeviceStatus_Error => RequestDeviceErrorCode.Error, - c.WGPURequestDeviceStatus_Unknown => RequestDeviceErrorCode.Unknown, - else => unreachable, - }, - }, - }; - - callback_info.type_erased_callback(callback_info.type_erased_ctx, response); - } - }).cCallback; - - c.wgpuAdapterRequestDevice(adapter, &desc, cCallback, callback); - } - }).requestDevice, -}; - -fn wrapDevice(device: c.WGPUDevice) Device { - var supported_limits: c.WGPUSupportedLimits = undefined; - supported_limits.nextInChain = null; - if (!c.wgpuDeviceGetLimits(device.?, &supported_limits)) @panic("failed to get device limits (this is a bug in mach/gpu)"); - - var wrapped = Device{ - .features = undefined, - .limits = @bitCast(Limits, supported_limits.limits), - .ptr = device.?, - .vtable = &device_vtable, - }; - - const features_len = c.wgpuDeviceEnumerateFeatures(device.?, @ptrCast([*]c.WGPUFeatureName, &wrapped._features)); - wrapped.features = wrapped._features[0..features_len]; - return wrapped; -} - -const device_vtable = Device.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuDeviceReference(@ptrCast(c.WGPUDevice, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuDeviceRelease(@ptrCast(c.WGPUDevice, ptr)); - } - }).release, - .getQueue = (struct { - pub fn getQueue(ptr: *anyopaque) Queue { - return wrapQueue(c.wgpuDeviceGetQueue(@ptrCast(c.WGPUDevice, ptr))); - } - }).getQueue, - .injectError = (struct { - pub fn injectError(ptr: *anyopaque, typ: ErrorType, message: [*:0]const u8) void { - c.wgpuDeviceInjectError(@ptrCast(c.WGPUDevice, ptr), @enumToInt(typ), message); - } - }).injectError, - .loseForTesting = (struct { - pub fn loseForTesting(ptr: *anyopaque) void { - c.wgpuDeviceLoseForTesting(@ptrCast(c.WGPUDevice, ptr)); - } - }).loseForTesting, - .popErrorScope = (struct { - pub fn popErrorScope(ptr: *anyopaque, callback: *ErrorCallback) bool { - const cCallback = (struct { - pub fn cCallback( - typ: c.WGPUErrorType, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*ErrorCallback, @alignCast(std.meta.alignment(*ErrorCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(ErrorType, typ), - std.mem.span(message), - ); - } - }).cCallback; - - return c.wgpuDevicePopErrorScope( - @ptrCast(c.WGPUDevice, ptr), - cCallback, - callback, - ); - } - }).popErrorScope, - .createBindGroup = (struct { - pub fn createBindGroup(ptr: *anyopaque, descriptor: *const BindGroup.Descriptor) BindGroup { - var few_entries: [16]c.WGPUBindGroupEntry = undefined; - const entries = if (descriptor.entries.len <= 8) - few_entries[0..descriptor.entries.len] - else - std.heap.page_allocator.alloc(c.WGPUBindGroupEntry, descriptor.entries.len) catch unreachable; - defer if (entries.len > 8) std.heap.page_allocator.free(entries); - - for (descriptor.entries) |entry, i| { - entries[i] = c.WGPUBindGroupEntry{ - .nextInChain = null, - .binding = entry.binding, - .buffer = if (entry.buffer) |buf| - @ptrCast(c.WGPUBuffer, buf.ptr) - else - null, - .offset = entry.offset, - .size = entry.size, - .sampler = if (entry.sampler) |samp| - @ptrCast(c.WGPUSampler, samp.ptr) - else - null, - .textureView = if (entry.texture_view) |tex| - @ptrCast(c.WGPUTextureView, tex.ptr) - else - null, - }; - } - - const desc = c.WGPUBindGroupDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .layout = @ptrCast(c.WGPUBindGroupLayout, descriptor.layout.ptr), - .entryCount = @intCast(u32, entries.len), - .entries = entries.ptr, - }; - - return wrapBindGroup(c.wgpuDeviceCreateBindGroup(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createBindGroup, - .pushErrorScope = (struct { - pub fn pushErrorScope(ptr: *anyopaque, filter: ErrorFilter) void { - c.wgpuDevicePushErrorScope(@ptrCast(c.WGPUDevice, ptr), @enumToInt(filter)); - } - }).pushErrorScope, - .setLostCallback = (struct { - pub fn setLostCallback(ptr: *anyopaque, callback: *Device.LostCallback) void { - const cCallback = (struct { - pub fn cCallback( - reason: c.WGPUDeviceLostReason, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*Device.LostCallback, @alignCast(std.meta.alignment(*Device.LostCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(Device.LostReason, reason), - std.mem.span(message), - ); - } - }).cCallback; - - c.wgpuDeviceSetDeviceLostCallback( - @ptrCast(c.WGPUDevice, ptr), - cCallback, - callback, - ); - } - }).setLostCallback, - .createBindGroupLayout = (struct { - pub fn createBindGroupLayout(ptr: *anyopaque, descriptor: *const BindGroupLayout.Descriptor) BindGroupLayout { - const desc = c.WGPUBindGroupLayoutDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .entryCount = @intCast(u32, descriptor.entries.len), - .entries = @ptrCast([*]const c.WGPUBindGroupLayoutEntry, descriptor.entries.ptr), - }; - return wrapBindGroupLayout(c.wgpuDeviceCreateBindGroupLayout(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createBindGroupLayout, - .createSampler = (struct { - pub fn createSampler(ptr: *anyopaque, descriptor: *const Sampler.Descriptor) Sampler { - return wrapSampler(c.wgpuDeviceCreateSampler( - @ptrCast(c.WGPUDevice, ptr), - @ptrCast(*const c.WGPUSamplerDescriptor, descriptor), - )); - } - }).createSampler, - .createShaderModule = (struct { - pub fn createShaderModule(ptr: *anyopaque, descriptor: *const ShaderModule.Descriptor) ShaderModule { - switch (descriptor.code) { - .wgsl => |wgsl| { - const wgsl_desc = c.WGPUShaderModuleWGSLDescriptor{ - .chain = c.WGPUChainedStruct{ - .next = null, - .sType = c.WGPUSType_ShaderModuleWGSLDescriptor, - }, - .source = wgsl, - }; - const desc = c.WGPUShaderModuleDescriptor{ - .nextInChain = @ptrCast(*const c.WGPUChainedStruct, &wgsl_desc), - .label = if (descriptor.label) |l| l else null, - }; - return wrapShaderModule(c.wgpuDeviceCreateShaderModule(@ptrCast(c.WGPUDevice, ptr), &desc)); - }, - .spirv => |spirv| { - const spirv_desc = c.WGPUShaderModuleSPIRVDescriptor{ - .chain = c.WGPUChainedStruct{ - .next = null, - .sType = c.WGPUSType_ShaderModuleSPIRVDescriptor, - }, - .code = spirv.ptr, - .codeSize = @intCast(u32, spirv.len), - }; - const desc = c.WGPUShaderModuleDescriptor{ - .nextInChain = @ptrCast(*const c.WGPUChainedStruct, &spirv_desc), - .label = if (descriptor.label) |l| l else null, - }; - return wrapShaderModule(c.wgpuDeviceCreateShaderModule(@ptrCast(c.WGPUDevice, ptr), &desc)); - }, - } - } - }).createShaderModule, - .nativeCreateSwapChain = (struct { - pub fn nativeCreateSwapChain(ptr: *anyopaque, surface: ?Surface, descriptor: *const SwapChain.Descriptor) SwapChain { - const desc = c.WGPUSwapChainDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .usage = @bitCast(u32, descriptor.usage), - .format = @enumToInt(descriptor.format), - .width = descriptor.width, - .height = descriptor.height, - .presentMode = @enumToInt(descriptor.present_mode), - .implementation = descriptor.implementation, - }; - return wrapSwapChain(c.wgpuDeviceCreateSwapChain( - @ptrCast(c.WGPUDevice, ptr), - if (surface) |surf| @ptrCast(c.WGPUSurface, surf.ptr) else null, - &desc, - )); - } - }).nativeCreateSwapChain, - .createTexture = (struct { - pub fn createTexture(ptr: *anyopaque, descriptor: *const Texture.Descriptor) Texture { - const desc = c.WGPUTextureDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .usage = @bitCast(u32, descriptor.usage), - .dimension = @enumToInt(descriptor.dimension), - .size = @bitCast(c.WGPUExtent3D, descriptor.size), - .format = @enumToInt(descriptor.format), - .mipLevelCount = descriptor.mip_level_count, - .sampleCount = descriptor.sample_count, - .viewFormatCount = if (descriptor.view_formats) |vf| @intCast(u32, vf.len) else 0, - .viewFormats = if (descriptor.view_formats) |vf| @ptrCast([*]const c.WGPUTextureFormat, vf.ptr) else null, - }; - return wrapTexture(c.wgpuDeviceCreateTexture(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createTexture, - .destroy = (struct { - pub fn destroy(ptr: *anyopaque) void { - c.wgpuDeviceDestroy(@ptrCast(c.WGPUDevice, ptr)); - } - }).destroy, - .createBuffer = (struct { - pub fn createBuffer(ptr: *anyopaque, descriptor: *const Buffer.Descriptor) Buffer { - return wrapBuffer(c.wgpuDeviceCreateBuffer( - @ptrCast(c.WGPUDevice, ptr), - @ptrCast(*const c.WGPUBufferDescriptor, descriptor), - )); - } - }).createBuffer, - .createCommandEncoder = (struct { - pub fn createCommandEncoder(ptr: *anyopaque, descriptor: ?*const CommandEncoder.Descriptor) CommandEncoder { - const desc: ?*c.WGPUCommandEncoderDescriptor = if (descriptor) |d| &.{ - .nextInChain = null, - .label = if (d.label) |l| l else "", - } else null; - return wrapCommandEncoder(c.wgpuDeviceCreateCommandEncoder(@ptrCast(c.WGPUDevice, ptr), desc)); - } - }).createCommandEncoder, - .createComputePipeline = (struct { - pub fn createComputePipeline( - ptr: *anyopaque, - descriptor: *const ComputePipeline.Descriptor, - ) ComputePipeline { - const desc = convertComputePipelineDescriptor(descriptor); - - return wrapComputePipeline(c.wgpuDeviceCreateComputePipeline( - @ptrCast(c.WGPUDevice, ptr), - &desc, - )); - } - }).createComputePipeline, - .createComputePipelineAsync = (struct { - pub fn createComputePipelineAsync( - ptr: *anyopaque, - descriptor: *const ComputePipeline.Descriptor, - callback: *ComputePipeline.CreateCallback, - ) void { - const desc = convertComputePipelineDescriptor(descriptor); - - const cCallback = (struct { - pub fn cCallback( - status: c.WGPUCreatePipelineAsyncStatus, - pipeline: c.WGPUComputePipeline, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*ComputePipeline.CreateCallback, @alignCast(std.meta.alignment(*ComputePipeline.CreateCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(ComputePipeline.CreateStatus, status), - wrapComputePipeline(pipeline), - std.mem.span(message), - ); - } - }).cCallback; - - c.wgpuDeviceCreateComputePipelineAsync( - @ptrCast(c.WGPUDevice, ptr), - &desc, - cCallback, - callback, - ); - } - }).createComputePipelineAsync, - .createErrorBuffer = (struct { - pub fn createErrorBuffer(ptr: *anyopaque) Buffer { - return wrapBuffer(c.wgpuDeviceCreateErrorBuffer( - @ptrCast(c.WGPUDevice, ptr), - )); - } - }).createErrorBuffer, - .createExternalTexture = (struct { - pub fn createExternalTexture(ptr: *anyopaque, descriptor: *const ExternalTexture.Descriptor) ExternalTexture { - const desc = c.WGPUExternalTextureDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .plane0 = @ptrCast(c.WGPUTextureView, descriptor.plane0.ptr), - .plane1 = @ptrCast(c.WGPUTextureView, descriptor.plane1.ptr), - .colorSpace = @enumToInt(descriptor.color_space), - }; - return wrapExternalTexture(c.wgpuDeviceCreateExternalTexture(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createExternalTexture, - .createPipelineLayout = (struct { - pub fn createPipelineLayout(ptr: *anyopaque, descriptor: *const PipelineLayout.Descriptor) PipelineLayout { - var few_bind_group_layouts: [16]c.WGPUBindGroupLayout = undefined; - const bind_group_layouts = if (descriptor.bind_group_layouts.len <= 16) blk: { - for (descriptor.bind_group_layouts) |layout, i| { - few_bind_group_layouts[i] = @ptrCast(c.WGPUBindGroupLayout, layout.ptr); - } - break :blk few_bind_group_layouts[0..descriptor.bind_group_layouts.len]; - } else blk: { - const mem = std.heap.page_allocator.alloc(c.WGPUBindGroupLayout, descriptor.bind_group_layouts.len) catch unreachable; - for (descriptor.bind_group_layouts) |layout, i| { - mem[i] = @ptrCast(c.WGPUBindGroupLayout, layout.ptr); - } - break :blk mem; - }; - defer if (descriptor.bind_group_layouts.len > 16) std.heap.page_allocator.free(descriptor.bind_group_layouts); - - const desc = c.WGPUPipelineLayoutDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .bindGroupLayoutCount = @intCast(u32, bind_group_layouts.len), - .bindGroupLayouts = bind_group_layouts.ptr, - }; - return wrapPipelineLayout(c.wgpuDeviceCreatePipelineLayout(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createPipelineLayout, - .createQuerySet = (struct { - pub fn createQuerySet(ptr: *anyopaque, descriptor: *const QuerySet.Descriptor) QuerySet { - const desc = c.WGPUQuerySetDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .type = @enumToInt(descriptor.type), - .count = descriptor.count, - .pipelineStatistics = @ptrCast([*]const c.WGPUPipelineStatisticName, descriptor.pipeline_statistics.ptr), - .pipelineStatisticsCount = @intCast(u32, descriptor.pipeline_statistics.len), - }; - return wrapQuerySet(c.wgpuDeviceCreateQuerySet(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createQuerySet, - .createRenderBundleEncoder = (struct { - pub fn createRenderBundleEncoder(ptr: *anyopaque, descriptor: *const RenderBundleEncoder.Descriptor) RenderBundleEncoder { - const desc = c.WGPURenderBundleEncoderDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .colorFormatsCount = @intCast(u32, descriptor.color_formats.len), - .colorFormats = @ptrCast([*]const c.WGPUTextureFormat, descriptor.color_formats.ptr), - .depthStencilFormat = @enumToInt(descriptor.depth_stencil_format), - .sampleCount = descriptor.sample_count, - .depthReadOnly = descriptor.depth_read_only, - .stencilReadOnly = descriptor.stencil_read_only, - }; - return wrapRenderBundleEncoder(c.wgpuDeviceCreateRenderBundleEncoder(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createRenderBundleEncoder, - .createRenderPipeline = (struct { - pub fn createRenderPipeline(ptr: *anyopaque, descriptor: *const RenderPipeline.Descriptor) RenderPipeline { - var tmp_depth_stencil: c.WGPUDepthStencilState = undefined; - var tmp_fragment_state: c.WGPUFragmentState = undefined; - const desc = convertRenderPipelineDescriptor(descriptor, &tmp_depth_stencil, &tmp_fragment_state); - return wrapRenderPipeline(c.wgpuDeviceCreateRenderPipeline(@ptrCast(c.WGPUDevice, ptr), &desc)); - } - }).createRenderPipeline, - .createRenderPipelineAsync = (struct { - pub fn createRenderPipelineAsync( - ptr: *anyopaque, - descriptor: *const RenderPipeline.Descriptor, - callback: *RenderPipeline.CreateCallback, - ) void { - var tmp_depth_stencil: c.WGPUDepthStencilState = undefined; - var tmp_fragment_state: c.WGPUFragmentState = undefined; - const desc = convertRenderPipelineDescriptor(descriptor, &tmp_depth_stencil, &tmp_fragment_state); - - const cCallback = (struct { - pub fn cCallback( - status: c.WGPUCreatePipelineAsyncStatus, - pipeline: c.WGPURenderPipeline, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*RenderPipeline.CreateCallback, @alignCast(std.meta.alignment(*RenderPipeline.CreateCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(RenderPipeline.CreateStatus, status), - wrapRenderPipeline(pipeline), - std.mem.span(message), - ); - } - }).cCallback; - - c.wgpuDeviceCreateRenderPipelineAsync( - @ptrCast(c.WGPUDevice, ptr), - &desc, - cCallback, - callback, - ); - } - }).createRenderPipelineAsync, - .setUncapturedErrorCallback = (struct { - pub fn setUncapturedErrorCallback( - ptr: *anyopaque, - callback: *ErrorCallback, - ) void { - const cCallback = (struct { - pub fn cCallback( - typ: c.WGPUErrorType, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*ErrorCallback, @alignCast(std.meta.alignment(*ErrorCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(ErrorType, typ), - std.mem.span(message), - ); - } - }).cCallback; - - return c.wgpuDeviceSetUncapturedErrorCallback( - @ptrCast(c.WGPUDevice, ptr), - cCallback, - callback, - ); - } - }).setUncapturedErrorCallback, - .setLoggingCallback = (struct { - pub fn setLoggingCallback( - ptr: *anyopaque, - callback: *LoggingCallback, - ) void { - const cCallback = (struct { - pub fn cCallback( - typ: c.WGPULoggingType, - message: [*c]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - const callback_info = @ptrCast(*LoggingCallback, @alignCast(std.meta.alignment(*LoggingCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(LoggingType, typ), - std.mem.span(message), - ); - } - }).cCallback; - - return c.wgpuDeviceSetLoggingCallback( - @ptrCast(c.WGPUDevice, ptr), - cCallback, - callback, - ); - } - }).setLoggingCallback, - .tick = (struct { - pub fn tick(ptr: *anyopaque) void { - c.wgpuDeviceTick(@ptrCast(c.WGPUDevice, ptr)); - } - }.tick), -}; - -inline fn convertComputePipelineDescriptor(descriptor: *const ComputePipeline.Descriptor) c.WGPUComputePipelineDescriptor { - return .{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - .layout = if (descriptor.layout) |l| @ptrCast(c.WGPUPipelineLayout, l.ptr) else null, - .compute = c.WGPUProgrammableStageDescriptor{ - .nextInChain = null, - .module = @ptrCast(c.WGPUShaderModule, descriptor.compute.module.ptr), - .entryPoint = descriptor.compute.entry_point, - .constantCount = if (descriptor.compute.constants) |v| @intCast(u32, v.len) else 0, - .constants = if (descriptor.compute.constants) |v| @ptrCast([*]const c.WGPUConstantEntry, v.ptr) else null, - }, - }; -} - -inline fn convertRenderPipelineDescriptor( - d: *const RenderPipeline.Descriptor, - tmp_depth_stencil: *c.WGPUDepthStencilState, - tmp_fragment_state: *c.WGPUFragmentState, -) c.WGPURenderPipelineDescriptor { - if (d.depth_stencil) |ds| { - tmp_depth_stencil.* = c.WGPUDepthStencilState{ - .nextInChain = null, - .format = @enumToInt(ds.format), - .depthWriteEnabled = ds.depth_write_enabled, - .depthCompare = @enumToInt(ds.depth_compare), - .stencilFront = @bitCast(c.WGPUStencilFaceState, ds.stencil_front), - .stencilBack = @bitCast(c.WGPUStencilFaceState, ds.stencil_back), - .stencilReadMask = ds.stencil_read_mask, - .stencilWriteMask = ds.stencil_write_mask, - .depthBias = ds.depth_bias, - .depthBiasSlopeScale = ds.depth_bias_slope_scale, - .depthBiasClamp = ds.depth_bias_clamp, - }; - } - - if (d.fragment) |frag| { - tmp_fragment_state.* = c.WGPUFragmentState{ - .nextInChain = null, - .module = @ptrCast(c.WGPUShaderModule, frag.module.ptr), - .entryPoint = frag.entry_point, - .constantCount = if (frag.constants) |v| @intCast(u32, v.len) else 0, - .constants = if (frag.constants) |v| @ptrCast([*]const c.WGPUConstantEntry, v.ptr) else null, - .targetCount = if (frag.targets) |v| @intCast(u32, v.len) else 0, - .targets = if (frag.targets) |v| @ptrCast([*]const c.WGPUColorTargetState, v.ptr) else null, - }; - } - - return c.WGPURenderPipelineDescriptor{ - .nextInChain = null, - .label = if (d.label) |l| l else null, - .layout = if (d.layout) |v| @ptrCast(c.WGPUPipelineLayout, v.ptr) else null, - .vertex = c.WGPUVertexState{ - .nextInChain = null, - .module = @ptrCast(c.WGPUShaderModule, d.vertex.module.ptr), - .entryPoint = d.vertex.entry_point, - .constantCount = if (d.vertex.constants) |v| @intCast(u32, v.len) else 0, - .constants = if (d.vertex.constants) |v| @ptrCast([*]const c.WGPUConstantEntry, v.ptr) else null, - .bufferCount = if (d.vertex.buffers) |v| @intCast(u32, v.len) else 0, - .buffers = if (d.vertex.buffers) |v| @ptrCast([*]const c.WGPUVertexBufferLayout, v.ptr) else null, - }, - .primitive = c.WGPUPrimitiveState{ - .nextInChain = null, - .topology = @enumToInt(d.primitive.topology), - .stripIndexFormat = @enumToInt(d.primitive.strip_index_format), - .frontFace = @enumToInt(d.primitive.front_face), - .cullMode = @enumToInt(d.primitive.cull_mode), - }, - .depthStencil = if (d.depth_stencil != null) tmp_depth_stencil else null, - .multisample = c.WGPUMultisampleState{ - .nextInChain = null, - .count = d.multisample.count, - .mask = d.multisample.mask, - .alphaToCoverageEnabled = d.multisample.alpha_to_coverage_enabled, - }, - .fragment = if (d.fragment != null) tmp_fragment_state else null, - }; -} - -fn wrapQueue(queue: c.WGPUQueue) Queue { - return .{ - .ptr = queue.?, - .vtable = &queue_vtable, - }; -} - -const queue_vtable = Queue.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuQueueReference(@ptrCast(c.WGPUQueue, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuQueueRelease(@ptrCast(c.WGPUQueue, ptr)); - } - }).release, - .submit = (struct { - pub fn submit(queue: *Queue, cmds: []const CommandBuffer) void { - const wgpu_queue = @ptrCast(c.WGPUQueue, queue.ptr); - - if (queue.on_submitted_work_done) |_| { - // Note: signalValue is not available in the web API, and it's usage is undocumented - // kainino says "It's basically reserved for future use, though it's been suggested - // to remove it instead" - const signal_value: u64 = 0; - - const cCallback = (struct { - pub fn cCallback(status: c.WGPUQueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void { - const callback_info = @ptrCast(*Queue.WorkDoneCallback, @alignCast(std.meta.alignment(*Queue.WorkDoneCallback), userdata)); - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(Queue.WorkDoneStatus, status), - ); - } - }).cCallback; - - c.wgpuQueueOnSubmittedWorkDone( - wgpu_queue, - signal_value, - cCallback, - queue.on_submitted_work_done, - ); - } - - var few_commands: [16]c.WGPUCommandBuffer = undefined; - const commands = if (cmds.len <= 16) blk: { - for (cmds) |cmd, i| { - few_commands[i] = @ptrCast(c.WGPUCommandBuffer, cmd.ptr); - } - break :blk few_commands[0..cmds.len]; - } else blk: { - const mem = std.heap.page_allocator.alloc(c.WGPUCommandBuffer, cmds.len) catch unreachable; - for (cmds) |cmd, i| { - mem[i] = @ptrCast(c.WGPUCommandBuffer, cmd.ptr); - } - break :blk mem; - }; - defer if (cmds.len > 16) std.heap.page_allocator.free(cmds); - - c.wgpuQueueSubmit( - wgpu_queue, - @intCast(u32, commands.len), - @ptrCast([*]c.WGPUCommandBuffer, commands.ptr), - ); - } - }).submit, - .writeBuffer = (struct { - pub fn writeBuffer(ptr: *anyopaque, buffer: Buffer, buffer_offset: u64, data: *const anyopaque, size: u64) void { - c.wgpuQueueWriteBuffer( - @ptrCast(c.WGPUQueue, ptr), - @ptrCast(c.WGPUBuffer, buffer.ptr), - buffer_offset, - data, - size, - ); - } - }).writeBuffer, - .writeTexture = (struct { - pub fn writeTexture( - ptr: *anyopaque, - destination: *const ImageCopyTexture, - data: *const anyopaque, - data_size: usize, - data_layout: *const Texture.DataLayout, - write_size: *const Extent3D, - ) void { - c.wgpuQueueWriteTexture( - @ptrCast(c.WGPUQueue, ptr), - &c.WGPUImageCopyTexture{ - .nextInChain = null, - .texture = @ptrCast(c.WGPUTexture, destination.texture.ptr), - .mipLevel = destination.mip_level, - .origin = @bitCast(c.WGPUOrigin3D, destination.origin), - .aspect = @bitCast(c.WGPUTextureAspect, destination.aspect), - }, - data, - data_size, - @ptrCast(*const c.WGPUTextureDataLayout, data_layout), - @ptrCast(*const c.WGPUExtent3D, write_size), - ); - } - }).writeTexture, -}; - -fn wrapShaderModule(shader_module: c.WGPUShaderModule) ShaderModule { - return .{ - .ptr = shader_module.?, - .vtable = &shader_module_vtable, - }; -} - -const shader_module_vtable = ShaderModule.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuShaderModuleReference(@ptrCast(c.WGPUShaderModule, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuShaderModuleRelease(@ptrCast(c.WGPUShaderModule, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuShaderModuleSetLabel(@ptrCast(c.WGPUShaderModule, ptr), label); - } - }).setLabel, - .getCompilationInfo = (struct { - pub fn getCompilationInfo(ptr: *anyopaque, callback: *ShaderModule.CompilationInfoCallback) void { - const cCallback = (struct { - pub fn cCallback(status: c.WGPUCompilationInfoRequestStatus, info: [*c]const c.WGPUCompilationInfo, userdata: ?*anyopaque) callconv(.C) void { - const callback_info = @ptrCast(*ShaderModule.CompilationInfoCallback, @alignCast(std.meta.alignment(*ShaderModule.CompilationInfoCallback), userdata.?)); - - callback_info.type_erased_callback( - callback_info.type_erased_ctx, - @intToEnum(ShaderModule.CompilationInfoRequestStatus, status), - &ShaderModule.CompilationInfo{ - .messages = @bitCast([]const ShaderModule.CompilationMessage, info[0].messages[0..info[0].messageCount]), - }, - ); - } - }).cCallback; - - c.wgpuShaderModuleGetCompilationInfo(@ptrCast(c.WGPUShaderModule, ptr), cCallback, callback); - } - }).getCompilationInfo, -}; - -fn wrapSwapChain(swap_chain: c.WGPUSwapChain) SwapChain { - return .{ - .ptr = swap_chain.?, - .vtable = &swap_chain_vtable, - }; -} - -const swap_chain_vtable = SwapChain.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuSwapChainReference(@ptrCast(c.WGPUSwapChain, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuSwapChainRelease(@ptrCast(c.WGPUSwapChain, ptr)); - } - }).release, - .configure = (struct { - pub fn configure(ptr: *anyopaque, format: Texture.Format, allowed_usage: Texture.Usage, width: u32, height: u32) void { - c.wgpuSwapChainConfigure( - @ptrCast(c.WGPUSwapChain, ptr), - @enumToInt(format), - @bitCast(u32, allowed_usage), - width, - height, - ); - } - }).configure, - .getCurrentTextureView = (struct { - pub fn getCurrentTextureView(ptr: *anyopaque) TextureView { - return wrapTextureView(c.wgpuSwapChainGetCurrentTextureView(@ptrCast(c.WGPUSwapChain, ptr))); - } - }).getCurrentTextureView, - .present = (struct { - pub fn present(ptr: *anyopaque) void { - c.wgpuSwapChainPresent(@ptrCast(c.WGPUSwapChain, ptr)); - } - }).present, -}; - -fn wrapTextureView(texture_view: c.WGPUTextureView) TextureView { - return .{ - .ptr = texture_view.?, - .vtable = &texture_view_vtable, - }; -} - -const texture_view_vtable = TextureView.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuTextureViewReference(@ptrCast(c.WGPUTextureView, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuTextureViewRelease(@ptrCast(c.WGPUTextureView, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuTextureViewSetLabel(@ptrCast(c.WGPUTextureView, ptr), label); - } - }).setLabel, -}; - -fn wrapTexture(texture: c.WGPUTexture) Texture { - return .{ - .ptr = texture.?, - .vtable = &texture_vtable, - }; -} - -const texture_vtable = Texture.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuTextureReference(@ptrCast(c.WGPUTexture, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuTextureRelease(@ptrCast(c.WGPUTexture, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuTextureSetLabel(@ptrCast(c.WGPUTexture, ptr), label); - } - }).setLabel, - .destroy = (struct { - pub fn destroy(ptr: *anyopaque) void { - c.wgpuTextureDestroy(@ptrCast(c.WGPUTexture, ptr)); - } - }).destroy, - .createView = (struct { - pub fn createView(ptr: *anyopaque, descriptor: *const TextureView.Descriptor) TextureView { - const desc = c.WGPUTextureViewDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else "", - .format = @enumToInt(descriptor.format), - .dimension = @enumToInt(descriptor.dimension), - .baseMipLevel = descriptor.base_mip_level, - .mipLevelCount = descriptor.mip_level_count, - .baseArrayLayer = descriptor.base_array_layer, - .arrayLayerCount = descriptor.array_layer_count, - .aspect = @enumToInt(descriptor.aspect), - }; - return wrapTextureView(c.wgpuTextureCreateView( - @ptrCast(c.WGPUTexture, ptr), - &desc, - )); - } - }).createView, -}; - -fn wrapSampler(sampler: c.WGPUSampler) Sampler { - return .{ - .ptr = sampler.?, - .vtable = &sampler_vtable, - }; -} - -const sampler_vtable = Sampler.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuSamplerReference(@ptrCast(c.WGPUSampler, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuSamplerRelease(@ptrCast(c.WGPUSampler, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuSamplerSetLabel(@ptrCast(c.WGPUSampler, ptr), label); - } - }).setLabel, -}; - -fn wrapRenderPipeline(pipeline: c.WGPURenderPipeline) RenderPipeline { - return .{ - .ptr = pipeline.?, - .vtable = &render_pipeline_vtable, - }; -} - -const render_pipeline_vtable = RenderPipeline.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuRenderPipelineReference(@ptrCast(c.WGPURenderPipeline, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuRenderPipelineRelease(@ptrCast(c.WGPURenderPipeline, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuRenderPipelineSetLabel(@ptrCast(c.WGPURenderPipeline, ptr), label); - } - }).setLabel, - .getBindGroupLayout = (struct { - pub fn getBindGroupLayout(ptr: *anyopaque, group_index: u32) BindGroupLayout { - return wrapBindGroupLayout(c.wgpuRenderPipelineGetBindGroupLayout( - @ptrCast(c.WGPURenderPipeline, ptr), - group_index, - )); - } - }).getBindGroupLayout, -}; - -fn wrapRenderPassEncoder(pass: c.WGPURenderPassEncoder) RenderPassEncoder { - return .{ - .ptr = pass.?, - .vtable = &render_pass_encoder_vtable, - }; -} - -const render_pass_encoder_vtable = RenderPassEncoder.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuRenderPassEncoderReference(@ptrCast(c.WGPURenderPassEncoder, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuRenderPassEncoderRelease(@ptrCast(c.WGPURenderPassEncoder, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuRenderPassEncoderSetLabel(@ptrCast(c.WGPURenderPassEncoder, ptr), label); - } - }).setLabel, - .setPipeline = (struct { - pub fn setPipeline(ptr: *anyopaque, pipeline: RenderPipeline) void { - c.wgpuRenderPassEncoderSetPipeline(@ptrCast(c.WGPURenderPassEncoder, ptr), @ptrCast(c.WGPURenderPipeline, pipeline.ptr)); - } - }).setPipeline, - .draw = (struct { - pub fn draw(ptr: *anyopaque, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void { - c.wgpuRenderPassEncoderDraw(@ptrCast(c.WGPURenderPassEncoder, ptr), vertex_count, instance_count, first_vertex, first_instance); - } - }).draw, - .drawIndexed = (struct { - pub fn drawIndexed( - ptr: *anyopaque, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, - ) void { - c.wgpuRenderPassEncoderDrawIndexed( - @ptrCast(c.WGPURenderPassEncoder, ptr), - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ); - } - }).drawIndexed, - .drawIndexedIndirect = (struct { - pub fn drawIndexedIndirect(ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void { - c.wgpuRenderPassEncoderDrawIndexedIndirect( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @ptrCast(c.WGPUBuffer, indirect_buffer.ptr), - indirect_offset, - ); - } - }).drawIndexedIndirect, - .drawIndirect = (struct { - pub fn drawIndirect(ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void { - c.wgpuRenderPassEncoderDrawIndexedIndirect( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @ptrCast(c.WGPUBuffer, indirect_buffer.ptr), - indirect_offset, - ); - } - }).drawIndirect, - .beginOcclusionQuery = (struct { - pub fn beginOcclusionQuery(ptr: *anyopaque, query_index: u32) void { - c.wgpuRenderPassEncoderBeginOcclusionQuery(@ptrCast(c.WGPURenderPassEncoder, ptr), query_index); - } - }).beginOcclusionQuery, - .endOcclusionQuery = (struct { - pub fn endOcclusionQuery(ptr: *anyopaque) void { - c.wgpuRenderPassEncoderEndOcclusionQuery(@ptrCast(c.WGPURenderPassEncoder, ptr)); - } - }).endOcclusionQuery, - .end = (struct { - pub fn end(ptr: *anyopaque) void { - c.wgpuRenderPassEncoderEnd(@ptrCast(c.WGPURenderPassEncoder, ptr)); - } - }).end, - .executeBundles = (struct { - pub fn executeBundles(ptr: *anyopaque, bundles: []RenderBundle) void { - var few_bundles: [16]c.WGPURenderBundle = undefined; - const c_bundles = if (bundles.len <= 8) blk: { - for (bundles) |bundle, i| { - few_bundles[i] = @ptrCast(c.WGPURenderBundle, bundle.ptr); - } - break :blk few_bundles[0..bundles.len]; - } else blk: { - const mem = std.heap.page_allocator.alloc(c.WGPURenderBundle, bundles.len) catch unreachable; - for (bundles) |bundle, i| { - mem[i] = @ptrCast(c.WGPURenderBundle, bundle.ptr); - } - break :blk mem; - }; - defer if (bundles.len > 8) std.heap.page_allocator.free(c_bundles); - - c.wgpuRenderPassEncoderExecuteBundles( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @intCast(u32, c_bundles.len), - c_bundles.ptr, - ); - } - }).executeBundles, - .insertDebugMarker = (struct { - pub fn insertDebugMarker(ptr: *anyopaque, marker_label: [*:0]const u8) void { - c.wgpuRenderPassEncoderInsertDebugMarker(@ptrCast(c.WGPURenderPassEncoder, ptr), marker_label); - } - }).insertDebugMarker, - .popDebugGroup = (struct { - pub fn popDebugGroup(ptr: *anyopaque) void { - c.wgpuRenderPassEncoderPopDebugGroup(@ptrCast(c.WGPURenderPassEncoder, ptr)); - } - }).popDebugGroup, - .pushDebugGroup = (struct { - pub fn pushDebugGroup(ptr: *anyopaque, group_label: [*:0]const u8) void { - c.wgpuRenderPassEncoderPushDebugGroup(@ptrCast(c.WGPURenderPassEncoder, ptr), group_label); - } - }).pushDebugGroup, - .setBindGroup = (struct { - pub fn setBindGroup( - ptr: *anyopaque, - group_index: u32, - group: BindGroup, - dynamic_offsets: ?[]const u32, - ) void { - c.wgpuRenderPassEncoderSetBindGroup( - @ptrCast(c.WGPURenderPassEncoder, ptr), - group_index, - @ptrCast(c.WGPUBindGroup, group.ptr), - if (dynamic_offsets) |d| @intCast(u32, d.len) else 0, - if (dynamic_offsets) |d| d.ptr else null, - ); - } - }).setBindGroup, - .setBlendConstant = (struct { - pub fn setBlendConstant(ptr: *anyopaque, color: *const Color) void { - c.wgpuRenderPassEncoderSetBlendConstant( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @ptrCast(*const c.WGPUColor, color), - ); - } - }).setBlendConstant, - .setIndexBuffer = (struct { - pub fn setIndexBuffer( - ptr: *anyopaque, - buffer: Buffer, - format: IndexFormat, - offset: u64, - size: u64, - ) void { - c.wgpuRenderPassEncoderSetIndexBuffer( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @ptrCast(c.WGPUBuffer, buffer.ptr), - @enumToInt(format), - offset, - size, - ); - } - }).setIndexBuffer, - .setScissorRect = (struct { - pub fn setScissorRect(ptr: *anyopaque, x: u32, y: u32, width: u32, height: u32) void { - c.wgpuRenderPassEncoderSetScissorRect( - @ptrCast(c.WGPURenderPassEncoder, ptr), - x, - y, - width, - height, - ); - } - }).setScissorRect, - .setStencilReference = (struct { - pub fn setStencilReference(ptr: *anyopaque, reference: u32) void { - c.wgpuRenderPassEncoderSetStencilReference( - @ptrCast(c.WGPURenderPassEncoder, ptr), - reference, - ); - } - }).setStencilReference, - .setVertexBuffer = (struct { - pub fn setVertexBuffer(ptr: *anyopaque, slot: u32, buffer: Buffer, offset: u64, size: u64) void { - c.wgpuRenderPassEncoderSetVertexBuffer( - @ptrCast(c.WGPURenderPassEncoder, ptr), - slot, - @ptrCast(c.WGPUBuffer, buffer.ptr), - offset, - size, - ); - } - }).setVertexBuffer, - .setViewport = (struct { - pub fn setViewport( - ptr: *anyopaque, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, - ) void { - c.wgpuRenderPassEncoderSetViewport( - @ptrCast(c.WGPURenderPassEncoder, ptr), - x, - y, - width, - height, - min_depth, - max_depth, - ); - } - }).setViewport, - .writeTimestamp = (struct { - pub fn writeTimestamp(ptr: *anyopaque, query_set: QuerySet, query_index: u32) void { - c.wgpuRenderPassEncoderWriteTimestamp( - @ptrCast(c.WGPURenderPassEncoder, ptr), - @ptrCast(c.WGPUQuerySet, query_set.ptr), - query_index, - ); - } - }).writeTimestamp, -}; - -fn wrapRenderBundleEncoder(enc: c.WGPURenderBundleEncoder) RenderBundleEncoder { - return .{ - .ptr = enc.?, - .vtable = &render_bundle_encoder_vtable, - }; -} - -const render_bundle_encoder_vtable = RenderBundleEncoder.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuRenderBundleEncoderReference(@ptrCast(c.WGPURenderBundleEncoder, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuRenderBundleEncoderRelease(@ptrCast(c.WGPURenderBundleEncoder, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuRenderBundleEncoderSetLabel(@ptrCast(c.WGPURenderBundleEncoder, ptr), label); - } - }).setLabel, - .setPipeline = (struct { - pub fn setPipeline(ptr: *anyopaque, pipeline: RenderPipeline) void { - c.wgpuRenderBundleEncoderSetPipeline(@ptrCast(c.WGPURenderBundleEncoder, ptr), @ptrCast(c.WGPURenderPipeline, pipeline.ptr)); - } - }).setPipeline, - .draw = (struct { - pub fn draw(ptr: *anyopaque, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void { - c.wgpuRenderBundleEncoderDraw(@ptrCast(c.WGPURenderBundleEncoder, ptr), vertex_count, instance_count, first_vertex, first_instance); - } - }).draw, - .drawIndexed = (struct { - pub fn drawIndexed( - ptr: *anyopaque, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, - ) void { - c.wgpuRenderBundleEncoderDrawIndexed( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ); - } - }).drawIndexed, - .drawIndexedIndirect = (struct { - pub fn drawIndexedIndirect(ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void { - c.wgpuRenderBundleEncoderDrawIndexedIndirect( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - @ptrCast(c.WGPUBuffer, indirect_buffer.ptr), - indirect_offset, - ); - } - }).drawIndexedIndirect, - .drawIndirect = (struct { - pub fn drawIndirect(ptr: *anyopaque, indirect_buffer: Buffer, indirect_offset: u64) void { - c.wgpuRenderBundleEncoderDrawIndexedIndirect( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - @ptrCast(c.WGPUBuffer, indirect_buffer.ptr), - indirect_offset, - ); - } - }).drawIndirect, - .finish = (struct { - pub fn finish(ptr: *anyopaque, descriptor: *const RenderBundle.Descriptor) RenderBundle { - const desc = c.WGPURenderBundleDescriptor{ - .nextInChain = null, - .label = if (descriptor.label) |l| l else null, - }; - return wrapRenderBundle(c.wgpuRenderBundleEncoderFinish(@ptrCast(c.WGPURenderBundleEncoder, ptr), &desc)); - } - }).finish, - .insertDebugMarker = (struct { - pub fn insertDebugMarker(ptr: *anyopaque, marker_label: [*:0]const u8) void { - c.wgpuRenderBundleEncoderInsertDebugMarker(@ptrCast(c.WGPURenderBundleEncoder, ptr), marker_label); - } - }).insertDebugMarker, - .popDebugGroup = (struct { - pub fn popDebugGroup(ptr: *anyopaque) void { - c.wgpuRenderBundleEncoderPopDebugGroup(@ptrCast(c.WGPURenderBundleEncoder, ptr)); - } - }).popDebugGroup, - .pushDebugGroup = (struct { - pub fn pushDebugGroup(ptr: *anyopaque, group_label: [*:0]const u8) void { - c.wgpuRenderBundleEncoderPushDebugGroup(@ptrCast(c.WGPURenderBundleEncoder, ptr), group_label); - } - }).pushDebugGroup, - .setBindGroup = (struct { - pub fn setBindGroup( - ptr: *anyopaque, - group_index: u32, - group: BindGroup, - dynamic_offsets: ?[]const u32, - ) void { - c.wgpuRenderBundleEncoderSetBindGroup( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - group_index, - @ptrCast(c.WGPUBindGroup, group.ptr), - if (dynamic_offsets) |d| @intCast(u32, d.len) else 0, - if (dynamic_offsets) |d| d.ptr else null, - ); - } - }).setBindGroup, - .setIndexBuffer = (struct { - pub fn setIndexBuffer( - ptr: *anyopaque, - buffer: Buffer, - format: IndexFormat, - offset: u64, - size: u64, - ) void { - c.wgpuRenderBundleEncoderSetIndexBuffer( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - @ptrCast(c.WGPUBuffer, buffer.ptr), - @enumToInt(format), - offset, - size, - ); - } - }).setIndexBuffer, - .setVertexBuffer = (struct { - pub fn setVertexBuffer(ptr: *anyopaque, slot: u32, buffer: Buffer, offset: u64, size: u64) void { - c.wgpuRenderBundleEncoderSetVertexBuffer( - @ptrCast(c.WGPURenderBundleEncoder, ptr), - slot, - @ptrCast(c.WGPUBuffer, buffer.ptr), - offset, - size, - ); - } - }).setVertexBuffer, -}; - -fn wrapRenderBundle(bundle: c.WGPURenderBundle) RenderBundle { - return .{ - .ptr = bundle.?, - .vtable = &render_bundle_vtable, - }; -} - -const render_bundle_vtable = RenderBundle.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuRenderBundleReference(@ptrCast(c.WGPURenderBundle, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuRenderBundleRelease(@ptrCast(c.WGPURenderBundle, ptr)); - } - }).release, -}; - -fn wrapQuerySet(qset: c.WGPUQuerySet) QuerySet { - return .{ - .ptr = qset.?, - .vtable = &query_set_vtable, - }; -} - -const query_set_vtable = QuerySet.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuQuerySetReference(@ptrCast(c.WGPUQuerySet, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuQuerySetRelease(@ptrCast(c.WGPUQuerySet, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuQuerySetSetLabel(@ptrCast(c.WGPUQuerySet, ptr), label); - } - }).setLabel, - .destroy = (struct { - pub fn destroy(ptr: *anyopaque) void { - c.wgpuQuerySetDestroy(@ptrCast(c.WGPUQuerySet, ptr)); - } - }).destroy, -}; - -fn wrapPipelineLayout(layout: c.WGPUPipelineLayout) PipelineLayout { - return .{ - .ptr = layout.?, - .vtable = &pipeline_layout_vtable, - }; -} - -const pipeline_layout_vtable = PipelineLayout.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuPipelineLayoutReference(@ptrCast(c.WGPUPipelineLayout, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuPipelineLayoutRelease(@ptrCast(c.WGPUPipelineLayout, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuPipelineLayoutSetLabel(@ptrCast(c.WGPUPipelineLayout, ptr), label); - } - }).setLabel, -}; - -fn wrapExternalTexture(texture: c.WGPUExternalTexture) ExternalTexture { - return .{ - .ptr = texture.?, - .vtable = &external_texture_vtable, - }; -} - -const external_texture_vtable = ExternalTexture.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuExternalTextureReference(@ptrCast(c.WGPUExternalTexture, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuExternalTextureRelease(@ptrCast(c.WGPUExternalTexture, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuExternalTextureSetLabel(@ptrCast(c.WGPUExternalTexture, ptr), label); - } - }).setLabel, - .destroy = (struct { - pub fn destroy(ptr: *anyopaque) void { - c.wgpuExternalTextureDestroy(@ptrCast(c.WGPUExternalTexture, ptr)); - } - }).destroy, -}; - -fn wrapBindGroup(group: c.WGPUBindGroup) BindGroup { - return .{ - .ptr = group.?, - .vtable = &bind_group_vtable, - }; -} - -const bind_group_vtable = BindGroup.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuBindGroupReference(@ptrCast(c.WGPUBindGroup, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuBindGroupRelease(@ptrCast(c.WGPUBindGroup, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuBindGroupSetLabel(@ptrCast(c.WGPUBindGroup, ptr), label); - } - }).setLabel, -}; - -fn wrapBindGroupLayout(layout: c.WGPUBindGroupLayout) BindGroupLayout { - return .{ - .ptr = layout.?, - .vtable = &bind_group_layout_vtable, - }; -} - -const bind_group_layout_vtable = BindGroupLayout.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuBindGroupLayoutReference(@ptrCast(c.WGPUBindGroupLayout, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuBindGroupLayoutRelease(@ptrCast(c.WGPUBindGroupLayout, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuBindGroupLayoutSetLabel(@ptrCast(c.WGPUBindGroupLayout, ptr), label); - } - }).setLabel, -}; - -fn wrapBuffer(buffer: c.WGPUBuffer) Buffer { - return .{ - .ptr = buffer.?, - .vtable = &buffer_vtable, - }; -} - -const buffer_vtable = Buffer.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuBufferReference(@ptrCast(c.WGPUBuffer, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuBufferRelease(@ptrCast(c.WGPUBuffer, ptr)); - } - }).release, - .getConstMappedRange = (struct { - pub fn getConstMappedRange(ptr: *anyopaque, offset: usize, size: usize) []const u8 { - const range = c.wgpuBufferGetConstMappedRange(@ptrCast(c.WGPUBuffer, ptr), offset, size); - return @ptrCast([*c]const u8, range.?)[0..size]; - } - }).getConstMappedRange, - .getMappedRange = (struct { - pub fn getMappedRange(ptr: *anyopaque, offset: usize, size: usize) []u8 { - const range = c.wgpuBufferGetMappedRange(@ptrCast(c.WGPUBuffer, ptr), offset, size); - return @ptrCast([*c]u8, range.?)[0..size]; - } - }).getMappedRange, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuBufferSetLabel(@ptrCast(c.WGPUBuffer, ptr), label); - } - }).setLabel, - .destroy = (struct { - pub fn destroy(ptr: *anyopaque) void { - c.wgpuBufferDestroy(@ptrCast(c.WGPUBuffer, ptr)); - } - }).destroy, - .mapAsync = (struct { - pub fn mapAsync( - ptr: *anyopaque, - mode: Buffer.MapMode, - offset: usize, - size: usize, - callback: *Buffer.MapCallback, - ) void { - const cCallback = (struct { - pub fn cCallback(status: c.WGPUBufferMapAsyncStatus, userdata: ?*anyopaque) callconv(.C) void { - const callback_info = @ptrCast(*Buffer.MapCallback, @alignCast(std.meta.alignment(*Buffer.MapCallback), userdata.?)); - callback_info.type_erased_callback(callback_info.type_erased_ctx, @intToEnum(Buffer.MapAsyncStatus, status)); - } - }).cCallback; - c.wgpuBufferMapAsync(@ptrCast(c.WGPUBuffer, ptr), @enumToInt(mode), offset, size, cCallback, callback); - } - }).mapAsync, - .unmap = (struct { - pub fn unmap(ptr: *anyopaque) void { - c.wgpuBufferUnmap(@ptrCast(c.WGPUBuffer, ptr)); - } - }).unmap, -}; - -fn wrapCommandBuffer(buffer: c.WGPUCommandBuffer) CommandBuffer { - return .{ - .ptr = buffer.?, - .vtable = &command_buffer_vtable, - }; -} - -const command_buffer_vtable = CommandBuffer.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuCommandBufferReference(@ptrCast(c.WGPUCommandBuffer, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuCommandBufferRelease(@ptrCast(c.WGPUCommandBuffer, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuCommandBufferSetLabel(@ptrCast(c.WGPUCommandBuffer, ptr), label); - } - }).setLabel, -}; - -fn wrapCommandEncoder(enc: c.WGPUCommandEncoder) CommandEncoder { - return .{ - .ptr = enc.?, - .vtable = &command_encoder_vtable, - }; -} - -const command_encoder_vtable = CommandEncoder.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuCommandEncoderReference(@ptrCast(c.WGPUCommandEncoder, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuCommandEncoderRelease(@ptrCast(c.WGPUCommandEncoder, ptr)); - } - }).release, - .finish = (struct { - pub fn finish(ptr: *anyopaque, descriptor: ?*const CommandBuffer.Descriptor) CommandBuffer { - const desc: ?*c.WGPUCommandBufferDescriptor = if (descriptor) |d| &.{ - .nextInChain = null, - .label = if (d.label) |l| l else "", - } else null; - return wrapCommandBuffer(c.wgpuCommandEncoderFinish(@ptrCast(c.WGPUCommandEncoder, ptr), desc)); - } - }).finish, - .injectValidationError = (struct { - pub fn injectValidationError(ptr: *anyopaque, message: [*:0]const u8) void { - c.wgpuCommandEncoderInjectValidationError(@ptrCast(c.WGPUCommandEncoder, ptr), message); - } - }).injectValidationError, - .insertDebugMarker = (struct { - pub fn insertDebugMarker(ptr: *anyopaque, marker_label: [*:0]const u8) void { - c.wgpuCommandEncoderInsertDebugMarker(@ptrCast(c.WGPUCommandEncoder, ptr), marker_label); - } - }).insertDebugMarker, - .resolveQuerySet = (struct { - pub fn resolveQuerySet( - ptr: *anyopaque, - query_set: QuerySet, - first_query: u32, - query_count: u32, - destination: Buffer, - destination_offset: u64, - ) void { - c.wgpuCommandEncoderResolveQuerySet( - @ptrCast(c.WGPUCommandEncoder, ptr), - @ptrCast(c.WGPUQuerySet, query_set.ptr), - first_query, - query_count, - @ptrCast(c.WGPUBuffer, destination.ptr), - destination_offset, - ); - } - }).resolveQuerySet, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuCommandEncoderSetLabel(@ptrCast(c.WGPUCommandEncoder, ptr), label); - } - }).setLabel, - .beginComputePass = (struct { - pub fn beginComputePass(ptr: *anyopaque, descriptor: ?*const ComputePassEncoder.Descriptor) ComputePassEncoder { - if (descriptor) |d| { - var few_timestamp_writes: [8]c.WGPUComputePassTimestampWrite = undefined; - const timestamp_writes = if (d.timestamp_writes.len <= 8) blk: { - for (d.timestamp_writes) |v, i| { - few_timestamp_writes[i] = c.WGPUComputePassTimestampWrite{ - .querySet = @ptrCast(c.WGPUQuerySet, v.query_set.ptr), - .queryIndex = v.query_index, - .location = @enumToInt(v.location), - }; - } - break :blk few_timestamp_writes[0..d.timestamp_writes.len]; - } else blk: { - const mem = std.heap.page_allocator.alloc(c.WGPUComputePassTimestampWrite, d.timestamp_writes.len) catch unreachable; - for (d.timestamp_writes) |v, i| { - mem[i] = c.WGPUComputePassTimestampWrite{ - .querySet = @ptrCast(c.WGPUQuerySet, v.query_set.ptr), - .queryIndex = v.query_index, - .location = @enumToInt(v.location), - }; - } - break :blk mem; - }; - defer if (d.timestamp_writes.len > 8) std.heap.page_allocator.free(timestamp_writes); - - const desc = c.WGPUComputePassDescriptor{ - .nextInChain = null, - .label = if (d.label) |l| l else null, - .timestampWriteCount = @intCast(u32, timestamp_writes.len), - .timestampWrites = @ptrCast([*]const c.WGPUComputePassTimestampWrite, timestamp_writes.ptr), - }; - return wrapComputePassEncoder(c.wgpuCommandEncoderBeginComputePass(@ptrCast(c.WGPUCommandEncoder, ptr), &desc)); - } else { - return wrapComputePassEncoder(c.wgpuCommandEncoderBeginComputePass(@ptrCast(c.WGPUCommandEncoder, ptr), null)); - } - } - }).beginComputePass, - .beginRenderPass = (struct { - pub fn beginRenderPass(ptr: *anyopaque, d: *const RenderPassEncoder.Descriptor) RenderPassEncoder { - var few_color_attachments: [8]c.WGPURenderPassColorAttachment = undefined; - const color_attachments = if (d.color_attachments.len <= 8) blk: { - for (d.color_attachments) |v, i| { - few_color_attachments[i] = c.WGPURenderPassColorAttachment{ - .view = @ptrCast(c.WGPUTextureView, v.view.ptr), - .resolveTarget = if (v.resolve_target) |t| @ptrCast(c.WGPUTextureView, t.ptr) else null, - .loadOp = @enumToInt(v.load_op), - .storeOp = @enumToInt(v.store_op), - .clearValue = @bitCast(c.WGPUColor, v.clear_value), - // deprecated: - .clearColor = c.WGPUColor{ - .r = std.math.nan(f32), - .g = std.math.nan(f32), - .b = std.math.nan(f32), - .a = std.math.nan(f32), - }, - }; - } - break :blk few_color_attachments[0..d.color_attachments.len]; - } else blk: { - const mem = std.heap.page_allocator.alloc(c.WGPURenderPassColorAttachment, d.color_attachments.len) catch unreachable; - for (d.color_attachments) |v, i| { - mem[i] = c.WGPURenderPassColorAttachment{ - .view = @ptrCast(c.WGPUTextureView, v.view.ptr), - .resolveTarget = if (v.resolve_target) |t| @ptrCast(c.WGPUTextureView, t.ptr) else null, - .loadOp = @enumToInt(v.load_op), - .storeOp = @enumToInt(v.store_op), - .clearValue = @bitCast(c.WGPUColor, v.clear_value), - // deprecated: - .clearColor = c.WGPUColor{ - .r = std.math.nan(f32), - .g = std.math.nan(f32), - .b = std.math.nan(f32), - .a = std.math.nan(f32), - }, - }; - } - break :blk mem; - }; - defer if (d.color_attachments.len > 8) std.heap.page_allocator.free(color_attachments); - - var few_timestamp_writes: [8]c.WGPURenderPassTimestampWrite = undefined; - const timestamp_writes = if (d.timestamp_writes) |writes| blk: { - if (writes.len <= 8) { - for (writes) |v, i| { - few_timestamp_writes[i] = c.WGPURenderPassTimestampWrite{ - .querySet = @ptrCast(c.WGPUQuerySet, v.query_set.ptr), - .queryIndex = v.query_index, - .location = @enumToInt(v.location), - }; - } - break :blk few_timestamp_writes[0..writes.len]; - } else { - const mem = std.heap.page_allocator.alloc(c.WGPURenderPassTimestampWrite, writes.len) catch unreachable; - for (writes) |v, i| { - mem[i] = c.WGPURenderPassTimestampWrite{ - .querySet = @ptrCast(c.WGPUQuerySet, v.query_set.ptr), - .queryIndex = v.query_index, - .location = @enumToInt(v.location), - }; - } - break :blk mem; - } - } else null; - defer if (timestamp_writes != null and timestamp_writes.?.len > 8) std.heap.page_allocator.free(timestamp_writes.?); - - const desc = c.WGPURenderPassDescriptor{ - .nextInChain = null, - .label = if (d.label) |l| l else null, - .colorAttachmentCount = @intCast(u32, color_attachments.len), - .colorAttachments = color_attachments.ptr, - .depthStencilAttachment = if (d.depth_stencil_attachment) |v| &c.WGPURenderPassDepthStencilAttachment{ - .view = @ptrCast(c.WGPUTextureView, v.view.ptr), - .depthLoadOp = @enumToInt(v.depth_load_op), - .depthStoreOp = @enumToInt(v.depth_store_op), - .clearDepth = v.clear_depth, - .depthClearValue = v.depth_clear_value, - .depthReadOnly = v.depth_read_only, - .stencilLoadOp = @enumToInt(v.stencil_load_op), - .stencilStoreOp = @enumToInt(v.stencil_store_op), - .clearStencil = v.clear_stencil, - .stencilClearValue = v.stencil_clear_value, - .stencilReadOnly = v.stencil_read_only, - } else null, - .occlusionQuerySet = if (d.occlusion_query_set) |v| @ptrCast(c.WGPUQuerySet, v.ptr) else null, - .timestampWriteCount = if (timestamp_writes) |v| @intCast(u32, v.len) else 0, - .timestampWrites = if (timestamp_writes) |v| @ptrCast([*]const c.WGPURenderPassTimestampWrite, v.ptr) else null, - }; - return wrapRenderPassEncoder(c.wgpuCommandEncoderBeginRenderPass(@ptrCast(c.WGPUCommandEncoder, ptr), &desc)); - } - }).beginRenderPass, - .clearBuffer = (struct { - pub fn clearBuffer(ptr: *anyopaque, buffer: Buffer, offset: u64, size: u64) void { - c.wgpuCommandEncoderClearBuffer( - @ptrCast(c.WGPUCommandEncoder, ptr), - @ptrCast(c.WGPUBuffer, buffer.ptr), - offset, - size, - ); - } - }).clearBuffer, - .copyBufferToBuffer = (struct { - pub fn copyBufferToBuffer( - ptr: *anyopaque, - source: Buffer, - source_offset: u64, - destination: Buffer, - destination_offset: u64, - size: u64, - ) void { - c.wgpuCommandEncoderCopyBufferToBuffer( - @ptrCast(c.WGPUCommandEncoder, ptr), - @ptrCast(c.WGPUBuffer, source.ptr), - source_offset, - @ptrCast(c.WGPUBuffer, destination.ptr), - destination_offset, - size, - ); - } - }).copyBufferToBuffer, - .copyBufferToTexture = (struct { - pub fn copyBufferToTexture( - ptr: *anyopaque, - source: *const ImageCopyBuffer, - destination: *const ImageCopyTexture, - copy_size: *const Extent3D, - ) void { - c.wgpuCommandEncoderCopyBufferToTexture( - @ptrCast(c.WGPUCommandEncoder, ptr), - &convertImageCopyBuffer(source), - &convertImageCopyTexture(destination), - @ptrCast(*const c.WGPUExtent3D, copy_size), - ); - } - }).copyBufferToTexture, - .copyTextureToBuffer = (struct { - pub fn copyTextureToBuffer( - ptr: *anyopaque, - source: *const ImageCopyTexture, - destination: *const ImageCopyBuffer, - copy_size: *const Extent3D, - ) void { - c.wgpuCommandEncoderCopyTextureToBuffer( - @ptrCast(c.WGPUCommandEncoder, ptr), - &convertImageCopyTexture(source), - &convertImageCopyBuffer(destination), - @ptrCast(*const c.WGPUExtent3D, copy_size), - ); - } - }).copyTextureToBuffer, - .copyTextureToTexture = (struct { - pub fn copyTextureToTexture( - ptr: *anyopaque, - source: *const ImageCopyTexture, - destination: *const ImageCopyTexture, - copy_size: *const Extent3D, - ) void { - c.wgpuCommandEncoderCopyTextureToTexture( - @ptrCast(c.WGPUCommandEncoder, ptr), - &convertImageCopyTexture(source), - &convertImageCopyTexture(destination), - @ptrCast(*const c.WGPUExtent3D, copy_size), - ); - } - }).copyTextureToTexture, - .popDebugGroup = (struct { - pub fn popDebugGroup(ptr: *anyopaque) void { - c.wgpuCommandEncoderPopDebugGroup(@ptrCast(c.WGPUCommandEncoder, ptr)); - } - }).popDebugGroup, - .pushDebugGroup = (struct { - pub fn pushDebugGroup(ptr: *anyopaque, group_label: [*:0]const u8) void { - c.wgpuCommandEncoderPushDebugGroup(@ptrCast(c.WGPUCommandEncoder, ptr), group_label); - } - }).pushDebugGroup, - .writeBuffer = (struct { - pub fn writeBuffer(ptr: *anyopaque, buffer: Buffer, buffer_offset: u64, data: [*]const u8, size: u64) void { - c.wgpuCommandEncoderWriteBuffer( - @ptrCast(c.WGPUCommandEncoder, ptr), - @ptrCast(c.WGPUBuffer, buffer.ptr), - buffer_offset, - data, - size, - ); - } - }).writeBuffer, - .writeTimestamp = (struct { - pub fn writeTimestamp(ptr: *anyopaque, query_set: QuerySet, query_index: u32) void { - c.wgpuCommandEncoderWriteTimestamp( - @ptrCast(c.WGPUCommandEncoder, ptr), - @ptrCast(c.WGPUQuerySet, query_set.ptr), - query_index, - ); - } - }).writeTimestamp, -}; - -inline fn convertImageCopyBuffer(v: *const ImageCopyBuffer) c.WGPUImageCopyBuffer { - return .{ - .nextInChain = null, - .layout = convertTextureDataLayout(v.layout), - .buffer = @ptrCast(c.WGPUBuffer, v.buffer.ptr), - }; -} - -inline fn convertImageCopyTexture(v: *const ImageCopyTexture) c.WGPUImageCopyTexture { - return .{ - .nextInChain = null, - .texture = @ptrCast(c.WGPUTexture, v.texture.ptr), - .mipLevel = v.mip_level, - .origin = @bitCast(c.WGPUOrigin3D, v.origin), - .aspect = @enumToInt(v.aspect), - }; -} - -inline fn convertTextureDataLayout(v: Texture.DataLayout) c.WGPUTextureDataLayout { - return .{ - .nextInChain = null, - .offset = v.offset, - .bytesPerRow = v.bytes_per_row, - .rowsPerImage = v.rows_per_image, - }; -} - -fn wrapComputePassEncoder(enc: c.WGPUComputePassEncoder) ComputePassEncoder { - return .{ - .ptr = enc.?, - .vtable = &compute_pass_encoder_vtable, - }; -} - -const compute_pass_encoder_vtable = ComputePassEncoder.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuComputePassEncoderReference(@ptrCast(c.WGPUComputePassEncoder, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuComputePassEncoderRelease(@ptrCast(c.WGPUComputePassEncoder, ptr)); - } - }).release, - .dispatch = (struct { - pub fn dispatch( - ptr: *anyopaque, - workgroup_count_x: u32, - workgroup_count_y: u32, - workgroup_count_z: u32, - ) void { - c.wgpuComputePassEncoderDispatch( - @ptrCast(c.WGPUComputePassEncoder, ptr), - workgroup_count_x, - workgroup_count_y, - workgroup_count_z, - ); - } - }).dispatch, - .dispatchIndirect = (struct { - pub fn dispatchIndirect( - ptr: *anyopaque, - indirect_buffer: Buffer, - indirect_offset: u64, - ) void { - c.wgpuComputePassEncoderDispatchIndirect( - @ptrCast(c.WGPUComputePassEncoder, ptr), - @ptrCast(c.WGPUBuffer, indirect_buffer.ptr), - indirect_offset, - ); - } - }).dispatchIndirect, - .end = (struct { - pub fn end(ptr: *anyopaque) void { - c.wgpuComputePassEncoderEnd(@ptrCast(c.WGPUComputePassEncoder, ptr)); - } - }).end, - .setBindGroup = (struct { - pub fn setBindGroup( - ptr: *anyopaque, - group_index: u32, - group: BindGroup, - dynamic_offsets: ?[]const u32, - ) void { - c.wgpuComputePassEncoderSetBindGroup( - @ptrCast(c.WGPUComputePassEncoder, ptr), - group_index, - @ptrCast(c.WGPUBindGroup, group.ptr), - if (dynamic_offsets) |d| @intCast(u32, d.len) else 0, - if (dynamic_offsets) |d| d.ptr else null, - ); - } - }).setBindGroup, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuComputePassEncoderSetLabel(@ptrCast(c.WGPUComputePassEncoder, ptr), label); - } - }).setLabel, - .insertDebugMarker = (struct { - pub fn insertDebugMarker(ptr: *anyopaque, marker_label: [*:0]const u8) void { - c.wgpuComputePassEncoderInsertDebugMarker(@ptrCast(c.WGPUComputePassEncoder, ptr), marker_label); - } - }).insertDebugMarker, - .popDebugGroup = (struct { - pub fn popDebugGroup(ptr: *anyopaque) void { - c.wgpuComputePassEncoderPopDebugGroup(@ptrCast(c.WGPUComputePassEncoder, ptr)); - } - }).popDebugGroup, - .pushDebugGroup = (struct { - pub fn pushDebugGroup(ptr: *anyopaque, group_label: [*:0]const u8) void { - c.wgpuComputePassEncoderPushDebugGroup(@ptrCast(c.WGPUComputePassEncoder, ptr), group_label); - } - }).pushDebugGroup, - .setPipeline = (struct { - pub fn setPipeline(ptr: *anyopaque, pipeline: ComputePipeline) void { - c.wgpuComputePassEncoderSetPipeline(@ptrCast(c.WGPUComputePassEncoder, ptr), @ptrCast(c.WGPUComputePipeline, pipeline.ptr)); - } - }).setPipeline, - .writeTimestamp = (struct { - pub fn writeTimestamp(ptr: *anyopaque, query_set: QuerySet, query_index: u32) void { - c.wgpuComputePassEncoderWriteTimestamp( - @ptrCast(c.WGPUComputePassEncoder, ptr), - @ptrCast(c.WGPUQuerySet, query_set.ptr), - query_index, - ); - } - }).writeTimestamp, -}; - -fn wrapComputePipeline(pipeline: c.WGPUComputePipeline) ComputePipeline { - return .{ - .ptr = pipeline.?, - .vtable = &compute_pipeline_vtable, - }; -} - -const compute_pipeline_vtable = ComputePipeline.VTable{ - .reference = (struct { - pub fn reference(ptr: *anyopaque) void { - c.wgpuComputePipelineReference(@ptrCast(c.WGPUComputePipeline, ptr)); - } - }).reference, - .release = (struct { - pub fn release(ptr: *anyopaque) void { - c.wgpuComputePipelineRelease(@ptrCast(c.WGPUComputePipeline, ptr)); - } - }).release, - .setLabel = (struct { - pub fn setLabel(ptr: *anyopaque, label: [:0]const u8) void { - c.wgpuComputePipelineSetLabel(@ptrCast(c.WGPUComputePipeline, ptr), label); - } - }).setLabel, - .getBindGroupLayout = (struct { - pub fn getBindGroupLayout(ptr: *anyopaque, group_index: u32) BindGroupLayout { - return wrapBindGroupLayout(c.wgpuComputePipelineGetBindGroupLayout( - @ptrCast(c.WGPUComputePipeline, ptr), - group_index, - )); - } - }).getBindGroupLayout, -}; - -test { - _ = wrap; - _ = interface_vtable; - _ = interface; - _ = createSurface; - _ = surface_vtable; - _ = adapter_vtable; - _ = wrapDevice; - _ = device_vtable; - _ = wrapQueue; - _ = wrapShaderModule; - _ = wrapSwapChain; - _ = wrapTextureView; - _ = wrapTexture; - _ = wrapSampler; - _ = wrapRenderPipeline; - _ = wrapRenderPassEncoder; - _ = wrapRenderBundleEncoder; - _ = wrapRenderBundle; - _ = wrapQuerySet; - _ = wrapPipelineLayout; - _ = wrapExternalTexture; - _ = wrapBindGroup; - _ = wrapBindGroupLayout; - _ = wrapBuffer; - _ = wrapCommandBuffer; - _ = wrapCommandEncoder; - _ = wrapComputePassEncoder; - _ = wrapComputePipeline; -} diff --git a/gpu/src/PipelineLayout.zig b/gpu/src/PipelineLayout.zig deleted file mode 100644 index a1e98d60..00000000 --- a/gpu/src/PipelineLayout.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/QuerySet.zig b/gpu/src/QuerySet.zig deleted file mode 100644 index 52bb367a..00000000 --- a/gpu/src/QuerySet.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Queue.zig b/gpu/src/Queue.zig deleted file mode 100644 index 2e5b5a9c..00000000 --- a/gpu/src/Queue.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/RenderBundle.zig b/gpu/src/RenderBundle.zig deleted file mode 100644 index 02a9365e..00000000 --- a/gpu/src/RenderBundle.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/RenderBundleEncoder.zig b/gpu/src/RenderBundleEncoder.zig deleted file mode 100644 index 15567592..00000000 --- a/gpu/src/RenderBundleEncoder.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/RenderPassEncoder.zig b/gpu/src/RenderPassEncoder.zig deleted file mode 100644 index 9c9e1496..00000000 --- a/gpu/src/RenderPassEncoder.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/RenderPipeline.zig b/gpu/src/RenderPipeline.zig deleted file mode 100644 index 99b74cec..00000000 --- a/gpu/src/RenderPipeline.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Sampler.zig b/gpu/src/Sampler.zig deleted file mode 100644 index 858816a4..00000000 --- a/gpu/src/Sampler.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/ShaderModule.zig b/gpu/src/ShaderModule.zig deleted file mode 100644 index 3f168ea9..00000000 --- a/gpu/src/ShaderModule.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Surface.zig b/gpu/src/Surface.zig deleted file mode 100644 index f0d062ff..00000000 --- a/gpu/src/Surface.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/SwapChain.zig b/gpu/src/SwapChain.zig deleted file mode 100644 index a3a7db33..00000000 --- a/gpu/src/SwapChain.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/Texture.zig b/gpu/src/Texture.zig deleted file mode 100644 index eba7fcec..00000000 --- a/gpu/src/Texture.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/TextureView.zig b/gpu/src/TextureView.zig deleted file mode 100644 index b62f5398..00000000 --- a/gpu/src/TextureView.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/c.zig b/gpu/src/c.zig deleted file mode 100644 index aa00631d..00000000 --- a/gpu/src/c.zig +++ /dev/null @@ -1,3 +0,0 @@ -pub const c = @cImport({ - @cInclude("webgpu/webgpu.h"); -}); diff --git a/gpu/src/data.zig b/gpu/src/data.zig deleted file mode 100644 index c55097e8..00000000 --- a/gpu/src/data.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/enums.zig b/gpu/src/enums.zig deleted file mode 100644 index ed194beb..00000000 --- a/gpu/src/enums.zig +++ /dev/null @@ -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; -} diff --git a/gpu/src/main.zig b/gpu/src/main.zig deleted file mode 100644 index b49bc5d5..00000000 --- a/gpu/src/main.zig +++ /dev/null @@ -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: WebGPU’s coordinate systems match DirectX’s 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()); -} diff --git a/gpu/src/structs.zig b/gpu/src/structs.zig deleted file mode 100644 index 1262b0ef..00000000 --- a/gpu/src/structs.zig +++ /dev/null @@ -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; -}