137 lines
5.8 KiB
Zig
137 lines
5.8 KiB
Zig
//! A native webgpu.h implementation of the gpu.Interface
|
|
const c = @import("c.zig").c;
|
|
const Interface = @import("Interface.zig");
|
|
const Surface = @import("Surface.zig");
|
|
|
|
const NativeInstance = @This();
|
|
|
|
/// The WGPUInstance that is wrapped by this native instance.
|
|
instance: c.WGPUInstance,
|
|
|
|
/// Wraps a native WGPUInstance to provide an implementation of the gpu.Interface.
|
|
pub fn wrap(instance: *anyopaque) NativeInstance {
|
|
return .{ .instance = @ptrCast(c.WGPUInstance, instance) };
|
|
}
|
|
|
|
const interface_vtable = Interface.VTable{
|
|
.reference = (struct {
|
|
pub fn reference(ptr: *anyopaque) void {
|
|
const native = @ptrCast(*NativeInstance, @alignCast(@alignOf(*NativeInstance), ptr));
|
|
c.wgpuInstanceReference(native.instance);
|
|
}
|
|
}).reference,
|
|
.release = (struct {
|
|
pub fn release(ptr: *anyopaque) void {
|
|
const native = @ptrCast(*NativeInstance, @alignCast(@alignOf(*NativeInstance), ptr));
|
|
c.wgpuInstanceRelease(native.instance);
|
|
}
|
|
}).release,
|
|
};
|
|
|
|
/// Returns the gpu.Interface for interacting with this native instance.
|
|
pub fn interface(native: *NativeInstance) Interface {
|
|
return .{
|
|
.ptr = native,
|
|
.vtable = &interface_vtable,
|
|
};
|
|
// TODO: implement Device interface
|
|
|
|
// 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);
|
|
}
|
|
|
|
pub fn createSurface(native: *const NativeInstance, descriptor: *const Surface.Descriptor) Surface {
|
|
const surface = switch (descriptor.*) {
|
|
.metal_layer => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromMetalLayer = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromMetalLayer;
|
|
desc.layer = src.layer;
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
.windows_hwnd => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromWindowsHWND = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsHWND;
|
|
desc.hinstance = src.hinstance;
|
|
desc.hwnd = src.hwnd;
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
.windows_core_window => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromWindowsCoreWindow = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsCoreWindow;
|
|
desc.coreWindow = src.core_window;
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
.windows_swap_chain_panel => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromWindowsSwapChainPanel = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsSwapChainPanel;
|
|
desc.swapChainPanel = src.swap_chain_panel;
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
.xlib_window => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromXlibWindow = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromXlibWindow;
|
|
desc.display = src.display;
|
|
desc.window = src.window;
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
.canvas_html_selector => |src| blk: {
|
|
var desc: c.WGPUSurfaceDescriptorFromCanvasHTMLSelector = undefined;
|
|
desc.chain.next = null;
|
|
desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
|
|
desc.selector = @ptrCast([*c]const u8, src.selector);
|
|
break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{
|
|
.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc),
|
|
.label = if (src.label) |l| @ptrCast([*c]const u8, l) else null,
|
|
});
|
|
},
|
|
};
|
|
|
|
return Surface{
|
|
.ptr = surface.?,
|
|
.vtable = &surface_vtable,
|
|
};
|
|
}
|
|
|
|
const surface_vtable = Surface.VTable{
|
|
.reference = (struct {
|
|
pub fn reference(ptr: *anyopaque) void {
|
|
c.wgpuSurfaceReference(@ptrCast(c.WGPUSurface, ptr));
|
|
}
|
|
}).reference,
|
|
.release = (struct {
|
|
pub fn release(ptr: *anyopaque) void {
|
|
c.wgpuSurfaceRelease(@ptrCast(c.WGPUSurface, ptr));
|
|
}
|
|
}).release,
|
|
};
|
|
|
|
test "syntax" {
|
|
_ = wrap;
|
|
_ = interface;
|
|
_ = createSurface;
|
|
}
|