Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
24 changes: 12 additions & 12 deletions src/wgpu.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
45 changes: 24 additions & 21 deletions src/zgpu.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The buffer is left uninitialized (undefined). While this works with FixedBufferAllocator, it's better practice to initialize it with .{} for clarity and to avoid potential issues with future Zig versions that may have stricter safety checks.

Suggested change
var buffer: [32]wgpu.CommandBuffer = undefined;
var buffer: [32]wgpu.CommandBuffer = .{};

Copilot uses AI. Check for mistakes.
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) {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1762,29 +1765,29 @@ 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,
args_meta[0].type,
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"),
};

Expand All @@ -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}),
Expand Down Expand Up @@ -1855,14 +1858,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 {};
}
Loading