From 0d7222522969c53007e1fbdacffb8aa951ece3fe Mon Sep 17 00:00:00 2001 From: abux Date: Tue, 28 Jul 2026 22:37:49 +0200 Subject: [PATCH] Added Plugins [Platform, Window, Device] --- src/plugins/device/resource/wgpu_device.zig | 4 + src/plugins/device/root.zig | 32 ++++ src/plugins/device/system/lifetime.zig | 161 ++++++++++++++++++ .../platform/resource/wgpu_instance.zig | 3 + src/plugins/platform/root.zig | 64 +++++++ src/plugins/template/root.zig | 28 +++ src/plugins/window/root.zig | 28 +++ 7 files changed, 320 insertions(+) create mode 100644 src/plugins/device/resource/wgpu_device.zig create mode 100644 src/plugins/device/root.zig create mode 100644 src/plugins/device/system/lifetime.zig create mode 100644 src/plugins/platform/resource/wgpu_instance.zig create mode 100644 src/plugins/platform/root.zig create mode 100644 src/plugins/template/root.zig create mode 100644 src/plugins/window/root.zig diff --git a/src/plugins/device/resource/wgpu_device.zig b/src/plugins/device/resource/wgpu_device.zig new file mode 100644 index 0000000..de74769 --- /dev/null +++ b/src/plugins/device/resource/wgpu_device.zig @@ -0,0 +1,4 @@ +const wgpu = @import("wgpu"); + +raw: *wgpu.WGPUDeviceImpl, +queue: *wgpu.WGPUQueueImpl, diff --git a/src/plugins/device/root.zig b/src/plugins/device/root.zig new file mode 100644 index 0000000..1f00102 --- /dev/null +++ b/src/plugins/device/root.zig @@ -0,0 +1,32 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const App = @import("app"); +const lifetime = @import("system/lifetime.zig"); + +// +// PUBLIC +// + +pub const WGPUDevice = @import("resource/wgpu_device.zig"); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "Device", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + try app.schedules.add(App.stage.init, lifetime.init); + try app.schedules.add(App.stage.deinit, lifetime.deinit); +} diff --git a/src/plugins/device/system/lifetime.zig b/src/plugins/device/system/lifetime.zig new file mode 100644 index 0000000..bb2e011 --- /dev/null +++ b/src/plugins/device/system/lifetime.zig @@ -0,0 +1,161 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +const std = @import("std"); +const wgpu = @import("wgpu"); +const App = @import("app"); + +const WGPUInstance = @import("../../platform/resource/wgpu_instance.zig"); +const WGPUDevice = @import("../resource/wgpu_device.zig"); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +const AdapterUD = struct { + adapter: ?*wgpu.WGPUAdapterImpl = null, + ended: bool = false, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +const DeviceUD = struct { + device: ?*wgpu.WGPUDeviceImpl = null, + ended: bool = false, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn init(app: *App) !void { + // --- GET WGPU INSTANCE --- + const instance = app.resources.getPtr( + WGPUInstance, + ) orelse return error.WGPUInstanceNotSet; + + // + // ADAPTER + // + + // TODO: Mabe Mabe add other backends n stuff + var adapter_userdata: AdapterUD = .{}; + _ = wgpu.wgpuInstanceRequestAdapter( + instance.raw, + &wgpu.WGPURequestAdapterOptions{ + .backendType = wgpu.WGPUBackendType_Vulkan, + }, + wgpu.WGPURequestAdapterCallbackInfo{ + .callback = adapterCallback, + .userdata1 = &adapter_userdata, + }, + ); + + // --- ADAPTER --- + const adapter = if (adapter_userdata.adapter) |v| v else return error.NoAdapter; + defer wgpu.wgpuAdapterRelease(adapter); + + // + // DEVICE + // + + // --- REQUEST DEVICE --- + var device_userdata: DeviceUD = .{}; + _ = wgpu.wgpuAdapterRequestDevice( + adapter, + &wgpu.WGPUDeviceDescriptor{ + .label = .{ .data = "MainDevice", .length = wgpu.WGPU_STRLEN }, + .uncapturedErrorCallbackInfo = .{ + .callback = uncapturedErrorCallback, + }, + }, + .{ + .callback = deviceCallback, + .userdata1 = &device_userdata, + }, + ); + + // --- NEW WGPU DEVICE --- + try app.resources.set(WGPUDevice{ + .raw = device_userdata.device orelse return error.DeviceIsBeginRetarded, + .queue = wgpu.wgpuDeviceGetQueue( + device_userdata.device, + ) orelse return error.FailedToGetDeviceQueue, + }); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn deinit(app: *App) !void { + // --- # --- + const device = app.resources.getPtr( + WGPUDevice, + ) orelse return error.WGPUDeviceNotSet; + + // --- # --- + wgpu.wgpuQueueRelease(device.queue); + wgpu.wgpuDeviceRelease(device.raw); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn uncapturedErrorCallback( + _: [*c]const wgpu.WGPUDevice, + err_type: wgpu.WGPUErrorType, + message: wgpu.WGPUStringView, + _: ?*anyopaque, + _: ?*anyopaque, +) callconv(.c) void { + std.debug.print("[{s}] {s}\n", .{ + switch (err_type) { + wgpu.WGPUErrorType_Validation => "\x1b[33mVALIDATION\x1b[0m", + wgpu.WGPUErrorType_OutOfMemory => "\x1b[31mOUT_OF_MEMORY\x1b[0m", + else => "IDK", + }, + message.data, + }); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn adapterCallback( + status: wgpu.WGPURequestAdapterStatus, + adapter: wgpu.WGPUAdapter, + message: wgpu.WGPUStringView, + raw_userdata: ?*anyopaque, + _: ?*anyopaque, +) callconv(.c) void { + // --- USERDATA --- + const userdata: *AdapterUD = @ptrCast(@alignCast(raw_userdata)); + defer userdata.ended = true; + + // --- STATUS --- + switch (status) { + wgpu.WGPURequestAdapterStatus_Success => userdata.adapter = adapter, + else => { + std.debug.print("Failed to get WebGPU adapter: {s}\n", .{ + message.data, + }); + }, + } +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn deviceCallback( + status: wgpu.WGPURequestDeviceStatus, + device: wgpu.WGPUDevice, + message: wgpu.WGPUStringView, + raw_userdata: ?*anyopaque, + _: ?*anyopaque, +) callconv(.c) void { + // --- USERDATA --- + const userdata: *DeviceUD = @ptrCast(@alignCast(raw_userdata)); + defer userdata.ended = true; + + // --- STATUS --- + switch (status) { + wgpu.WGPURequestDeviceStatus_Success => userdata.device = device, + else => { + std.debug.print("Failed to get WebGPU adapter: {s}\n", .{ + message.data, + }); + }, + } +} diff --git a/src/plugins/platform/resource/wgpu_instance.zig b/src/plugins/platform/resource/wgpu_instance.zig new file mode 100644 index 0000000..d9f6e23 --- /dev/null +++ b/src/plugins/platform/resource/wgpu_instance.zig @@ -0,0 +1,3 @@ +const wgpu = @import("wgpu"); + +raw: *wgpu.WGPUInstanceImpl, diff --git a/src/plugins/platform/root.zig b/src/plugins/platform/root.zig new file mode 100644 index 0000000..53b6639 --- /dev/null +++ b/src/plugins/platform/root.zig @@ -0,0 +1,64 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const std = @import("std"); +const sdl = @import("sdl"); +const wgpu = @import("wgpu"); +const App = @import("app"); + +// +// PUBLIC +// + +pub const WGPUInstance = @import("resource/wgpu_instance.zig"); + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "Platform", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + try app.schedules.add(App.stage.init, init); + try app.schedules.add(App.stage.deinit, deinit); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn init(app: *App) !void { + // --- SDL3 INIT --- + if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) { + std.debug.print("[SDL_ERROR] SDL_Init: {s}\n", .{sdl.SDL_GetError()}); + return error.SDL_INIT; + } + + // --- WGPU INIT --- + try app.resources.set(WGPUInstance{ + .raw = wgpu.wgpuCreateInstance(&wgpu.WGPUInstanceDescriptor{}) orelse return { + return error.WGPU_Init; + }, + }); +} + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub fn deinit(app: *App) !void { + // --- # --- + const res = try app.resources.getMany(struct { + instance: *WGPUInstance, + }); + + // --- # --- + wgpu.wgpuInstanceRelease(res.instance.raw); + sdl.SDL_Quit(); +} diff --git a/src/plugins/template/root.zig b/src/plugins/template/root.zig new file mode 100644 index 0000000..8c9d392 --- /dev/null +++ b/src/plugins/template/root.zig @@ -0,0 +1,28 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const App = @import("app"); + +// +// PUBLIC +// + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "Template", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + _ = app; +} diff --git a/src/plugins/window/root.zig b/src/plugins/window/root.zig new file mode 100644 index 0000000..de05945 --- /dev/null +++ b/src/plugins/window/root.zig @@ -0,0 +1,28 @@ +//! ---------------------------------------------------- +//! ---------------------------------------------------- + +// +// PRIVATE +// + +const App = @import("app"); + +// +// PUBLIC +// + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +pub const plugin: App.plugin.Plugin = .{ + .name = "Window", + .build = build, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn build( + _: *App.plugin.Plugin, + app: *App, +) !void { + _ = app; +}