diff --git a/gpu/src/Buffer.zig b/gpu/src/Buffer.zig index 8165dfe4..d9967a71 100644 --- a/gpu/src/Buffer.zig +++ b/gpu/src/Buffer.zig @@ -14,8 +14,14 @@ pub const VTable = struct { // TODO: // WGPU_EXPORT void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size); // WGPU_EXPORT void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size); - // WGPU_EXPORT void wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata); 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, }; @@ -35,6 +41,38 @@ 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(@ptrCast(*Context, @alignCast(@alignOf(*Context), type_erased_ctx)), status); + } + }).erased; + + return .{ + .type_erased_ctx = ctx, + .type_erased_callback = erased, + }; + } +}; + pub inline fn unmap(buf: Buffer) void { buf.vtable.unmap(buf.ptr); } @@ -68,6 +106,12 @@ pub const MapAsyncStatus = enum(u32) { unmapped_before_callback = 0x00000005, }; +pub const MapMode = enum(u32) { + none = 0x00000000, + read = 0x00000001, + write = 0x00000002, +}; + test "syntax" { _ = VTable; _ = reference; @@ -78,4 +122,5 @@ test "syntax" { _ = BindingType; _ = BindingLayout; _ = MapAsyncStatus; + _ = MapMode; } diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index ae7e0b72..79c9b5d9 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -514,18 +514,18 @@ const queue_vtable = Queue.VTable{ // to remove it instead" const signal_value: u64 = 0; - const callback = (struct { - pub fn callback(status: c.WGPUQueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void { + const cCallback = (struct { + pub fn cCallback(status: c.WGPUQueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void { const callback_info = @ptrCast(*Queue.WorkDoneCallback, @alignCast(@alignOf(*Queue.WorkDoneCallback), userdata)); callback_info.type_erased_callback( callback_info.type_erased_ctx, @intToEnum(Queue.WorkDoneStatus, status), ); } - }).callback; + }).cCallback; var mut_on_submitted_work_done = on_submitted_work_done; - c.wgpuQueueOnSubmittedWorkDone(wgpu_queue, signal_value, callback, &mut_on_submitted_work_done); + c.wgpuQueueOnSubmittedWorkDone(wgpu_queue, signal_value, cCallback, &mut_on_submitted_work_done); } var few_commands: [16]c.WGPUCommandBuffer = undefined; @@ -971,6 +971,23 @@ const buffer_vtable = Buffer.VTable{ 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(@alignOf(*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)); diff --git a/gpu/src/enums.zig b/gpu/src/enums.zig index 003f76c7..20f201ad 100644 --- a/gpu/src/enums.zig +++ b/gpu/src/enums.zig @@ -265,12 +265,6 @@ pub const ColorWriteMask = enum(u32) { all = 0x0000000F, }; -pub const MapMode = enum(u32) { - none = 0x00000000, - read = 0x00000001, - write = 0x00000002, -}; - pub const ShaderStage = enum(u32) { none = 0x00000000, vertex = 0x00000001, @@ -315,6 +309,5 @@ test "syntax" { _ = VertexStepMode; _ = BufferUsage; _ = ColorWriteMask; - _ = MapMode; _ = ShaderStage; } diff --git a/gpu/src/main.zig b/gpu/src/main.zig index aec48fdd..c4c56824 100644 --- a/gpu/src/main.zig +++ b/gpu/src/main.zig @@ -145,7 +145,6 @@ 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 MapMode = @import("enums.zig").MapMode; pub const ShaderStage = @import("enums.zig").ShaderStage; // Constants