Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.zig-cache/
zig-cache/
zig-out/
zig-pkg/
examples/output/
NOTES.md
NOTES.md
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ b.getInstallStep().dependOn(&install_dll.step);
message: StringView,
userdata1: ?*anyopaque,
userdata2: ?*anyopaque
) callconv(.C) void {
) callconv(.c) void {
switch(status) {
.success => {
const ud_adapter: **Adapter = @ptrCast(@alignCast(userdata1));
Expand Down Expand Up @@ -148,14 +148,14 @@ b.getInstallStep().dependOn(&install_dll.step);

instance.processEvents();
while(!completed) {
std.Thread.sleep(200_000_000);
io.sleep(std.Io.Duration.fromMilliseconds(200), std.Io.Clock.cpu_thread) catch {};
instance.processEvents();
}
```
whereas the non-callback version looks like
```zig
// The wrapper methods use polling, so 200_000_000 is the polling interval in nanoseconds.
const response = instance.requestAdapterSync(null, 200_000_000);
// The wrapper methods use polling, waiting the passed in duration between polling attempts
const response = instance.requestAdapterSync(null, io, std.Io.Duration.fromMilliseconds(200));

const adapter_ptr: ?*Adapter = switch (response.status) {
.success => response.adapter,
Expand Down
62 changes: 28 additions & 34 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
const std = @import("std");

fn link_windows_system_libraries(comptime T: type, mod: *T, is_gnu: bool) void {
const linkSystemLibrary = switch (T) {
std.Build.Module => std.Build.Module.linkSystemLibrary,
std.Build.Step.Compile => std.Build.Step.Compile.linkSystemLibrary2,
else => @compileError("Provided type must either be std.Build.Module or std.Build.Step.Compile"),
};

fn link_windows_system_libraries(mod: *std.Build.Module, is_gnu: bool) void {
if (is_gnu) {
// For gnu, the linker needs the d3dcompiler dll since it can't find a suitable static lib
// (I'd guess it tries to search for something like "libd3dcompiler.a" instead of "d3dcompiler.lib").
linkSystemLibrary(mod, "d3dcompiler_47", .{});
mod.linkSystemLibrary("d3dcompiler_47", .{});

// This seems to have something to do with the windows-result crate in wgpu-native's dependencies
linkSystemLibrary(mod, "api-ms-win-core-winrt-error-l1-1-0", .{});
mod.linkSystemLibrary("api-ms-win-core-winrt-error-l1-1-0", .{});
} else {
linkSystemLibrary(mod, "d3dcompiler", .{});
mod.linkSystemLibrary("d3dcompiler", .{});

// GetClientRect is unresolved unless we link this for msvc
linkSystemLibrary(mod, "user32", .{});
mod.linkSystemLibrary("user32", .{});

linkSystemLibrary(mod, "RuntimeObject", .{});
mod.linkSystemLibrary("RuntimeObject", .{});
}
linkSystemLibrary(mod, "opengl32", .{});
linkSystemLibrary(mod, "gdi32", .{});
mod.linkSystemLibrary("opengl32", .{});
mod.linkSystemLibrary("gdi32", .{});

// COM-related
linkSystemLibrary(mod, "OleAut32", .{});
linkSystemLibrary(mod, "Ole32", .{});
mod.linkSystemLibrary("OleAut32", .{});
mod.linkSystemLibrary("Ole32", .{});

// Apparently these are needed because of rust stdlib
linkSystemLibrary(mod, "ws2_32", .{});
linkSystemLibrary(mod, "userenv", .{});
mod.linkSystemLibrary("ws2_32", .{});
mod.linkSystemLibrary("userenv", .{});

// Needed by windows-rs (wgpu-native dependency)
linkSystemLibrary(mod, "propsys", .{});
mod.linkSystemLibrary("propsys", .{});
}

fn link_mac_frameworks(mod: *std.Build.Step.Compile) void {
mod.linkFramework("Foundation");
mod.linkFramework("QuartzCore");
mod.linkFramework("Metal");
mod.root_module.linkFramework("Foundation", .{});
mod.root_module.linkFramework("QuartzCore", .{});
mod.root_module.linkFramework("Metal", .{});
}

const WGPUBuildContext = struct {
Expand Down Expand Up @@ -142,8 +136,8 @@ const WGPUBuildContext = struct {
if (link_mode == .static) {
libwgpu_path = wgpu_dep.path("lib/wgpu_native.lib");

link_windows_system_libraries(std.Build.Module, wgpu_mod, false);
link_windows_system_libraries(std.Build.Module, wgpu_c_mod, false);
link_windows_system_libraries(wgpu_mod, false);
link_windows_system_libraries(wgpu_c_mod, false);
} else {
libwgpu_path = wgpu_dep.path("lib/wgpu_native.dll.lib");

Expand All @@ -162,8 +156,8 @@ const WGPUBuildContext = struct {
if (link_mode == .static) {
libwgpu_path = wgpu_dep.path("lib/libwgpu_native.a");

link_windows_system_libraries(std.Build.Module, wgpu_mod, true);
link_windows_system_libraries(std.Build.Module, wgpu_c_mod, true);
link_windows_system_libraries(wgpu_mod, true);
link_windows_system_libraries(wgpu_c_mod, true);
} else {
libwgpu_path = wgpu_dep.path("lib/libwgpu_native.dll.a");

Expand Down Expand Up @@ -218,8 +212,8 @@ const WGPUBuildContext = struct {

fn dynamic_link(context: *const WGPUBuildContext, c: *std.Build.Step.Compile, cmd: *std.Build.Step.Run) void {
if (!context.is_windows) {
c.addLibraryPath(context.wgpu_dep.path("lib"));
c.linkSystemLibrary2("wgpu_native", .{});
c.root_module.addLibraryPath(context.wgpu_dep.path("lib"));
c.root_module.linkSystemLibrary("wgpu_native", .{});
}
cmd.addPathDir(context.install_lib_dir);
}
Expand Down Expand Up @@ -292,12 +286,12 @@ fn unit_tests(b: *std.Build, context: *const WGPUBuildContext) void {
});
handle_rt(context, t);
if (context.libwgpu_path != null) {
t.addObjectFile(context.libwgpu_path.?);
t.root_module.addObjectFile(context.libwgpu_path.?);
}
if (context.is_windows) {
t.linkLibC();
t.root_module.link_libc = true;
} else {
t.linkLibCpp();
t.root_module.link_libcpp = true;
}

const run_test = b.addRunArtifact(t);
Expand All @@ -310,12 +304,12 @@ fn unit_tests(b: *std.Build, context: *const WGPUBuildContext) void {
dynamic_link(context, t, run_test);
} else if (context.is_windows) {
if (context.target.result.abi == .gnu) {
link_windows_system_libraries(std.Build.Step.Compile, t, true);
link_windows_system_libraries(t.root_module, true);

// TODO: Find out why this is only required here; seems suspicious
t.linkSystemLibrary2("unwind", .{});
t.root_module.linkSystemLibrary("unwind", .{});
} else {
link_windows_system_libraries(std.Build.Step.Compile, t, false);
link_windows_system_libraries(t.root_module, false);
}
}

Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// This field is optional.
// This is currently advisory only; Zig does not yet do anything
// with this value.
.minimum_zig_version = "0.14.0",
.minimum_zig_version = "0.16.0",

// This field is optional.
// Each dependency must either provide a `url` and `hash`, or a `path`.
Expand Down
2 changes: 1 addition & 1 deletion examples/triangle/triangle.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const output_extent = wgpu.Extent3D {
const output_bytes_per_row = 4 * output_extent.width;
const output_size = output_bytes_per_row * output_extent.height;

fn handleBufferMap(status: wgpu.MapAsyncStatus, _: wgpu.StringView, userdata1: ?*anyopaque, _: ?*anyopaque) callconv(.C) void {
fn handleBufferMap(status: wgpu.MapAsyncStatus, _: wgpu.StringView, userdata1: ?*anyopaque, _: ?*anyopaque) callconv(.c) void {
std.log.info("buffer_map status={x:.8}\n", .{@intFromEnum(status)});
const complete: *bool = @ptrCast(@alignCast(userdata1));
complete.* = true;
Expand Down
30 changes: 15 additions & 15 deletions src/adapter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub const RequestAdapterCallback = *const fn(
message: StringView,
userdata1: ?*anyopaque,
userdata2: ?*anyopaque,
) callconv(.C) void;
) callconv(.c) void;

pub const RequestAdapterResponse = struct {
status: RequestAdapterStatus,
Expand All @@ -119,7 +119,7 @@ pub const RequestAdapterResponse = struct {
};

pub const AdapterInfoProcs = struct {
pub const FreeMembers = *const fn(AdapterInfo) callconv(.C) void;
pub const FreeMembers = *const fn(AdapterInfo) callconv(.c) void;
};

extern fn wgpuAdapterInfoFreeMembers(adapter_info: AdapterInfo) void;
Expand All @@ -141,13 +141,13 @@ pub const AdapterInfo = extern struct {
};

pub const AdapterProcs = struct {
pub const GetFeatures = *const fn(*Adapter, *SupportedFeatures) callconv(.C) void;
pub const GetLimits = *const fn(*Adapter, *Limits) callconv(.C) Status;
pub const GetInfo = *const fn(*Adapter, *AdapterInfo) callconv(.C) Status;
pub const HasFeature = *const fn(*Adapter, FeatureName) callconv(.C) WGPUBool;
pub const RequestDevice = *const fn(*Adapter, ?*const DeviceDescriptor, RequestDeviceCallbackInfo) callconv(.C) Future;
pub const AddRef = *const fn(*Adapter) callconv(.C) void;
pub const Release = *const fn(*Adapter) callconv(.C) void;
pub const GetFeatures = *const fn(*Adapter, *SupportedFeatures) callconv(.c) void;
pub const GetLimits = *const fn(*Adapter, *Limits) callconv(.c) Status;
pub const GetInfo = *const fn(*Adapter, *AdapterInfo) callconv(.c) Status;
pub const HasFeature = *const fn(*Adapter, FeatureName) callconv(.c) WGPUBool;
pub const RequestDevice = *const fn(*Adapter, ?*const DeviceDescriptor, RequestDeviceCallbackInfo) callconv(.c) Future;
pub const AddRef = *const fn(*Adapter) callconv(.c) void;
pub const Release = *const fn(*Adapter) callconv(.c) void;
};

extern fn wgpuAdapterGetFeatures(adapter: *Adapter, features: *SupportedFeatures) void;
Expand All @@ -172,7 +172,7 @@ pub const Adapter = opaque{
return wgpuAdapterHasFeature(self, feature) != 0;
}

fn defaultDeviceCallback(status: RequestDeviceStatus, device: ?*Device, message: StringView, userdata1: ?*anyopaque, userdata2: ?*anyopaque) callconv(.C) void {
fn defaultDeviceCallback(status: RequestDeviceStatus, device: ?*Device, message: StringView, userdata1: ?*anyopaque, userdata2: ?*anyopaque) callconv(.c) void {
const ud_response: *RequestDeviceResponse = @ptrCast(@alignCast(userdata1));
ud_response.* = RequestDeviceResponse {
.status = status,
Expand All @@ -186,7 +186,7 @@ pub const Adapter = opaque{

// This is a synchronous wrapper that handles asynchronous (callback) logic.
// It uses polling to see when the request has been fulfilled, so needs a polling interval parameter.
pub fn requestDeviceSync(self: *Adapter, instance: *Instance, descriptor: ?*const DeviceDescriptor, polling_interval_nanoseconds: u64) RequestDeviceResponse {
pub fn requestDeviceSync(self: *Adapter, instance: *Instance, descriptor: ?*const DeviceDescriptor, io: std.Io, polling_interval: std.Io.Duration) RequestDeviceResponse {
var response: RequestDeviceResponse = undefined;
var completed = false;
const callback_info = RequestDeviceCallbackInfo {
Expand All @@ -201,7 +201,7 @@ pub const Adapter = opaque{
_ = device_future;
instance.processEvents();
while(!completed) {
std.Thread.sleep(polling_interval_nanoseconds);
io.sleep(polling_interval, std.Io.Clock.cpu_thread) catch {}; // is this the correct clock?
instance.processEvents();
}

Expand All @@ -223,15 +223,15 @@ test "can request device" {
const testing = @import("std").testing;

const instance = Instance.create(null);
const adapter_response = instance.?.requestAdapterSync(null, 200_000_000);
const adapter_response = instance.?.requestAdapterSync(null, testing.io, std.Io.Duration.fromMilliseconds(200));
const adapter: ?*Adapter = switch(adapter_response.status) {
.success => adapter_response.adapter,
else => null,
};
const device_response = adapter.?.requestDeviceSync(instance.?, null, 200_000_000);
const device_response = adapter.?.requestDeviceSync(instance.?, null, testing.io, std.Io.Duration.fromMilliseconds(200));
const device: ?*Device = switch(device_response.status) {
.success => device_response.device,
else => null
};
try testing.expect(device != null);
}
}
12 changes: 6 additions & 6 deletions src/bind_group.zig
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ pub const BindGroupLayoutDescriptor = extern struct {
};

pub const BindGroupLayoutProcs = struct {
pub const SetLabel = *const fn(*BindGroupLayout, StringView) callconv(.C) void;
pub const AddRef = *const fn(*BindGroupLayout) callconv(.C) void;
pub const Release = *const fn(*BindGroupLayout) callconv(.C) void;
pub const SetLabel = *const fn(*BindGroupLayout, StringView) callconv(.c) void;
pub const AddRef = *const fn(*BindGroupLayout) callconv(.c) void;
pub const Release = *const fn(*BindGroupLayout) callconv(.c) void;
};

extern fn wgpuBindGroupLayoutSetLabel(bind_group_layout: *BindGroupLayout, label: StringView) void;
Expand Down Expand Up @@ -129,9 +129,9 @@ pub const BindGroupDescriptor = extern struct {
};

pub const BindGroupProcs = struct {
pub const SetLabel = *const fn(*BindGroup, StringView) callconv(.C) void;
pub const AddRef = *const fn(*BindGroup) callconv(.C) void;
pub const Release = *const fn(*BindGroup) callconv(.C) void;
pub const SetLabel = *const fn(*BindGroup, StringView) callconv(.c) void;
pub const AddRef = *const fn(*BindGroup) callconv(.c) void;
pub const Release = *const fn(*BindGroup) callconv(.c) void;
};

extern fn wgpuBindGroupSetLabel(bind_group: *BindGroup, label: StringView) void;
Expand Down
24 changes: 12 additions & 12 deletions src/buffer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub const BufferMapCallbackInfo = extern struct {
userdata2: ?*anyopaque = null,
};

pub const BufferMapCallback = *const fn(status: MapAsyncStatus, message: StringView, userdata1: ?*anyopaque, userdata2: ?*anyopaque) callconv(.C) void;
pub const BufferMapCallback = *const fn(status: MapAsyncStatus, message: StringView, userdata1: ?*anyopaque, userdata2: ?*anyopaque) callconv(.c) void;

pub const BufferDescriptor = extern struct {
next_in_chain: ?*const ChainedStruct = null,
Expand All @@ -86,17 +86,17 @@ pub const BufferDescriptor = extern struct {
};

pub const BufferProcs = struct {
pub const Destroy = *const fn(*Buffer) callconv(.C) void;
pub const GetConstMappedRange = *const fn(*Buffer, usize, usize) callconv(.C) ?*const anyopaque;
pub const GetMapState = *const fn(*Buffer) callconv(.C) BufferMapState;
pub const GetMappedRange = *const fn(*Buffer, usize, usize) callconv(.C) ?*anyopaque;
pub const GetSize = *const fn(*Buffer) callconv(.C) u64;
pub const GetUsage = *const fn(*Buffer) callconv(.C) BufferUsage;
pub const MapAsync = *const fn(*Buffer, MapMode, usize, usize, BufferMapCallbackInfo) callconv(.C) Future;
pub const SetLabel = *const fn(*Buffer, StringView) callconv(.C) void;
pub const Unmap = *const fn(*Buffer) callconv(.C) void;
pub const AddRef = *const fn(*Buffer) callconv(.C) void;
pub const Release = *const fn(*Buffer) callconv(.C) void;
pub const Destroy = *const fn(*Buffer) callconv(.c) void;
pub const GetConstMappedRange = *const fn(*Buffer, usize, usize) callconv(.c) ?*const anyopaque;
pub const GetMapState = *const fn(*Buffer) callconv(.c) BufferMapState;
pub const GetMappedRange = *const fn(*Buffer, usize, usize) callconv(.c) ?*anyopaque;
pub const GetSize = *const fn(*Buffer) callconv(.c) u64;
pub const GetUsage = *const fn(*Buffer) callconv(.c) BufferUsage;
pub const MapAsync = *const fn(*Buffer, MapMode, usize, usize, BufferMapCallbackInfo) callconv(.c) Future;
pub const SetLabel = *const fn(*Buffer, StringView) callconv(.c) void;
pub const Unmap = *const fn(*Buffer) callconv(.c) void;
pub const AddRef = *const fn(*Buffer) callconv(.c) void;
pub const Release = *const fn(*Buffer) callconv(.c) void;
};

extern fn wgpuBufferDestroy(buffer: *Buffer) void;
Expand Down
Loading