diff --git a/gpu/TODO-webgpu.h b/gpu/TODO-webgpu.h index c0363c5a..0bc9c4c3 100644 --- a/gpu/TODO-webgpu.h +++ b/gpu/TODO-webgpu.h @@ -5,13 +5,11 @@ typedef void (*WGPUCreateRenderPipelineAsyncCallback)(WGPUCreatePipelineAsyncSta typedef void (*WGPUDeviceLostCallback)(WGPUDeviceLostReason reason, char const * message, void * userdata); typedef void (*WGPUErrorCallback)(WGPUErrorType type, char const * message, void * userdata); typedef void (*WGPULoggingCallback)(WGPULoggingType type, char const * message, void * userdata); -typedef void (*WGPUProc)(void); typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, void * userdata); typedef void (*WGPURequestAdapterCallback)(WGPURequestAdapterStatus status, WGPUAdapter adapter, char const * message, void * userdata); typedef void (*WGPURequestDeviceCallback)(WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * userdata); // Methods of Adapter -WGPU_EXPORT WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor /* nullable */); WGPU_EXPORT size_t wgpuAdapterEnumerateFeatures(WGPUAdapter adapter, WGPUFeatureName * features); WGPU_EXPORT bool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPUSupportedLimits * limits); WGPU_EXPORT void wgpuAdapterGetProperties(WGPUAdapter adapter, WGPUAdapterProperties * properties); diff --git a/gpu/src/adapter.zig b/gpu/src/adapter.zig index b4404c23..e13044f2 100644 --- a/gpu/src/adapter.zig +++ b/gpu/src/adapter.zig @@ -1,7 +1,14 @@ const testing = @import("std").testing; const ChainedStructOut = @import("types.zig").ChainedStructOut; +const Device = @import("device.zig").Device; +const DeviceDescriptor = @import("device.zig").DeviceDescriptor; +const impl = @import("interface.zig").impl; -pub const Adapter = *opaque {}; +pub const Adapter = *opaque { + pub inline fn createDevice(adapter: Adapter, descriptor: ?*const DeviceDescriptor) ?Device { + return impl.createDevice(adapter, descriptor); + } +}; pub const AdapterType = enum(u32) { discrete_gpu, diff --git a/gpu/src/interface.zig b/gpu/src/interface.zig index daac8700..6c3885fb 100644 --- a/gpu/src/interface.zig +++ b/gpu/src/interface.zig @@ -2,10 +2,24 @@ const Instance = @import("instance.zig").Instance; const InstanceDescriptor = @import("instance.zig").InstanceDescriptor; const gpu = @import("main.zig"); +/// The gpu.Interface implementation that is used by the entire program. Only one may exist, since +/// it is resolved fully at comptime with no vtable indirection, etc. +pub const impl = blk: { + if (@import("builtin").is_test) { + break :blk NullInterface{}; + } else { + const root = @import("root"); + if (!@hasField(root, "gpu_interface")) @compileError("expected to find `pub const gpu_interface: gpu.Interface(T) = T{};` in root file"); + _ = gpu.Interface(@TypeOf(root.gpu_interface)); // verify the type + break :blk root.gpu_interface; + } +}; + /// Verifies that a gpu.Interface implementation exposes the expected function declarations. pub fn Interface(comptime Impl: type) type { assertDecl(Impl, "createInstance", fn (descriptor: *const InstanceDescriptor) callconv(.Inline) ?Instance); assertDecl(Impl, "getProcAddress", fn (device: gpu.Device, proc_name: [*:0]const u8) callconv(.Inline) ?gpu.Proc); + assertDecl(Impl, "adapterCreateDevice", fn (adapter: gpu.Adapter, descriptor: ?*const gpu.DeviceDescriptor) callconv(.Inline) ?gpu.Device); return Impl; } @@ -25,9 +39,14 @@ pub fn Export(comptime Impl: type) type { } // WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName); - export fn getProcAddress(device: gpu.Device, proc_name: [*:0]const u8) ?gpu.Proc { + export fn wgpuGetProcAddress(device: gpu.Device, proc_name: [*:0]const u8) ?gpu.Proc { return Impl.getProcAddress(device, proc_name); } + + // WGPU_EXPORT WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor /* nullable */); + export fn wgpuAdapterCreateDevice(adapter: gpu.Adapter, descriptor: ?*const gpu.DeviceDescriptor) ?gpu.Device { + return Impl.adapterCreateDevice(adapter, descriptor); + } }; } @@ -43,6 +62,12 @@ pub const NullInterface = Interface(struct { _ = proc_name; return null; } + + pub inline fn adapterCreateDevice(adapter: gpu.Adapter, descriptor: ?*const gpu.DeviceDescriptor) ?gpu.Device { + _ = adapter; + _ = descriptor; + return null; + } }); test "null" {