diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig index cc0d7e7e..0ad85488 100644 --- a/gpu/src/Device.zig +++ b/gpu/src/Device.zig @@ -9,6 +9,7 @@ const FeatureName = @import("feature_name.zig").FeatureName; const Limits = @import("Limits.zig"); const Queue = @import("Queue.zig"); +const ShaderModule = @import("ShaderModule.zig"); const Device = @This(); @@ -33,7 +34,7 @@ pub const VTable = struct { // WGPU_EXPORT WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor); // WGPU_EXPORT void wgpuDeviceCreateRenderPipelineAsync(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata); // WGPU_EXPORT WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPUSamplerDescriptor const * descriptor); - // WGPU_EXPORT WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor); + createShaderModule: fn (ptr: *anyopaque, descriptor: *const ShaderModule.Descriptor) ShaderModule, // WGPU_EXPORT WGPUSwapChain wgpuDeviceCreateSwapChain(WGPUDevice device, WGPUSurface surface, WGPUSwapChainDescriptor const * descriptor); // WGPU_EXPORT WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor); // WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device); @@ -66,6 +67,10 @@ pub inline fn release(device: Device) void { device.vtable.release(device.ptr); } +pub inline fn createShaderModule(device: Device, descriptor: *const ShaderModule.Descriptor) ShaderModule { + return device.vtable.createShaderModule(device.ptr, descriptor); +} + // TODO: docs pub const Descriptor = struct { label: ?[]const u8 = null, @@ -78,5 +83,6 @@ test "syntax" { _ = getQueue; _ = reference; _ = release; + _ = createShaderModule; _ = Descriptor; } diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index f1d5331e..49e2ed39 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -18,6 +18,7 @@ const Surface = @import("Surface.zig"); const Limits = @import("Limits.zig"); const Queue = @import("Queue.zig"); const CommandBuffer = @import("CommandBuffer.zig"); +const ShaderModule = @import("ShaderModule.zig"); const NativeInstance = @This(); @@ -301,6 +302,41 @@ const device_vtable = Device.VTable{ return wrapQueue(c.wgpuDeviceGetQueue(@ptrCast(c.WGPUDevice, ptr))); } }).getQueue, + .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| @ptrCast([*c]const u8, 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 = @ptrCast([*c]const u32, &spirv[0]), + .codeSize = @intCast(u32, spirv.len), + }; + const desc = c.WGPUShaderModuleDescriptor{ + .nextInChain = @ptrCast(*const c.WGPUChainedStruct, &spirv_desc), + .label = if (descriptor.label) |l| @ptrCast([*c]const u8, l) else null, + }; + return wrapShaderModule(c.wgpuDeviceCreateShaderModule(@ptrCast(c.WGPUDevice, ptr), &desc)); + }, + } + } + }).createShaderModule, }; // TODO: maybe make Limits an extern struct that can be cast? @@ -386,6 +422,26 @@ const queue_vtable = Queue.VTable{ }).submit, }; +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, +}; + test "syntax" { _ = wrap; _ = interface_vtable; @@ -397,4 +453,5 @@ test "syntax" { _ = device_vtable; _ = convertLimits; _ = wrapQueue; + _ = wrapShaderModule; } diff --git a/gpu/src/ShaderModule.zig b/gpu/src/ShaderModule.zig new file mode 100644 index 00000000..d1d1e030 --- /dev/null +++ b/gpu/src/ShaderModule.zig @@ -0,0 +1,36 @@ +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, +}; + +pub inline fn reference(queue: ShaderModule) void { + queue.vtable.reference(queue.ptr); +} + +pub inline fn release(queue: ShaderModule) void { + queue.vtable.release(queue.ptr); +} + +pub const CodeTag = enum { + spirv, + wgsl, +}; + +pub const Descriptor = struct { + label: ?[]const u8 = null, + code: union(CodeTag) { + wgsl: [:0]const u8, + spirv: []const u32, + }, +}; + +// // Methods of ShaderModule +// WGPU_EXPORT void wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata); +// WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char const * label); diff --git a/gpu/src/TODO b/gpu/src/TODO index 534cd2d3..00089251 100644 --- a/gpu/src/TODO +++ b/gpu/src/TODO @@ -24,7 +24,6 @@ typedef struct WGPURenderBundleEncoderImpl* WGPURenderBundleEncoder; typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder; typedef struct WGPURenderPipelineImpl* WGPURenderPipeline; typedef struct WGPUSamplerImpl* WGPUSampler; -typedef struct WGPUShaderModuleImpl* WGPUShaderModule; typedef struct WGPUSwapChainImpl* WGPUSwapChain; typedef struct WGPUTextureImpl* WGPUTexture; typedef struct WGPUTextureViewImpl* WGPUTextureView; @@ -262,8 +261,6 @@ typedef enum WGPURenderPassTimestampLocation { typedef enum WGPUSType { WGPUSType_Invalid = 0x00000000, - WGPUSType_ShaderModuleSPIRVDescriptor = 0x00000005, - WGPUSType_ShaderModuleWGSLDescriptor = 0x00000006, WGPUSType_ExternalTextureBindingEntry = 0x00000009, WGPUSType_ExternalTextureBindingLayout = 0x0000000A, WGPUSType_DawnTextureInternalUsageDescriptor = 0x000003E8, @@ -792,22 +789,6 @@ typedef struct WGPUSamplerDescriptor { uint16_t maxAnisotropy; } WGPUSamplerDescriptor; -typedef struct WGPUShaderModuleDescriptor { - WGPUChainedStruct const * nextInChain; - char const * label; -} WGPUShaderModuleDescriptor; - -typedef struct WGPUShaderModuleSPIRVDescriptor { - WGPUChainedStruct chain; - uint32_t codeSize; - uint32_t const * code; -} WGPUShaderModuleSPIRVDescriptor; - -typedef struct WGPUShaderModuleWGSLDescriptor { - WGPUChainedStruct chain; - char const * source; -} WGPUShaderModuleWGSLDescriptor; - typedef struct WGPUStencilFaceState { WGPUCompareFunction compare; WGPUStencilOperation failOp; @@ -1205,12 +1186,6 @@ WGPU_EXPORT void wgpuSamplerSetLabel(WGPUSampler sampler, char const * label); WGPU_EXPORT void wgpuSamplerReference(WGPUSampler sampler); WGPU_EXPORT void wgpuSamplerRelease(WGPUSampler sampler); -// Methods of ShaderModule -WGPU_EXPORT void wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata); -WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char const * label); -WGPU_EXPORT void wgpuShaderModuleReference(WGPUShaderModule shaderModule); -WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule); - // Methods of SwapChain WGPU_EXPORT void wgpuSwapChainConfigure(WGPUSwapChain swapChain, WGPUTextureFormat format, WGPUTextureUsageFlags allowedUsage, uint32_t width, uint32_t height); WGPU_EXPORT WGPUTextureView wgpuSwapChainGetCurrentTextureView(WGPUSwapChain swapChain); diff --git a/gpu/src/main.zig b/gpu/src/main.zig index ab3c0944..f219dfe4 100644 --- a/gpu/src/main.zig +++ b/gpu/src/main.zig @@ -33,6 +33,7 @@ pub const Surface = @import("Surface.zig"); pub const Limits = @import("Limits.zig"); pub const Queue = @import("Queue.zig"); pub const CommandBuffer = @import("CommandBuffer.zig"); +pub const ShaderModule = @import("ShaderModule.zig"); pub const FeatureName = @import("feature_name.zig").FeatureName; @@ -46,6 +47,7 @@ test "syntax" { _ = Limits; _ = Queue; _ = CommandBuffer; + _ = ShaderModule; _ = FeatureName; }