From 38535c7b5fd5e3222fa1e5382b3865fb377256ea Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Tue, 15 Mar 2022 20:04:34 -0700 Subject: [PATCH] gpu: implement Device.createComputePipelineAsync Signed-off-by: Stephen Gutekanst --- gpu/src/ComputePipeline.zig | 52 +++++++++++++++++++++++++++++++++++++ gpu/src/Device.zig | 16 ++++++++++-- gpu/src/NativeInstance.zig | 44 +++++++++++++++++++++++++++++++ gpu/src/TODO | 1 - gpu/src/enums.zig | 9 ------- gpu/src/main.zig | 1 - 6 files changed, 110 insertions(+), 13 deletions(-) diff --git a/gpu/src/ComputePipeline.zig b/gpu/src/ComputePipeline.zig index 2d948179..b7e9182c 100644 --- a/gpu/src/ComputePipeline.zig +++ b/gpu/src/ComputePipeline.zig @@ -34,9 +34,61 @@ pub const Descriptor = struct { 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( + @ptrCast(*Context, @alignCast(@alignOf(*Context), type_erased_ctx)), + status, + pipeline, + message, + ); + } + }).erased; + + return .{ + .type_erased_ctx = ctx, + .type_erased_callback = erased, + }; + } +}; + test "syntax" { _ = VTable; _ = reference; _ = release; _ = Descriptor; + _ = CreateStatus; + _ = CreateCallback; } diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig index 01a980db..0671d220 100644 --- a/gpu/src/Device.zig +++ b/gpu/src/Device.zig @@ -14,6 +14,7 @@ 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 Device = @This(); @@ -29,8 +30,11 @@ pub const VTable = struct { // WGPU_EXPORT WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor); createCommandEncoder: fn (ptr: *anyopaque, descriptor: ?*const CommandEncoder.Descriptor) CommandEncoder, // WGPU_EXPORT WGPUComputePipeline wgpuDeviceCreateComputePipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor); - // TODO: callback - // WGPU_EXPORT void wgpuDeviceCreateComputePipelineAsync(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata); + createComputePipelineAsync: fn ( + ptr: *anyopaque, + descriptor: *const ComputePipeline.Descriptor, + callback: *ComputePipeline.CreateCallback, + ) void, // WGPU_EXPORT WGPUBuffer wgpuDeviceCreateErrorBuffer(WGPUDevice device); // WGPU_EXPORT WGPUExternalTexture wgpuDeviceCreateExternalTexture(WGPUDevice device, WGPUExternalTextureDescriptor const * externalTextureDescriptor); // WGPU_EXPORT WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor); @@ -93,6 +97,14 @@ pub inline fn createCommandEncoder(device: Device, descriptor: ?*const CommandEn return device.vtable.createCommandEncoder(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 createRenderPipeline(device: Device, descriptor: *const RenderPipeline.Descriptor) RenderPipeline { return device.vtable.createRenderPipeline(device.ptr, descriptor); } diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index c9938510..3861a567 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -382,6 +382,50 @@ const device_vtable = Device.VTable{ return wrapCommandEncoder(c.wgpuDeviceCreateCommandEncoder(@ptrCast(c.WGPUDevice, ptr), desc)); } }).createCommandEncoder, + .createComputePipelineAsync = (struct { + pub fn createComputePipelineAsync( + ptr: *anyopaque, + descriptor: *const ComputePipeline.Descriptor, + callback: *ComputePipeline.CreateCallback, + ) void { + const desc = c.WGPUComputePipelineDescriptor{ + .nextInChain = null, + .label = if (descriptor.label) |l| l else null, + .layout = @ptrCast(c.WGPUPipelineLayout, descriptor.layout.ptr), + .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[0]) else null, + }, + }; + + 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(@alignOf(*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, .createRenderPipeline = (struct { pub fn createRenderPipeline(ptr: *anyopaque, descriptor: *const RenderPipeline.Descriptor) RenderPipeline { var tmp_depth_stencil: c.WGPUDepthStencilState = undefined; diff --git a/gpu/src/TODO b/gpu/src/TODO index 8e324f71..dc99514c 100644 --- a/gpu/src/TODO +++ b/gpu/src/TODO @@ -46,7 +46,6 @@ typedef struct WGPUCopyTextureForBrowserOptions { -typedef void (*WGPUCreateComputePipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, char const * message, void * userdata); typedef void (*WGPUCreateRenderPipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, char const * message, void * userdata); typedef void (*WGPUDeviceLostCallback)(WGPUDeviceLostReason reason, char const * message, void * userdata); typedef void (*WGPUErrorCallback)(WGPUErrorType type, char const * message, void * userdata); diff --git a/gpu/src/enums.zig b/gpu/src/enums.zig index ad5bc048..619fb5a8 100644 --- a/gpu/src/enums.zig +++ b/gpu/src/enums.zig @@ -74,14 +74,6 @@ pub const ComputePassTimestampLocation = enum(u32) { end = 0x00000001, }; -pub const CreatePipelineAsyncStatus = enum(u32) { - success = 0x00000000, - err = 0x00000001, - device_lost = 0x00000002, - device_destroyed = 0x00000003, - unknown = 0x00000004, -}; - pub const CullMode = enum(u32) { none = 0x00000000, front = 0x00000001, @@ -272,7 +264,6 @@ test "syntax" { _ = BlendOperation; _ = CompareFunction; _ = ComputePassTimestampLocation; - _ = CreatePipelineAsyncStatus; _ = CullMode; _ = ErrorFilter; _ = ErrorType; diff --git a/gpu/src/main.zig b/gpu/src/main.zig index 74d40375..208092a7 100644 --- a/gpu/src/main.zig +++ b/gpu/src/main.zig @@ -119,7 +119,6 @@ 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 CreatePipelineAsyncStatus = @import("enums.zig").CreatePipelineAsyncStatus; pub const CullMode = @import("enums.zig").CullMode; pub const ErrorFilter = @import("enums.zig").ErrorFilter; pub const ErrorType = @import("enums.zig").ErrorType;