remove Dawn / WebGPU support in favor of sysgpu
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
e6cecc3ebe
commit
98801a258e
47 changed files with 25 additions and 8474 deletions
349
build.zig
349
build.zig
|
|
@ -46,7 +46,7 @@ pub fn build(b: *std.Build) !void {
|
|||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
const sysgpu_backend = b.option(SysgpuBackend, "sysgpu_backend", "sysgpu API backend") orelse .default;
|
||||
const core_platform = b.option(CoreApp.Platform, "core_platform", "mach core platform to use") orelse CoreApp.Platform.fromTarget(target.result);
|
||||
const core_platform = b.option(Platform, "core_platform", "mach core platform to use") orelse Platform.fromTarget(target.result);
|
||||
|
||||
const build_examples = b.option(bool, "examples", "build/install examples specifically");
|
||||
const build_libs = b.option(bool, "libs", "build/install libraries specifically");
|
||||
|
|
@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {
|
|||
build_options.addOption(bool, "want_sysaudio", want_sysaudio);
|
||||
build_options.addOption(bool, "want_sysgpu", want_sysgpu);
|
||||
build_options.addOption(SysgpuBackend, "sysgpu_backend", sysgpu_backend);
|
||||
build_options.addOption(CoreApp.Platform, "core_platform", core_platform);
|
||||
build_options.addOption(Platform, "core_platform", core_platform);
|
||||
|
||||
const module = b.addModule("mach", .{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
|
|
@ -142,7 +142,6 @@ pub fn build(b: *std.Build) !void {
|
|||
lib.linkLibrary(dep.artifact("wayland-headers"));
|
||||
}
|
||||
}
|
||||
if (want_examples) try buildCoreExamples(b, optimize, target, module, core_platform);
|
||||
}
|
||||
if (want_sysaudio) {
|
||||
// Can build sysaudio examples if desired, then.
|
||||
|
|
@ -251,44 +250,6 @@ pub fn build(b: *std.Build) !void {
|
|||
}
|
||||
}
|
||||
|
||||
if (true) { // want_gpu
|
||||
if (b.lazyDependency("mach_gpu_dawn", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |dep| {
|
||||
_ = dep;
|
||||
const gpu_dawn = @import("mach_gpu_dawn");
|
||||
gpu_dawn.addPathsToModule(b, module, .{});
|
||||
module.addIncludePath(b.path("src/gpu"));
|
||||
}
|
||||
|
||||
if (want_examples) {
|
||||
const example_exe = b.addExecutable(.{
|
||||
.name = "dawn-gpu-hello-triangle",
|
||||
.root_source_file = b.path("src/gpu/example/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
example_exe.root_module.addImport("mach", module);
|
||||
link(b, example_exe);
|
||||
|
||||
if (b.lazyDependency("mach_glfw", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |dep| example_exe.root_module.addImport("mach-glfw", dep.module("mach-glfw"));
|
||||
|
||||
const example_compile_step = b.step("dawn-gpu-hello-triangle", "Install 'dawn-gpu-hello-triangle'");
|
||||
example_compile_step.dependOn(b.getInstallStep());
|
||||
|
||||
const example_run_cmd = b.addRunArtifact(example_exe);
|
||||
example_run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| example_run_cmd.addArgs(args);
|
||||
|
||||
const example_run_step = b.step("run-dawn-gpu-hello-triangle", "Run 'dawn-gpu-hello-triangle' example");
|
||||
example_run_step.dependOn(&example_run_cmd.step);
|
||||
}
|
||||
}
|
||||
|
||||
if (target.result.cpu.arch != .wasm32) {
|
||||
// Creates a step for unit testing. This only builds the test executable
|
||||
// but does not run it.
|
||||
|
|
@ -302,7 +263,6 @@ pub fn build(b: *std.Build) !void {
|
|||
unit_tests.root_module.addImport(e.key_ptr.*, e.value_ptr.*);
|
||||
}
|
||||
addPaths(&unit_tests.root_module);
|
||||
link(b, unit_tests);
|
||||
|
||||
// Linux gamemode requires libc.
|
||||
if (target.result.os.tag == .linux) unit_tests.root_module.link_libc = true;
|
||||
|
|
@ -317,183 +277,18 @@ pub fn build(b: *std.Build) !void {
|
|||
}
|
||||
}
|
||||
|
||||
pub const CoreApp = struct {
|
||||
b: *std.Build,
|
||||
name: []const u8,
|
||||
module: *std.Build.Module,
|
||||
compile: *std.Build.Step.Compile,
|
||||
install: *std.Build.Step.InstallArtifact,
|
||||
run: *std.Build.Step.Run,
|
||||
platform: Platform,
|
||||
res_dirs: ?[]const []const u8,
|
||||
watch_paths: ?[]const []const u8,
|
||||
pub const Platform = enum {
|
||||
glfw,
|
||||
x11,
|
||||
wayland,
|
||||
web,
|
||||
|
||||
pub const Platform = enum {
|
||||
glfw,
|
||||
x11,
|
||||
wayland,
|
||||
web,
|
||||
|
||||
pub fn fromTarget(target: std.Target) Platform {
|
||||
if (target.cpu.arch == .wasm32) return .web;
|
||||
return .glfw;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn init(
|
||||
app_builder: *std.Build,
|
||||
mach_builder: *std.Build,
|
||||
options: struct {
|
||||
name: []const u8,
|
||||
src: []const u8,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
custom_entrypoint: ?[]const u8 = null,
|
||||
deps: ?[]const std.Build.Module.Import = null,
|
||||
res_dirs: ?[]const []const u8 = null,
|
||||
watch_paths: ?[]const []const u8 = null,
|
||||
mach_mod: ?*std.Build.Module = null,
|
||||
platform: ?Platform = null,
|
||||
},
|
||||
) !CoreApp {
|
||||
const target = options.target.result;
|
||||
const platform = options.platform orelse Platform.fromTarget(target);
|
||||
|
||||
var imports = std.ArrayList(std.Build.Module.Import).init(app_builder.allocator);
|
||||
|
||||
const mach_mod = options.mach_mod orelse app_builder.dependency("mach", .{
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
}).module("mach");
|
||||
try imports.append(.{
|
||||
.name = "mach",
|
||||
.module = mach_mod,
|
||||
});
|
||||
|
||||
if (options.deps) |app_deps| try imports.appendSlice(app_deps);
|
||||
|
||||
const app_module = app_builder.createModule(.{
|
||||
.root_source_file = app_builder.path(options.src),
|
||||
.imports = try imports.toOwnedSlice(),
|
||||
});
|
||||
|
||||
// Tell mach about the chosen platform
|
||||
const platform_options = app_builder.addOptions();
|
||||
platform_options.addOption(Platform, "platform", platform);
|
||||
mach_mod.addOptions("platform_options", platform_options);
|
||||
|
||||
const compile = blk: {
|
||||
if (platform == .web) {
|
||||
// wasm libraries should go into zig-out/www/
|
||||
app_builder.lib_dir = app_builder.fmt("{s}/www", .{app_builder.install_path});
|
||||
|
||||
const lib = app_builder.addStaticLibrary(.{
|
||||
.name = options.name,
|
||||
.root_source_file = if (options.custom_entrypoint) |e|
|
||||
app_builder.path(e)
|
||||
else
|
||||
mach_builder.path("src/core/platform/wasm/entrypoint.zig"),
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
});
|
||||
lib.rdynamic = true;
|
||||
|
||||
break :blk lib;
|
||||
} else {
|
||||
const exe = app_builder.addExecutable(.{
|
||||
.name = options.name,
|
||||
.root_source_file = if (options.custom_entrypoint) |e|
|
||||
app_builder.path(e)
|
||||
else
|
||||
mach_builder.path("src/core/platform/native_entrypoint.zig"),
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
});
|
||||
// TODO(core): figure out why we need to disable LTO: https://github.com/hexops/mach/issues/597
|
||||
exe.want_lto = false;
|
||||
|
||||
break :blk exe;
|
||||
}
|
||||
};
|
||||
|
||||
compile.root_module.addImport("mach", mach_mod);
|
||||
compile.root_module.addImport("app", app_module);
|
||||
|
||||
// Installation step
|
||||
const install = app_builder.addInstallArtifact(compile, .{});
|
||||
if (options.res_dirs) |res_dirs| {
|
||||
for (res_dirs) |res| {
|
||||
const install_res = app_builder.addInstallDirectory(.{
|
||||
.source_dir = app_builder.path(res),
|
||||
.install_dir = install.dest_dir.?,
|
||||
.install_subdir = std.fs.path.basename(res),
|
||||
.exclude_extensions = &.{},
|
||||
});
|
||||
install.step.dependOn(&install_res.step);
|
||||
}
|
||||
}
|
||||
if (platform == .web) {
|
||||
inline for (.{ "src/core/platform/wasm/mach.js", "src/sysjs/mach-sysjs.js" }) |js| {
|
||||
const install_js = app_builder.addInstallFileWithDir(
|
||||
mach_builder.path(js),
|
||||
std.Build.InstallDir{ .custom = "www" },
|
||||
std.fs.path.basename(js),
|
||||
);
|
||||
install.step.dependOn(&install_js.step);
|
||||
}
|
||||
}
|
||||
|
||||
// Link dependencies
|
||||
if (platform != .web) {
|
||||
link(mach_builder, compile);
|
||||
}
|
||||
|
||||
const run = app_builder.addRunArtifact(compile);
|
||||
run.step.dependOn(&install.step);
|
||||
return .{
|
||||
.b = app_builder,
|
||||
.module = app_module,
|
||||
.compile = compile,
|
||||
.install = install,
|
||||
.run = run,
|
||||
.name = options.name,
|
||||
.platform = platform,
|
||||
.res_dirs = options.res_dirs,
|
||||
.watch_paths = options.watch_paths,
|
||||
};
|
||||
pub fn fromTarget(target: std.Target) Platform {
|
||||
if (target.cpu.arch == .wasm32) return .web;
|
||||
return .glfw;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(sysgpu): remove this once we switch to sysgpu fully
|
||||
pub fn link(mach_builder: *std.Build, step: *std.Build.Step.Compile) void {
|
||||
const target = step.root_module.resolved_target.?.result;
|
||||
if (target.cpu.arch == .wasm32) return;
|
||||
|
||||
if (mach_builder.lazyDependency("mach_gpu_dawn", .{
|
||||
.target = step.root_module.resolved_target.?,
|
||||
.optimize = step.root_module.optimize.?,
|
||||
})) |dep| {
|
||||
_ = dep;
|
||||
const gpu_dawn = @import("mach_gpu_dawn");
|
||||
const Options = struct {
|
||||
gpu_dawn_options: gpu_dawn.Options = .{},
|
||||
};
|
||||
const options: Options = .{};
|
||||
|
||||
gpu_dawn.link(
|
||||
mach_builder,
|
||||
step,
|
||||
&step.root_module,
|
||||
options.gpu_dawn_options,
|
||||
);
|
||||
step.addCSourceFile(.{
|
||||
.file = mach_builder.path("src/gpu/mach_dawn.cpp"),
|
||||
.flags = &.{"-std=c++17"},
|
||||
});
|
||||
step.addIncludePath(mach_builder.path("src/gpu"));
|
||||
}
|
||||
}
|
||||
|
||||
fn linkSysgpu(b: *std.Build, module: *std.Build.Module) void {
|
||||
const resolved_target = module.resolved_target orelse b.host;
|
||||
const target = resolved_target.result;
|
||||
|
|
@ -591,7 +386,6 @@ fn buildExamples(
|
|||
});
|
||||
exe.root_module.addImport("mach", mach_mod);
|
||||
addPaths(&exe.root_module);
|
||||
link(b, exe);
|
||||
b.installArtifact(exe);
|
||||
|
||||
for (example.deps) |d| {
|
||||
|
|
@ -629,129 +423,6 @@ fn buildExamples(
|
|||
}
|
||||
}
|
||||
|
||||
fn buildCoreExamples(
|
||||
b: *std.Build,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
target: std.Build.ResolvedTarget,
|
||||
mach_mod: *std.Build.Module,
|
||||
platform: CoreApp.Platform,
|
||||
) !void {
|
||||
const Dependency = enum {
|
||||
zigimg,
|
||||
assets,
|
||||
zmath,
|
||||
};
|
||||
|
||||
inline for ([_]struct {
|
||||
name: []const u8,
|
||||
deps: []const Dependency = &.{},
|
||||
std_platform_only: bool = false,
|
||||
sysgpu: bool = false,
|
||||
}{
|
||||
.{ .name = "wasm-test", .deps = &.{.zmath} },
|
||||
.{ .name = "triangle", .deps = &.{.zmath} },
|
||||
.{ .name = "triangle-msaa", .deps = &.{.zmath} },
|
||||
.{ .name = "clear-color", .deps = &.{.zmath} },
|
||||
.{ .name = "procedural-primitives", .deps = &.{.zmath} },
|
||||
.{ .name = "boids", .deps = &.{.zmath} },
|
||||
.{ .name = "rotating-cube", .deps = &.{.zmath} },
|
||||
.{ .name = "pixel-post-process", .deps = &.{.zmath} },
|
||||
.{ .name = "two-cubes", .deps = &.{.zmath} },
|
||||
.{ .name = "instanced-cube", .deps = &.{.zmath} },
|
||||
.{ .name = "gen-texture-light", .deps = &.{.zmath} },
|
||||
.{ .name = "fractal-cube", .deps = &.{.zmath} },
|
||||
.{ .name = "map-async", .deps = &.{.zmath} },
|
||||
.{ .name = "rgb-quad", .deps = &.{.zmath} },
|
||||
.{ .name = "textured-cube", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
.{ .name = "textured-quad", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
.{ .name = "sprite2d", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
.{ .name = "image", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
.{ .name = "image-blur", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
.{ .name = "cubemap", .deps = &.{ .zmath, .zigimg, .assets } },
|
||||
|
||||
// sysgpu
|
||||
.{ .name = "boids", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "clear-color", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "cubemap", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "fractal-cube", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "gen-texture-light", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "image-blur", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "instanced-cube", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "map-async", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "pixel-post-process", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "procedural-primitives", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "rotating-cube", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "sprite2d", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "image", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "textured-cube", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "textured-quad", .deps = &.{ .zmath, .zigimg, .assets }, .sysgpu = true },
|
||||
.{ .name = "triangle", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "triangle-msaa", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "two-cubes", .deps = &.{.zmath}, .sysgpu = true },
|
||||
.{ .name = "rgb-quad", .deps = &.{.zmath}, .sysgpu = true },
|
||||
}) |example| {
|
||||
// FIXME: this is workaround for a problem that some examples
|
||||
// (having the std_platform_only=true field) as well as zigimg
|
||||
// uses IO and depends on gpu-dawn which is not supported
|
||||
// in freestanding environments. So break out of this loop
|
||||
// as soon as any such examples is found. This does means that any
|
||||
// example which works on wasm should be placed before those who dont.
|
||||
if (example.std_platform_only)
|
||||
if (target.result.cpu.arch == .wasm32)
|
||||
break;
|
||||
|
||||
const cmd_name = if (example.sysgpu) "sysgpu-" ++ example.name else example.name;
|
||||
const app = try CoreApp.init(
|
||||
b,
|
||||
b,
|
||||
.{
|
||||
.name = "core-" ++ cmd_name,
|
||||
.src = if (example.sysgpu)
|
||||
"src/core/examples/sysgpu/" ++ example.name ++ "/main.zig"
|
||||
else
|
||||
"src/core/examples/" ++ example.name ++ "/main.zig",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.watch_paths = if (example.sysgpu)
|
||||
&.{"src/core/examples/sysgpu/" ++ example.name}
|
||||
else
|
||||
&.{"src/core/examples/" ++ example.name},
|
||||
.mach_mod = mach_mod,
|
||||
.platform = platform,
|
||||
},
|
||||
);
|
||||
|
||||
for (example.deps) |d| {
|
||||
switch (d) {
|
||||
.zigimg => {
|
||||
if (b.lazyDependency("zigimg", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |dep| app.module.addImport("zigimg", dep.module("zigimg"));
|
||||
},
|
||||
.assets => {
|
||||
if (b.lazyDependency("mach_example_assets", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |dep| app.module.addImport("assets", dep.module("mach-example-assets"));
|
||||
},
|
||||
.zmath => {
|
||||
const zmath = b.createModule(.{
|
||||
.root_source_file = b.path("src/core/examples/zmath.zig"),
|
||||
});
|
||||
app.module.addImport("zmath", zmath);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const install_step = b.step("core-" ++ cmd_name, "Install core-" ++ cmd_name);
|
||||
install_step.dependOn(&app.install.step);
|
||||
|
||||
const run_step = b.step("run-core-" ++ cmd_name, "Run core-" ++ cmd_name);
|
||||
run_step.dependOn(&app.run.step);
|
||||
}
|
||||
}
|
||||
|
||||
comptime {
|
||||
const supported_zig = std.SemanticVersion.parse("0.13.0-dev.351+64ef45eb0") catch unreachable;
|
||||
if (builtin.zig_version.order(supported_zig) != .eq) {
|
||||
|
|
|
|||
|
|
@ -21,12 +21,6 @@
|
|||
.hash = "12202b816e7c31c516bd87218fd56f9b1f93671e4ab42a2a98110d586c4b3bdd2730",
|
||||
.lazy = true,
|
||||
},
|
||||
.mach_gpu_dawn = .{
|
||||
.url = "https://pkg.machengine.org/mach-gpu-dawn/d0a1e11ac96401108ba7c35bf99101c0756ded2d.tar.gz",
|
||||
.hash = "122060fbe61aa4a828002ca8949d9c3ef1b6b7ae3fa92558af7ccea7182e8d9d516c",
|
||||
// TODO(build): be able to mark this dependency as lazy
|
||||
// .lazy = true,
|
||||
},
|
||||
.mach_glfw = .{
|
||||
.url = "https://pkg.machengine.org/mach-glfw/8da44b719e345097664ff2e0a7620474eb11db5f.tar.gz",
|
||||
.hash = "1220e5343c2fe2a490aa90dc52d92fd34ebfd7d0ffc7d246dd4720bb5c339ead4d7b",
|
||||
|
|
|
|||
|
|
@ -81,12 +81,7 @@ fn init(
|
|||
&gpu.BindGroup.Descriptor.init(.{
|
||||
.label = label,
|
||||
.layout = bind_group_layout,
|
||||
.entries = &.{
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(0, uniform_buffer, uniform_offset * i, @sizeOf(UniformBufferObject), @sizeOf(UniformBufferObject))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(0, uniform_buffer, uniform_offset * i, @sizeOf(UniformBufferObject)),
|
||||
},
|
||||
.entries = &.{gpu.BindGroup.Entry.buffer(0, uniform_buffer, uniform_offset * i, @sizeOf(UniformBufferObject), @sizeOf(UniformBufferObject))},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,8 +149,7 @@ fn initModule(entities: *mach.Entities.Mod, core: *Mod) !void {
|
|||
mach.core.allocator = gpa.allocator(); // TODO: banish this global allocator
|
||||
|
||||
// Initialize GPU implementation
|
||||
if (comptime !mach.use_sysgpu) try mach.wgpu.Impl.init(mach.core.allocator, .{});
|
||||
if (comptime mach.use_sysgpu) try mach.sysgpu.Impl.init(mach.core.allocator, .{});
|
||||
try mach.sysgpu.Impl.init(mach.core.allocator, .{});
|
||||
|
||||
const main_window = try entities.new();
|
||||
try core.set(main_window, .fullscreen, false);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ fn ErrorSet(comptime F: type) type {
|
|||
return @typeInfo(@typeInfo(F).Fn.return_type.?).ErrorUnion.error_set;
|
||||
}
|
||||
|
||||
const gpu = if (mach.use_sysgpu) sysgpu.sysgpu else @import("../gpu/main.zig");
|
||||
const gpu = sysgpu.sysgpu;
|
||||
|
||||
pub fn AppInterface(comptime app_entry: anytype) void {
|
||||
if (!@hasDecl(app_entry, "App")) {
|
||||
|
|
|
|||
|
|
@ -137,8 +137,7 @@ pub fn init(
|
|||
input: *Frequency,
|
||||
options: Options,
|
||||
) !void {
|
||||
if (!@import("builtin").is_test and !mach.use_sysgpu) _ = mach.wgpu.Export(mach.wgpu.Impl);
|
||||
if (!@import("builtin").is_test and mach.use_sysgpu) _ = mach.sysgpu.sysgpu.Export(mach.sysgpu.Impl);
|
||||
if (!@import("builtin").is_test) _ = mach.sysgpu.sysgpu.Export(mach.sysgpu.Impl);
|
||||
|
||||
const backend_type = try detectBackendType(allocator);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,6 @@ const std = @import("std");
|
|||
const mach = @import("mach");
|
||||
const core = mach.core;
|
||||
|
||||
pub usingnamespace if (!@hasDecl(App, "GPUInterface")) struct {
|
||||
pub const GPUInterface = mach.wgpu.dawn.Interface;
|
||||
} else struct {};
|
||||
|
||||
pub usingnamespace if (!@hasDecl(App, "SYSGPUInterface")) extern struct {
|
||||
pub const SYSGPUInterface = mach.sysgpu.Impl;
|
||||
} else struct {};
|
||||
|
|
@ -31,8 +27,7 @@ pub fn main() !void {
|
|||
core.allocator = gpa.allocator();
|
||||
|
||||
// Initialize GPU implementation
|
||||
if (comptime !mach.use_sysgpu) try mach.wgpu.Impl.init(core.allocator, .{});
|
||||
if (comptime mach.use_sysgpu) try mach.sysgpu.Impl.init(core.allocator, .{});
|
||||
try mach.sysgpu.Impl.init(core.allocator, .{});
|
||||
|
||||
var app: App = undefined;
|
||||
try app.init();
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ const mach = @import("mach");
|
|||
const core = mach.core;
|
||||
const gpu = mach.gpu;
|
||||
|
||||
pub const GPUInterface = gpu.StubInterface;
|
||||
|
||||
var app: App = undefined;
|
||||
export fn wasmInit() void {
|
||||
App.init(&app) catch |err| @panic(@errorName(err));
|
||||
|
|
|
|||
|
|
@ -300,8 +300,7 @@ pub fn init(
|
|||
input: *Frequency,
|
||||
options: Options,
|
||||
) !void {
|
||||
if (!@import("builtin").is_test and !mach.use_sysgpu) _ = mach.wgpu.Export(mach.wgpu.Impl);
|
||||
if (!@import("builtin").is_test and mach.use_sysgpu) _ = mach.sysgpu.sysgpu.Export(mach.sysgpu.Impl);
|
||||
if (!@import("builtin").is_test) _ = mach.sysgpu.sysgpu.Export(mach.sysgpu.Impl);
|
||||
|
||||
const libx11 = try LibX11.load();
|
||||
const libxcursor: ?LibXCursor = LibXCursor.load() catch |err| switch (err) {
|
||||
|
|
|
|||
|
|
@ -260,22 +260,10 @@ fn buildPipeline(
|
|||
.label = label,
|
||||
.layout = bind_group_layout,
|
||||
.entries = &.{
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms), @sizeOf(Uniforms))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms)),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * sprite_buffer_cap, @sizeOf(math.Mat4x4))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * sprite_buffer_cap),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(2, uv_transforms, 0, @sizeOf(math.Mat3x3) * sprite_buffer_cap, @sizeOf(math.Mat3x3))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(2, uv_transforms, 0, @sizeOf(math.Mat3x3) * sprite_buffer_cap),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(3, sizes, 0, @sizeOf(math.Vec2) * sprite_buffer_cap, @sizeOf(math.Vec2))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(3, sizes, 0, @sizeOf(math.Vec2) * sprite_buffer_cap),
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms), @sizeOf(Uniforms)),
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * sprite_buffer_cap, @sizeOf(math.Mat4x4)),
|
||||
gpu.BindGroup.Entry.buffer(2, uv_transforms, 0, @sizeOf(math.Mat3x3) * sprite_buffer_cap, @sizeOf(math.Mat3x3)),
|
||||
gpu.BindGroup.Entry.buffer(3, sizes, 0, @sizeOf(math.Vec2) * sprite_buffer_cap, @sizeOf(math.Vec2)),
|
||||
gpu.BindGroup.Entry.sampler(4, texture_sampler),
|
||||
gpu.BindGroup.Entry.textureView(5, texture_view),
|
||||
gpu.BindGroup.Entry.textureView(6, texture2_view),
|
||||
|
|
|
|||
|
|
@ -297,22 +297,10 @@ fn buildPipeline(
|
|||
.label = label,
|
||||
.layout = bind_group_layout,
|
||||
.entries = &.{
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms), @sizeOf(Uniforms))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms)),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * texts_buffer_cap, @sizeOf(math.Mat4x4))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * texts_buffer_cap),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(2, colors, 0, @sizeOf(math.Vec4) * texts_buffer_cap, @sizeOf(math.Vec4))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(2, colors, 0, @sizeOf(math.Vec4) * texts_buffer_cap),
|
||||
if (mach.use_sysgpu)
|
||||
gpu.BindGroup.Entry.buffer(3, glyphs, 0, @sizeOf(Glyph) * texts_buffer_cap, @sizeOf(Glyph))
|
||||
else
|
||||
gpu.BindGroup.Entry.buffer(3, glyphs, 0, @sizeOf(Glyph) * texts_buffer_cap),
|
||||
gpu.BindGroup.Entry.buffer(0, uniforms, 0, @sizeOf(Uniforms), @sizeOf(Uniforms)),
|
||||
gpu.BindGroup.Entry.buffer(1, transforms, 0, @sizeOf(math.Mat4x4) * texts_buffer_cap, @sizeOf(math.Mat4x4)),
|
||||
gpu.BindGroup.Entry.buffer(2, colors, 0, @sizeOf(math.Vec4) * texts_buffer_cap, @sizeOf(math.Vec4)),
|
||||
gpu.BindGroup.Entry.buffer(3, glyphs, 0, @sizeOf(Glyph) * texts_buffer_cap, @sizeOf(Glyph)),
|
||||
gpu.BindGroup.Entry.sampler(4, texture_sampler),
|
||||
gpu.BindGroup.Entry.textureView(5, texture_view),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const dawn = @import("dawn.zig");
|
||||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStructOut = @import("main.zig").ChainedStructOut;
|
||||
const Device = @import("device.zig").Device;
|
||||
const Instance = @import("instance.zig").Instance;
|
||||
const FeatureName = @import("main.zig").FeatureName;
|
||||
const SupportedLimits = @import("main.zig").SupportedLimits;
|
||||
const RequestDeviceStatus = @import("main.zig").RequestDeviceStatus;
|
||||
const BackendType = @import("main.zig").BackendType;
|
||||
const RequestDeviceCallback = @import("main.zig").RequestDeviceCallback;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const Adapter = opaque {
|
||||
pub const Type = enum(u32) {
|
||||
discrete_gpu,
|
||||
integrated_gpu,
|
||||
cpu,
|
||||
unknown,
|
||||
|
||||
pub fn name(t: Type) []const u8 {
|
||||
return switch (t) {
|
||||
.discrete_gpu => "Discrete GPU",
|
||||
.integrated_gpu => "Integrated GPU",
|
||||
.cpu => "CPU",
|
||||
.unknown => "Unknown",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Properties = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStructOut,
|
||||
dawn_adapter_properties_power_preference: *const dawn.AdapterPropertiesPowerPreference,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
vendor_id: u32,
|
||||
vendor_name: [*:0]const u8,
|
||||
architecture: [*:0]const u8,
|
||||
device_id: u32,
|
||||
name: [*:0]const u8,
|
||||
driver_description: [*:0]const u8,
|
||||
adapter_type: Type,
|
||||
backend_type: BackendType,
|
||||
compatibility_mode: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub inline fn createDevice(adapter: *Adapter, descriptor: ?*const Device.Descriptor) ?*Device {
|
||||
return Impl.adapterCreateDevice(adapter, descriptor);
|
||||
}
|
||||
|
||||
/// Call once with null to determine the array length, and again to fetch the feature list.
|
||||
///
|
||||
/// Consider using the enumerateFeaturesOwned helper.
|
||||
pub inline fn enumerateFeatures(adapter: *Adapter, features: ?[*]FeatureName) usize {
|
||||
return Impl.adapterEnumerateFeatures(adapter, features);
|
||||
}
|
||||
|
||||
/// Enumerates the adapter features, storing the result in an allocated slice which is owned by
|
||||
/// the caller.
|
||||
pub inline fn enumerateFeaturesOwned(adapter: *Adapter, allocator: std.mem.Allocator) ![]FeatureName {
|
||||
const count = adapter.enumerateFeatures(null);
|
||||
const data = try allocator.alloc(FeatureName, count);
|
||||
_ = adapter.enumerateFeatures(data.ptr);
|
||||
return data;
|
||||
}
|
||||
|
||||
pub inline fn getInstance(adapter: *Adapter) *Instance {
|
||||
return Impl.adapterGetInstance(adapter);
|
||||
}
|
||||
|
||||
pub inline fn getLimits(adapter: *Adapter, limits: *SupportedLimits) bool {
|
||||
return Impl.adapterGetLimits(adapter, limits) != 0;
|
||||
}
|
||||
|
||||
pub inline fn getProperties(adapter: *Adapter, properties: *Adapter.Properties) void {
|
||||
Impl.adapterGetProperties(adapter, properties);
|
||||
}
|
||||
|
||||
pub inline fn hasFeature(adapter: *Adapter, feature: FeatureName) bool {
|
||||
return Impl.adapterHasFeature(adapter, feature) != 0;
|
||||
}
|
||||
|
||||
pub inline fn requestDevice(
|
||||
adapter: *Adapter,
|
||||
descriptor: ?*const Device.Descriptor,
|
||||
context: anytype,
|
||||
comptime callback: fn (
|
||||
ctx: @TypeOf(context),
|
||||
status: RequestDeviceStatus,
|
||||
device: *Device,
|
||||
message: ?[*:0]const u8,
|
||||
) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(status: RequestDeviceStatus, device: *Device, message: ?[*:0]const u8, userdata: ?*anyopaque) callconv(.C) void {
|
||||
callback(
|
||||
if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))),
|
||||
status,
|
||||
device,
|
||||
message,
|
||||
);
|
||||
}
|
||||
};
|
||||
Impl.adapterRequestDevice(adapter, descriptor, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn reference(adapter: *Adapter) void {
|
||||
Impl.adapterReference(adapter);
|
||||
}
|
||||
|
||||
pub inline fn release(adapter: *Adapter) void {
|
||||
Impl.adapterRelease(adapter);
|
||||
}
|
||||
};
|
||||
|
||||
test "Adapter.Type name" {
|
||||
try testing.expectEqualStrings("Discrete GPU", Adapter.Type.discrete_gpu.name());
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const Sampler = @import("sampler.zig").Sampler;
|
||||
const TextureView = @import("texture_view.zig").TextureView;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
|
||||
const ExternalTexture = @import("external_texture.zig").ExternalTexture;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const BindGroup = opaque {
|
||||
pub const Entry = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
external_texture_binding_entry: *const ExternalTexture.BindingEntry,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
binding: u32,
|
||||
buffer: ?*Buffer = null,
|
||||
offset: u64 = 0,
|
||||
size: u64,
|
||||
sampler: ?*Sampler = null,
|
||||
texture_view: ?*TextureView = null,
|
||||
|
||||
/// Helper to create a buffer BindGroup.Entry.
|
||||
pub fn buffer(binding: u32, buf: *Buffer, offset: u64, size: u64) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.buffer = buf,
|
||||
.offset = offset,
|
||||
.size = size,
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to create a sampler BindGroup.Entry.
|
||||
pub fn sampler(binding: u32, _sampler: *Sampler) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.sampler = _sampler,
|
||||
.size = 0,
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to create a texture view BindGroup.Entry.
|
||||
pub fn textureView(binding: u32, texture_view: *TextureView) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.texture_view = texture_view,
|
||||
.size = 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
layout: *BindGroupLayout,
|
||||
entry_count: usize = 0,
|
||||
entries: ?[*]const Entry = null,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
layout: *BindGroupLayout,
|
||||
entries: ?[]const Entry = null,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.layout = v.layout,
|
||||
.entry_count = if (v.entries) |e| e.len else 0,
|
||||
.entries = if (v.entries) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn setLabel(bind_group: *BindGroup, label: [*:0]const u8) void {
|
||||
Impl.bindGroupSetLabel(bind_group, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(bind_group: *BindGroup) void {
|
||||
Impl.bindGroupReference(bind_group);
|
||||
}
|
||||
|
||||
pub inline fn release(bind_group: *BindGroup) void {
|
||||
Impl.bindGroupRelease(bind_group);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ShaderStageFlags = @import("main.zig").ShaderStageFlags;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const Sampler = @import("sampler.zig").Sampler;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
const TextureView = @import("texture_view.zig").TextureView;
|
||||
const StorageTextureBindingLayout = @import("main.zig").StorageTextureBindingLayout;
|
||||
const StorageTextureAccess = @import("main.zig").StorageTextureAccess;
|
||||
const ExternalTexture = @import("external_texture.zig").ExternalTexture;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const BindGroupLayout = opaque {
|
||||
pub const Entry = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
external_texture_binding_layout: *const ExternalTexture.BindingLayout,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
binding: u32,
|
||||
visibility: ShaderStageFlags,
|
||||
buffer: Buffer.BindingLayout = .{},
|
||||
sampler: Sampler.BindingLayout = .{},
|
||||
texture: Texture.BindingLayout = .{},
|
||||
storage_texture: StorageTextureBindingLayout = .{},
|
||||
|
||||
/// Helper to create a buffer BindGroupLayout.Entry.
|
||||
pub fn buffer(
|
||||
binding: u32,
|
||||
visibility: ShaderStageFlags,
|
||||
binding_type: Buffer.BindingType,
|
||||
has_dynamic_offset: bool,
|
||||
min_binding_size: u64,
|
||||
) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.visibility = visibility,
|
||||
.buffer = .{
|
||||
.type = binding_type,
|
||||
.has_dynamic_offset = Bool32.from(has_dynamic_offset),
|
||||
.min_binding_size = min_binding_size,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to create a sampler BindGroupLayout.Entry.
|
||||
pub fn sampler(
|
||||
binding: u32,
|
||||
visibility: ShaderStageFlags,
|
||||
binding_type: Sampler.BindingType,
|
||||
) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.visibility = visibility,
|
||||
.sampler = .{ .type = binding_type },
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to create a texture BindGroupLayout.Entry.
|
||||
pub fn texture(
|
||||
binding: u32,
|
||||
visibility: ShaderStageFlags,
|
||||
sample_type: Texture.SampleType,
|
||||
view_dimension: TextureView.Dimension,
|
||||
multisampled: bool,
|
||||
) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.visibility = visibility,
|
||||
.texture = .{
|
||||
.sample_type = sample_type,
|
||||
.view_dimension = view_dimension,
|
||||
.multisampled = Bool32.from(multisampled),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to create a storage texture BindGroupLayout.Entry.
|
||||
pub fn storageTexture(
|
||||
binding: u32,
|
||||
visibility: ShaderStageFlags,
|
||||
access: StorageTextureAccess,
|
||||
format: Texture.Format,
|
||||
view_dimension: TextureView.Dimension,
|
||||
) Entry {
|
||||
return .{
|
||||
.binding = binding,
|
||||
.visibility = visibility,
|
||||
.storage_texture = .{
|
||||
.access = access,
|
||||
.format = format,
|
||||
.view_dimension = view_dimension,
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
entry_count: usize = 0,
|
||||
entries: ?[*]const Entry = null,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
entries: ?[]const Entry = null,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.entry_count = if (v.entries) |e| e.len else 0,
|
||||
.entries = if (v.entries) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn setLabel(bind_group_layout: *BindGroupLayout, label: [*:0]const u8) void {
|
||||
Impl.bindGroupLayoutSetLabel(bind_group_layout, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(bind_group_layout: *BindGroupLayout) void {
|
||||
Impl.bindGroupLayoutReference(bind_group_layout);
|
||||
}
|
||||
|
||||
pub inline fn release(bind_group_layout: *BindGroupLayout) void {
|
||||
Impl.bindGroupLayoutRelease(bind_group_layout);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
const std = @import("std");
|
||||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const dawn = @import("dawn.zig");
|
||||
const MapModeFlags = @import("main.zig").MapModeFlags;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const Buffer = opaque {
|
||||
pub const MapCallback = *const fn (status: MapAsyncStatus, userdata: ?*anyopaque) callconv(.C) void;
|
||||
|
||||
pub const BindingType = enum(u32) {
|
||||
undefined = 0x00000000,
|
||||
uniform = 0x00000001,
|
||||
storage = 0x00000002,
|
||||
read_only_storage = 0x00000003,
|
||||
};
|
||||
|
||||
pub const MapState = enum(u32) {
|
||||
unmapped = 0x00000000,
|
||||
pending = 0x00000001,
|
||||
mapped = 0x00000002,
|
||||
};
|
||||
|
||||
pub const MapAsyncStatus = enum(u32) {
|
||||
success = 0x00000000,
|
||||
validation_error = 0x00000001,
|
||||
unknown = 0x00000002,
|
||||
device_lost = 0x00000003,
|
||||
destroyed_before_callback = 0x00000004,
|
||||
unmapped_before_callback = 0x00000005,
|
||||
mapping_already_pending = 0x00000006,
|
||||
offset_out_of_range = 0x00000007,
|
||||
size_out_of_range = 0x00000008,
|
||||
};
|
||||
|
||||
pub const UsageFlags = packed struct(u32) {
|
||||
map_read: bool = false,
|
||||
map_write: bool = false,
|
||||
copy_src: bool = false,
|
||||
copy_dst: bool = false,
|
||||
index: bool = false,
|
||||
vertex: bool = false,
|
||||
uniform: bool = false,
|
||||
storage: bool = false,
|
||||
indirect: bool = false,
|
||||
query_resolve: bool = false,
|
||||
|
||||
_padding: u22 = 0,
|
||||
|
||||
comptime {
|
||||
std.debug.assert(
|
||||
@sizeOf(@This()) == @sizeOf(u32) and
|
||||
@bitSizeOf(@This()) == @bitSizeOf(u32),
|
||||
);
|
||||
}
|
||||
|
||||
pub const none = UsageFlags{};
|
||||
|
||||
pub fn equal(a: UsageFlags, b: UsageFlags) bool {
|
||||
return @as(u10, @truncate(@as(u32, @bitCast(a)))) == @as(u10, @truncate(@as(u32, @bitCast(b))));
|
||||
}
|
||||
};
|
||||
|
||||
pub const BindingLayout = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
type: BindingType = .undefined,
|
||||
has_dynamic_offset: Bool32 = .false,
|
||||
min_binding_size: u64 = 0,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
dawn_buffer_descriptor_error_info_from_wire_client: *const dawn.BufferDescriptorErrorInfoFromWireClient,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
usage: UsageFlags,
|
||||
size: u64,
|
||||
mapped_at_creation: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub inline fn destroy(buffer: *Buffer) void {
|
||||
Impl.bufferDestroy(buffer);
|
||||
}
|
||||
|
||||
pub inline fn getMapState(buffer: *Buffer) MapState {
|
||||
return Impl.bufferGetMapState(buffer);
|
||||
}
|
||||
|
||||
/// Default `offset_bytes`: 0
|
||||
/// Default `len`: `gpu.whole_map_size` / `std.math.maxint(usize)` (whole range)
|
||||
pub inline fn getConstMappedRange(
|
||||
buffer: *Buffer,
|
||||
comptime T: type,
|
||||
offset_bytes: usize,
|
||||
len: usize,
|
||||
) ?[]const T {
|
||||
const size = @sizeOf(T) * len;
|
||||
const data = Impl.bufferGetConstMappedRange(
|
||||
buffer,
|
||||
offset_bytes,
|
||||
size + size % 4,
|
||||
);
|
||||
return if (data) |d| @as([*]const T, @ptrCast(@alignCast(d)))[0..len] else null;
|
||||
}
|
||||
|
||||
/// Default `offset_bytes`: 0
|
||||
/// Default `len`: `gpu.whole_map_size` / `std.math.maxint(usize)` (whole range)
|
||||
pub inline fn getMappedRange(
|
||||
buffer: *Buffer,
|
||||
comptime T: type,
|
||||
offset_bytes: usize,
|
||||
len: usize,
|
||||
) ?[]T {
|
||||
const size = @sizeOf(T) * len;
|
||||
const data = Impl.bufferGetMappedRange(
|
||||
buffer,
|
||||
offset_bytes,
|
||||
size + size % 4,
|
||||
);
|
||||
return if (data) |d| @as([*]T, @ptrCast(@alignCast(d)))[0..len] else null;
|
||||
}
|
||||
|
||||
pub inline fn getSize(buffer: *Buffer) u64 {
|
||||
return Impl.bufferGetSize(buffer);
|
||||
}
|
||||
|
||||
pub inline fn getUsage(buffer: *Buffer) Buffer.UsageFlags {
|
||||
return Impl.bufferGetUsage(buffer);
|
||||
}
|
||||
|
||||
pub inline fn mapAsync(
|
||||
buffer: *Buffer,
|
||||
mode: MapModeFlags,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
context: anytype,
|
||||
comptime callback: fn (ctx: @TypeOf(context), status: MapAsyncStatus) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(status: MapAsyncStatus, userdata: ?*anyopaque) callconv(.C) void {
|
||||
callback(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), status);
|
||||
}
|
||||
};
|
||||
Impl.bufferMapAsync(buffer, mode, offset, size, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(buffer: *Buffer, label: [*:0]const u8) void {
|
||||
Impl.bufferSetLabel(buffer, label);
|
||||
}
|
||||
|
||||
pub inline fn unmap(buffer: *Buffer) void {
|
||||
Impl.bufferUnmap(buffer);
|
||||
}
|
||||
|
||||
pub inline fn reference(buffer: *Buffer) void {
|
||||
Impl.bufferReference(buffer);
|
||||
}
|
||||
|
||||
pub inline fn release(buffer: *Buffer) void {
|
||||
Impl.bufferRelease(buffer);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const CommandBuffer = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub inline fn setLabel(command_buffer: *CommandBuffer, label: [*:0]const u8) void {
|
||||
Impl.commandBufferSetLabel(command_buffer, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(command_buffer: *CommandBuffer) void {
|
||||
Impl.commandBufferReference(command_buffer);
|
||||
}
|
||||
|
||||
pub inline fn release(command_buffer: *CommandBuffer) void {
|
||||
Impl.commandBufferRelease(command_buffer);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
const std = @import("std");
|
||||
const ComputePassEncoder = @import("compute_pass_encoder.zig").ComputePassEncoder;
|
||||
const RenderPassEncoder = @import("render_pass_encoder.zig").RenderPassEncoder;
|
||||
const CommandBuffer = @import("command_buffer.zig").CommandBuffer;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const QuerySet = @import("query_set.zig").QuerySet;
|
||||
const RenderPassDescriptor = @import("main.zig").RenderPassDescriptor;
|
||||
const ComputePassDescriptor = @import("main.zig").ComputePassDescriptor;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ImageCopyBuffer = @import("main.zig").ImageCopyBuffer;
|
||||
const ImageCopyTexture = @import("main.zig").ImageCopyTexture;
|
||||
const Extent3D = @import("main.zig").Extent3D;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const dawn = @import("dawn.zig");
|
||||
|
||||
pub const CommandEncoder = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
dawn_encoder_internal_usage_descriptor: *const dawn.EncoderInternalUsageDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub inline fn beginComputePass(command_encoder: *CommandEncoder, descriptor: ?*const ComputePassDescriptor) *ComputePassEncoder {
|
||||
return Impl.commandEncoderBeginComputePass(command_encoder, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn beginRenderPass(command_encoder: *CommandEncoder, descriptor: *const RenderPassDescriptor) *RenderPassEncoder {
|
||||
return Impl.commandEncoderBeginRenderPass(command_encoder, descriptor);
|
||||
}
|
||||
|
||||
/// Default `offset`: 0
|
||||
/// Default `size`: `gpu.whole_size`
|
||||
pub inline fn clearBuffer(command_encoder: *CommandEncoder, buffer: *Buffer, offset: u64, size: u64) void {
|
||||
Impl.commandEncoderClearBuffer(command_encoder, buffer, offset, size);
|
||||
}
|
||||
|
||||
pub inline fn copyBufferToBuffer(command_encoder: *CommandEncoder, source: *Buffer, source_offset: u64, destination: *Buffer, destination_offset: u64, size: u64) void {
|
||||
Impl.commandEncoderCopyBufferToBuffer(command_encoder, source, source_offset, destination, destination_offset, size);
|
||||
}
|
||||
|
||||
pub inline fn copyBufferToTexture(command_encoder: *CommandEncoder, source: *const ImageCopyBuffer, destination: *const ImageCopyTexture, copy_size: *const Extent3D) void {
|
||||
Impl.commandEncoderCopyBufferToTexture(command_encoder, source, destination, copy_size);
|
||||
}
|
||||
|
||||
pub inline fn copyTextureToBuffer(command_encoder: *CommandEncoder, source: *const ImageCopyTexture, destination: *const ImageCopyBuffer, copy_size: *const Extent3D) void {
|
||||
Impl.commandEncoderCopyTextureToBuffer(command_encoder, source, destination, copy_size);
|
||||
}
|
||||
|
||||
pub inline fn copyTextureToTexture(command_encoder: *CommandEncoder, source: *const ImageCopyTexture, destination: *const ImageCopyTexture, copy_size: *const Extent3D) void {
|
||||
Impl.commandEncoderCopyTextureToTexture(command_encoder, source, destination, copy_size);
|
||||
}
|
||||
|
||||
pub inline fn finish(command_encoder: *CommandEncoder, descriptor: ?*const CommandBuffer.Descriptor) *CommandBuffer {
|
||||
return Impl.commandEncoderFinish(command_encoder, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn injectValidationError(command_encoder: *CommandEncoder, message: [*:0]const u8) void {
|
||||
Impl.commandEncoderInjectValidationError(command_encoder, message);
|
||||
}
|
||||
|
||||
pub inline fn insertDebugMarker(command_encoder: *CommandEncoder, marker_label: [*:0]const u8) void {
|
||||
Impl.commandEncoderInsertDebugMarker(command_encoder, marker_label);
|
||||
}
|
||||
|
||||
pub inline fn popDebugGroup(command_encoder: *CommandEncoder) void {
|
||||
Impl.commandEncoderPopDebugGroup(command_encoder);
|
||||
}
|
||||
|
||||
pub inline fn pushDebugGroup(command_encoder: *CommandEncoder, group_label: [*:0]const u8) void {
|
||||
Impl.commandEncoderPushDebugGroup(command_encoder, group_label);
|
||||
}
|
||||
|
||||
pub inline fn resolveQuerySet(command_encoder: *CommandEncoder, query_set: *QuerySet, first_query: u32, query_count: u32, destination: *Buffer, destination_offset: u64) void {
|
||||
Impl.commandEncoderResolveQuerySet(command_encoder, query_set, first_query, query_count, destination, destination_offset);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(command_encoder: *CommandEncoder, label: [*:0]const u8) void {
|
||||
Impl.commandEncoderSetLabel(command_encoder, label);
|
||||
}
|
||||
|
||||
pub inline fn writeBuffer(
|
||||
command_encoder: *CommandEncoder,
|
||||
buffer: *Buffer,
|
||||
buffer_offset_bytes: u64,
|
||||
data_slice: anytype,
|
||||
) void {
|
||||
Impl.commandEncoderWriteBuffer(
|
||||
command_encoder,
|
||||
buffer,
|
||||
buffer_offset_bytes,
|
||||
@as([*]const u8, @ptrCast(std.mem.sliceAsBytes(data_slice).ptr)),
|
||||
@as(u64, @intCast(data_slice.len)) * @sizeOf(std.meta.Elem(@TypeOf(data_slice))),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn writeTimestamp(command_encoder: *CommandEncoder, query_set: *QuerySet, query_index: u32) void {
|
||||
Impl.commandEncoderWriteTimestamp(command_encoder, query_set, query_index);
|
||||
}
|
||||
|
||||
pub inline fn reference(command_encoder: *CommandEncoder) void {
|
||||
Impl.commandEncoderReference(command_encoder);
|
||||
}
|
||||
|
||||
pub inline fn release(command_encoder: *CommandEncoder) void {
|
||||
Impl.commandEncoderRelease(command_encoder);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const BindGroup = @import("bind_group.zig").BindGroup;
|
||||
const ComputePipeline = @import("compute_pipeline.zig").ComputePipeline;
|
||||
const QuerySet = @import("query_set.zig").QuerySet;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const ComputePassEncoder = opaque {
|
||||
/// Default `workgroup_count_y`: 1
|
||||
/// Default `workgroup_count_z`: 1
|
||||
pub inline fn dispatchWorkgroups(compute_pass_encoder: *ComputePassEncoder, workgroup_count_x: u32, workgroup_count_y: u32, workgroup_count_z: u32) void {
|
||||
Impl.computePassEncoderDispatchWorkgroups(compute_pass_encoder, workgroup_count_x, workgroup_count_y, workgroup_count_z);
|
||||
}
|
||||
|
||||
pub inline fn dispatchWorkgroupsIndirect(compute_pass_encoder: *ComputePassEncoder, indirect_buffer: *Buffer, indirect_offset: u64) void {
|
||||
Impl.computePassEncoderDispatchWorkgroupsIndirect(compute_pass_encoder, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
pub inline fn end(compute_pass_encoder: *ComputePassEncoder) void {
|
||||
Impl.computePassEncoderEnd(compute_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn insertDebugMarker(compute_pass_encoder: *ComputePassEncoder, marker_label: [*:0]const u8) void {
|
||||
Impl.computePassEncoderInsertDebugMarker(compute_pass_encoder, marker_label);
|
||||
}
|
||||
|
||||
pub inline fn popDebugGroup(compute_pass_encoder: *ComputePassEncoder) void {
|
||||
Impl.computePassEncoderPopDebugGroup(compute_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn pushDebugGroup(compute_pass_encoder: *ComputePassEncoder, group_label: [*:0]const u8) void {
|
||||
Impl.computePassEncoderPushDebugGroup(compute_pass_encoder, group_label);
|
||||
}
|
||||
|
||||
/// Default `dynamic_offsets`: null
|
||||
pub inline fn setBindGroup(compute_pass_encoder: *ComputePassEncoder, group_index: u32, group: *BindGroup, dynamic_offsets: ?[]const u32) void {
|
||||
Impl.computePassEncoderSetBindGroup(
|
||||
compute_pass_encoder,
|
||||
group_index,
|
||||
group,
|
||||
if (dynamic_offsets) |v| v.len else 0,
|
||||
if (dynamic_offsets) |v| v.ptr else null,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(compute_pass_encoder: *ComputePassEncoder, label: [*:0]const u8) void {
|
||||
Impl.computePassEncoderSetLabel(compute_pass_encoder, label);
|
||||
}
|
||||
|
||||
pub inline fn setPipeline(compute_pass_encoder: *ComputePassEncoder, pipeline: *ComputePipeline) void {
|
||||
Impl.computePassEncoderSetPipeline(compute_pass_encoder, pipeline);
|
||||
}
|
||||
|
||||
pub inline fn writeTimestamp(compute_pass_encoder: *ComputePassEncoder, query_set: *QuerySet, query_index: u32) void {
|
||||
Impl.computePassEncoderWriteTimestamp(compute_pass_encoder, query_set, query_index);
|
||||
}
|
||||
|
||||
pub inline fn reference(compute_pass_encoder: *ComputePassEncoder) void {
|
||||
Impl.computePassEncoderReference(compute_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn release(compute_pass_encoder: *ComputePassEncoder) void {
|
||||
Impl.computePassEncoderRelease(compute_pass_encoder);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ProgrammableStageDescriptor = @import("main.zig").ProgrammableStageDescriptor;
|
||||
const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
|
||||
const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const ComputePipeline = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
layout: ?*PipelineLayout = null,
|
||||
compute: ProgrammableStageDescriptor,
|
||||
};
|
||||
|
||||
pub inline fn getBindGroupLayout(compute_pipeline: *ComputePipeline, group_index: u32) *BindGroupLayout {
|
||||
return Impl.computePipelineGetBindGroupLayout(compute_pipeline, group_index);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(compute_pipeline: *ComputePipeline, label: [*:0]const u8) void {
|
||||
Impl.computePipelineSetLabel(compute_pipeline, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(compute_pipeline: *ComputePipeline) void {
|
||||
Impl.computePipelineReference(compute_pipeline);
|
||||
}
|
||||
|
||||
pub inline fn release(compute_pipeline: *ComputePipeline) void {
|
||||
Impl.computePipelineRelease(compute_pipeline);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ChainedStructOut = @import("main.zig").ChainedStructOut;
|
||||
const PowerPreference = @import("main.zig").PowerPreference;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
pub const Interface = @import("dawn_impl.zig").Interface;
|
||||
|
||||
pub const CacheDeviceDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_cache_device_descriptor },
|
||||
isolation_key: [*:0]const u8 = "",
|
||||
};
|
||||
|
||||
pub const EncoderInternalUsageDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_encoder_internal_usage_descriptor },
|
||||
use_internal_usages: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub const MultisampleStateRenderToSingleSampled = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_multisample_state_render_to_single_sampled },
|
||||
enabled: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub const RenderPassColorAttachmentRenderToSingleSampled = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_render_pass_color_attachment_render_to_single_sampled },
|
||||
implicit_sample_count: u32 = 1,
|
||||
};
|
||||
|
||||
pub const TextureInternalUsageDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_texture_internal_usage_descriptor },
|
||||
internal_usage: Texture.UsageFlags = Texture.UsageFlags.none,
|
||||
};
|
||||
|
||||
pub const TogglesDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_toggles_descriptor },
|
||||
enabled_toggles_count: usize = 0,
|
||||
enabled_toggles: ?[*]const [*:0]const u8 = null,
|
||||
disabled_toggles_count: usize = 0,
|
||||
disabled_toggles: ?[*]const [*:0]const u8 = null,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_toggles_descriptor },
|
||||
enabled_toggles: ?[]const [*:0]const u8 = null,
|
||||
disabled_toggles: ?[]const [*:0]const u8 = null,
|
||||
}) TogglesDescriptor {
|
||||
return .{
|
||||
.chain = v.chain,
|
||||
.enabled_toggles_count = if (v.enabled_toggles) |e| e.len else 0,
|
||||
.enabled_toggles = if (v.enabled_toggles) |e| e.ptr else null,
|
||||
.disabled_toggles_count = if (v.disabled_toggles) |e| e.len else 0,
|
||||
.disabled_toggles = if (v.disabled_toggles) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const ShaderModuleSPIRVOptionsDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .dawn_shader_module_spirv_options_descriptor },
|
||||
allow_non_uniform_derivatives: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub const AdapterPropertiesPowerPreference = extern struct {
|
||||
chain: ChainedStructOut = .{
|
||||
.next = null,
|
||||
.s_type = .dawn_adapter_properties_power_preference,
|
||||
},
|
||||
power_preference: PowerPreference = .undefined,
|
||||
};
|
||||
|
||||
pub const BufferDescriptorErrorInfoFromWireClient = extern struct {
|
||||
chain: ChainedStruct = .{
|
||||
.next = null,
|
||||
.s_type = .dawn_buffer_descriptor_error_info_from_wire_client,
|
||||
},
|
||||
out_of_memory: Bool32 = .false,
|
||||
};
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,368 +0,0 @@
|
|||
const std = @import("std");
|
||||
const Adapter = @import("adapter.zig").Adapter;
|
||||
const Queue = @import("queue.zig").Queue;
|
||||
const BindGroup = @import("bind_group.zig").BindGroup;
|
||||
const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const CommandEncoder = @import("command_encoder.zig").CommandEncoder;
|
||||
const ComputePipeline = @import("compute_pipeline.zig").ComputePipeline;
|
||||
const ExternalTexture = @import("external_texture.zig").ExternalTexture;
|
||||
const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
|
||||
const QuerySet = @import("query_set.zig").QuerySet;
|
||||
const RenderBundleEncoder = @import("render_bundle_encoder.zig").RenderBundleEncoder;
|
||||
const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
|
||||
const Sampler = @import("sampler.zig").Sampler;
|
||||
const ShaderModule = @import("shader_module.zig").ShaderModule;
|
||||
const Surface = @import("surface.zig").Surface;
|
||||
const SwapChain = @import("swap_chain.zig").SwapChain;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const FeatureName = @import("main.zig").FeatureName;
|
||||
const RequiredLimits = @import("main.zig").RequiredLimits;
|
||||
const SupportedLimits = @import("main.zig").SupportedLimits;
|
||||
const ErrorType = @import("main.zig").ErrorType;
|
||||
const ErrorFilter = @import("main.zig").ErrorFilter;
|
||||
const LoggingType = @import("main.zig").LoggingType;
|
||||
const CreatePipelineAsyncStatus = @import("main.zig").CreatePipelineAsyncStatus;
|
||||
const LoggingCallback = @import("main.zig").LoggingCallback;
|
||||
const ErrorCallback = @import("main.zig").ErrorCallback;
|
||||
const CreateComputePipelineAsyncCallback = @import("main.zig").CreateComputePipelineAsyncCallback;
|
||||
const CreateRenderPipelineAsyncCallback = @import("main.zig").CreateRenderPipelineAsyncCallback;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const dawn = @import("dawn.zig");
|
||||
|
||||
pub const Device = opaque {
|
||||
pub const LostCallback = *const fn (
|
||||
reason: LostReason,
|
||||
message: [*:0]const u8,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void;
|
||||
|
||||
pub const LostReason = enum(u32) {
|
||||
undefined = 0x00000000,
|
||||
destroyed = 0x00000001,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
dawn_toggles_descriptor: *const dawn.TogglesDescriptor,
|
||||
dawn_cache_device_descriptor: *const dawn.CacheDeviceDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
required_features_count: usize = 0,
|
||||
required_features: ?[*]const FeatureName = null,
|
||||
required_limits: ?*const RequiredLimits = null,
|
||||
default_queue: Queue.Descriptor = Queue.Descriptor{},
|
||||
device_lost_callback: LostCallback,
|
||||
device_lost_userdata: ?*anyopaque,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
required_features: ?[]const FeatureName = null,
|
||||
required_limits: ?*const RequiredLimits = null,
|
||||
default_queue: Queue.Descriptor = Queue.Descriptor{},
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.required_features_count = if (v.required_features) |e| e.len else 0,
|
||||
.required_features = if (v.required_features) |e| e.ptr else null,
|
||||
.default_queue = v.default_queue,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn createBindGroup(device: *Device, descriptor: *const BindGroup.Descriptor) *BindGroup {
|
||||
return Impl.deviceCreateBindGroup(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createBindGroupLayout(device: *Device, descriptor: *const BindGroupLayout.Descriptor) *BindGroupLayout {
|
||||
return Impl.deviceCreateBindGroupLayout(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createBuffer(device: *Device, descriptor: *const Buffer.Descriptor) *Buffer {
|
||||
return Impl.deviceCreateBuffer(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createCommandEncoder(device: *Device, descriptor: ?*const CommandEncoder.Descriptor) *CommandEncoder {
|
||||
return Impl.deviceCreateCommandEncoder(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createComputePipeline(device: *Device, descriptor: *const ComputePipeline.Descriptor) *ComputePipeline {
|
||||
return Impl.deviceCreateComputePipeline(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createComputePipelineAsync(
|
||||
device: *Device,
|
||||
descriptor: *const ComputePipeline.Descriptor,
|
||||
context: anytype,
|
||||
comptime callback: fn (
|
||||
status: CreatePipelineAsyncStatus,
|
||||
compute_pipeline: ?*ComputePipeline,
|
||||
message: ?[*:0]const u8,
|
||||
ctx: @TypeOf(context),
|
||||
) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(
|
||||
status: CreatePipelineAsyncStatus,
|
||||
compute_pipeline: ?*ComputePipeline,
|
||||
message: ?[*:0]const u8,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void {
|
||||
callback(
|
||||
status,
|
||||
compute_pipeline,
|
||||
message,
|
||||
if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))),
|
||||
);
|
||||
}
|
||||
};
|
||||
Impl.deviceCreateComputePipelineAsync(device, descriptor, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn createErrorBuffer(device: *Device, descriptor: *const Buffer.Descriptor) *Buffer {
|
||||
return Impl.deviceCreateErrorBuffer(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createErrorExternalTexture(device: *Device) *ExternalTexture {
|
||||
return Impl.deviceCreateErrorExternalTexture(device);
|
||||
}
|
||||
|
||||
pub inline fn createErrorTexture(device: *Device, descriptor: *const Texture.Descriptor) *Texture {
|
||||
return Impl.deviceCreateErrorTexture(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createExternalTexture(device: *Device, external_texture_descriptor: *const ExternalTexture.Descriptor) *ExternalTexture {
|
||||
return Impl.deviceCreateExternalTexture(device, external_texture_descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createPipelineLayout(device: *Device, pipeline_layout_descriptor: *const PipelineLayout.Descriptor) *PipelineLayout {
|
||||
return Impl.deviceCreatePipelineLayout(device, pipeline_layout_descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createQuerySet(device: *Device, descriptor: *const QuerySet.Descriptor) *QuerySet {
|
||||
return Impl.deviceCreateQuerySet(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createRenderBundleEncoder(device: *Device, descriptor: *const RenderBundleEncoder.Descriptor) *RenderBundleEncoder {
|
||||
return Impl.deviceCreateRenderBundleEncoder(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createRenderPipeline(device: *Device, descriptor: *const RenderPipeline.Descriptor) *RenderPipeline {
|
||||
return Impl.deviceCreateRenderPipeline(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createRenderPipelineAsync(
|
||||
device: *Device,
|
||||
descriptor: *const RenderPipeline.Descriptor,
|
||||
context: anytype,
|
||||
comptime callback: fn (
|
||||
ctx: @TypeOf(context),
|
||||
status: CreatePipelineAsyncStatus,
|
||||
pipeline: ?*RenderPipeline,
|
||||
message: ?[*:0]const u8,
|
||||
) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(
|
||||
status: CreatePipelineAsyncStatus,
|
||||
pipeline: ?*RenderPipeline,
|
||||
message: ?[*:0]const u8,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void {
|
||||
callback(
|
||||
if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))),
|
||||
status,
|
||||
pipeline,
|
||||
message,
|
||||
);
|
||||
}
|
||||
};
|
||||
Impl.deviceCreateRenderPipelineAsync(device, descriptor, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn createSampler(device: *Device, descriptor: ?*const Sampler.Descriptor) *Sampler {
|
||||
return Impl.deviceCreateSampler(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createShaderModule(device: *Device, descriptor: *const ShaderModule.Descriptor) *ShaderModule {
|
||||
return Impl.deviceCreateShaderModule(device, descriptor);
|
||||
}
|
||||
|
||||
/// Helper to make createShaderModule invocations slightly nicer.
|
||||
pub inline fn createShaderModuleWGSL(
|
||||
device: *Device,
|
||||
label: ?[*:0]const u8,
|
||||
wgsl_code: [*:0]const u8,
|
||||
) *ShaderModule {
|
||||
return device.createShaderModule(&ShaderModule.Descriptor{
|
||||
.next_in_chain = .{ .wgsl_descriptor = &.{
|
||||
.code = wgsl_code,
|
||||
} },
|
||||
.label = label,
|
||||
});
|
||||
}
|
||||
|
||||
pub inline fn createSwapChain(device: *Device, surface: ?*Surface, descriptor: *const SwapChain.Descriptor) *SwapChain {
|
||||
return Impl.deviceCreateSwapChain(device, surface, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn createTexture(device: *Device, descriptor: *const Texture.Descriptor) *Texture {
|
||||
return Impl.deviceCreateTexture(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn destroy(device: *Device) void {
|
||||
Impl.deviceDestroy(device);
|
||||
}
|
||||
|
||||
/// Call once with null to determine the array length, and again to fetch the feature list.
|
||||
///
|
||||
/// Consider using the enumerateFeaturesOwned helper.
|
||||
pub inline fn enumerateFeatures(device: *Device, features: ?[*]FeatureName) usize {
|
||||
return Impl.deviceEnumerateFeatures(device, features);
|
||||
}
|
||||
|
||||
/// Enumerates the adapter features, storing the result in an allocated slice which is owned by
|
||||
/// the caller.
|
||||
pub inline fn enumerateFeaturesOwned(device: *Device, allocator: std.mem.Allocator) ![]FeatureName {
|
||||
const count = device.enumerateFeatures(null);
|
||||
const data = try allocator.alloc(FeatureName, count);
|
||||
_ = device.enumerateFeatures(data.ptr);
|
||||
return data;
|
||||
}
|
||||
|
||||
pub inline fn forceLoss(device: *Device, reason: LostReason, message: [*:0]const u8) void {
|
||||
return Impl.deviceForceLoss(device, reason, message);
|
||||
}
|
||||
|
||||
pub inline fn getAdapter(device: *Device) *Adapter {
|
||||
return Impl.deviceGetAdapter(device);
|
||||
}
|
||||
|
||||
pub inline fn getLimits(device: *Device, limits: *SupportedLimits) bool {
|
||||
return Impl.deviceGetLimits(device, limits) != 0;
|
||||
}
|
||||
|
||||
pub inline fn getQueue(device: *Device) *Queue {
|
||||
return Impl.deviceGetQueue(device);
|
||||
}
|
||||
|
||||
pub inline fn hasFeature(device: *Device, feature: FeatureName) bool {
|
||||
return Impl.deviceHasFeature(device, feature) != 0;
|
||||
}
|
||||
|
||||
pub inline fn injectError(device: *Device, typ: ErrorType, message: [*:0]const u8) void {
|
||||
Impl.deviceInjectError(device, typ, message);
|
||||
}
|
||||
|
||||
pub inline fn popErrorScope(
|
||||
device: *Device,
|
||||
context: anytype,
|
||||
comptime callback: fn (ctx: @TypeOf(context), typ: ErrorType, message: [*:0]const u8) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(typ: ErrorType, message: [*:0]const u8, userdata: ?*anyopaque) callconv(.C) void {
|
||||
callback(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), typ, message);
|
||||
}
|
||||
};
|
||||
Impl.devicePopErrorScope(device, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn pushErrorScope(device: *Device, filter: ErrorFilter) void {
|
||||
Impl.devicePushErrorScope(device, filter);
|
||||
}
|
||||
|
||||
pub inline fn setDeviceLostCallback(
|
||||
device: *Device,
|
||||
context: anytype,
|
||||
comptime callback: ?fn (ctx: @TypeOf(context), reason: LostReason, message: [*:0]const u8) callconv(.Inline) void,
|
||||
) void {
|
||||
if (callback) |cb| {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(reason: LostReason, message: [*:0]const u8, userdata: ?*anyopaque) callconv(.C) void {
|
||||
cb(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), reason, message);
|
||||
}
|
||||
};
|
||||
Impl.deviceSetDeviceLostCallback(device, Helper.cCallback, if (Context == void) null else context);
|
||||
} else {
|
||||
Impl.deviceSetDeviceLostCallback(device, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn setLabel(device: *Device, label: [*:0]const u8) void {
|
||||
Impl.deviceSetLabel(device, label);
|
||||
}
|
||||
|
||||
pub inline fn setLoggingCallback(
|
||||
device: *Device,
|
||||
context: anytype,
|
||||
comptime callback: ?fn (ctx: @TypeOf(context), typ: LoggingType, message: [*:0]const u8) callconv(.Inline) void,
|
||||
) void {
|
||||
if (callback) |cb| {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(typ: LoggingType, message: [*:0]const u8, userdata: ?*anyopaque) callconv(.C) void {
|
||||
cb(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), typ, message);
|
||||
}
|
||||
};
|
||||
Impl.deviceSetLoggingCallback(device, Helper.cCallback, if (Context == void) null else context);
|
||||
} else {
|
||||
Impl.deviceSetLoggingCallback(device, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn setUncapturedErrorCallback(
|
||||
device: *Device,
|
||||
context: anytype,
|
||||
comptime callback: ?fn (ctx: @TypeOf(context), typ: ErrorType, message: [*:0]const u8) callconv(.Inline) void,
|
||||
) void {
|
||||
if (callback) |cb| {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(typ: ErrorType, message: [*:0]const u8, userdata: ?*anyopaque) callconv(.C) void {
|
||||
cb(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), typ, message);
|
||||
}
|
||||
};
|
||||
Impl.deviceSetUncapturedErrorCallback(device, Helper.cCallback, if (Context == void) null else context);
|
||||
} else {
|
||||
Impl.deviceSetUncapturedErrorCallback(device, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn tick(device: *Device) void {
|
||||
Impl.deviceTick(device);
|
||||
}
|
||||
|
||||
// Mach WebGPU extension. Supported with mach-gpu-dawn.
|
||||
//
|
||||
// When making Metal interop with other APIs, we need to be careful that QueueSubmit doesn't
|
||||
// mean that the operations will be visible to other APIs/Metal devices right away. macOS
|
||||
// does have a global queue of graphics operations, but the command buffers are inserted there
|
||||
// when they are "scheduled". Submitting other operations before the command buffer is
|
||||
// scheduled could lead to races in who gets scheduled first and incorrect rendering.
|
||||
pub inline fn machWaitForCommandsToBeScheduled(device: *Device) void {
|
||||
Impl.machDeviceWaitForCommandsToBeScheduled(device);
|
||||
}
|
||||
|
||||
pub inline fn validateTextureDescriptor(device: *Device, descriptor: *const Texture.Descriptor) void {
|
||||
Impl.deviceVlidateTextureDescriptor(device, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn reference(device: *Device) void {
|
||||
Impl.deviceReference(device);
|
||||
}
|
||||
|
||||
pub inline fn release(device: *Device) void {
|
||||
Impl.deviceRelease(device);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,245 +0,0 @@
|
|||
const std = @import("std");
|
||||
const util = @import("util.zig");
|
||||
const glfw = @import("mach-glfw");
|
||||
const gpu = @import("mach").gpu;
|
||||
|
||||
pub const GPUInterface = gpu.dawn.Interface;
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
var allocator = gpa.allocator();
|
||||
|
||||
try gpu.Impl.init(allocator, .{});
|
||||
const setup = try setupWindow(allocator);
|
||||
const framebuffer_size = setup.window.getFramebufferSize();
|
||||
|
||||
const window_data = try allocator.create(WindowData);
|
||||
window_data.* = .{
|
||||
.surface = setup.surface,
|
||||
.swap_chain = null,
|
||||
.swap_chain_format = undefined,
|
||||
.current_desc = undefined,
|
||||
.target_desc = undefined,
|
||||
};
|
||||
setup.window.setUserPointer(window_data);
|
||||
|
||||
window_data.swap_chain_format = .bgra8_unorm;
|
||||
const descriptor = gpu.SwapChain.Descriptor{
|
||||
.label = "basic swap chain",
|
||||
.usage = .{ .render_attachment = true },
|
||||
.format = window_data.swap_chain_format,
|
||||
.width = framebuffer_size.width,
|
||||
.height = framebuffer_size.height,
|
||||
.present_mode = .fifo,
|
||||
};
|
||||
|
||||
window_data.current_desc = descriptor;
|
||||
window_data.target_desc = descriptor;
|
||||
|
||||
const vs =
|
||||
\\ @vertex fn main(
|
||||
\\ @builtin(vertex_index) VertexIndex : u32
|
||||
\\ ) -> @builtin(position) vec4<f32> {
|
||||
\\ var pos = array<vec2<f32>, 3>(
|
||||
\\ vec2<f32>( 0.0, 0.5),
|
||||
\\ vec2<f32>(-0.5, -0.5),
|
||||
\\ vec2<f32>( 0.5, -0.5)
|
||||
\\ );
|
||||
\\ return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
||||
\\ }
|
||||
;
|
||||
const vs_module = setup.device.createShaderModuleWGSL("my vertex shader", vs);
|
||||
|
||||
const fs =
|
||||
\\ @fragment fn main() -> @location(0) vec4<f32> {
|
||||
\\ return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
\\ }
|
||||
;
|
||||
const fs_module = setup.device.createShaderModuleWGSL("my fragment shader", fs);
|
||||
|
||||
// Fragment state
|
||||
const blend = gpu.BlendState{
|
||||
.color = .{
|
||||
.dst_factor = .one,
|
||||
},
|
||||
.alpha = .{
|
||||
.dst_factor = .one,
|
||||
},
|
||||
};
|
||||
const color_target = gpu.ColorTargetState{
|
||||
.format = window_data.swap_chain_format,
|
||||
.blend = &blend,
|
||||
.write_mask = gpu.ColorWriteMaskFlags.all,
|
||||
};
|
||||
const fragment = gpu.FragmentState.init(.{
|
||||
.module = fs_module,
|
||||
.entry_point = "main",
|
||||
.targets = &.{color_target},
|
||||
});
|
||||
const pipeline_descriptor = gpu.RenderPipeline.Descriptor{
|
||||
.fragment = &fragment,
|
||||
.layout = null,
|
||||
.depth_stencil = null,
|
||||
.vertex = gpu.VertexState{
|
||||
.module = vs_module,
|
||||
.entry_point = "main",
|
||||
},
|
||||
.multisample = .{},
|
||||
.primitive = .{},
|
||||
};
|
||||
const pipeline = setup.device.createRenderPipeline(&pipeline_descriptor);
|
||||
|
||||
vs_module.release();
|
||||
fs_module.release();
|
||||
|
||||
// Reconfigure the swap chain with the new framebuffer width/height, otherwise e.g. the Vulkan
|
||||
// device would be lost after a resize.
|
||||
setup.window.setFramebufferSizeCallback((struct {
|
||||
fn callback(window: glfw.Window, width: u32, height: u32) void {
|
||||
const pl = window.getUserPointer(WindowData);
|
||||
pl.?.target_desc.width = width;
|
||||
pl.?.target_desc.height = height;
|
||||
}
|
||||
}).callback);
|
||||
|
||||
const queue = setup.device.getQueue();
|
||||
while (!setup.window.shouldClose()) {
|
||||
try frame(.{
|
||||
.window = setup.window,
|
||||
.device = setup.device,
|
||||
.pipeline = pipeline,
|
||||
.queue = queue,
|
||||
});
|
||||
std.time.sleep(16 * std.time.ns_per_ms);
|
||||
}
|
||||
}
|
||||
|
||||
const WindowData = struct {
|
||||
surface: ?*gpu.Surface,
|
||||
swap_chain: ?*gpu.SwapChain,
|
||||
swap_chain_format: gpu.Texture.Format,
|
||||
current_desc: gpu.SwapChain.Descriptor,
|
||||
target_desc: gpu.SwapChain.Descriptor,
|
||||
};
|
||||
|
||||
const FrameParams = struct {
|
||||
window: glfw.Window,
|
||||
device: *gpu.Device,
|
||||
pipeline: *gpu.RenderPipeline,
|
||||
queue: *gpu.Queue,
|
||||
};
|
||||
|
||||
fn frame(params: FrameParams) !void {
|
||||
glfw.pollEvents();
|
||||
params.device.tick();
|
||||
const pl = params.window.getUserPointer(WindowData).?;
|
||||
if (pl.swap_chain == null or !std.meta.eql(pl.current_desc, pl.target_desc)) {
|
||||
pl.swap_chain = params.device.createSwapChain(pl.surface, &pl.target_desc);
|
||||
pl.current_desc = pl.target_desc;
|
||||
}
|
||||
|
||||
const back_buffer_view = pl.swap_chain.?.getCurrentTextureView().?;
|
||||
const color_attachment = gpu.RenderPassColorAttachment{
|
||||
.view = back_buffer_view,
|
||||
.resolve_target = null,
|
||||
.clear_value = std.mem.zeroes(gpu.Color),
|
||||
.load_op = .clear,
|
||||
.store_op = .store,
|
||||
};
|
||||
|
||||
const encoder = params.device.createCommandEncoder(null);
|
||||
const render_pass_info = gpu.RenderPassDescriptor.init(.{
|
||||
.color_attachments = &.{color_attachment},
|
||||
});
|
||||
const pass = encoder.beginRenderPass(&render_pass_info);
|
||||
pass.setPipeline(params.pipeline);
|
||||
pass.draw(3, 1, 0, 0);
|
||||
pass.end();
|
||||
pass.release();
|
||||
|
||||
var command = encoder.finish(null);
|
||||
encoder.release();
|
||||
|
||||
params.queue.submit(&[_]*gpu.CommandBuffer{command});
|
||||
command.release();
|
||||
pl.swap_chain.?.present();
|
||||
back_buffer_view.release();
|
||||
}
|
||||
|
||||
const Setup = struct {
|
||||
instance: *gpu.Instance,
|
||||
adapter: *gpu.Adapter,
|
||||
device: *gpu.Device,
|
||||
window: glfw.Window,
|
||||
surface: *gpu.Surface,
|
||||
};
|
||||
|
||||
/// Default GLFW error handling callback
|
||||
fn errorCallback(error_code: glfw.ErrorCode, description: [:0]const u8) void {
|
||||
std.log.err("glfw: {}: {s}\n", .{ error_code, description });
|
||||
}
|
||||
|
||||
pub fn setupWindow(allocator: std.mem.Allocator) !Setup {
|
||||
const backend_type = try util.detectBackendType(allocator);
|
||||
|
||||
glfw.setErrorCallback(errorCallback);
|
||||
if (!glfw.init(.{})) {
|
||||
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
// Create the test window and discover adapters using it (esp. for OpenGL)
|
||||
var hints = util.glfwWindowHintsForBackend(backend_type);
|
||||
hints.cocoa_retina_framebuffer = true;
|
||||
const window = glfw.Window.create(640, 480, "mach/gpu window", null, null, hints) orelse {
|
||||
std.log.err("failed to create GLFW window: {?s}", .{glfw.getErrorString()});
|
||||
std.process.exit(1);
|
||||
};
|
||||
|
||||
if (backend_type == .opengl) glfw.makeContextCurrent(window);
|
||||
if (backend_type == .opengles) glfw.makeContextCurrent(window);
|
||||
|
||||
const instance = gpu.createInstance(null);
|
||||
if (instance == null) {
|
||||
std.debug.print("failed to create GPU instance\n", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
const surface = try util.createSurfaceForWindow(instance.?, window, comptime util.detectGLFWOptions());
|
||||
|
||||
var response: util.RequestAdapterResponse = undefined;
|
||||
instance.?.requestAdapter(&gpu.RequestAdapterOptions{
|
||||
.compatible_surface = surface,
|
||||
.power_preference = .undefined,
|
||||
.force_fallback_adapter = .false,
|
||||
}, &response, util.requestAdapterCallback);
|
||||
if (response.status != .success) {
|
||||
std.debug.print("failed to create GPU adapter: {s}\n", .{response.message.?});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
// Print which adapter we are using.
|
||||
var props = std.mem.zeroes(gpu.Adapter.Properties);
|
||||
response.adapter.?.getProperties(&props);
|
||||
std.debug.print("found {s} backend on {s} adapter: {s}, {s}\n", .{
|
||||
props.backend_type.name(),
|
||||
props.adapter_type.name(),
|
||||
props.name,
|
||||
props.driver_description,
|
||||
});
|
||||
|
||||
// Create a device with default limits/features.
|
||||
const device = response.adapter.?.createDevice(null);
|
||||
if (device == null) {
|
||||
std.debug.print("failed to create GPU device\n", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
device.?.setUncapturedErrorCallback({}, util.printUnhandledErrorCallback);
|
||||
return Setup{
|
||||
.instance = instance.?,
|
||||
.adapter = response.adapter.?,
|
||||
.device = device.?,
|
||||
.window = window,
|
||||
.surface = surface,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// Extracted from `zig translate-c tmp.c` with `#include <objc/message.h>` in the file.
|
||||
pub const SEL = opaque {};
|
||||
pub const Class = opaque {};
|
||||
|
||||
pub extern fn sel_getUid(str: [*c]const u8) ?*SEL;
|
||||
pub extern fn objc_getClass(name: [*c]const u8) ?*Class;
|
||||
pub extern fn objc_msgSend() void;
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
const std = @import("std");
|
||||
|
||||
const glfw = @import("mach-glfw");
|
||||
const gpu = @import("mach").gpu;
|
||||
const objc = @import("objc_message.zig");
|
||||
|
||||
pub inline fn printUnhandledErrorCallback(_: void, typ: gpu.ErrorType, message: [*:0]const u8) void {
|
||||
switch (typ) {
|
||||
.validation => std.log.err("gpu: validation error: {s}\n", .{message}),
|
||||
.out_of_memory => std.log.err("gpu: out of memory: {s}\n", .{message}),
|
||||
.device_lost => std.log.err("gpu: device lost: {s}\n", .{message}),
|
||||
.unknown => std.log.err("gpu: unknown error: {s}\n", .{message}),
|
||||
else => unreachable,
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
fn getEnvVarOwned(allocator: std.mem.Allocator, key: []const u8) error{ OutOfMemory, InvalidUtf8, InvalidWtf8 }!?[]u8 {
|
||||
return std.process.getEnvVarOwned(allocator, key) catch |err| switch (err) {
|
||||
error.EnvironmentVariableNotFound => @as(?[]u8, null),
|
||||
else => |e| e,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn detectBackendType(allocator: std.mem.Allocator) !gpu.BackendType {
|
||||
const MACH_GPU_BACKEND = try getEnvVarOwned(allocator, "MACH_GPU_BACKEND");
|
||||
if (MACH_GPU_BACKEND) |backend| {
|
||||
defer allocator.free(backend);
|
||||
if (std.ascii.eqlIgnoreCase(backend, "null")) return .null;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "d3d11")) return .d3d11;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "d3d12")) return .d3d12;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "metal")) return .metal;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "vulkan")) return .vulkan;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "opengl")) return .opengl;
|
||||
if (std.ascii.eqlIgnoreCase(backend, "opengles")) return .opengles;
|
||||
@panic("unknown MACH_GPU_BACKEND type");
|
||||
}
|
||||
|
||||
const target = @import("builtin").target;
|
||||
if (target.isDarwin()) return .metal;
|
||||
if (target.os.tag == .windows) return .d3d12;
|
||||
return .vulkan;
|
||||
}
|
||||
|
||||
pub const RequestAdapterResponse = struct {
|
||||
status: gpu.RequestAdapterStatus,
|
||||
adapter: ?*gpu.Adapter,
|
||||
message: ?[*:0]const u8,
|
||||
};
|
||||
|
||||
pub inline fn requestAdapterCallback(
|
||||
context: *RequestAdapterResponse,
|
||||
status: gpu.RequestAdapterStatus,
|
||||
adapter: ?*gpu.Adapter,
|
||||
message: ?[*:0]const u8,
|
||||
) void {
|
||||
context.* = RequestAdapterResponse{
|
||||
.status = status,
|
||||
.adapter = adapter,
|
||||
.message = message,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn glfwWindowHintsForBackend(backend: gpu.BackendType) glfw.Window.Hints {
|
||||
return switch (backend) {
|
||||
.opengl => .{
|
||||
// Ask for OpenGL 4.4 which is what the GL backend requires for compute shaders and
|
||||
// texture views.
|
||||
.context_version_major = 4,
|
||||
.context_version_minor = 4,
|
||||
.opengl_forward_compat = true,
|
||||
.opengl_profile = .opengl_core_profile,
|
||||
},
|
||||
.opengles => .{
|
||||
.context_version_major = 3,
|
||||
.context_version_minor = 1,
|
||||
.client_api = .opengl_es_api,
|
||||
.context_creation_api = .egl_context_api,
|
||||
},
|
||||
else => .{
|
||||
// Without this GLFW will initialize a GL context on the window, which prevents using
|
||||
// the window with other APIs (by crashing in weird ways).
|
||||
.client_api = .no_api,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn detectGLFWOptions() glfw.BackendOptions {
|
||||
const target = @import("builtin").target;
|
||||
if (target.isDarwin()) return .{ .cocoa = true };
|
||||
return switch (target.os.tag) {
|
||||
.windows => .{ .win32 = true },
|
||||
.linux => .{ .x11 = true, .wayland = true },
|
||||
else => .{},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createSurfaceForWindow(
|
||||
instance: *gpu.Instance,
|
||||
window: glfw.Window,
|
||||
comptime glfw_options: glfw.BackendOptions,
|
||||
) !*gpu.Surface {
|
||||
const glfw_native = glfw.Native(glfw_options);
|
||||
if (glfw_options.win32) {
|
||||
return instance.createSurface(&gpu.Surface.Descriptor{
|
||||
.next_in_chain = .{
|
||||
.from_windows_hwnd = &.{
|
||||
.hinstance = std.os.windows.kernel32.GetModuleHandleW(null).?,
|
||||
.hwnd = glfw_native.getWin32Window(window),
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if (glfw_options.x11) {
|
||||
return instance.createSurface(&gpu.Surface.Descriptor{
|
||||
.next_in_chain = .{
|
||||
.from_xlib_window = &.{
|
||||
.display = glfw_native.getX11Display(),
|
||||
.window = glfw_native.getX11Window(window),
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if (glfw_options.wayland) {
|
||||
return instance.createSurface(&gpu.Surface.Descriptor{
|
||||
.next_in_chain = .{
|
||||
.from_wayland_surface = &.{
|
||||
.display = glfw_native.getWaylandDisplay(),
|
||||
.surface = glfw_native.getWaylandWindow(window),
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if (glfw_options.cocoa) {
|
||||
const pool = try AutoReleasePool.init();
|
||||
defer AutoReleasePool.release(pool);
|
||||
|
||||
const ns_window = glfw_native.getCocoaWindow(window);
|
||||
const ns_view = msgSend(ns_window, "contentView", .{}, *anyopaque); // [nsWindow contentView]
|
||||
|
||||
// Create a CAMetalLayer that covers the whole window that will be passed to CreateSurface.
|
||||
msgSend(ns_view, "setWantsLayer:", .{true}, void); // [view setWantsLayer:YES]
|
||||
const layer = msgSend(objc.objc_getClass("CAMetalLayer"), "layer", .{}, ?*anyopaque); // [CAMetalLayer layer]
|
||||
if (layer == null) @panic("failed to create Metal layer");
|
||||
msgSend(ns_view, "setLayer:", .{layer.?}, void); // [view setLayer:layer]
|
||||
|
||||
// Use retina if the window was created with retina support.
|
||||
const scale_factor = msgSend(ns_window, "backingScaleFactor", .{}, f64); // [ns_window backingScaleFactor]
|
||||
msgSend(layer.?, "setContentsScale:", .{scale_factor}, void); // [layer setContentsScale:scale_factor]
|
||||
|
||||
return instance.createSurface(&gpu.Surface.Descriptor{
|
||||
.next_in_chain = .{
|
||||
.from_metal_layer = &.{ .layer = layer.? },
|
||||
},
|
||||
});
|
||||
} else unreachable;
|
||||
}
|
||||
|
||||
pub const AutoReleasePool = if (!@import("builtin").target.isDarwin()) opaque {
|
||||
pub fn init() error{OutOfMemory}!?*AutoReleasePool {
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn release(pool: ?*AutoReleasePool) void {
|
||||
_ = pool;
|
||||
return;
|
||||
}
|
||||
} else opaque {
|
||||
pub fn init() error{OutOfMemory}!?*AutoReleasePool {
|
||||
// pool = [NSAutoreleasePool alloc];
|
||||
var pool = msgSend(objc.objc_getClass("NSAutoreleasePool"), "alloc", .{}, ?*AutoReleasePool);
|
||||
if (pool == null) return error.OutOfMemory;
|
||||
|
||||
// pool = [pool init];
|
||||
pool = msgSend(pool, "init", .{}, ?*AutoReleasePool);
|
||||
if (pool == null) unreachable;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
pub fn release(pool: ?*AutoReleasePool) void {
|
||||
// [pool release];
|
||||
msgSend(pool, "release", .{}, void);
|
||||
}
|
||||
};
|
||||
|
||||
// Borrowed from https://github.com/hazeycode/zig-objcrt
|
||||
pub fn msgSend(obj: anytype, sel_name: [:0]const u8, args: anytype, comptime ReturnType: type) ReturnType {
|
||||
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,
|
||||
2 => *const fn (@TypeOf(obj), ?*objc.SEL, args_meta[0].type, args_meta[1].type) 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,
|
||||
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,
|
||||
else => @compileError("Unsupported number of args"),
|
||||
};
|
||||
|
||||
const func = @as(FnType, @ptrCast(&objc.objc_msgSend));
|
||||
const sel = objc.sel_getUid(@as([*c]const u8, @ptrCast(sel_name)));
|
||||
|
||||
return @call(.auto, func, .{ obj, sel } ++ args);
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const TextureView = @import("texture_view.zig").TextureView;
|
||||
const Origin2D = @import("main.zig").Origin2D;
|
||||
const Extent2D = @import("main.zig").Extent2D;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const ExternalTexture = opaque {
|
||||
pub const BindingEntry = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .external_texture_binding_entry },
|
||||
external_texture: *ExternalTexture,
|
||||
};
|
||||
|
||||
pub const BindingLayout = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .external_texture_binding_layout },
|
||||
};
|
||||
|
||||
const Rotation = enum(u32) {
|
||||
rotate_0_degrees = 0x00000000,
|
||||
rotate_90_degrees = 0x00000001,
|
||||
rotate_180_degrees = 0x00000002,
|
||||
rotate_270_degrees = 0x00000003,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
plane0: *TextureView,
|
||||
plane1: ?*TextureView = null,
|
||||
visible_origin: Origin2D,
|
||||
visible_size: Extent2D,
|
||||
do_yuv_to_rgb_conversion_only: Bool32 = .false,
|
||||
yuv_to_rgb_conversion_matrix: ?*const [12]f32 = null,
|
||||
src_transform_function_parameters: *const [7]f32,
|
||||
dst_transform_function_parameters: *const [7]f32,
|
||||
gamut_conversion_matrix: *const [9]f32,
|
||||
flip_y: Bool32,
|
||||
rotation: Rotation,
|
||||
};
|
||||
|
||||
pub inline fn destroy(external_texture: *ExternalTexture) void {
|
||||
Impl.externalTextureDestroy(external_texture);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(external_texture: *ExternalTexture, label: [*:0]const u8) void {
|
||||
Impl.externalTextureSetLabel(external_texture, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(external_texture: *ExternalTexture) void {
|
||||
Impl.externalTextureReference(external_texture);
|
||||
}
|
||||
|
||||
pub inline fn release(external_texture: *ExternalTexture) void {
|
||||
Impl.externalTextureRelease(external_texture);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const RequestAdapterStatus = @import("main.zig").RequestAdapterStatus;
|
||||
const Surface = @import("surface.zig").Surface;
|
||||
const Adapter = @import("adapter.zig").Adapter;
|
||||
const RequestAdapterOptions = @import("main.zig").RequestAdapterOptions;
|
||||
const RequestAdapterCallback = @import("main.zig").RequestAdapterCallback;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const dawn = @import("dawn.zig");
|
||||
|
||||
pub const Instance = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
dawn_toggles_descriptor: *const dawn.TogglesDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
};
|
||||
|
||||
pub inline fn createSurface(instance: *Instance, descriptor: *const Surface.Descriptor) *Surface {
|
||||
return Impl.instanceCreateSurface(instance, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn processEvents(instance: *Instance) void {
|
||||
Impl.instanceProcessEvents(instance);
|
||||
}
|
||||
|
||||
pub inline fn requestAdapter(
|
||||
instance: *Instance,
|
||||
options: ?*const RequestAdapterOptions,
|
||||
context: anytype,
|
||||
comptime callback: fn (
|
||||
ctx: @TypeOf(context),
|
||||
status: RequestAdapterStatus,
|
||||
adapter: ?*Adapter,
|
||||
message: ?[*:0]const u8,
|
||||
) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(
|
||||
status: RequestAdapterStatus,
|
||||
adapter: ?*Adapter,
|
||||
message: ?[*:0]const u8,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void {
|
||||
callback(
|
||||
if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))),
|
||||
status,
|
||||
adapter,
|
||||
message,
|
||||
);
|
||||
}
|
||||
};
|
||||
Impl.instanceRequestAdapter(instance, options, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn reference(instance: *Instance) void {
|
||||
Impl.instanceReference(instance);
|
||||
}
|
||||
|
||||
pub inline fn release(instance: *Instance) void {
|
||||
Impl.instanceRelease(instance);
|
||||
}
|
||||
};
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,28 +0,0 @@
|
|||
#include <dawn/native/DawnNative.h>
|
||||
#include "mach_dawn.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
namespace dawn::native::metal {
|
||||
DAWN_NATIVE_EXPORT void WaitForCommandsToBeScheduled(WGPUDevice device);
|
||||
} // namespace dawn::native
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MACH_EXPORT const DawnProcTable machDawnGetProcTable() {
|
||||
return dawn::native::GetProcs();
|
||||
}
|
||||
|
||||
MACH_EXPORT void machDawnDeviceWaitForCommandsToBeScheduled(WGPUDevice device) {
|
||||
#if defined(__APPLE__)
|
||||
return dawn::native::metal::WaitForCommandsToBeScheduled(device);
|
||||
#else
|
||||
return;
|
||||
#endif // defined(__APPLE__)
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef MACH_DAWN_C_H_
|
||||
#define MACH_DAWN_C_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MACH_DAWN_C_SHARED_LIBRARY)
|
||||
# if defined(_WIN32)
|
||||
# if defined(MACH_DAWN_C_IMPLEMENTATION)
|
||||
# define MACH_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define MACH_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else // defined(_WIN32)
|
||||
# if defined(MACH_DAWN_C_IMPLEMENTATION)
|
||||
# define MACH_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define MACH_EXPORT
|
||||
# endif
|
||||
# endif // defined(_WIN32)
|
||||
#else // defined(MACH_DAWN_C_SHARED_LIBRARY)
|
||||
# define MACH_EXPORT
|
||||
#endif // defined(MACH_DAWN_C_SHARED_LIBRARY)
|
||||
|
||||
#include <dawn/webgpu.h>
|
||||
#include <dawn/dawn_proc_table.h>
|
||||
|
||||
MACH_EXPORT const DawnProcTable machDawnGetProcTable();
|
||||
MACH_EXPORT void machDawnDeviceWaitForCommandsToBeScheduled(WGPUDevice device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // MACH_DAWN_C_H_
|
||||
1025
src/gpu/main.zig
1025
src/gpu/main.zig
File diff suppressed because it is too large
Load diff
|
|
@ -1,38 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const PipelineLayout = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
bind_group_layout_count: usize = 0,
|
||||
bind_group_layouts: ?[*]const *BindGroupLayout = null,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
bind_group_layouts: ?[]const *BindGroupLayout = null,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.bind_group_layout_count = if (v.bind_group_layouts) |e| e.len else 0,
|
||||
.bind_group_layouts = if (v.bind_group_layouts) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn setLabel(pipeline_layout: *PipelineLayout, label: [*:0]const u8) void {
|
||||
Impl.pipelineLayoutSetLabel(pipeline_layout, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(pipeline_layout: *PipelineLayout) void {
|
||||
Impl.pipelineLayoutReference(pipeline_layout);
|
||||
}
|
||||
|
||||
pub inline fn release(pipeline_layout: *PipelineLayout) void {
|
||||
Impl.pipelineLayoutRelease(pipeline_layout);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const PipelineStatisticName = @import("main.zig").PipelineStatisticName;
|
||||
const QueryType = @import("main.zig").QueryType;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const QuerySet = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
type: QueryType,
|
||||
count: u32,
|
||||
pipeline_statistics: ?[*]const PipelineStatisticName = null,
|
||||
pipeline_statistics_count: usize = 0,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
type: QueryType,
|
||||
count: u32,
|
||||
pipeline_statistics: ?[]const PipelineStatisticName = null,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.type = v.type,
|
||||
.count = v.count,
|
||||
.pipeline_statistics_count = if (v.pipeline_statistics) |e| e.len else 0,
|
||||
.pipeline_statistics = if (v.pipeline_statistics) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn destroy(query_set: *QuerySet) void {
|
||||
Impl.querySetDestroy(query_set);
|
||||
}
|
||||
|
||||
pub inline fn getCount(query_set: *QuerySet) u32 {
|
||||
return Impl.querySetGetCount(query_set);
|
||||
}
|
||||
|
||||
pub inline fn getType(query_set: *QuerySet) QueryType {
|
||||
return Impl.querySetGetType(query_set);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(query_set: *QuerySet, label: [*:0]const u8) void {
|
||||
Impl.querySetSetLabel(query_set, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(query_set: *QuerySet) void {
|
||||
Impl.querySetReference(query_set);
|
||||
}
|
||||
|
||||
pub inline fn release(query_set: *QuerySet) void {
|
||||
Impl.querySetRelease(query_set);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
const std = @import("std");
|
||||
const CommandBuffer = @import("command_buffer.zig").CommandBuffer;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
const ImageCopyTexture = @import("main.zig").ImageCopyTexture;
|
||||
const ImageCopyExternalTexture = @import("main.zig").ImageCopyExternalTexture;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const Extent3D = @import("main.zig").Extent3D;
|
||||
const CopyTextureForBrowserOptions = @import("main.zig").CopyTextureForBrowserOptions;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const Queue = opaque {
|
||||
pub const WorkDoneCallback = *const fn (
|
||||
status: WorkDoneStatus,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void;
|
||||
|
||||
pub const WorkDoneStatus = enum(u32) {
|
||||
success = 0x00000000,
|
||||
err = 0x00000001,
|
||||
unknown = 0x00000002,
|
||||
device_lost = 0x00000003,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub inline fn copyExternalTextureForBrowser(queue: *Queue, source: *const ImageCopyExternalTexture, destination: *const ImageCopyTexture, copy_size: *const Extent3D, options: *const CopyTextureForBrowserOptions) void {
|
||||
Impl.queueCopyExternalTextureForBrowser(queue, source, destination, copy_size, options);
|
||||
}
|
||||
|
||||
pub inline fn copyTextureForBrowser(queue: *Queue, source: *const ImageCopyTexture, destination: *const ImageCopyTexture, copy_size: *const Extent3D, options: *const CopyTextureForBrowserOptions) void {
|
||||
Impl.queueCopyTextureForBrowser(queue, source, destination, copy_size, options);
|
||||
}
|
||||
|
||||
// TODO: dawn: does not allow unsetting this callback to null
|
||||
pub inline fn onSubmittedWorkDone(
|
||||
queue: *Queue,
|
||||
signal_value: u64,
|
||||
context: anytype,
|
||||
comptime callback: fn (ctx: @TypeOf(context), status: WorkDoneStatus) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(status: WorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void {
|
||||
callback(if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))), status);
|
||||
}
|
||||
};
|
||||
Impl.queueOnSubmittedWorkDone(queue, signal_value, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(queue: *Queue, label: [*:0]const u8) void {
|
||||
Impl.queueSetLabel(queue, label);
|
||||
}
|
||||
|
||||
pub inline fn submit(queue: *Queue, commands: []const *const CommandBuffer) void {
|
||||
Impl.queueSubmit(queue, commands.len, commands.ptr);
|
||||
}
|
||||
|
||||
pub inline fn writeBuffer(
|
||||
queue: *Queue,
|
||||
buffer: *Buffer,
|
||||
buffer_offset_bytes: u64,
|
||||
data_slice: anytype,
|
||||
) void {
|
||||
Impl.queueWriteBuffer(
|
||||
queue,
|
||||
buffer,
|
||||
buffer_offset_bytes,
|
||||
@as(*const anyopaque, @ptrCast(std.mem.sliceAsBytes(data_slice).ptr)),
|
||||
data_slice.len * @sizeOf(std.meta.Elem(@TypeOf(data_slice))),
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn writeTexture(
|
||||
queue: *Queue,
|
||||
destination: *const ImageCopyTexture,
|
||||
data_layout: *const Texture.DataLayout,
|
||||
write_size: *const Extent3D,
|
||||
data_slice: anytype,
|
||||
) void {
|
||||
Impl.queueWriteTexture(
|
||||
queue,
|
||||
destination,
|
||||
@as(*const anyopaque, @ptrCast(std.mem.sliceAsBytes(data_slice).ptr)),
|
||||
@as(usize, @intCast(data_slice.len)) * @sizeOf(std.meta.Elem(@TypeOf(data_slice))),
|
||||
data_layout,
|
||||
write_size,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn reference(queue: *Queue) void {
|
||||
Impl.queueReference(queue);
|
||||
}
|
||||
|
||||
pub inline fn release(queue: *Queue) void {
|
||||
Impl.queueRelease(queue);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const RenderBundle = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub inline fn setLabel(render_bundle: *RenderBundle, label: [*:0]const u8) void {
|
||||
Impl.renderBundleSetLabel(render_bundle, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(render_bundle: *RenderBundle) void {
|
||||
Impl.renderBundleReference(render_bundle);
|
||||
}
|
||||
|
||||
pub inline fn release(render_bundle: *RenderBundle) void {
|
||||
Impl.renderBundleRelease(render_bundle);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
const Texture = @import("texture.zig").Texture;
|
||||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const BindGroup = @import("bind_group.zig").BindGroup;
|
||||
const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
|
||||
const RenderBundle = @import("render_bundle.zig").RenderBundle;
|
||||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const IndexFormat = @import("main.zig").IndexFormat;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const RenderBundleEncoder = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
color_formats_count: usize = 0,
|
||||
color_formats: ?[*]const Texture.Format = null,
|
||||
depth_stencil_format: Texture.Format = .undefined,
|
||||
sample_count: u32 = 1,
|
||||
depth_read_only: Bool32 = .false,
|
||||
stencil_read_only: Bool32 = .false,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
color_formats: ?[]const Texture.Format = null,
|
||||
depth_stencil_format: Texture.Format = .undefined,
|
||||
sample_count: u32 = 1,
|
||||
depth_read_only: bool = false,
|
||||
stencil_read_only: bool = false,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.color_formats_count = if (v.color_formats) |e| e.len else 0,
|
||||
.color_formats = if (v.color_formats) |e| e.ptr else null,
|
||||
.depth_stencil_format = v.depth_stencil_format,
|
||||
.sample_count = v.sample_count,
|
||||
.depth_read_only = Bool32.from(v.depth_read_only),
|
||||
.stencil_read_only = Bool32.from(v.stencil_read_only),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Default `instance_count`: 1
|
||||
/// Default `first_vertex`: 0
|
||||
/// Default `first_instance`: 0
|
||||
pub inline fn draw(render_bundle_encoder: *RenderBundleEncoder, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void {
|
||||
Impl.renderBundleEncoderDraw(render_bundle_encoder, vertex_count, instance_count, first_vertex, first_instance);
|
||||
}
|
||||
|
||||
/// Default `instance_count`: 1
|
||||
/// Default `first_index`: 0
|
||||
/// Default `base_vertex`: 0
|
||||
/// Default `first_instance`: 0
|
||||
pub inline fn drawIndexed(render_bundle_encoder: *RenderBundleEncoder, index_count: u32, instance_count: u32, first_index: u32, base_vertex: i32, first_instance: u32) void {
|
||||
Impl.renderBundleEncoderDrawIndexed(render_bundle_encoder, index_count, instance_count, first_index, base_vertex, first_instance);
|
||||
}
|
||||
|
||||
pub inline fn drawIndexedIndirect(render_bundle_encoder: *RenderBundleEncoder, indirect_buffer: *Buffer, indirect_offset: u64) void {
|
||||
Impl.renderBundleEncoderDrawIndexedIndirect(render_bundle_encoder, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
pub inline fn drawIndirect(render_bundle_encoder: *RenderBundleEncoder, indirect_buffer: *Buffer, indirect_offset: u64) void {
|
||||
Impl.renderBundleEncoderDrawIndirect(render_bundle_encoder, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
pub inline fn finish(render_bundle_encoder: *RenderBundleEncoder, descriptor: ?*const RenderBundle.Descriptor) *RenderBundle {
|
||||
return Impl.renderBundleEncoderFinish(render_bundle_encoder, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn insertDebugMarker(render_bundle_encoder: *RenderBundleEncoder, marker_label: [*:0]const u8) void {
|
||||
Impl.renderBundleEncoderInsertDebugMarker(render_bundle_encoder, marker_label);
|
||||
}
|
||||
|
||||
pub inline fn popDebugGroup(render_bundle_encoder: *RenderBundleEncoder) void {
|
||||
Impl.renderBundleEncoderPopDebugGroup(render_bundle_encoder);
|
||||
}
|
||||
|
||||
pub inline fn pushDebugGroup(render_bundle_encoder: *RenderBundleEncoder, group_label: [*:0]const u8) void {
|
||||
Impl.renderBundleEncoderPushDebugGroup(render_bundle_encoder, group_label);
|
||||
}
|
||||
|
||||
/// Default `dynamic_offsets`: `null`
|
||||
pub inline fn setBindGroup(render_bundle_encoder: *RenderBundleEncoder, group_index: u32, group: *BindGroup, dynamic_offsets: ?[]const u32) void {
|
||||
Impl.renderBundleEncoderSetBindGroup(
|
||||
render_bundle_encoder,
|
||||
group_index,
|
||||
group,
|
||||
if (dynamic_offsets) |v| v.len else 0,
|
||||
if (dynamic_offsets) |v| v.ptr else null,
|
||||
);
|
||||
}
|
||||
|
||||
/// Default `offset`: 0
|
||||
/// Default `size`: `gpu.whole_size`
|
||||
pub inline fn setIndexBuffer(render_bundle_encoder: *RenderBundleEncoder, buffer: *Buffer, format: IndexFormat, offset: u64, size: u64) void {
|
||||
Impl.renderBundleEncoderSetIndexBuffer(render_bundle_encoder, buffer, format, offset, size);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(render_bundle_encoder: *RenderBundleEncoder, label: [*:0]const u8) void {
|
||||
Impl.renderBundleEncoderSetLabel(render_bundle_encoder, label);
|
||||
}
|
||||
|
||||
pub inline fn setPipeline(render_bundle_encoder: *RenderBundleEncoder, pipeline: *RenderPipeline) void {
|
||||
Impl.renderBundleEncoderSetPipeline(render_bundle_encoder, pipeline);
|
||||
}
|
||||
|
||||
/// Default `offset`: 0
|
||||
/// Default `size`: `gpu.whole_size`
|
||||
pub inline fn setVertexBuffer(render_bundle_encoder: *RenderBundleEncoder, slot: u32, buffer: *Buffer, offset: u64, size: u64) void {
|
||||
Impl.renderBundleEncoderSetVertexBuffer(render_bundle_encoder, slot, buffer, offset, size);
|
||||
}
|
||||
|
||||
pub inline fn reference(render_bundle_encoder: *RenderBundleEncoder) void {
|
||||
Impl.renderBundleEncoderReference(render_bundle_encoder);
|
||||
}
|
||||
|
||||
pub inline fn release(render_bundle_encoder: *RenderBundleEncoder) void {
|
||||
Impl.renderBundleEncoderRelease(render_bundle_encoder);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
const Buffer = @import("buffer.zig").Buffer;
|
||||
const RenderBundle = @import("render_bundle.zig").RenderBundle;
|
||||
const BindGroup = @import("bind_group.zig").BindGroup;
|
||||
const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
|
||||
const QuerySet = @import("query_set.zig").QuerySet;
|
||||
const Color = @import("main.zig").Color;
|
||||
const IndexFormat = @import("main.zig").IndexFormat;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const RenderPassEncoder = opaque {
|
||||
pub inline fn beginOcclusionQuery(render_pass_encoder: *RenderPassEncoder, query_index: u32) void {
|
||||
Impl.renderPassEncoderBeginOcclusionQuery(render_pass_encoder, query_index);
|
||||
}
|
||||
|
||||
/// Default `instance_count`: 1
|
||||
/// Default `first_vertex`: 0
|
||||
/// Default `first_instance`: 0
|
||||
pub inline fn draw(render_pass_encoder: *RenderPassEncoder, vertex_count: u32, instance_count: u32, first_vertex: u32, first_instance: u32) void {
|
||||
Impl.renderPassEncoderDraw(render_pass_encoder, vertex_count, instance_count, first_vertex, first_instance);
|
||||
}
|
||||
|
||||
/// Default `instance_count`: 1
|
||||
/// Default `first_index`: 0
|
||||
/// Default `base_vertex`: 0
|
||||
/// Default `first_instance`: 0
|
||||
pub inline fn drawIndexed(render_pass_encoder: *RenderPassEncoder, index_count: u32, instance_count: u32, first_index: u32, base_vertex: i32, first_instance: u32) void {
|
||||
Impl.renderPassEncoderDrawIndexed(render_pass_encoder, index_count, instance_count, first_index, base_vertex, first_instance);
|
||||
}
|
||||
|
||||
pub inline fn drawIndexedIndirect(render_pass_encoder: *RenderPassEncoder, indirect_buffer: *Buffer, indirect_offset: u64) void {
|
||||
Impl.renderPassEncoderDrawIndexedIndirect(render_pass_encoder, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
pub inline fn drawIndirect(render_pass_encoder: *RenderPassEncoder, indirect_buffer: *Buffer, indirect_offset: u64) void {
|
||||
Impl.renderPassEncoderDrawIndirect(render_pass_encoder, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
pub inline fn end(render_pass_encoder: *RenderPassEncoder) void {
|
||||
Impl.renderPassEncoderEnd(render_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn endOcclusionQuery(render_pass_encoder: *RenderPassEncoder) void {
|
||||
Impl.renderPassEncoderEndOcclusionQuery(render_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn executeBundles(
|
||||
render_pass_encoder: *RenderPassEncoder,
|
||||
bundles: []*const RenderBundle,
|
||||
) void {
|
||||
Impl.renderPassEncoderExecuteBundles(
|
||||
render_pass_encoder,
|
||||
bundles.len,
|
||||
bundles.ptr,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn insertDebugMarker(render_pass_encoder: *RenderPassEncoder, marker_label: [*:0]const u8) void {
|
||||
Impl.renderPassEncoderInsertDebugMarker(render_pass_encoder, marker_label);
|
||||
}
|
||||
|
||||
pub inline fn popDebugGroup(render_pass_encoder: *RenderPassEncoder) void {
|
||||
Impl.renderPassEncoderPopDebugGroup(render_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn pushDebugGroup(render_pass_encoder: *RenderPassEncoder, group_label: [*:0]const u8) void {
|
||||
Impl.renderPassEncoderPushDebugGroup(render_pass_encoder, group_label);
|
||||
}
|
||||
|
||||
/// Default `dynamic_offsets_count`: 0
|
||||
/// Default `dynamic_offsets`: `null`
|
||||
pub inline fn setBindGroup(render_pass_encoder: *RenderPassEncoder, group_index: u32, group: *BindGroup, dynamic_offsets: ?[]const u32) void {
|
||||
Impl.renderPassEncoderSetBindGroup(
|
||||
render_pass_encoder,
|
||||
group_index,
|
||||
group,
|
||||
if (dynamic_offsets) |v| v.len else 0,
|
||||
if (dynamic_offsets) |v| v.ptr else null,
|
||||
);
|
||||
}
|
||||
|
||||
pub inline fn setBlendConstant(render_pass_encoder: *RenderPassEncoder, color: *const Color) void {
|
||||
Impl.renderPassEncoderSetBlendConstant(render_pass_encoder, color);
|
||||
}
|
||||
|
||||
/// Default `offset`: 0
|
||||
/// Default `size`: `gpu.whole_size`
|
||||
pub inline fn setIndexBuffer(render_pass_encoder: *RenderPassEncoder, buffer: *Buffer, format: IndexFormat, offset: u64, size: u64) void {
|
||||
Impl.renderPassEncoderSetIndexBuffer(render_pass_encoder, buffer, format, offset, size);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(render_pass_encoder: *RenderPassEncoder, label: [*:0]const u8) void {
|
||||
Impl.renderPassEncoderSetLabel(render_pass_encoder, label);
|
||||
}
|
||||
|
||||
pub inline fn setPipeline(render_pass_encoder: *RenderPassEncoder, pipeline: *RenderPipeline) void {
|
||||
Impl.renderPassEncoderSetPipeline(render_pass_encoder, pipeline);
|
||||
}
|
||||
|
||||
pub inline fn setScissorRect(render_pass_encoder: *RenderPassEncoder, x: u32, y: u32, width: u32, height: u32) void {
|
||||
Impl.renderPassEncoderSetScissorRect(render_pass_encoder, x, y, width, height);
|
||||
}
|
||||
|
||||
pub inline fn setStencilReference(render_pass_encoder: *RenderPassEncoder, _reference: u32) void {
|
||||
Impl.renderPassEncoderSetStencilReference(render_pass_encoder, _reference);
|
||||
}
|
||||
|
||||
/// Default `offset`: 0
|
||||
/// Default `size`: `gpu.whole_size`
|
||||
pub inline fn setVertexBuffer(render_pass_encoder: *RenderPassEncoder, slot: u32, buffer: *Buffer, offset: u64, size: u64) void {
|
||||
Impl.renderPassEncoderSetVertexBuffer(render_pass_encoder, slot, buffer, offset, size);
|
||||
}
|
||||
|
||||
pub inline fn setViewport(render_pass_encoder: *RenderPassEncoder, x: f32, y: f32, width: f32, height: f32, min_depth: f32, max_depth: f32) void {
|
||||
Impl.renderPassEncoderSetViewport(render_pass_encoder, x, y, width, height, min_depth, max_depth);
|
||||
}
|
||||
|
||||
pub inline fn writeTimestamp(render_pass_encoder: *RenderPassEncoder, query_set: *QuerySet, query_index: u32) void {
|
||||
Impl.renderPassEncoderWriteTimestamp(render_pass_encoder, query_set, query_index);
|
||||
}
|
||||
|
||||
pub inline fn reference(render_pass_encoder: *RenderPassEncoder) void {
|
||||
Impl.renderPassEncoderReference(render_pass_encoder);
|
||||
}
|
||||
|
||||
pub inline fn release(render_pass_encoder: *RenderPassEncoder) void {
|
||||
Impl.renderPassEncoderRelease(render_pass_encoder);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const DepthStencilState = @import("main.zig").DepthStencilState;
|
||||
const MultisampleState = @import("main.zig").MultisampleState;
|
||||
const VertexState = @import("main.zig").VertexState;
|
||||
const PrimitiveState = @import("main.zig").PrimitiveState;
|
||||
const FragmentState = @import("main.zig").FragmentState;
|
||||
const PipelineLayout = @import("pipeline_layout.zig").PipelineLayout;
|
||||
const BindGroupLayout = @import("bind_group_layout.zig").BindGroupLayout;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const RenderPipeline = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
layout: ?*PipelineLayout = null,
|
||||
vertex: VertexState,
|
||||
primitive: PrimitiveState = .{},
|
||||
depth_stencil: ?*const DepthStencilState = null,
|
||||
multisample: MultisampleState = .{},
|
||||
fragment: ?*const FragmentState = null,
|
||||
};
|
||||
|
||||
pub inline fn getBindGroupLayout(render_pipeline: *RenderPipeline, group_index: u32) *BindGroupLayout {
|
||||
return Impl.renderPipelineGetBindGroupLayout(render_pipeline, group_index);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(render_pipeline: *RenderPipeline, label: [*:0]const u8) void {
|
||||
Impl.renderPipelineSetLabel(render_pipeline, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(render_pipeline: *RenderPipeline) void {
|
||||
Impl.renderPipelineReference(render_pipeline);
|
||||
}
|
||||
|
||||
pub inline fn release(render_pipeline: *RenderPipeline) void {
|
||||
Impl.renderPipelineRelease(render_pipeline);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const FilterMode = @import("main.zig").FilterMode;
|
||||
const MipmapFilterMode = @import("main.zig").MipmapFilterMode;
|
||||
const CompareFunction = @import("main.zig").CompareFunction;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const Sampler = opaque {
|
||||
pub const AddressMode = enum(u32) {
|
||||
repeat = 0x00000000,
|
||||
mirror_repeat = 0x00000001,
|
||||
clamp_to_edge = 0x00000002,
|
||||
};
|
||||
|
||||
pub const BindingType = enum(u32) {
|
||||
undefined = 0x00000000,
|
||||
filtering = 0x00000001,
|
||||
non_filtering = 0x00000002,
|
||||
comparison = 0x00000003,
|
||||
};
|
||||
|
||||
pub const BindingLayout = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
type: BindingType = .undefined,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
address_mode_u: AddressMode = .clamp_to_edge,
|
||||
address_mode_v: AddressMode = .clamp_to_edge,
|
||||
address_mode_w: AddressMode = .clamp_to_edge,
|
||||
mag_filter: FilterMode = .nearest,
|
||||
min_filter: FilterMode = .nearest,
|
||||
mipmap_filter: MipmapFilterMode = .nearest,
|
||||
lod_min_clamp: f32 = 0.0,
|
||||
lod_max_clamp: f32 = 32.0,
|
||||
compare: CompareFunction = .undefined,
|
||||
max_anisotropy: u16 = 1,
|
||||
};
|
||||
|
||||
pub inline fn setLabel(sampler: *Sampler, label: [*:0]const u8) void {
|
||||
Impl.samplerSetLabel(sampler, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(sampler: *Sampler) void {
|
||||
Impl.samplerReference(sampler);
|
||||
}
|
||||
|
||||
pub inline fn release(sampler: *Sampler) void {
|
||||
Impl.samplerRelease(sampler);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const CompilationInfoCallback = @import("main.zig").CompilationInfoCallback;
|
||||
const CompilationInfoRequestStatus = @import("main.zig").CompilationInfoRequestStatus;
|
||||
const CompilationInfo = @import("main.zig").CompilationInfo;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const dawn = @import("dawn.zig");
|
||||
|
||||
pub const ShaderModule = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
spirv_descriptor: ?*const SPIRVDescriptor,
|
||||
wgsl_descriptor: ?*const WGSLDescriptor,
|
||||
dawn_shader_module_spirv_options_descriptor: ?*const dawn.ShaderModuleSPIRVOptionsDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub const SPIRVDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shader_module_spirv_descriptor },
|
||||
code_size: u32,
|
||||
code: [*]const u32,
|
||||
};
|
||||
|
||||
pub const WGSLDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shader_module_wgsl_descriptor },
|
||||
code: [*:0]const u8,
|
||||
};
|
||||
|
||||
pub inline fn getCompilationInfo(
|
||||
shader_module: *ShaderModule,
|
||||
context: anytype,
|
||||
comptime callback: fn (
|
||||
ctx: @TypeOf(context),
|
||||
status: CompilationInfoRequestStatus,
|
||||
compilation_info: *const CompilationInfo,
|
||||
) callconv(.Inline) void,
|
||||
) void {
|
||||
const Context = @TypeOf(context);
|
||||
const Helper = struct {
|
||||
pub fn cCallback(
|
||||
status: CompilationInfoRequestStatus,
|
||||
compilation_info: *const CompilationInfo,
|
||||
userdata: ?*anyopaque,
|
||||
) callconv(.C) void {
|
||||
callback(
|
||||
if (Context == void) {} else @as(Context, @ptrCast(@alignCast(userdata))),
|
||||
status,
|
||||
compilation_info,
|
||||
);
|
||||
}
|
||||
};
|
||||
Impl.shaderModuleGetCompilationInfo(shader_module, Helper.cCallback, if (Context == void) null else context);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(shader_module: *ShaderModule, label: [*:0]const u8) void {
|
||||
Impl.shaderModuleSetLabel(shader_module, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(shader_module: *ShaderModule) void {
|
||||
Impl.shaderModuleReference(shader_module);
|
||||
}
|
||||
|
||||
pub inline fn release(shader_module: *ShaderModule) void {
|
||||
Impl.shaderModuleRelease(shader_module);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ChainedStructOut = @import("main.zig").ChainedStructOut;
|
||||
|
||||
pub const SharedFence = opaque {
|
||||
pub const Type = enum(u32) {
|
||||
shared_fence_type_undefined = 0x00000000,
|
||||
shared_fence_type_vk_semaphore_opaque_fd = 0x00000001,
|
||||
shared_fence_type_vk_semaphore_sync_fd = 0x00000002,
|
||||
shared_fence_type_vk_semaphore_zircon_handle = 0x00000003,
|
||||
shared_fence_type_dxgi_shared_handle = 0x00000004,
|
||||
shared_fence_type_mtl_shared_event = 0x00000005,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
vk_semaphore_opaque_fd_descriptor: *const VkSemaphoreOpaqueFDDescriptor,
|
||||
vk_semaphore_sync_fd_descriptor: *const VkSemaphoreSyncFDDescriptor,
|
||||
vk_semaphore_zircon_handle_descriptor: *const VkSemaphoreZirconHandleDescriptor,
|
||||
dxgi_shared_handle_descriptor: *const DXGISharedHandleDescriptor,
|
||||
mtl_shared_event_descriptor: *const MTLSharedEventDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*]const u8,
|
||||
};
|
||||
|
||||
pub const DXGISharedHandleDescriptor = extern struct {
|
||||
chain: ChainedStruct,
|
||||
handle: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DXGISharedHandleExportInfo = extern struct {
|
||||
chain: ChainedStructOut,
|
||||
handle: *anyopaque,
|
||||
};
|
||||
|
||||
pub const ExportInfo = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStructOut,
|
||||
dxgi_shared_handle_export_info: *const DXGISharedHandleExportInfo,
|
||||
mtl_shared_event_export_info: *const MTLSharedEventExportInfo,
|
||||
vk_semaphore_opaque_fd_export_info: *const VkSemaphoreOpaqueFDExportInfo,
|
||||
vk_semaphore_sync_fd_export_info: *const VkSemaphoreSyncFDExportInfo,
|
||||
vk_semaphore_zircon_handle_export_info: *const VkSemaphoreZirconHandleExportInfo,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
type: Type,
|
||||
};
|
||||
|
||||
pub const MTLSharedEventDescriptor = extern struct {
|
||||
chain: ChainedStruct,
|
||||
shared_event: *anyopaque,
|
||||
};
|
||||
|
||||
pub const MTLSharedEventExportInfo = extern struct {
|
||||
chain: ChainedStructOut,
|
||||
shared_event: *anyopaque,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreOpaqueFDDescriptor = extern struct {
|
||||
chain: ChainedStruct,
|
||||
handle: c_int,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreOpaqueFDExportInfo = extern struct {
|
||||
chain: ChainedStructOut,
|
||||
handle: c_int,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreSyncFDDescriptor = extern struct {
|
||||
chain: ChainedStruct,
|
||||
handle: c_int,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreSyncFDExportInfo = extern struct {
|
||||
chain: ChainedStructOut,
|
||||
handle: c_int,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreZirconHandleDescriptor = extern struct {
|
||||
chain: ChainedStruct,
|
||||
handle: u32,
|
||||
};
|
||||
|
||||
pub const VkSemaphoreZirconHandleExportInfo = extern struct {
|
||||
chain: ChainedStructOut,
|
||||
handle: u32,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,124 +0,0 @@
|
|||
const Texture = @import("texture.zig").Texture;
|
||||
const Bool32 = @import("main.zig").Bool32;
|
||||
const Extent3D = @import("main.zig").Extent3D;
|
||||
const SharedFence = @import("shared_fence.zig").SharedFence;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const ChainedStructOut = @import("main.zig").ChainedStructOut;
|
||||
|
||||
pub const SharedTextureMemory = opaque {
|
||||
pub const Properties = extern struct {
|
||||
next_in_chain: *const ChainedStruct,
|
||||
usage: Texture.UsageFlags,
|
||||
size: Extent3D,
|
||||
format: Texture.Format,
|
||||
};
|
||||
|
||||
pub const VkImageDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_vk_image_descriptor },
|
||||
vk_format: i32,
|
||||
vk_usage_flags: Texture.UsageFlags,
|
||||
vk_extent3D: Extent3D,
|
||||
};
|
||||
|
||||
pub const AHardwareBufferDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_a_hardware_buffer_descriptor },
|
||||
handle: *anyopaque,
|
||||
};
|
||||
|
||||
pub const BeginAccessDescriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
vk_image_layout_begin_state: *const VkImageLayoutBeginState,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
initialized: Bool32,
|
||||
fence_count: usize,
|
||||
fences: *const SharedFence,
|
||||
signaled_values: *const u64,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
a_hardware_buffer_descriptor: *const AHardwareBufferDescriptor,
|
||||
dma_buf_descriptor: *const DmaBufDescriptor,
|
||||
dxgi_shared_handle_descriptor: *const DXGISharedHandleDescriptor,
|
||||
egl_image_descriptor: *const EGLImageDescriptor,
|
||||
io_surface_descriptor: *const IOSurfaceDescriptor,
|
||||
opaque_fd_descriptor: *const OpaqueFDDescriptor,
|
||||
vk_dedicated_allocation_descriptor: *const VkDedicatedAllocationDescriptor,
|
||||
zircon_handle_descriptor: *const ZirconHandleDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*]const u8,
|
||||
};
|
||||
|
||||
pub const DmaBufDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_dma_buf_descriptor },
|
||||
memory_fd: c_int,
|
||||
allocation_size: u64,
|
||||
drm_modifier: u64,
|
||||
plane_count: usize,
|
||||
plane_offsets: *const u64,
|
||||
plane_strides: *const u32,
|
||||
};
|
||||
|
||||
pub const DXGISharedHandleDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_dxgi_shared_handle_descriptor },
|
||||
handle: *anyopaque,
|
||||
};
|
||||
|
||||
pub const EGLImageDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_egl_image_descriptor },
|
||||
image: *anyopaque,
|
||||
};
|
||||
|
||||
pub const EndAccessState = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
vk_image_layout_end_state: *const VkImageLayoutEndState,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
initialized: Bool32,
|
||||
fence_count: usize,
|
||||
fences: *const SharedFence,
|
||||
signaled_values: *const u64,
|
||||
};
|
||||
|
||||
pub const IOSurfaceDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_io_surface_descriptor },
|
||||
ioSurface: *anyopaque,
|
||||
};
|
||||
|
||||
pub const OpaqueFDDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_opaque_fd_descriptor },
|
||||
memory_fd: c_int,
|
||||
allocation_size: u64,
|
||||
};
|
||||
|
||||
pub const VkDedicatedAllocationDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_vk_dedicated_allocation_descriptor },
|
||||
dedicated_allocation: Bool32,
|
||||
};
|
||||
|
||||
pub const VkImageLayoutBeginState = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_vk_image_layout_begin_state },
|
||||
old_layout: i32,
|
||||
new_layout: i32,
|
||||
};
|
||||
|
||||
pub const VkImageLayoutEndState = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_vk_image_layout_end_state },
|
||||
old_layout: i32,
|
||||
new_layout: i32,
|
||||
};
|
||||
|
||||
pub const ZirconHandleDescriptor = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .shared_texture_memory_zircon_handle_descriptor },
|
||||
memory_fd: u32,
|
||||
allocation_size: u64,
|
||||
};
|
||||
};
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const Surface = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
from_android_native_window: *const DescriptorFromAndroidNativeWindow,
|
||||
from_canvas_html_selector: *const DescriptorFromCanvasHTMLSelector,
|
||||
from_metal_layer: *const DescriptorFromMetalLayer,
|
||||
from_wayland_surface: *const DescriptorFromWaylandSurface,
|
||||
from_windows_core_window: *const DescriptorFromWindowsCoreWindow,
|
||||
from_windows_hwnd: *const DescriptorFromWindowsHWND,
|
||||
from_windows_swap_chain_panel: *const DescriptorFromWindowsSwapChainPanel,
|
||||
from_xlib_window: *const DescriptorFromXlibWindow,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
};
|
||||
|
||||
pub const DescriptorFromAndroidNativeWindow = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_android_native_window },
|
||||
window: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromCanvasHTMLSelector = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_canvas_html_selector },
|
||||
selector: [*:0]const u8,
|
||||
};
|
||||
|
||||
pub const DescriptorFromMetalLayer = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_metal_layer },
|
||||
layer: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromWaylandSurface = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_wayland_surface },
|
||||
display: *anyopaque,
|
||||
surface: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromWindowsCoreWindow = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_windows_core_window },
|
||||
core_window: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromWindowsHWND = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_windows_hwnd },
|
||||
hinstance: *anyopaque,
|
||||
hwnd: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromWindowsSwapChainPanel = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_windows_swap_chain_panel },
|
||||
swap_chain_panel: *anyopaque,
|
||||
};
|
||||
|
||||
pub const DescriptorFromXlibWindow = extern struct {
|
||||
chain: ChainedStruct = .{ .next = null, .s_type = .surface_descriptor_from_xlib_window },
|
||||
display: *anyopaque,
|
||||
window: u32,
|
||||
};
|
||||
|
||||
pub inline fn reference(surface: *Surface) void {
|
||||
Impl.surfaceReference(surface);
|
||||
}
|
||||
|
||||
pub inline fn release(surface: *Surface) void {
|
||||
Impl.surfaceRelease(surface);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const PresentMode = @import("main.zig").PresentMode;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
const TextureView = @import("texture_view.zig").TextureView;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
|
||||
pub const SwapChain = opaque {
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
usage: Texture.UsageFlags,
|
||||
format: Texture.Format,
|
||||
width: u32,
|
||||
height: u32,
|
||||
present_mode: PresentMode,
|
||||
};
|
||||
|
||||
pub inline fn getCurrentTexture(swap_chain: *SwapChain) ?*Texture {
|
||||
return Impl.swapChainGetCurrentTexture(swap_chain);
|
||||
}
|
||||
|
||||
pub inline fn getCurrentTextureView(swap_chain: *SwapChain) ?*TextureView {
|
||||
return Impl.swapChainGetCurrentTextureView(swap_chain);
|
||||
}
|
||||
|
||||
pub inline fn present(swap_chain: *SwapChain) void {
|
||||
Impl.swapChainPresent(swap_chain);
|
||||
}
|
||||
|
||||
pub inline fn reference(swap_chain: *SwapChain) void {
|
||||
Impl.swapChainReference(swap_chain);
|
||||
}
|
||||
|
||||
pub inline fn release(swap_chain: *SwapChain) void {
|
||||
Impl.swapChainRelease(swap_chain);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
const std = @import("std");
|
||||
const Bool32 = @import("main.zig").Bool32;
|
||||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const TextureView = @import("texture_view.zig").TextureView;
|
||||
const Extent3D = @import("main.zig").Extent3D;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const types = @import("main.zig");
|
||||
const dawn = @import("dawn.zig");
|
||||
|
||||
pub const Texture = opaque {
|
||||
pub const Aspect = enum(u32) {
|
||||
all = 0x00000000,
|
||||
stencil_only = 0x00000001,
|
||||
depth_only = 0x00000002,
|
||||
plane0_only = 0x00000003,
|
||||
plane1_only = 0x00000004,
|
||||
};
|
||||
|
||||
pub const Dimension = enum(u32) {
|
||||
dimension_1d = 0x00000000,
|
||||
dimension_2d = 0x00000001,
|
||||
dimension_3d = 0x00000002,
|
||||
};
|
||||
|
||||
pub const Format = enum(u32) {
|
||||
undefined = 0x00000000,
|
||||
r8_unorm = 0x00000001,
|
||||
r8_snorm = 0x00000002,
|
||||
r8_uint = 0x00000003,
|
||||
r8_sint = 0x00000004,
|
||||
r16_uint = 0x00000005,
|
||||
r16_sint = 0x00000006,
|
||||
r16_float = 0x00000007,
|
||||
rg8_unorm = 0x00000008,
|
||||
rg8_snorm = 0x00000009,
|
||||
rg8_uint = 0x0000000a,
|
||||
rg8_sint = 0x0000000b,
|
||||
r32_float = 0x0000000c,
|
||||
r32_uint = 0x0000000d,
|
||||
r32_sint = 0x0000000e,
|
||||
rg16_uint = 0x0000000f,
|
||||
rg16_sint = 0x00000010,
|
||||
rg16_float = 0x00000011,
|
||||
rgba8_unorm = 0x00000012,
|
||||
rgba8_unorm_srgb = 0x00000013,
|
||||
rgba8_snorm = 0x00000014,
|
||||
rgba8_uint = 0x00000015,
|
||||
rgba8_sint = 0x00000016,
|
||||
bgra8_unorm = 0x00000017,
|
||||
bgra8_unorm_srgb = 0x00000018,
|
||||
rgb10_a2_unorm = 0x00000019,
|
||||
rg11_b10_ufloat = 0x0000001a,
|
||||
rgb9_e5_ufloat = 0x0000001b,
|
||||
rg32_float = 0x0000001c,
|
||||
rg32_uint = 0x0000001d,
|
||||
rg32_sint = 0x0000001e,
|
||||
rgba16_uint = 0x0000001f,
|
||||
rgba16_sint = 0x00000020,
|
||||
rgba16_float = 0x00000021,
|
||||
rgba32_float = 0x00000022,
|
||||
rgba32_uint = 0x00000023,
|
||||
rgba32_sint = 0x00000024,
|
||||
stencil8 = 0x00000025,
|
||||
depth16_unorm = 0x00000026,
|
||||
depth24_plus = 0x00000027,
|
||||
depth24_plus_stencil8 = 0x00000028,
|
||||
depth32_float = 0x00000029,
|
||||
depth32_float_stencil8 = 0x0000002a,
|
||||
bc1_rgba_unorm = 0x0000002b,
|
||||
bc1_rgba_unorm_srgb = 0x0000002c,
|
||||
bc2_rgba_unorm = 0x0000002d,
|
||||
bc2_rgba_unorm_srgb = 0x0000002e,
|
||||
bc3_rgba_unorm = 0x0000002f,
|
||||
bc3_rgba_unorm_srgb = 0x00000030,
|
||||
bc4_runorm = 0x00000031,
|
||||
bc4_rsnorm = 0x00000032,
|
||||
bc5_rg_unorm = 0x00000033,
|
||||
bc5_rg_snorm = 0x00000034,
|
||||
bc6_hrgb_ufloat = 0x00000035,
|
||||
bc6_hrgb_float = 0x00000036,
|
||||
bc7_rgba_unorm = 0x00000037,
|
||||
bc7_rgba_unorm_srgb = 0x00000038,
|
||||
etc2_rgb8_unorm = 0x00000039,
|
||||
etc2_rgb8_unorm_srgb = 0x0000003a,
|
||||
etc2_rgb8_a1_unorm = 0x0000003b,
|
||||
etc2_rgb8_a1_unorm_srgb = 0x0000003c,
|
||||
etc2_rgba8_unorm = 0x0000003d,
|
||||
etc2_rgba8_unorm_srgb = 0x0000003e,
|
||||
eacr11_unorm = 0x0000003f,
|
||||
eacr11_snorm = 0x00000040,
|
||||
eacrg11_unorm = 0x00000041,
|
||||
eacrg11_snorm = 0x00000042,
|
||||
astc4x4_unorm = 0x00000043,
|
||||
astc4x4_unorm_srgb = 0x00000044,
|
||||
astc5x4_unorm = 0x00000045,
|
||||
astc5x4_unorm_srgb = 0x00000046,
|
||||
astc5x5_unorm = 0x00000047,
|
||||
astc5x5_unorm_srgb = 0x00000048,
|
||||
astc6x5_unorm = 0x00000049,
|
||||
astc6x5_unorm_srgb = 0x0000004a,
|
||||
astc6x6_unorm = 0x0000004b,
|
||||
astc6x6_unorm_srgb = 0x0000004c,
|
||||
astc8x5_unorm = 0x0000004d,
|
||||
astc8x5_unorm_srgb = 0x0000004e,
|
||||
astc8x6_unorm = 0x0000004f,
|
||||
astc8x6_unorm_srgb = 0x00000050,
|
||||
astc8x8_unorm = 0x00000051,
|
||||
astc8x8_unorm_srgb = 0x00000052,
|
||||
astc10x5_unorm = 0x00000053,
|
||||
astc10x5_unorm_srgb = 0x00000054,
|
||||
astc10x6_unorm = 0x00000055,
|
||||
astc10x6_unorm_srgb = 0x00000056,
|
||||
astc10x8_unorm = 0x00000057,
|
||||
astc10x8_unorm_srgb = 0x00000058,
|
||||
astc10x10_unorm = 0x00000059,
|
||||
astc10x10_unorm_srgb = 0x0000005a,
|
||||
astc12x10_unorm = 0x0000005b,
|
||||
astc12x10_unorm_srgb = 0x0000005c,
|
||||
astc12x12_unorm = 0x0000005d,
|
||||
astc12x12_unorm_srgb = 0x0000005e,
|
||||
r8_bg8_biplanar420_unorm = 0x0000005f,
|
||||
};
|
||||
|
||||
pub const SampleType = enum(u32) {
|
||||
undefined = 0x00000000,
|
||||
float = 0x00000001,
|
||||
unfilterable_float = 0x00000002,
|
||||
depth = 0x00000003,
|
||||
sint = 0x00000004,
|
||||
uint = 0x00000005,
|
||||
};
|
||||
|
||||
pub const UsageFlags = packed struct(u32) {
|
||||
copy_src: bool = false,
|
||||
copy_dst: bool = false,
|
||||
texture_binding: bool = false,
|
||||
storage_binding: bool = false,
|
||||
render_attachment: bool = false,
|
||||
transient_attachment: bool = false,
|
||||
|
||||
_padding: u26 = 0,
|
||||
|
||||
comptime {
|
||||
std.debug.assert(
|
||||
@sizeOf(@This()) == @sizeOf(u32) and
|
||||
@bitSizeOf(@This()) == @bitSizeOf(u32),
|
||||
);
|
||||
}
|
||||
|
||||
pub const none = UsageFlags{};
|
||||
|
||||
pub fn equal(a: UsageFlags, b: UsageFlags) bool {
|
||||
return @as(u6, @truncate(@as(u32, @bitCast(a)))) == @as(u6, @truncate(@as(u32, @bitCast(b))));
|
||||
}
|
||||
};
|
||||
|
||||
pub const BindingLayout = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
sample_type: SampleType = .undefined,
|
||||
view_dimension: TextureView.Dimension = .dimension_undefined,
|
||||
multisampled: Bool32 = .false,
|
||||
};
|
||||
|
||||
pub const DataLayout = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
offset: u64 = 0,
|
||||
bytes_per_row: u32 = types.copy_stride_undefined,
|
||||
rows_per_image: u32 = types.copy_stride_undefined,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
pub const NextInChain = extern union {
|
||||
generic: ?*const ChainedStruct,
|
||||
dawn_texture_internal_usage_descriptor: *const dawn.TextureInternalUsageDescriptor,
|
||||
};
|
||||
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
usage: UsageFlags,
|
||||
dimension: Dimension = .dimension_2d,
|
||||
size: Extent3D,
|
||||
format: Format,
|
||||
mip_level_count: u32 = 1,
|
||||
sample_count: u32 = 1,
|
||||
view_format_count: usize = 0,
|
||||
view_formats: ?[*]const Format = null,
|
||||
|
||||
/// Provides a slightly friendlier Zig API to initialize this structure.
|
||||
pub inline fn init(v: struct {
|
||||
next_in_chain: NextInChain = .{ .generic = null },
|
||||
label: ?[*:0]const u8 = null,
|
||||
usage: UsageFlags,
|
||||
dimension: Dimension = .dimension_2d,
|
||||
size: Extent3D,
|
||||
format: Format,
|
||||
mip_level_count: u32 = 1,
|
||||
sample_count: u32 = 1,
|
||||
view_formats: ?[]const Format = null,
|
||||
}) Descriptor {
|
||||
return .{
|
||||
.next_in_chain = v.next_in_chain,
|
||||
.label = v.label,
|
||||
.usage = v.usage,
|
||||
.dimension = v.dimension,
|
||||
.size = v.size,
|
||||
.format = v.format,
|
||||
.mip_level_count = v.mip_level_count,
|
||||
.sample_count = v.sample_count,
|
||||
.view_format_count = if (v.view_formats) |e| e.len else 0,
|
||||
.view_formats = if (v.view_formats) |e| e.ptr else null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub inline fn createView(texture: *Texture, descriptor: ?*const TextureView.Descriptor) *TextureView {
|
||||
return Impl.textureCreateView(texture, descriptor);
|
||||
}
|
||||
|
||||
pub inline fn destroy(texture: *Texture) void {
|
||||
Impl.textureDestroy(texture);
|
||||
}
|
||||
|
||||
pub inline fn getDepthOrArrayLayers(texture: *Texture) u32 {
|
||||
return Impl.textureGetDepthOrArrayLayers(texture);
|
||||
}
|
||||
|
||||
pub inline fn getDimension(texture: *Texture) Dimension {
|
||||
return Impl.textureGetDimension(texture);
|
||||
}
|
||||
|
||||
pub inline fn getFormat(texture: *Texture) Format {
|
||||
return Impl.textureGetFormat(texture);
|
||||
}
|
||||
|
||||
pub inline fn getHeight(texture: *Texture) u32 {
|
||||
return Impl.textureGetHeight(texture);
|
||||
}
|
||||
|
||||
pub inline fn getMipLevelCount(texture: *Texture) u32 {
|
||||
return Impl.textureGetMipLevelCount(texture);
|
||||
}
|
||||
|
||||
pub inline fn getSampleCount(texture: *Texture) u32 {
|
||||
return Impl.textureGetSampleCount(texture);
|
||||
}
|
||||
|
||||
pub inline fn getUsage(texture: *Texture) UsageFlags {
|
||||
return Impl.textureGetUsage(texture);
|
||||
}
|
||||
|
||||
pub inline fn getWidth(texture: *Texture) u32 {
|
||||
return Impl.textureGetWidth(texture);
|
||||
}
|
||||
|
||||
pub inline fn setLabel(texture: *Texture, label: [*:0]const u8) void {
|
||||
Impl.textureSetLabel(texture, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(texture: *Texture) void {
|
||||
Impl.textureReference(texture);
|
||||
}
|
||||
|
||||
pub inline fn release(texture: *Texture) void {
|
||||
Impl.textureRelease(texture);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
const ChainedStruct = @import("main.zig").ChainedStruct;
|
||||
const Texture = @import("texture.zig").Texture;
|
||||
const Impl = @import("interface.zig").Impl;
|
||||
const types = @import("main.zig");
|
||||
|
||||
pub const TextureView = opaque {
|
||||
pub const Dimension = enum(u32) {
|
||||
dimension_undefined = 0x00000000,
|
||||
dimension_1d = 0x00000001,
|
||||
dimension_2d = 0x00000002,
|
||||
dimension_2d_array = 0x00000003,
|
||||
dimension_cube = 0x00000004,
|
||||
dimension_cube_array = 0x00000005,
|
||||
dimension_3d = 0x00000006,
|
||||
};
|
||||
|
||||
pub const Descriptor = extern struct {
|
||||
next_in_chain: ?*const ChainedStruct = null,
|
||||
label: ?[*:0]const u8 = null,
|
||||
format: Texture.Format = .undefined,
|
||||
dimension: Dimension = .dimension_undefined,
|
||||
base_mip_level: u32 = 0,
|
||||
mip_level_count: u32 = types.mip_level_count_undefined,
|
||||
base_array_layer: u32 = 0,
|
||||
array_layer_count: u32 = types.array_layer_count_undefined,
|
||||
aspect: Texture.Aspect = .all,
|
||||
};
|
||||
|
||||
pub inline fn setLabel(texture_view: *TextureView, label: [*:0]const u8) void {
|
||||
Impl.textureViewSetLabel(texture_view, label);
|
||||
}
|
||||
|
||||
pub inline fn reference(texture_view: *TextureView) void {
|
||||
Impl.textureViewReference(texture_view);
|
||||
}
|
||||
|
||||
pub inline fn release(texture_view: *TextureView) void {
|
||||
Impl.textureViewRelease(texture_view);
|
||||
}
|
||||
};
|
||||
10
src/main.zig
10
src/main.zig
|
|
@ -4,7 +4,6 @@ const builtin = @import("builtin");
|
|||
// Core
|
||||
pub const core = if (build_options.want_core) @import("core/main.zig") else struct {};
|
||||
pub const Timer = if (build_options.want_core) core.Timer else struct {};
|
||||
pub const wgpu = if (build_options.want_core) @import("gpu/main.zig") else struct {};
|
||||
pub const sysjs = if (build_options.want_core) @import("mach-sysjs") else struct {};
|
||||
pub const Core = if (build_options.want_core) @import("Core.zig") else struct {};
|
||||
|
||||
|
|
@ -18,6 +17,7 @@ pub const testing = @import("testing.zig");
|
|||
|
||||
pub const sysaudio = if (build_options.want_sysaudio) @import("sysaudio/main.zig") else struct {};
|
||||
pub const sysgpu = if (build_options.want_sysgpu) @import("sysgpu/main.zig") else struct {};
|
||||
pub const gpu = sysgpu.sysgpu;
|
||||
|
||||
// Module system
|
||||
pub const modules = blk: {
|
||||
|
|
@ -42,14 +42,6 @@ pub const merge = @import("module/main.zig").merge;
|
|||
pub const builtin_modules = @import("module/main.zig").builtin_modules;
|
||||
pub const Entities = @import("module/main.zig").Entities;
|
||||
|
||||
/// To use experimental sysgpu graphics API, you can write this in your main.zig:
|
||||
///
|
||||
/// ```
|
||||
/// pub const use_sysgpu = true;
|
||||
/// ```
|
||||
pub const use_sysgpu = if (@hasDecl(@import("root"), "use_sysgpu")) @import("root").use_sysgpu else false;
|
||||
pub const gpu = if (use_sysgpu) sysgpu.sysgpu else wgpu;
|
||||
|
||||
pub const is_debug = builtin.mode == .Debug;
|
||||
|
||||
test {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue