From 6a6510597562f47ce84c4c579e56ff8c8f17c164 Mon Sep 17 00:00:00 2001 From: TotoShampoin Date: Sat, 5 Jul 2025 16:48:41 +0200 Subject: [PATCH 1/3] Implement toWGPU() method for structs in adapter.zig and device.zig --- src/adapter.zig | 56 ++++++++++++++++++++++++++++++++---------------- src/device.zig | 22 +++++++++++++++++++ src/instance.zig | 5 +++-- 3 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/adapter.zig b/src/adapter.zig index 6dbc9bc..dace752 100644 --- a/src/adapter.zig +++ b/src/adapter.zig @@ -72,6 +72,42 @@ pub const RequestAdapterOptions = extern struct { power_preference: PowerPreference = PowerPreference.@"undefined", + // If true, requires the adapter to be a "fallback" adapter as defined by the JS spec. + // If this is not possible, the request returns null. + force_fallback_adapter: bool = false, + + // If set, requires the adapter to have a particular backend type. + // If this is not possible, the request returns null. + backend_type: BackendType = BackendType.@"undefined", + + // If set, requires the adapter to be able to output to a particular surface. + // If this is not possible, the request returns null. + compatible_surface: ?*Surface = null, + + pub fn toWGPU(self: RequestAdapterOptions) WGPURequestAdapterOptions { + return WGPURequestAdapterOptions{ + .next_in_chain = self.next_in_chain, + .feature_level = self.feature_level, + .power_preference = self.power_preference, + .force_fallback_adapter = @intFromBool(self.force_fallback_adapter), + .backend_type = self.backend_type, + .compatible_surface = self.compatible_surface, + }; + } +}; + +pub const WGPURequestAdapterOptions = extern struct { + next_in_chain: ?*const ChainedStruct = null, + + // "Feature level" for the adapter request. If an adapter is returned, + // it must support the features and limits in the requested feature level. + // + // Implementations may ignore FeatureLevel.compatibility and provide FeatureLevel.core instead. + // FeatureLevel.core is the default in the JS API, but in C, this field is **required** (must not be undefined). + feature_level: FeatureLevel = FeatureLevel.core, + + power_preference: PowerPreference = PowerPreference.@"undefined", + // If true, requires the adapter to be a "fallback" adapter as defined by the JS spec. // If this is not possible, the request returns null. force_fallback_adapter: WGPUBool = @intFromBool(false), @@ -284,25 +320,7 @@ pub const Adapter = opaque{ }; if(descriptor) |d| { - var device_extras: ?*const ChainedStruct = undefined; - if(d.native_extras) |native_extras| { - device_extras = @ptrCast(&WGPUDeviceExtras { - .trace_path = .fromSlice(native_extras.trace_path), - }); - } else { - device_extras = null; - } - - return wgpuAdapterRequestDevice(self, &WGPUDeviceDescriptor{ - .next_in_chain = device_extras, - .label = .fromSlice(d.label), - .required_feature_count = d.required_features.len, - .required_features = d.required_features.ptr, - .required_limits = if(d.required_limits) |l| &l else null, - .default_queue = d.default_queue, - .device_lost_callback_info = d.device_lost_callback_info, - .uncaptured_error_callback_info = d.uncaptured_error_callback_info, - }, callback_info); + return wgpuAdapterRequestDevice(self, &d.toWGPU(), callback_info); } else { return wgpuAdapterRequestDevice(self, null, callback_info); } diff --git a/src/device.zig b/src/device.zig index a88d1b5..abb9bdd 100644 --- a/src/device.zig +++ b/src/device.zig @@ -147,6 +147,28 @@ pub const DeviceDescriptor = struct { device_lost_callback_info: DeviceLostCallbackInfo = DeviceLostCallbackInfo {}, uncaptured_error_callback_info: UncapturedErrorCallbackInfo = UncapturedErrorCallbackInfo{}, native_extras: ?DeviceExtras = null, + + pub fn toWGPU(self: DeviceDescriptor) WGPUDeviceDescriptor { + var device_extras: ?*const ChainedStruct = undefined; + if(self.native_extras) |native_extras| { + device_extras = @ptrCast(&WGPUDeviceExtras { + .trace_path = .fromSlice(native_extras.trace_path), + }); + } else { + device_extras = null; + } + + return WGPUDeviceDescriptor { + .next_in_chain = device_extras, + .label = .fromSlice(self.label), + .required_feature_count = self.required_features.len, + .required_features = self.required_features.ptr, + .required_limits = if(self.required_limits) |l| &l else null, + .default_queue = self.default_queue, + .device_lost_callback_info = self.device_lost_callback_info, + .uncaptured_error_callback_info = self.uncaptured_error_callback_info, + }; + } }; pub const WGPUDeviceDescriptor = extern struct { diff --git a/src/instance.zig b/src/instance.zig index cf4d51c..8fd26a6 100644 --- a/src/instance.zig +++ b/src/instance.zig @@ -8,6 +8,7 @@ const SType = _chained_struct.SType; const _adapter = @import("adapter.zig"); const Adapter = _adapter.Adapter; const RequestAdapterOptions = _adapter.RequestAdapterOptions; +const WGPURequestAdapterOptions = _adapter.WGPURequestAdapterOptions; const RequestAdapterCallbackInfo = _adapter.RequestAdapterCallbackInfo; const RequestAdapterCallback = _adapter.RequestAdapterCallback; const RequestAdapterError = _adapter.RequestAdapterError; @@ -213,7 +214,7 @@ extern fn wgpuInstanceCreateSurface(instance: *Instance, descriptor: *const Surf extern fn wgpuInstanceGetWGSLLanguageFeatures(instance: *Instance, features: *WGPUSupportedWGSLLanguageFeatures) Status; extern fn wgpuInstanceHasWGSLLanguageFeature(instance: *Instance, feature: WGSLLanguageFeatureName) WGPUBool; extern fn wgpuInstanceProcessEvents(instance: *Instance) void; -extern fn wgpuInstanceRequestAdapter(instance: *Instance, options: ?*const RequestAdapterOptions, callback_info: RequestAdapterCallbackInfo) Future; +extern fn wgpuInstanceRequestAdapter(instance: *Instance, options: ?*const WGPURequestAdapterOptions, callback_info: RequestAdapterCallbackInfo) Future; extern fn wgpuInstanceWaitAny(instance: *Instance, future_count: usize, futures: ?[*] FutureWaitInfo, timeout_ns: u64) WaitStatus; extern fn wgpuInstanceAddRef(instance: *Instance) void; extern fn wgpuInstanceRelease(instance: *Instance) void; @@ -363,7 +364,7 @@ pub const Instance = opaque { .userdata2 = @constCast(@ptrCast(callback)), }; if (options) |o| { - return wgpuInstanceRequestAdapter(self, &o, callback_info); + return wgpuInstanceRequestAdapter(self, &o.toWGPU(), callback_info); } else { return wgpuInstanceRequestAdapter(self, null, callback_info); } From b4ad365ceffe0b0ca663bf99799460849c817962 Mon Sep 17 00:00:00 2001 From: TotoShampoin Date: Sat, 5 Jul 2025 17:09:10 +0200 Subject: [PATCH 2/3] Implement toWGPU() method for structs in adapter.zig --- src/adapter.zig | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/instance.zig | 5 +++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/adapter.zig b/src/adapter.zig index 6dbc9bc..2398780 100644 --- a/src/adapter.zig +++ b/src/adapter.zig @@ -72,6 +72,42 @@ pub const RequestAdapterOptions = extern struct { power_preference: PowerPreference = PowerPreference.@"undefined", + // If true, requires the adapter to be a "fallback" adapter as defined by the JS spec. + // If this is not possible, the request returns null. + force_fallback_adapter: bool = false, + + // If set, requires the adapter to have a particular backend type. + // If this is not possible, the request returns null. + backend_type: BackendType = BackendType.@"undefined", + + // If set, requires the adapter to be able to output to a particular surface. + // If this is not possible, the request returns null. + compatible_surface: ?*Surface = null, + + pub fn toWGPU(self: RequestAdapterOptions) WGPURequestAdapterOptions { + return WGPURequestAdapterOptions{ + .next_in_chain = self.next_in_chain, + .feature_level = self.feature_level, + .power_preference = self.power_preference, + .force_fallback_adapter = @intFromBool(self.force_fallback_adapter), + .backend_type = self.backend_type, + .compatible_surface = self.compatible_surface, + }; + } +}; + +pub const WGPURequestAdapterOptions = extern struct { + next_in_chain: ?*const ChainedStruct = null, + + // "Feature level" for the adapter request. If an adapter is returned, + // it must support the features and limits in the requested feature level. + // + // Implementations may ignore FeatureLevel.compatibility and provide FeatureLevel.core instead. + // FeatureLevel.core is the default in the JS API, but in C, this field is **required** (must not be undefined). + feature_level: FeatureLevel = FeatureLevel.core, + + power_preference: PowerPreference = PowerPreference.@"undefined", + // If true, requires the adapter to be a "fallback" adapter as defined by the JS spec. // If this is not possible, the request returns null. force_fallback_adapter: WGPUBool = @intFromBool(false), @@ -83,6 +119,17 @@ pub const RequestAdapterOptions = extern struct { // If set, requires the adapter to be able to output to a particular surface. // If this is not possible, the request returns null. compatible_surface: ?*Surface = null, + + pub fn toRequestAdapterOptions(self: WGPURequestAdapterOptions) RequestAdapterOptions { + return RequestAdapterOptions{ + .next_in_chain = self.next_in_chain, + .feature_level = self.feature_level, + .power_preference = self.power_preference, + .force_fallback_adapter = self.force_fallback_adapter != 0, + .backend_type = self.backend_type, + .compatible_surface = self.compatible_surface, + }; + } }; const RequestAdapterStatus = enum(u32) { diff --git a/src/instance.zig b/src/instance.zig index cf4d51c..8fd26a6 100644 --- a/src/instance.zig +++ b/src/instance.zig @@ -8,6 +8,7 @@ const SType = _chained_struct.SType; const _adapter = @import("adapter.zig"); const Adapter = _adapter.Adapter; const RequestAdapterOptions = _adapter.RequestAdapterOptions; +const WGPURequestAdapterOptions = _adapter.WGPURequestAdapterOptions; const RequestAdapterCallbackInfo = _adapter.RequestAdapterCallbackInfo; const RequestAdapterCallback = _adapter.RequestAdapterCallback; const RequestAdapterError = _adapter.RequestAdapterError; @@ -213,7 +214,7 @@ extern fn wgpuInstanceCreateSurface(instance: *Instance, descriptor: *const Surf extern fn wgpuInstanceGetWGSLLanguageFeatures(instance: *Instance, features: *WGPUSupportedWGSLLanguageFeatures) Status; extern fn wgpuInstanceHasWGSLLanguageFeature(instance: *Instance, feature: WGSLLanguageFeatureName) WGPUBool; extern fn wgpuInstanceProcessEvents(instance: *Instance) void; -extern fn wgpuInstanceRequestAdapter(instance: *Instance, options: ?*const RequestAdapterOptions, callback_info: RequestAdapterCallbackInfo) Future; +extern fn wgpuInstanceRequestAdapter(instance: *Instance, options: ?*const WGPURequestAdapterOptions, callback_info: RequestAdapterCallbackInfo) Future; extern fn wgpuInstanceWaitAny(instance: *Instance, future_count: usize, futures: ?[*] FutureWaitInfo, timeout_ns: u64) WaitStatus; extern fn wgpuInstanceAddRef(instance: *Instance) void; extern fn wgpuInstanceRelease(instance: *Instance) void; @@ -363,7 +364,7 @@ pub const Instance = opaque { .userdata2 = @constCast(@ptrCast(callback)), }; if (options) |o| { - return wgpuInstanceRequestAdapter(self, &o, callback_info); + return wgpuInstanceRequestAdapter(self, &o.toWGPU(), callback_info); } else { return wgpuInstanceRequestAdapter(self, null, callback_info); } From c05d469aea583146d686deb6b870ceb8d0b27a67 Mon Sep 17 00:00:00 2001 From: TotoShampoin Date: Sat, 5 Jul 2025 17:15:21 +0200 Subject: [PATCH 3/3] Implement toWGPU() method for structs in device.zig --- src/adapter.zig | 20 +------------------- src/device.zig | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/adapter.zig b/src/adapter.zig index 2398780..e114ee3 100644 --- a/src/adapter.zig +++ b/src/adapter.zig @@ -331,25 +331,7 @@ pub const Adapter = opaque{ }; if(descriptor) |d| { - var device_extras: ?*const ChainedStruct = undefined; - if(d.native_extras) |native_extras| { - device_extras = @ptrCast(&WGPUDeviceExtras { - .trace_path = .fromSlice(native_extras.trace_path), - }); - } else { - device_extras = null; - } - - return wgpuAdapterRequestDevice(self, &WGPUDeviceDescriptor{ - .next_in_chain = device_extras, - .label = .fromSlice(d.label), - .required_feature_count = d.required_features.len, - .required_features = d.required_features.ptr, - .required_limits = if(d.required_limits) |l| &l else null, - .default_queue = d.default_queue, - .device_lost_callback_info = d.device_lost_callback_info, - .uncaptured_error_callback_info = d.uncaptured_error_callback_info, - }, callback_info); + return wgpuAdapterRequestDevice(self, &d.toWGPU(), callback_info); } else { return wgpuAdapterRequestDevice(self, null, callback_info); } diff --git a/src/device.zig b/src/device.zig index a88d1b5..e573610 100644 --- a/src/device.zig +++ b/src/device.zig @@ -147,6 +147,28 @@ pub const DeviceDescriptor = struct { device_lost_callback_info: DeviceLostCallbackInfo = DeviceLostCallbackInfo {}, uncaptured_error_callback_info: UncapturedErrorCallbackInfo = UncapturedErrorCallbackInfo{}, native_extras: ?DeviceExtras = null, + + pub fn toWGPU(self: DeviceDescriptor) WGPUDeviceDescriptor { + var device_extras: ?*const ChainedStruct = undefined; + if(self.native_extras) |native_extras| { + device_extras = @ptrCast(&WGPUDeviceExtras { + .trace_path = .fromSlice(native_extras.trace_path), + }); + } else { + device_extras = null; + } + + return WGPUDeviceDescriptor { + .next_in_chain = device_extras, + .label = .fromSlice(self.label), + .required_feature_count = self.required_features.len, + .required_features = self.required_features.ptr, + .required_limits = if(self.required_limits) |l| &l else null, + .default_queue = self.default_queue, + .device_lost_callback_info = self.device_lost_callback_info, + .uncaptured_error_callback_info = self.uncaptured_error_callback_info, + }; + } }; pub const WGPUDeviceDescriptor = extern struct { @@ -158,6 +180,24 @@ pub const WGPUDeviceDescriptor = extern struct { default_queue: QueueDescriptor = QueueDescriptor{}, device_lost_callback_info: DeviceLostCallbackInfo = DeviceLostCallbackInfo {}, uncaptured_error_callback_info: UncapturedErrorCallbackInfo = UncapturedErrorCallbackInfo{}, + + pub fn toDeviceDescriptor(self: WGPUDeviceDescriptor) DeviceDescriptor { + var device_extras: ?*const WGPUDeviceExtras = null; + if(self.next_in_chain) |n| { + device_extras = @ptrCast(n); + } + + return DeviceDescriptor{ + .label = self.label, + .required_feature_count = self.required_feature_count, + .required_features = self.required_features, + .required_limits = self.required_limits, + .default_queue = self.default_queue, + .device_lost_callback_info = self.device_lost_callback_info, + .uncaptured_error_callback_info = self.uncaptured_error_callback_info, + .native_extras = if(device_extras) |d| d.trace_path.toSlice() else null, + }; + } }; const RequestDeviceStatus = enum(u32) {