From dd220eab31ebcdcf63fba11cd005c935e16b5984 Mon Sep 17 00:00:00 2001 From: Logickin-Lambda Date: Tue, 9 Sep 2025 21:36:30 +0800 Subject: [PATCH 1/4] - Updated to zig 0.15.0 The library has syntax updated to the lastest zig version; however, because of the usingnamespace update, this might requires people who use emscripten to confirm the validity of the new implementation. --- src/wgpu.zig | 24 ++++++++++++------------ src/zgpu.zig | 10 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/wgpu.zig b/src/wgpu.zig index 7bf50e2..02663ef 100644 --- a/src/wgpu.zig +++ b/src/wgpu.zig @@ -1273,62 +1273,62 @@ pub const CreateComputePipelineAsyncCallback = *const fn ( pipeline: ComputePipeline, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const CreateRenderPipelineAsyncCallback = *const fn ( status: CreatePipelineAsyncStatus, pipeline: RenderPipeline, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const ErrorCallback = *const fn ( err_type: ErrorType, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const LoggingCallback = *const fn ( log_type: LoggingType, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const DeviceLostCallback = *const fn ( reason: DeviceLostReason, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const RequestAdapterCallback = *const fn ( status: RequestAdapterStatus, adapter: Adapter, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const RequestDeviceCallback = *const fn ( status: RequestDeviceStatus, device: Device, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const BufferMapCallback = *const fn ( status: BufferMapAsyncStatus, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const QueueWorkDoneCallback = *const fn ( status: QueueWorkDoneStatus, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const CompilationInfoCallback = *const fn ( status: CompilationInfoRequestStatus, info: *const CompilationInfo, userdata: ?*anyopaque, -) callconv(.C) void; +) callconv(.c) void; pub const Adapter = *opaque { pub fn createDevice(adapter: Adapter, descriptor: DeviceDescriptor) Device { @@ -2238,7 +2238,7 @@ pub const Queue = *opaque { queue: Queue, callback: QueueWorkDoneCallback, userdata: ?*anyopaque, - ) callconv(.C) void, + ) callconv(.c) void, .{ .name = "wgpuQueueOnSubmittedWorkDone" }, ); oswd(queue, callback, userdata); @@ -2249,7 +2249,7 @@ pub const Queue = *opaque { signal_value: u64, callback: QueueWorkDoneCallback, userdata: ?*anyopaque, - ) callconv(.C) void, + ) callconv(.c) void, .{ .name = "wgpuQueueOnSubmittedWorkDone" }, ); oswd(queue, signal_value, callback, userdata); diff --git a/src/zgpu.zig b/src/zgpu.zig index 52156a0..85dad03 100644 --- a/src/zgpu.zig +++ b/src/zgpu.zig @@ -1855,14 +1855,14 @@ fn formatToShaderFormat(format: wgpu.TextureFormat) []const u8 { }; } -usingnamespace if (emscripten) struct { - // Missing symbols - var wgpuDeviceTickWarnPrinted: bool = false; - pub export fn wgpuDeviceTick() void { +var wgpuDeviceTickWarnPrinted: bool = false; + +pub fn wgpuDeviceTick() void { + if (emscripten) { if (!wgpuDeviceTickWarnPrinted) { std.log.warn("wgpuDeviceTick(): this fn should be avoided! RequestAnimationFrame() is advised for smooth rendering in browser.", .{}); wgpuDeviceTickWarnPrinted = true; } emscripten_sleep(1); } -} else struct {}; +} From f0e492b5c23b64bc759f2bd6db94563e3b329217 Mon Sep 17 00:00:00 2001 From: Logickin-Lambda Date: Tue, 9 Sep 2025 22:32:29 +0800 Subject: [PATCH 2/4] - Replace BoundedArray with std.ArrayList Suggested by https://ziglang.org/download/0.15.1/release-notes.html#Removal-of-BoundedArray, since std.BoundedArray is removed, the alternative is to use std.ArrayListUnmanaged; however, this type is also soon to be removed, in favor of std.ArrayList, but since this type require an allocator for appending the items; because the array is bounded, I decided to use a fixed buffer, with creating a fixedBufferAllocator for the arraylist. --- build.zig.zon | 2 +- src/zgpu.zig | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 1d3bf42..8a02cac 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .zgpu, .fingerprint = 0x670ebe04e453a19e, .version = "0.12.0-dev", - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.15.1", .paths = .{ "build.zig", "build.zig.zon", diff --git a/src/zgpu.zig b/src/zgpu.zig index 85dad03..c25b988 100644 --- a/src/zgpu.zig +++ b/src/zgpu.zig @@ -138,7 +138,7 @@ pub const GraphicsContext = struct { adapter: wgpu.Adapter, message: ?[*:0]const u8, userdata: ?*anyopaque, - ) callconv(.C) void { + ) callconv(.c) void { _ = message; const response = @as(*Response, @ptrCast(@alignCast(userdata))); response.status = status; @@ -197,7 +197,7 @@ pub const GraphicsContext = struct { device: wgpu.Device, message: ?[*:0]const u8, userdata: ?*anyopaque, - ) callconv(.C) void { + ) callconv(.c) void { _ = message; const response = @as(*Response, @ptrCast(@alignCast(userdata))); response.status = status; @@ -374,7 +374,7 @@ pub const GraphicsContext = struct { gctx.uniformsNextStagingBuffer(); } - fn uniformsMappedCallback(status: wgpu.BufferMapAsyncStatus, userdata: ?*anyopaque) callconv(.C) void { + fn uniformsMappedCallback(status: wgpu.BufferMapAsyncStatus, userdata: ?*anyopaque) callconv(.c) void { const usb = @as(*UniformsStagingBuffer, @ptrCast(@alignCast(userdata))); assert(usb.slice == null); if (status == .success) { @@ -471,19 +471,22 @@ pub const GraphicsContext = struct { defer stage_commands.release(); // TODO: We support up to 32 command buffers for now. Make it more robust. - var command_buffers = std.BoundedArray(wgpu.CommandBuffer, 32).init(0) catch unreachable; - command_buffers.append(stage_commands) catch unreachable; - command_buffers.appendSlice(commands) catch unreachable; + var buffer: [32]wgpu.CommandBuffer = undefined; + var fb_allocator = std.heap.FixedBufferAllocator.init(@ptrCast(&buffer)); + + var command_buffers = std.ArrayList(wgpu.CommandBuffer).initCapacity(fb_allocator.allocator(), 32) catch unreachable; + command_buffers.append(fb_allocator.allocator(), stage_commands) catch unreachable; + command_buffers.appendSlice(fb_allocator.allocator(), commands) catch unreachable; gctx.queue.onSubmittedWorkDone(0, gpuWorkDone, @ptrCast(&gctx.stats.gpu_frame_number)); - gctx.queue.submit(command_buffers.slice()); + gctx.queue.submit(command_buffers.items); gctx.stats.tick(gctx.window_provider.getTime()); gctx.uniformsNextStagingBuffer(); } - fn gpuWorkDone(status: wgpu.QueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void { + fn gpuWorkDone(status: wgpu.QueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.c) void { const gpu_frame_number: *u64 = @ptrCast(@alignCast(userdata)); gpu_frame_number.* += 1; if (status != .success) { @@ -632,7 +635,7 @@ pub const GraphicsContext = struct { pipeline: wgpu.RenderPipeline, message: ?[*:0]const u8, userdata: ?*anyopaque, - ) callconv(.C) void { + ) callconv(.c) void { const op = @as(*AsyncCreateOpRender, @ptrCast(@alignCast(userdata))); if (status == .success) { op.result.* = op.gctx.render_pipeline_pool.addResource( @@ -693,7 +696,7 @@ pub const GraphicsContext = struct { pipeline: wgpu.ComputePipeline, message: ?[*:0]const u8, userdata: ?*anyopaque, - ) callconv(.C) void { + ) callconv(.c) void { const op = @as(*AsyncCreateOpCompute, @ptrCast(@alignCast(userdata))); if (status == .success) { op.result.* = op.gctx.compute_pipeline_pool.addResource( @@ -1762,21 +1765,21 @@ fn msgSend(obj: anytype, sel_name: [:0]const u8, args: anytype, comptime ReturnT const args_meta = @typeInfo(@TypeOf(args)).@"struct".fields; const FnType = switch (args_meta.len) { - 0 => *const fn (@TypeOf(obj), objc.SEL) callconv(.C) ReturnType, - 1 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].type) callconv(.C) ReturnType, + 0 => *const fn (@TypeOf(obj), objc.SEL) callconv(.c) ReturnType, + 1 => *const fn (@TypeOf(obj), objc.SEL, args_meta[0].type) callconv(.c) ReturnType, 2 => *const fn ( @TypeOf(obj), objc.SEL, args_meta[0].type, args_meta[1].type, - ) callconv(.C) ReturnType, + ) callconv(.c) ReturnType, 3 => *const fn ( @TypeOf(obj), objc.SEL, args_meta[0].type, args_meta[1].type, args_meta[2].type, - ) callconv(.C) ReturnType, + ) callconv(.c) ReturnType, 4 => *const fn ( @TypeOf(obj), objc.SEL, @@ -1784,7 +1787,7 @@ fn msgSend(obj: anytype, sel_name: [:0]const u8, args: anytype, comptime ReturnT args_meta[1].type, args_meta[2].type, args_meta[3].type, - ) callconv(.C) ReturnType, + ) callconv(.c) ReturnType, else => @compileError("[zgpu] Unsupported number of args"), }; @@ -1798,7 +1801,7 @@ fn logUnhandledError( err_type: wgpu.ErrorType, message: ?[*:0]const u8, userdata: ?*anyopaque, -) callconv(.C) void { +) callconv(.c) void { _ = userdata; switch (err_type) { .no_error => std.log.info("[zgpu] No error: {?s}", .{message}), From 2048a530c302370dc05f965a0f55f7dea22c22f8 Mon Sep 17 00:00:00 2001 From: Logickin-Lambda Date: Sat, 20 Sep 2025 09:44:17 +0800 Subject: [PATCH 3/4] - Fixed Linux Build Error Suggested by @Erdragh, seems like setting the linkage for the dawn library could fix the linux build problem, and not impacted to other platform because running a testing triangle shader program with zgpu on windows still works without any issue. Let's see if this version could pass. --- build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/build.zig b/build.zig index 18586dd..982f428 100644 --- a/build.zig +++ b/build.zig @@ -112,6 +112,7 @@ pub fn build(b: *std.Build) void { const zdawn = b.addLibrary(.{ .name = "zdawn", + .linkage = .dynamic, .root_module = b.createModule(.{ .target = target, .optimize = optimize, From 31707a410b282568f99dff8e9ebce9d00425416f Mon Sep 17 00:00:00 2001 From: Logickin-Lambda Date: Fri, 17 Oct 2025 09:33:52 +0800 Subject: [PATCH 4/4] Adopted @tristanpemble Suggested Fix Due to the agreement to use llvm as a fix for the linux and potentially for the Mac, I have replaced the dynamic linkage with using llvm instead. On Windows, it compile fine, passed the test, and it works without any issues on my toy project that uses zgpu; however, futher testing is required to ensure linux and mac version of the library in working state. --- build.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 982f428..99287a6 100644 --- a/build.zig +++ b/build.zig @@ -112,7 +112,7 @@ pub fn build(b: *std.Build) void { const zdawn = b.addLibrary(.{ .name = "zdawn", - .linkage = .dynamic, + .use_llvm = true, .root_module = b.createModule(.{ .target = target, .optimize = optimize, @@ -144,6 +144,7 @@ pub fn build(b: *std.Build) void { const tests = b.addTest(.{ .name = "zgpu-tests", + .use_llvm = true, .root_module = b.createModule(.{ .root_source_file = b.path("src/zgpu.zig"), .target = target,