From 2b67ad54575a867a834a14abc95fbe301f605559 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Mon, 7 Mar 2022 23:58:11 -0700 Subject: [PATCH] gpu: basic Queue implementation Signed-off-by: Stephen Gutekanst --- gpu/src/Device.zig | 18 ++++++++++++++++- gpu/src/NativeInstance.zig | 27 +++++++++++++++++++++++++ gpu/src/Queue.zig | 40 ++++++++++++++++++++++++++++++++++++++ gpu/src/TODO | 19 ------------------ gpu/src/main.zig | 2 ++ 5 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 gpu/src/Queue.zig diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig index 490e93a5..cc0d7e7e 100644 --- a/gpu/src/Device.zig +++ b/gpu/src/Device.zig @@ -8,6 +8,7 @@ //! https://gpuweb.github.io/gpuweb/#gpuadapter const FeatureName = @import("feature_name.zig").FeatureName; const Limits = @import("Limits.zig"); +const Queue = @import("Queue.zig"); const Device = @This(); @@ -38,7 +39,7 @@ pub const VTable = struct { // WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device); // WGPU_EXPORT size_t wgpuDeviceEnumerateFeatures(WGPUDevice device, WGPUFeatureName * features); // WGPU_EXPORT bool wgpuDeviceGetLimits(WGPUDevice device, WGPUSupportedLimits * limits); - // WGPU_EXPORT WGPUQueue wgpuDeviceGetQueue(WGPUDevice device); + getQueue: fn (ptr: *anyopaque) Queue, // WGPU_EXPORT bool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature); // WGPU_EXPORT void wgpuDeviceInjectError(WGPUDevice device, WGPUErrorType type, char const * message); // WGPU_EXPORT void wgpuDeviceLoseForTesting(WGPUDevice device); @@ -53,6 +54,18 @@ pub const VTable = struct { release: fn (ptr: *anyopaque) void, }; +pub inline fn getQueue(device: Device) Queue { + return device.vtable.getQueue(device.ptr); +} + +pub inline fn reference(device: Device) void { + device.vtable.reference(device.ptr); +} + +pub inline fn release(device: Device) void { + device.vtable.release(device.ptr); +} + // TODO: docs pub const Descriptor = struct { label: ?[]const u8 = null, @@ -62,5 +75,8 @@ pub const Descriptor = struct { test "syntax" { _ = VTable; + _ = getQueue; + _ = reference; + _ = release; _ = Descriptor; } diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index ecc9c40a..86c0dd7b 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -16,6 +16,7 @@ const RequestDeviceResponse = Adapter.RequestDeviceResponse; const Device = @import("Device.zig"); const Surface = @import("Surface.zig"); const Limits = @import("Limits.zig"); +const Queue = @import("Queue.zig"); const NativeInstance = @This(); @@ -294,6 +295,11 @@ const device_vtable = Device.VTable{ c.wgpuDeviceRelease(@ptrCast(c.WGPUDevice, ptr)); } }).release, + .getQueue = (struct { + pub fn getQueue(ptr: *anyopaque) Queue { + return wrapQueue(c.wgpuDeviceGetQueue(@ptrCast(c.WGPUDevice, ptr))); + } + }).getQueue, }; // TODO: maybe make Limits an extern struct that can be cast? @@ -328,6 +334,26 @@ fn convertLimits(l: Limits) c.WGPULimits { }; } +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, +}; + test "syntax" { _ = wrap; _ = interface_vtable; @@ -338,4 +364,5 @@ test "syntax" { _ = wrapDevice; _ = device_vtable; _ = convertLimits; + _ = wrapQueue; } diff --git a/gpu/src/Queue.zig b/gpu/src/Queue.zig new file mode 100644 index 00000000..287aa9c5 --- /dev/null +++ b/gpu/src/Queue.zig @@ -0,0 +1,40 @@ +const Queue = @This(); + +/// 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, + // WGPU_EXPORT void wgpuQueueCopyTextureForBrowser(WGPUQueue queue, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options); + // WGPU_EXPORT void wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void * userdata); + // WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, uint32_t commandCount, WGPUCommandBuffer const * commands); + // WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size); + // WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize); +}; + +pub inline fn reference(queue: Queue) void { + queue.vtable.reference(queue.ptr); +} + +pub inline fn release(queue: Queue) void { + queue.vtable.release(queue.ptr); +} + +// typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, void * userdata); + +// typedef enum WGPUQueueWorkDoneStatus { +// WGPUQueueWorkDoneStatus_Success = 0x00000000, +// WGPUQueueWorkDoneStatus_Error = 0x00000001, +// WGPUQueueWorkDoneStatus_Unknown = 0x00000002, +// WGPUQueueWorkDoneStatus_DeviceLost = 0x00000003, +// WGPUQueueWorkDoneStatus_Force32 = 0x7FFFFFFF +// } WGPUQueueWorkDoneStatus; + +test "syntax" { + _ = VTable; + _ = reference; + _ = release; +} \ No newline at end of file diff --git a/gpu/src/TODO b/gpu/src/TODO index 1bc8f1ba..534cd2d3 100644 --- a/gpu/src/TODO +++ b/gpu/src/TODO @@ -19,7 +19,6 @@ typedef struct WGPUComputePipelineImpl* WGPUComputePipeline; typedef struct WGPUExternalTextureImpl* WGPUExternalTexture; typedef struct WGPUPipelineLayoutImpl* WGPUPipelineLayout; typedef struct WGPUQuerySetImpl* WGPUQuerySet; -typedef struct WGPUQueueImpl* WGPUQueue; typedef struct WGPURenderBundleImpl* WGPURenderBundle; typedef struct WGPURenderBundleEncoderImpl* WGPURenderBundleEncoder; typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder; @@ -255,14 +254,6 @@ typedef enum WGPUQueryType { WGPUQueryType_Force32 = 0x7FFFFFFF } WGPUQueryType; -typedef enum WGPUQueueWorkDoneStatus { - WGPUQueueWorkDoneStatus_Success = 0x00000000, - WGPUQueueWorkDoneStatus_Error = 0x00000001, - WGPUQueueWorkDoneStatus_Unknown = 0x00000002, - WGPUQueueWorkDoneStatus_DeviceLost = 0x00000003, - WGPUQueueWorkDoneStatus_Force32 = 0x7FFFFFFF -} WGPUQueueWorkDoneStatus; - typedef enum WGPURenderPassTimestampLocation { WGPURenderPassTimestampLocation_Beginning = 0x00000000, WGPURenderPassTimestampLocation_End = 0x00000001, @@ -1069,7 +1060,6 @@ typedef void (*WGPUDeviceLostCallback)(WGPUDeviceLostReason reason, char const * typedef void (*WGPUErrorCallback)(WGPUErrorType type, char const * message, void * userdata); typedef void (*WGPULoggingCallback)(WGPULoggingType type, char const * message, void * userdata); typedef void (*WGPUProc)(); -typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, void * userdata); WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName); @@ -1157,15 +1147,6 @@ WGPU_EXPORT void wgpuQuerySetSetLabel(WGPUQuerySet querySet, char const * label) WGPU_EXPORT void wgpuQuerySetReference(WGPUQuerySet querySet); WGPU_EXPORT void wgpuQuerySetRelease(WGPUQuerySet querySet); -// Methods of Queue -WGPU_EXPORT void wgpuQueueCopyTextureForBrowser(WGPUQueue queue, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options); -WGPU_EXPORT void wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void * userdata); -WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, uint32_t commandCount, WGPUCommandBuffer const * commands); -WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size); -WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize); -WGPU_EXPORT void wgpuQueueReference(WGPUQueue queue); -WGPU_EXPORT void wgpuQueueRelease(WGPUQueue queue); - // Methods of RenderBundle WGPU_EXPORT void wgpuRenderBundleReference(WGPURenderBundle renderBundle); WGPU_EXPORT void wgpuRenderBundleRelease(WGPURenderBundle renderBundle); diff --git a/gpu/src/main.zig b/gpu/src/main.zig index 59b61729..89185de7 100644 --- a/gpu/src/main.zig +++ b/gpu/src/main.zig @@ -31,6 +31,7 @@ pub const Adapter = @import("Adapter.zig"); pub const Device = @import("Device.zig"); pub const Surface = @import("Surface.zig"); pub const Limits = @import("Limits.zig"); +pub const Queue = @import("Queue.zig"); pub const FeatureName = @import("feature_name.zig").FeatureName; @@ -42,6 +43,7 @@ test "syntax" { _ = Device; _ = Surface; _ = Limits; + _ = Queue; _ = FeatureName; }