From a0d28a74b0c654e5d4b5553dd606f7bac267e0df Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Fri, 18 Mar 2022 18:46:00 -0700 Subject: [PATCH] gpu: implement Device.setLostCallback Signed-off-by: Stephen Gutekanst --- gpu/src/Device.zig | 31 ++++++++++++++++++++++++++++--- gpu/src/NativeInstance.zig | 29 +++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig index 8139329f..b322095d 100644 --- a/gpu/src/Device.zig +++ b/gpu/src/Device.zig @@ -75,9 +75,7 @@ pub const VTable = struct { loseForTesting: fn (ptr: *anyopaque) void, popErrorScope: fn (ptr: *anyopaque, callback: *ErrorCallback) bool, pushErrorScope: fn (ptr: *anyopaque, filter: ErrorFilter) void, - // TODO: callback - // setDeviceLostCallback: fn (ptr: *anyopaque, callback: DeviceLostCallback) void, - // WGPU_EXPORT void wgpuDeviceSetDeviceLostCallback(WGPUDevice device, WGPUDeviceLostCallback callback, void * userdata); + setLostCallback: fn (ptr: *anyopaque, callback: *LostCallback) void, // TODO: callback // setLoggingCallback: fn (ptr: *anyopaque, callback: LoggingCallback) void, // WGPU_EXPORT void wgpuDeviceSetLoggingCallback(WGPUDevice device, WGPULoggingCallback callback, void * userdata); @@ -113,6 +111,32 @@ 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(@ptrCast(*Context, @alignCast(@alignOf(*Context), type_erased_ctx)), reason, message); + } + }).erased; + + return .{ + .type_erased_ctx = ctx, + .type_erased_callback = erased, + }; + } +}; + pub inline fn createBindGroup(device: Device, descriptor: *const BindGroup.Descriptor) BindGroup { return device.vtable.createBindGroup(device.ptr, descriptor); } @@ -223,6 +247,7 @@ test { _ = injectError; _ = loseForTesting; _ = popErrorScope; + _ = setLostCallback; _ = createBindGroup; _ = pushErrorScope; _ = createBindGroupLayout; diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index dca260f8..92e2a1c0 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -335,10 +335,7 @@ const device_vtable = Device.VTable{ } }).loseForTesting, .popErrorScope = (struct { - pub fn popErrorScope( - ptr: *anyopaque, - callback: *ErrorCallback, - ) bool { + pub fn popErrorScope(ptr: *anyopaque, callback: *ErrorCallback) bool { const cCallback = (struct { pub fn cCallback( typ: c.WGPUErrorType, @@ -410,6 +407,30 @@ const device_vtable = Device.VTable{ 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(@alignOf(*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{