diff --git a/gpu/src/Adapter.zig b/gpu/src/Adapter.zig new file mode 100644 index 00000000..a846122c --- /dev/null +++ b/gpu/src/Adapter.zig @@ -0,0 +1,79 @@ +//! A GPUAdapter which identifies an implementation of WebGPU on the system. +//! +//! An adapter is both an instance of compute/rendering functionality on the platform, and an +//! instance of the WebGPU implementation on top of that functionality. +//! +//! Adapters do not uniquely represent underlying implementations: calling `requestAdapter()` +//! multiple times returns a different adapter object each time. +//! +//! An adapter object may become invalid at any time. This happens inside "lose the device" and +//! "mark adapters stale". An invalid adapter is unable to vend new devices. +//! +//! Note: This mechanism ensures that various adapter-creation scenarios look similar to +//! applications, so they can easily be robust to more scenarios with less testing: first +//! initialization, reinitialization due to an unplugged adapter, reinitialization due to a test +//! GPUDevice.destroy() call, etc. It also ensures applications use the latest system state to make +//! decisions about which adapter to use. +//! +//! https://gpuweb.github.io/gpuweb/#adapters +//! https://gpuweb.github.io/gpuweb/#gpuadapter + +const FeatureName = @import("feature_name.zig").FeatureName; +const SupportedLimits = @import("supported_limits.zig").SupportedLimits; + +const Adapter = @This(); + +/// The features which can be used to create devices on this adapter. +features: []FeatureName, + +/// The best limits which can be used to create devices on this adapter. +/// +/// Each adapter limit will be the same or better than its default value in supported limits. +limits: SupportedLimits, + +/// If set to true indicates that the adapter is a fallback adapter. +/// +/// An adapter may be considered a fallback adapter if it has significant performance caveats in +/// exchange for some combination of wider compatibility, more predictable behavior, or improved +/// privacy. It is not guaranteed that a fallback adapter is available on every system. +fallback: bool, + +// The type erased pointer to the Adapter implementation +ptr: *anyopaque, +vtable: *const VTable, + +pub const VTable = struct { + // TODO: + // WGPU_EXPORT void wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata); + // WGPU_EXPORT WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor); + // WGPU_EXPORT void wgpuAdapterReference(WGPUAdapter adapter); + // WGPU_EXPORT void wgpuAdapterRelease(WGPUAdapter adapter); +}; + +/// Tests of the given feature can be used to create devices on this adapter. +pub fn hasFeature(adapter: Adapter, feature: FeatureName) bool { + for (adapter.features) |f| { + if (f == feature) return true; + } + return false; +} + +// TODO: +// typedef struct WGPUAdapterProperties { +// WGPUChainedStructOut * nextInChain; +// uint32_t vendorID; +// uint32_t deviceID; +// char const * name; +// char const * driverDescription; +// WGPUAdapterType adapterType; +// WGPUBackendType backendType; +// } WGPUAdapterProperties; + +// TODO: +// typedef enum WGPUAdapterType { +// WGPUAdapterType_DiscreteGPU = 0x00000000, +// WGPUAdapterType_IntegratedGPU = 0x00000001, +// WGPUAdapterType_CPU = 0x00000002, +// WGPUAdapterType_Unknown = 0x00000003, +// WGPUAdapterType_Force32 = 0x7FFFFFFF +// } WGPUAdapterType; diff --git a/gpu/src/Device.zig b/gpu/src/Device.zig new file mode 100644 index 00000000..e4eff7fe --- /dev/null +++ b/gpu/src/Device.zig @@ -0,0 +1,12 @@ +//! A standard interface to a WebGPU implementation. +//! +//! Like std.mem.Allocator, but representing a WebGPU implementation. + +// The type erased pointer to the Device implementation +ptr: *anyopaque, +vtable: *const VTable, + +pub const VTable = struct { + // TODO(gpu): make these *const fn once stage2 is released. + free: fn (ptr: *anyopaque, buf: []u8, buf_align: u29, ret_addr: usize) void, +}; diff --git a/gpu/src/TODO b/gpu/src/TODO index b07ab172..8331f70f 100644 --- a/gpu/src/TODO +++ b/gpu/src/TODO @@ -9,7 +9,6 @@ typedef uint32_t WGPUFlags; -typedef struct WGPUAdapterImpl* WGPUAdapter; typedef struct WGPUBindGroupImpl* WGPUBindGroup; typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout; typedef struct WGPUBufferImpl* WGPUBuffer; @@ -34,14 +33,6 @@ typedef struct WGPUSwapChainImpl* WGPUSwapChain; typedef struct WGPUTextureImpl* WGPUTexture; typedef struct WGPUTextureViewImpl* WGPUTextureView; -typedef enum WGPUAdapterType { - WGPUAdapterType_DiscreteGPU = 0x00000000, - WGPUAdapterType_IntegratedGPU = 0x00000001, - WGPUAdapterType_CPU = 0x00000002, - WGPUAdapterType_Unknown = 0x00000003, - WGPUAdapterType_Force32 = 0x7FFFFFFF -} WGPUAdapterType; - typedef enum WGPUAddressMode { WGPUAddressMode_Repeat = 0x00000000, WGPUAddressMode_MirrorRepeat = 0x00000001, @@ -615,16 +606,6 @@ typedef struct WGPUChainedStructOut { WGPUSType sType; } WGPUChainedStructOut; -typedef struct WGPUAdapterProperties { - WGPUChainedStructOut * nextInChain; - uint32_t vendorID; - uint32_t deviceID; - char const * name; - char const * driverDescription; - WGPUAdapterType adapterType; - WGPUBackendType backendType; -} WGPUAdapterProperties; - typedef struct WGPUBindGroupEntry { WGPUChainedStruct const * nextInChain; uint32_t binding; @@ -762,35 +743,6 @@ typedef struct WGPUInstanceDescriptor { WGPUChainedStruct const * nextInChain; } WGPUInstanceDescriptor; -typedef struct WGPULimits { - uint32_t maxTextureDimension1D; - uint32_t maxTextureDimension2D; - uint32_t maxTextureDimension3D; - uint32_t maxTextureArrayLayers; - uint32_t maxBindGroups; - uint32_t maxDynamicUniformBuffersPerPipelineLayout; - uint32_t maxDynamicStorageBuffersPerPipelineLayout; - uint32_t maxSampledTexturesPerShaderStage; - uint32_t maxSamplersPerShaderStage; - uint32_t maxStorageBuffersPerShaderStage; - uint32_t maxStorageTexturesPerShaderStage; - uint32_t maxUniformBuffersPerShaderStage; - uint64_t maxUniformBufferBindingSize; - uint64_t maxStorageBufferBindingSize; - uint32_t minUniformBufferOffsetAlignment; - uint32_t minStorageBufferOffsetAlignment; - uint32_t maxVertexBuffers; - uint32_t maxVertexAttributes; - uint32_t maxVertexBufferArrayStride; - uint32_t maxInterStageShaderComponents; - uint32_t maxComputeWorkgroupStorageSize; - uint32_t maxComputeInvocationsPerWorkgroup; - uint32_t maxComputeWorkgroupSizeX; - uint32_t maxComputeWorkgroupSizeY; - uint32_t maxComputeWorkgroupSizeZ; - uint32_t maxComputeWorkgroupsPerDimension; -} WGPULimits; - typedef struct WGPUMultisampleState { WGPUChainedStruct const * nextInChain; uint32_t count; @@ -1092,11 +1044,6 @@ typedef struct WGPURequiredLimits { WGPULimits limits; } WGPURequiredLimits; -typedef struct WGPUSupportedLimits { - WGPUChainedStructOut * nextInChain; - WGPULimits limits; -} WGPUSupportedLimits; - typedef struct WGPUTextureDescriptor { WGPUChainedStruct const * nextInChain; char const * label; @@ -1221,16 +1168,6 @@ typedef void (*WGPURequestDeviceCallback)(WGPURequestDeviceStatus status, WGPUDe WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor); WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName); -// Methods of Adapter -WGPU_EXPORT WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor); -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); -WGPU_EXPORT bool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature); -WGPU_EXPORT void wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata); -WGPU_EXPORT void wgpuAdapterReference(WGPUAdapter adapter); -WGPU_EXPORT void wgpuAdapterRelease(WGPUAdapter adapter); - // Methods of BindGroup WGPU_EXPORT void wgpuBindGroupSetLabel(WGPUBindGroup bindGroup, char const * label); WGPU_EXPORT void wgpuBindGroupReference(WGPUBindGroup bindGroup); diff --git a/gpu/src/c.zig b/gpu/src/c.zig new file mode 100644 index 00000000..aa00631d --- /dev/null +++ b/gpu/src/c.zig @@ -0,0 +1,3 @@ +pub const c = @cImport({ + @cInclude("webgpu/webgpu.h"); +}); diff --git a/gpu/src/feature_name.zig b/gpu/src/feature_name.zig new file mode 100644 index 00000000..646b8ea2 --- /dev/null +++ b/gpu/src/feature_name.zig @@ -0,0 +1,21 @@ +pub const FeatureName = enum { + TODO, +}; +// TODO: +// typedef enum WGPUFeatureName { +// WGPUFeatureName_Undefined = 0x00000000, +// WGPUFeatureName_Depth24UnormStencil8 = 0x00000002, +// WGPUFeatureName_Depth32FloatStencil8 = 0x00000003, +// WGPUFeatureName_TimestampQuery = 0x00000004, +// WGPUFeatureName_PipelineStatisticsQuery = 0x00000005, +// WGPUFeatureName_TextureCompressionBC = 0x00000006, +// WGPUFeatureName_TextureCompressionETC2 = 0x00000007, +// WGPUFeatureName_TextureCompressionASTC = 0x00000008, +// WGPUFeatureName_IndirectFirstInstance = 0x00000009, +// WGPUFeatureName_DepthClamping = 0x000003E8, +// WGPUFeatureName_DawnShaderFloat16 = 0x000003E9, +// WGPUFeatureName_DawnInternalUsages = 0x000003EA, +// WGPUFeatureName_DawnMultiPlanarFormats = 0x000003EB, +// WGPUFeatureName_DawnNative = 0x000003EC, +// WGPUFeatureName_Force32 = 0x7FFFFFFF +// } WGPUFeatureName; diff --git a/gpu/src/main.zig b/gpu/src/main.zig index 66c72a83..20601d54 100644 --- a/gpu/src/main.zig +++ b/gpu/src/main.zig @@ -14,5 +14,20 @@ //! //! Note: WebGPU’s coordinate systems match DirectX’s coordinate systems in a graphics pipeline. //! -//! https://gpuweb.github.io/gpuweb +//! const std = @import("std"); +const Adapter = @import("Adapter.zig"); +const Device = @import("Device.zig"); + +const native = @import("native.zig").native; + +const FeatureName = @import("feature_name.zig").FeatureName; +const SupportedLimits = @import("supported_limits.zig").SupportedLimits; + +test "syntax" { + _ = Adapter; + _ = Device; + _ = native; + _ = FeatureName; + _ = SupportedLimits; +} diff --git a/gpu/src/native.zig b/gpu/src/native.zig new file mode 100644 index 00000000..3cac7de5 --- /dev/null +++ b/gpu/src/native.zig @@ -0,0 +1,16 @@ +//! A native webgpu.h based implementation of the Device interface. +const Device = @import("Device.zig"); + +/// Returns a native WebGPU implementation of the Device interface. +pub fn native() Device { + // TODO: implement Device interface + @panic("not implemented"); + + // TODO: implement Adapter interface: + // typedef struct WGPUAdapterImpl* WGPUAdapter; + // // Methods of Adapter + // WGPU_EXPORT size_t wgpuAdapterEnumerateFeatures(WGPUAdapter adapter, WGPUFeatureName * features); + // WGPU_EXPORT bool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature); + // WGPU_EXPORT bool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPUSupportedLimits * limits); + // WGPU_EXPORT void wgpuAdapterGetProperties(WGPUAdapter adapter, WGPUAdapterProperties * properties); +} diff --git a/gpu/src/supported_limits.zig b/gpu/src/supported_limits.zig new file mode 100644 index 00000000..9f67bcfd --- /dev/null +++ b/gpu/src/supported_limits.zig @@ -0,0 +1,34 @@ +pub const SupportedLimits = struct {}; +// TODO: +// typedef struct WGPUSupportedLimits { +// WGPUChainedStructOut * nextInChain; +// WGPULimits limits; +// } WGPUSupportedLimits; +// typedef struct WGPULimits { +// uint32_t maxTextureDimension1D; +// uint32_t maxTextureDimension2D; +// uint32_t maxTextureDimension3D; +// uint32_t maxTextureArrayLayers; +// uint32_t maxBindGroups; +// uint32_t maxDynamicUniformBuffersPerPipelineLayout; +// uint32_t maxDynamicStorageBuffersPerPipelineLayout; +// uint32_t maxSampledTexturesPerShaderStage; +// uint32_t maxSamplersPerShaderStage; +// uint32_t maxStorageBuffersPerShaderStage; +// uint32_t maxStorageTexturesPerShaderStage; +// uint32_t maxUniformBuffersPerShaderStage; +// uint64_t maxUniformBufferBindingSize; +// uint64_t maxStorageBufferBindingSize; +// uint32_t minUniformBufferOffsetAlignment; +// uint32_t minStorageBufferOffsetAlignment; +// uint32_t maxVertexBuffers; +// uint32_t maxVertexAttributes; +// uint32_t maxVertexBufferArrayStride; +// uint32_t maxInterStageShaderComponents; +// uint32_t maxComputeWorkgroupStorageSize; +// uint32_t maxComputeInvocationsPerWorkgroup; +// uint32_t maxComputeWorkgroupSizeX; +// uint32_t maxComputeWorkgroupSizeY; +// uint32_t maxComputeWorkgroupSizeZ; +// uint32_t maxComputeWorkgroupsPerDimension; +// } WGPULimits;