├── examples ├── zgpu ├── triangle │ ├── shader.wgsl │ └── main.zig ├── build.zig └── Deps.zig ├── .gitignore ├── .gitmodules ├── README.md ├── LICENSE └── zgpu.zig /examples/zgpu: -------------------------------------------------------------------------------- 1 | .. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | zig-cache/ 2 | zig-out/ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "wgpu-native"] 2 | path = wgpu-native 3 | url = https://github.com/gfx-rs/wgpu-native 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zgpu 2 | 3 | zgpu is a Zig wrapper for [wgpu-native]. 4 | It roughly mirrors the API of wgpu-rs and the WebGPU JS API. 5 | See `examples/triangle` for a usage example, and `examples/build.zig` for how to build. 6 | 7 | [wgpu-native]: https://github.com/gfx-rs/wgpu-native 8 | -------------------------------------------------------------------------------- /examples/triangle/shader.wgsl: -------------------------------------------------------------------------------- 1 | struct VertexOut { 2 | [[builtin(position)]] pos: vec4; 3 | [[location(0)]] color: vec4; 4 | }; 5 | 6 | var colors: array,3> = array,3>( 7 | vec4(1., 0., 0., 1.), 8 | vec4(0., 1., 0., 1.), 9 | vec4(0., 0., 1., 1.), 10 | ); 11 | 12 | [[stage(vertex)]] 13 | fn vs_main([[builtin(vertex_index)]] vert_idx: u32) -> VertexOut { 14 | let x = f32(i32(vert_idx) - 1); 15 | let y = f32(i32(vert_idx & 1u) * 2 - 1); 16 | return VertexOut( 17 | vec4(x, y, 0.0, 1.0), 18 | colors[vert_idx], 19 | ); 20 | } 21 | 22 | [[stage(fragment)]] 23 | fn fs_main(in: VertexOut) -> [[location(0)]] vec4 { 24 | return in.color; 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 silversquirl 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /examples/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const Deps = @import("Deps.zig"); 3 | const zgpu = @import("zgpu/build.zig"); 4 | 5 | pub fn build(b: *std.build.Builder) void { 6 | const target = b.standardTargetOptions(.{}); 7 | const mode = b.standardReleaseOptions(); 8 | 9 | const deps = Deps.init(b); 10 | deps.add("https://github.com/silversquirl/glfz", "main"); 11 | deps.addPackagePath("zgpu", "zgpu/zgpu.zig"); 12 | 13 | const opts = ExampleOpts{ 14 | .target = target, 15 | .mode = mode, 16 | .b = b, 17 | .deps = deps, 18 | .wgpu = zgpu.lib(b, "zgpu", .dynamic), 19 | }; 20 | 21 | example("triangle", opts); 22 | } 23 | 24 | fn example(name: []const u8, opts: ExampleOpts) void { 25 | const exe = opts.b.addExecutable( 26 | name, 27 | opts.b.fmt("{s}/main.zig", .{name}), 28 | ); 29 | 30 | opts.deps.addTo(exe); 31 | exe.linkLibC(); 32 | exe.linkSystemLibrary("glfw3"); 33 | exe.addObjectFileSource(opts.wgpu); 34 | 35 | exe.setTarget(opts.target); 36 | exe.setBuildMode(opts.mode); 37 | exe.install(); 38 | 39 | const run_cmd = exe.run(); 40 | run_cmd.step.dependOn(opts.b.getInstallStep()); 41 | if (opts.b.args) |args| { 42 | run_cmd.addArgs(args); 43 | } 44 | 45 | const run_step = opts.b.step( 46 | opts.b.fmt("run-{s}", .{name}), 47 | opts.b.fmt("Run the {s} example", .{name}), 48 | ); 49 | run_step.dependOn(&run_cmd.step); 50 | } 51 | 52 | const ExampleOpts = struct { 53 | target: std.build.Target, 54 | mode: std.builtin.Mode, 55 | b: *std.build.Builder, 56 | deps: *Deps, 57 | wgpu: std.build.FileSource, 58 | }; 59 | -------------------------------------------------------------------------------- /examples/triangle/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const glfw = @import("glfz"); 3 | const zgpu = @import("zgpu"); 4 | 5 | pub fn main() !void { 6 | try glfw.init(); 7 | defer glfw.deinit(); 8 | 9 | const win = try glfw.Window.init(800, 600, "zgpu triangle", .{ 10 | .client_api = .none, 11 | }); 12 | defer win.deinit(); 13 | 14 | // TODO: support not-X11 15 | const dpy = glfw.getX11Display(c_void) orelse { 16 | return error.DisplayError; 17 | }; 18 | const surface = zgpu.base.createSurface(&.{ 19 | .next_in_chain = &(zgpu.SurfaceDescriptorFromXlib{ 20 | .display = dpy, 21 | .window = win.getX11Window(), 22 | }).chain, 23 | }); 24 | 25 | var adapter: zgpu.Adapter = undefined; 26 | zgpu.base.requestAdapter(&.{ 27 | .compatible_surface = surface, 28 | .power_preference = .high_performance, 29 | .force_fallback_adapter = false, 30 | }, requestAdapterCallback, @ptrCast(*c_void, &adapter)); 31 | 32 | var device: zgpu.Device = undefined; 33 | adapter.requestDevice(&.{ 34 | .next_in_chain = &(zgpu.DeviceExtras{ 35 | .label = "Device", 36 | }).chain, 37 | .required_features_count = 0, 38 | .required_features = undefined, 39 | .required_limits = &.{ .limits = .{ 40 | .max_bind_groups = 1, 41 | } }, 42 | }, requestDeviceCallback, @ptrCast(*c_void, &device)); 43 | defer device.drop(); 44 | 45 | const shader = device.createShaderModule(&.{ 46 | .next_in_chain = &(zgpu.ShaderModuleWGSLDescriptor{ 47 | .source = @embedFile("shader.wgsl"), 48 | }).chain, 49 | .label = "shader.wgsl", 50 | }); 51 | defer shader.drop(); 52 | 53 | const pipeline_layout = device.createPipelineLayout(&.{ 54 | .next_in_chain = null, 55 | .label = "Pipeline layout", 56 | .bind_group_layouts = null, 57 | .bind_group_layout_count = 0, 58 | }); 59 | defer pipeline_layout.drop(); 60 | 61 | var swapchain_format = surface.getPreferredFormat(adapter); 62 | 63 | const pipeline = device.createRenderPipeline(&zgpu.RenderPipelineDescriptor{ 64 | .next_in_chain = null, 65 | .label = "Render Pipeline", 66 | .layout = pipeline_layout, 67 | .vertex = .{ 68 | .next_in_chain = null, 69 | .module = shader, 70 | .entry_point = "vs_main", 71 | .constant_count = 0, 72 | .constants = undefined, 73 | .buffer_count = 0, 74 | .buffers = undefined, 75 | }, 76 | .primitive = .{ 77 | .next_in_chain = null, 78 | .topology = .triangle_list, 79 | .strip_index_format = .unknown, 80 | .front_face = .ccw, 81 | .cull_mode = .none, 82 | }, 83 | .multisample = .{ 84 | .next_in_chain = null, 85 | .count = 1, 86 | .mask = ~@as(u32, 0), 87 | .alpha_to_coverage_enabled = false, 88 | }, 89 | .fragment = &.{ 90 | .next_in_chain = null, 91 | .module = shader, 92 | .entry_point = "fs_main", 93 | .constant_count = 0, 94 | .constants = undefined, 95 | .target_count = 1, 96 | .targets = &zgpu.ColorTargetState{ 97 | .next_in_chain = null, 98 | .format = swapchain_format, 99 | .blend = &.{ 100 | .color = .{ 101 | .src_factor = .one, 102 | .dst_factor = .zero, 103 | .operation = .add, 104 | }, 105 | .alpha = .{ 106 | .src_factor = .one, 107 | .dst_factor = .zero, 108 | .operation = .add, 109 | }, 110 | }, 111 | .write_mask = .{}, 112 | }, 113 | }, 114 | .depth_stencil = null, 115 | }); 116 | defer pipeline.drop(); 117 | 118 | var prev_size = win.windowSize(); 119 | var swapchain = device.createSwapChain(surface, &.{ 120 | .label = "Swap chain", 121 | .usage = .{ .render_attachment = true }, 122 | .format = swapchain_format, 123 | .width = prev_size[0], 124 | .height = prev_size[1], 125 | .present_mode = .fifo, 126 | }); 127 | 128 | while (!win.shouldClose()) { 129 | const size = win.windowSize(); 130 | if (!std.meta.eql(size, prev_size)) { 131 | prev_size = size; 132 | swapchain = device.createSwapChain(surface, &.{ 133 | .label = "Swap chain", 134 | .usage = .{ .render_attachment = true }, 135 | .format = swapchain_format, 136 | .width = prev_size[0], 137 | .height = prev_size[1], 138 | .present_mode = .fifo, 139 | }); 140 | } 141 | 142 | const next_texture = swapchain.getCurrentTextureView() orelse { 143 | return error.SwapchainTextureError; 144 | }; 145 | 146 | const encoder = device.createCommandEncoder( 147 | &.{ .label = "Command Encoder" }, 148 | ); 149 | 150 | const render_pass = encoder.beginRenderPass(&.{ 151 | .label = "Render pass", 152 | .color_attachments = &[_]zgpu.RenderPassColorAttachment{.{ 153 | .view = next_texture, 154 | .resolve_target = null, 155 | .load_op = .clear, 156 | .store_op = .store, 157 | .clear_color = .{ .r = 0, .g = 0, .b = 0, .a = 1 }, 158 | }}, 159 | .color_attachment_count = 1, 160 | }); 161 | 162 | render_pass.setPipeline(pipeline); 163 | render_pass.draw(3, 1, 0, 0); 164 | render_pass.endPass(); 165 | 166 | const queue = device.getQueue(); 167 | const cmd_buffer = [_]zgpu.CommandBuffer{encoder.finish(&.{})}; 168 | queue.submit(1, &cmd_buffer); 169 | swapchain.present(); 170 | 171 | glfw.pollEvents(); 172 | } 173 | } 174 | 175 | fn requestAdapterCallback(status: zgpu.RequestAdapterStatus, adapter: zgpu.Adapter, message: ?[*:0]const u8, userdata: ?*c_void) callconv(.C) void { 176 | _ = status; // TODO: check 177 | _ = message; 178 | @ptrCast(*align(1) zgpu.Adapter, userdata.?).* = adapter; 179 | } 180 | 181 | fn requestDeviceCallback(status: zgpu.RequestDeviceStatus, device: zgpu.Device, message: ?[*:0]const u8, userdata: ?*c_void) callconv(.C) void { 182 | _ = status; // TODO: check 183 | _ = message; 184 | @ptrCast(*align(1) zgpu.Device, userdata.?).* = device; 185 | } 186 | -------------------------------------------------------------------------------- /examples/Deps.zig: -------------------------------------------------------------------------------- 1 | // This file originates from https://github.com/silversquirl/deps.zig 2 | // 3 | // Copyright (c) 2021 silversquirl 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // Possible TODOs: 24 | // - Parse source to ensure all dependencies are actually used 25 | // - Allow multiple packages in one repo 26 | // - Fetch packages at build time 27 | 28 | const std = @import("std"); 29 | const builtin = @import("builtin"); 30 | 31 | update_step: std.build.Step, 32 | 33 | b: *std.build.Builder, 34 | dir: []const u8, 35 | deps: std.StringArrayHashMapUnmanaged(Dep) = .{}, 36 | import_set: std.StringArrayHashMapUnmanaged(void) = .{}, 37 | 38 | const Deps = @This(); 39 | pub const Dep = union(enum) { 40 | managed: struct { // Fully managed dependency - we download these 41 | url: []const u8, // Git URL for the package 42 | path: []const u8, // Path to package directory 43 | main_path: []const u8, // Path to package main file 44 | deps: []const []const u8, // Dependency names of this package 45 | }, 46 | tracked: struct { // Partially managed - we add dependencies to these 47 | main_path: []const u8, // Path to package main file 48 | deps: []const []const u8, // Dependency names of this package 49 | }, 50 | unmanaged: struct { // Unmanaged - we just allow these as deps of other deps 51 | main_path: std.build.FileSource, // Path to package main file 52 | deps: ?[]const std.build.Pkg, // Dependencies of this package 53 | }, 54 | }; 55 | 56 | pub fn init(b: *std.build.Builder) *Deps { 57 | const self = initNoStep(b); 58 | const step = b.step("update", "Update all dependencies to the latest allowed version"); 59 | step.dependOn(&self.update_step); 60 | 61 | return self; 62 | } 63 | pub fn initNoStep(b: *std.build.Builder) *Deps { 64 | const dir = std.os.getenv("DEPS_ZIG_CACHE") orelse switch (builtin.os.tag) { 65 | .windows => b.fmt("{s}\\Temp\\deps-zig", .{std.os.getenv("LOCALAPPDATA").?}), 66 | .macos => b.fmt("{s}/Library/Caches/deps-zig", .{std.os.getenv("HOME").?}), 67 | else => if (std.os.getenv("XDG_CACHE_HOME")) |cache| 68 | b.fmt("{s}/deps-zig", .{cache}) 69 | else 70 | b.fmt("{s}/.cache/deps-zig", .{std.os.getenv("HOME").?}), 71 | }; 72 | 73 | std.fs.cwd().makeDir(dir) catch {}; 74 | var dirh = std.fs.cwd().openDir(dir, .{}) catch |err| { 75 | std.debug.print("Could not open packages dir '{}': {s}\n", .{ std.fmt.fmtSliceEscapeLower(dir), @errorName(err) }); 76 | std.os.exit(1); 77 | }; 78 | defer dirh.close(); 79 | // Purposefully leak the file descriptor - it will be unlocked when the process exits 80 | _ = dirh.createFile(".lock", .{ .lock = .Exclusive, .lock_nonblocking = true }) catch |err| { 81 | std.debug.print("Failed to aqcuire package lock: {s}\n", .{@errorName(err)}); 82 | std.os.exit(1); 83 | }; 84 | 85 | const self = b.allocator.create(Deps) catch unreachable; 86 | self.* = .{ 87 | .update_step = std.build.Step.init(.custom, "update-deps", b.allocator, makeUpdate), 88 | .b = b, 89 | .dir = dir, 90 | }; 91 | return self; 92 | } 93 | 94 | pub fn addTo(self: Deps, step: *std.build.LibExeObjStep) void { 95 | var it = self.deps.iterator(); 96 | while (it.next()) |entry| { 97 | step.addPackage(self.createPkg(entry.key_ptr.*, entry.value_ptr.*)); 98 | } 99 | } 100 | fn createPkg(self: Deps, name: []const u8, dependency: Dep) std.build.Pkg { 101 | return switch (dependency) { 102 | .managed => |dep| .{ 103 | .name = name, 104 | .path = .{ .path = dep.main_path }, 105 | .dependencies = self.createPkgDeps(dep.deps), 106 | }, 107 | .tracked => |dep| .{ 108 | .name = name, 109 | .path = .{ .path = dep.main_path }, 110 | .dependencies = self.createPkgDeps(dep.deps), 111 | }, 112 | .unmanaged => |dep| .{ 113 | .name = name, 114 | .path = dep.main_path, 115 | .dependencies = dep.deps, 116 | }, 117 | }; 118 | } 119 | fn createPkgDeps(self: Deps, dep_names: []const []const u8) ?[]const std.build.Pkg { 120 | if (dep_names.len == 0) return null; 121 | const deps = self.b.allocator.alloc(std.build.Pkg, dep_names.len) catch unreachable; 122 | var i: usize = 0; 123 | for (dep_names) |dname| { 124 | if (self.deps.get(dname)) |ddep| { 125 | deps[i] = self.createPkg(dname, ddep); 126 | i += 1; 127 | } 128 | // If we don't have the dep, ignore it and let the compiler error 129 | } 130 | return deps[0..i]; 131 | } 132 | 133 | pub fn add(self: *Deps, url: []const u8, version: []const u8) void { 134 | const name = trimEnds( 135 | std.fs.path.basenamePosix(url), 136 | &.{"zig-"}, 137 | &.{ ".git", ".zig", "-zig" }, 138 | ); 139 | const path = self.fetchPkg(name, url, version); 140 | 141 | const main_file = blk: { 142 | var dirh = std.fs.cwd().openDir(path, .{}) catch { 143 | std.debug.print("Failed to open package dir: {s}\n", .{path}); 144 | std.os.exit(1); 145 | }; 146 | for ([_][]const u8{ 147 | self.b.fmt("{s}.zig", .{name}), 148 | "main.zig", 149 | self.b.fmt("src{c}{s}.zig", .{ std.fs.path.sep, name }), 150 | "src" ++ [_]u8{std.fs.path.sep} ++ "main.zig", 151 | }) |p| { 152 | if (dirh.access(p, .{})) |_| { 153 | dirh.close(); 154 | break :blk p; 155 | } else |_| {} 156 | } 157 | dirh.close(); 158 | 159 | std.debug.print("Could not find package entrypoint, attempted {s}.zig, main.zig, src{c}{[0]s}.zig and src{[1]c}main.zig\n", .{ name, std.fs.path.sep }); 160 | std.os.exit(1); 161 | }; 162 | const main_path = std.fs.path.join(self.b.allocator, &.{ path, main_file }) catch unreachable; 163 | 164 | const deps = self.parsePackageDeps(main_path) catch |err| switch (err) { 165 | error.InvalidSyntax => &[_][]const u8{}, 166 | else => { 167 | std.debug.print("Failed to parse package dependencies for {s}: {s}\n", .{ main_file, @errorName(err) }); 168 | std.os.exit(1); 169 | }, 170 | }; 171 | 172 | const dep = Dep{ .managed = .{ 173 | .url = url, 174 | .path = path, 175 | .main_path = main_path, 176 | .deps = deps, 177 | } }; 178 | if (self.deps.fetchPut(self.b.allocator, name, dep) catch unreachable) |_| { 179 | std.debug.print("Duplicate dependency '{s}'\n", .{std.fmt.fmtSliceEscapeLower(name)}); 180 | std.os.exit(1); 181 | } 182 | } 183 | 184 | pub fn addPackagePath(self: *Deps, name: []const u8, main_path: []const u8) void { 185 | const deps = self.parsePackageDeps(main_path) catch |err| switch (err) { 186 | error.InvalidSyntax => &[_][]const u8{}, 187 | else => { 188 | std.debug.print("Failed to parse package dependencies for {s}: {s}\n", .{ name, @errorName(err) }); 189 | std.os.exit(1); 190 | }, 191 | }; 192 | 193 | const dep = Dep{ .tracked = .{ 194 | .main_path = main_path, 195 | .deps = deps, 196 | } }; 197 | if (self.deps.fetchPut(self.b.allocator, name, dep) catch unreachable) |_| { 198 | std.debug.print("Duplicate dependency '{s}'\n", .{std.fmt.fmtSliceEscapeLower(name)}); 199 | std.os.exit(1); 200 | } 201 | } 202 | 203 | pub fn addPackage(self: *Deps, package: std.build.Pkg) void { 204 | const dep = Dep{ .unmanaged = .{ 205 | .main_path = package.path, 206 | .deps = package.dependencies, 207 | } }; 208 | if (self.deps.fetchPut(self.b.allocator, package.name, dep) catch unreachable) |_| { 209 | std.debug.print("Duplicate dependency '{s}'\n", .{std.fmt.fmtSliceEscapeLower(package.name)}); 210 | std.os.exit(1); 211 | } 212 | } 213 | 214 | fn fetchPkg(self: Deps, name: []const u8, url: []const u8, version: []const u8) []const u8 { 215 | const path = self.b.allocator.alloc(u8, self.dir.len + 1 + url.len + 1 + version.len) catch unreachable; 216 | 217 | // Base dir 218 | var i: usize = 0; 219 | std.mem.copy(u8, path[i..], self.dir); 220 | i += self.dir.len; 221 | 222 | // Path separator 223 | path[i] = std.fs.path.sep; 224 | i += 1; 225 | 226 | // Encoded URL (/ replaced with : so it's a valid path) 227 | std.mem.copy(u8, path[i..], url); 228 | std.mem.replaceScalar(u8, path[i .. i + url.len], '/', ':'); 229 | i += url.len; 230 | 231 | // Version separator 232 | path[i] = '@'; 233 | i += 1; 234 | 235 | // Version 236 | std.mem.copy(u8, path[i..], version); 237 | i += version.len; 238 | std.debug.assert(i == path.len); 239 | 240 | // If we don't have the dep already, clone it 241 | std.fs.cwd().access(path, .{}) catch self.updateDep(name, path, url, version); 242 | 243 | return path; 244 | } 245 | 246 | fn parsePackageDeps(self: *Deps, main_file: []const u8) ![]const []const u8 { 247 | defer self.import_set.clearRetainingCapacity(); 248 | 249 | var npkg = try self.collectImports(std.fs.cwd(), main_file); 250 | const pkgs = try self.b.allocator.alloc([]const u8, npkg); 251 | for (self.import_set.keys()) |key| { 252 | if (isPkg(key)) { 253 | npkg -= 1; 254 | pkgs[npkg] = key; 255 | } 256 | } 257 | 258 | return pkgs; 259 | } 260 | fn collectImports(self: *Deps, dir: std.fs.Dir, import: []const u8) CollectImportsError!usize { 261 | const data = dir.readFileAllocOptions(self.b.allocator, import, 4 << 30, null, 1, 0) catch |err| switch (err) { 262 | error.FileTooBig => { 263 | // If you have a 4GiB source file, you have a problem 264 | // However, we probably shouldn't outright error in this situation, so instead we'll warn and skip this file 265 | std.debug.print("Could not parse exceptionally large source file '{s}', skipping\n", .{std.fmt.fmtSliceEscapeLower(import)}); 266 | return 0; 267 | }, 268 | else => |e| return e, 269 | }; 270 | var subdir = try dir.openDir(std.fs.path.dirname(import) orelse ".", .{}); 271 | defer subdir.close(); 272 | 273 | var toks = std.zig.Tokenizer.init(data); 274 | var npkg: usize = 0; 275 | while (true) { 276 | const tok = toks.next(); 277 | if (tok.tag == .eof) break; 278 | 279 | if (tok.tag == .builtin and std.mem.eql(u8, data[tok.loc.start..tok.loc.end], "@import")) { 280 | if (toks.next().tag != .l_paren) return error.InvalidSyntax; 281 | const name_tok = toks.next(); 282 | if (name_tok.tag != .string_literal) return error.InvalidSyntax; 283 | if (toks.next().tag != .r_paren) return error.InvalidSyntax; 284 | 285 | const name = std.zig.string_literal.parseAlloc( 286 | self.b.allocator, 287 | data[name_tok.loc.start..name_tok.loc.end], 288 | ) catch |err| switch (err) { 289 | error.InvalidStringLiteral => return error.InvalidSyntax, 290 | else => |e| return e, 291 | }; 292 | 293 | if (try self.import_set.fetchPut(self.b.allocator, name, {})) |_| { 294 | // Do nothing, the entry is already in the set 295 | } else if (isPkg(name)) { 296 | npkg += 1; 297 | } else if (std.mem.endsWith(u8, name, ".zig")) { 298 | npkg += try self.collectImports(subdir, name); 299 | } 300 | } 301 | } 302 | 303 | return npkg; 304 | } 305 | const CollectImportsError = 306 | std.fs.Dir.OpenError || 307 | std.fs.File.OpenError || 308 | std.fs.File.ReadError || 309 | std.fs.File.SeekError || 310 | std.mem.Allocator.Error || 311 | error{InvalidSyntax}; 312 | 313 | fn makeUpdate(step: *std.build.Step) !void { 314 | const self = @fieldParentPtr(Deps, "update_step", step); 315 | var it = self.deps.iterator(); 316 | while (it.next()) |entry| { 317 | switch (entry.value_ptr.*) { 318 | .managed => |dep| { 319 | const version_idx = 1 + std.mem.lastIndexOfScalar(u8, dep.path, '@').?; 320 | const version = dep.path[version_idx..]; 321 | self.updateDep(entry.key_ptr.*, dep.path, dep.url, version); 322 | }, 323 | else => {}, 324 | } 325 | } 326 | } 327 | fn updateDep(self: Deps, name: []const u8, path: []const u8, url: []const u8, version: []const u8) void { 328 | std.fs.cwd().access(path, .{}) catch self.exec(&.{ 329 | "git", 330 | "clone", 331 | "--depth=1", 332 | "--no-single-branch", 333 | "--shallow-submodules", 334 | "--", 335 | url, 336 | path, 337 | }, null); 338 | 339 | self.exec(&.{ "git", "fetch", "--all", "-Ppqt" }, path); 340 | // Check if there are changes - we don't want to clobber them 341 | if (self.execOk(&.{ "git", "diff", "--quiet", "HEAD" }, path)) { 342 | // Clean; check if version is a branch 343 | if (self.execOk(&.{ 344 | "git", 345 | "show-ref", 346 | "--verify", 347 | "--", 348 | self.b.fmt("refs/remotes/origin/{s}", .{version}), 349 | }, path)) { 350 | // It is, so switch to it and pull 351 | self.exec(&.{ "git", "switch", "-q", "--", version }, path); 352 | self.exec(&.{ "git", "pull", "-q", "--ff-only" }, path); 353 | } else { 354 | // It isn't, check out detached 355 | self.exec(&.{ "git", "switch", "-dq", "--", version }, path); 356 | } 357 | } else { 358 | // Dirty; print a warning 359 | std.debug.print("WARNING: package {s} contains uncommitted changes, not attempting to update\n", .{name}); 360 | } 361 | } 362 | 363 | fn isPkg(name: []const u8) bool { 364 | if (std.mem.endsWith(u8, name, ".zig")) return false; 365 | if (std.mem.eql(u8, name, "std")) return false; 366 | if (std.mem.eql(u8, name, "root")) return false; 367 | return true; 368 | } 369 | 370 | /// Remove each prefix, then each suffix, in order 371 | fn trimEnds(haystack: []const u8, prefixes: []const []const u8, suffixes: []const []const u8) []const u8 { 372 | var s = haystack; 373 | for (prefixes) |prefix| { 374 | if (std.mem.startsWith(u8, s, prefix)) { 375 | s = s[prefix.len..]; 376 | } 377 | } 378 | for (suffixes) |suffix| { 379 | if (std.mem.endsWith(u8, s, suffix)) { 380 | s = s[0 .. s.len - suffix.len]; 381 | } 382 | } 383 | return s; 384 | } 385 | 386 | fn exec(self: Deps, argv: []const []const u8, cwd: ?[]const u8) void { 387 | if (!self.execInternal(argv, cwd, .Inherit)) { 388 | std.debug.print("Command failed: {s}", .{argv[0]}); 389 | for (argv[1..]) |arg| { 390 | std.debug.print(" {s}", .{arg}); 391 | } 392 | std.debug.print("\n", .{}); 393 | std.os.exit(1); 394 | } 395 | } 396 | 397 | fn execOk(self: Deps, argv: []const []const u8, cwd: ?[]const u8) bool { 398 | return self.execInternal(argv, cwd, .Ignore); 399 | } 400 | 401 | fn execInternal(self: Deps, argv: []const []const u8, cwd: ?[]const u8, io: std.ChildProcess.StdIo) bool { 402 | const child = std.ChildProcess.init(argv, self.b.allocator) catch unreachable; 403 | defer child.deinit(); 404 | 405 | child.cwd = cwd; 406 | child.stdin_behavior = .Ignore; 407 | child.stdout_behavior = io; 408 | child.stderr_behavior = io; 409 | child.env_map = self.b.env_map; 410 | 411 | const term = child.spawnAndWait() catch |err| { 412 | std.debug.print("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) }); 413 | return false; 414 | }; 415 | switch (term) { 416 | .Exited => |code| if (code != 0) { 417 | return false; 418 | }, 419 | .Signal, .Stopped, .Unknown => { 420 | return false; 421 | }, 422 | } 423 | return true; 424 | } 425 | -------------------------------------------------------------------------------- /zgpu.zig: -------------------------------------------------------------------------------- 1 | pub const BufferMapCallback = fn ( 2 | status: BufferMapAsyncStatus, 3 | userdata: *c_void, 4 | ) callconv(.C) void; 5 | 6 | pub const CreateComputePipelineAsyncCallback = fn ( 7 | status: CreatePipelineAsyncStatus, 8 | pipeline: ComputePipeline, 9 | message: [*:0]const u8, 10 | userdata: *c_void, 11 | ) callconv(.C) void; 12 | 13 | pub const CreateRenderPipelineAsyncCallback = fn ( 14 | status: CreatePipelineAsyncStatus, 15 | pipeline: RenderPipeline, 16 | message: [*:0]const u8, 17 | userdata: *c_void, 18 | ) callconv(.C) void; 19 | 20 | pub const DeviceLostCallback = fn ( 21 | reason: DeviceLostReason, 22 | message: [*:0]const u8, 23 | userdata: *c_void, 24 | ) callconv(.C) void; 25 | 26 | pub const ErrorCallback = fn ( 27 | type: ErrorType, 28 | message: [*:0]const u8, 29 | userdata: *c_void, 30 | ) callconv(.C) void; 31 | 32 | pub const QueueWorkDoneCallback = fn ( 33 | status: QueueWorkDoneStatus, 34 | userdata: *c_void, 35 | ) callconv(.C) void; 36 | 37 | pub const RequestAdapterCallback = fn ( 38 | status: RequestAdapterStatus, 39 | adapter: Adapter, 40 | message: ?[*:0]const u8, 41 | userdata: *c_void, 42 | ) callconv(.C) void; 43 | 44 | pub const RequestDeviceCallback = fn ( 45 | status: RequestDeviceStatus, 46 | device: Device, 47 | message: ?[*:0]const u8, 48 | userdata: *c_void, 49 | ) callconv(.C) void; 50 | 51 | pub const createInstance = wgpuCreateInstance; 52 | extern fn wgpuCreateInstance(descriptor: *const InstanceDescriptor) Instance; 53 | 54 | pub const getProcAddress = wgpuGetProcAddress; 55 | extern fn wgpuGetProcAddress(device: Device, proc_name: [*:0]const u8) Proc; 56 | pub const Proc = fn () callconv(.C) void; 57 | 58 | pub const Adapter = *opaque { 59 | pub const getLimits = wgpuAdapterGetLimits; 60 | extern fn wgpuAdapterGetLimits(adapter: Adapter, limits: *SupportedLimits) void; 61 | 62 | pub const getProperties = wgpuAdapterGetProperties; 63 | extern fn wgpuAdapterGetProperties(adapter: Adapter, properties: *AdapterProperties) void; 64 | 65 | pub const hasFeature = wgpuAdapterHasFeature; 66 | extern fn wgpuAdapterHasFeature(adapter: Adapter, feature: FeatureName) bool; 67 | 68 | pub const requestDevice = wgpuAdapterRequestDevice; 69 | extern fn wgpuAdapterRequestDevice( 70 | adapter: Adapter, 71 | descriptor: *const DeviceDescriptor, 72 | callback: RequestDeviceCallback, 73 | userdata: *c_void, 74 | ) void; 75 | }; 76 | 77 | pub const BindGroup = *opaque { 78 | // WGPU extras 79 | pub const drop = wgpuBindGroupDrop; 80 | extern fn wgpuBindGroupDrop(bind_group: BindGroup) void; 81 | }; 82 | 83 | pub const BindGroupLayout = *opaque { 84 | // WGPU extras 85 | pub const drop = wgpuBindGroupLayoutDrop; 86 | extern fn wgpuBindGroupLayoutDrop(bind_group_layout: BindGroupLayout) void; 87 | }; 88 | 89 | pub const Buffer = *opaque { 90 | pub const destroy = wgpuBufferDestroy; 91 | extern fn wgpuBufferDestroy(buffer: Buffer) void; 92 | 93 | pub const getConstMappedRange = wgpuBufferGetConstMappedRange; 94 | extern fn wgpuBufferGetConstMappedRange(buffer: Buffer, offset: usize, size: usize) *const c_void; 95 | 96 | pub const getMappedRange = wgpuBufferGetMappedRange; 97 | extern fn wgpuBufferGetMappedRange(buffer: Buffer, offset: usize, size: usize) *c_void; 98 | 99 | pub const mapAsync = wgpuBufferMapAsync; 100 | extern fn wgpuBufferMapAsync( 101 | buffer: Buffer, 102 | mode: MapMode, 103 | offset: usize, 104 | size: usize, 105 | callback: BufferMapCallback, 106 | userdata: *c_void, 107 | ) void; 108 | 109 | pub const unmap = wgpuBufferUnmap; 110 | extern fn wgpuBufferUnmap(buffer: Buffer) void; 111 | 112 | // WGPU extras 113 | pub const drop = wgpuBufferDrop; 114 | extern fn wgpuBufferDrop(buffer: Buffer) void; 115 | }; 116 | 117 | pub const CommandBuffer = *opaque { 118 | // WGPU extras 119 | pub const drop = wgpuCommandBufferDrop; 120 | extern fn wgpuCommandBufferDrop(command_buffer: CommandBuffer) void; 121 | }; 122 | 123 | pub const CommandEncoder = *opaque { 124 | pub const beginComputePass = wgpuCommandEncoderBeginComputePass; 125 | extern fn wgpuCommandEncoderBeginComputePass( 126 | command_encoder: CommandEncoder, 127 | descriptor: *const ComputePassDescriptor, 128 | ) ComputePassEncoder; 129 | 130 | pub const beginRenderPass = wgpuCommandEncoderBeginRenderPass; 131 | extern fn wgpuCommandEncoderBeginRenderPass( 132 | command_encoder: CommandEncoder, 133 | descriptor: *const RenderPassDescriptor, 134 | ) RenderPassEncoder; 135 | 136 | pub const copyBufferToBuffer = wgpuCommandEncoderCopyBufferToBuffer; 137 | extern fn wgpuCommandEncoderCopyBufferToBuffer( 138 | command_encoder: CommandEncoder, 139 | source: Buffer, 140 | source_offset: u64, 141 | destination: Buffer, 142 | destination_offset: u64, 143 | size: u64, 144 | ) void; 145 | 146 | pub const copyBufferToTexture = wgpuCommandEncoderCopyBufferToTexture; 147 | extern fn wgpuCommandEncoderCopyBufferToTexture( 148 | command_encoder: CommandEncoder, 149 | source: *const ImageCopyBuffer, 150 | destination: *const ImageCopyTexture, 151 | copy_size: *const Extent3D, 152 | ) void; 153 | 154 | pub const copyTextureToBuffer = wgpuCommandEncoderCopyTextureToBuffer; 155 | extern fn wgpuCommandEncoderCopyTextureToBuffer( 156 | command_encoder: CommandEncoder, 157 | source: *const ImageCopyTexture, 158 | destination: *const ImageCopyBuffer, 159 | copy_size: *const Extent3D, 160 | ) void; 161 | 162 | pub const copyTextureToTexture = wgpuCommandEncoderCopyTextureToTexture; 163 | extern fn wgpuCommandEncoderCopyTextureToTexture( 164 | command_encoder: CommandEncoder, 165 | source: *const ImageCopyTexture, 166 | destination: *const ImageCopyTexture, 167 | copy_size: *const Extent3D, 168 | ) void; 169 | 170 | pub const finish = wgpuCommandEncoderFinish; 171 | extern fn wgpuCommandEncoderFinish( 172 | command_encoder: CommandEncoder, 173 | descriptor: *const CommandBufferDescriptor, 174 | ) CommandBuffer; 175 | 176 | pub const insertDebugMarker = wgpuCommandEncoderInsertDebugMarker; 177 | extern fn wgpuCommandEncoderInsertDebugMarker(command_encoder: CommandEncoder, marker_label: [*:0]const u8) void; 178 | 179 | pub const popDebugGroup = wgpuCommandEncoderPopDebugGroup; 180 | extern fn wgpuCommandEncoderPopDebugGroup(command_encoder: CommandEncoder) void; 181 | 182 | pub const pushDebugGroup = wgpuCommandEncoderPushDebugGroup; 183 | extern fn wgpuCommandEncoderPushDebugGroup(command_encoder: CommandEncoder, group_label: [*:0]const u8) void; 184 | 185 | pub const resolveQuerySet = wgpuCommandEncoderResolveQuerySet; 186 | extern fn wgpuCommandEncoderResolveQuerySet( 187 | command_encoder: CommandEncoder, 188 | query_set: QuerySet, 189 | first_query: u32, 190 | query_count: u32, 191 | destination: Buffer, 192 | destination_offset: u64, 193 | ) void; 194 | 195 | pub const writeTimestamp = wgpuCommandEncoderWriteTimestamp; 196 | extern fn wgpuCommandEncoderWriteTimestamp( 197 | command_encoder: CommandEncoder, 198 | query_set: QuerySet, 199 | query_index: u32, 200 | ) void; 201 | 202 | // WGPU extras 203 | pub const drop = wgpuCommandEncoderDrop; 204 | extern fn wgpuCommandEncoderDrop(command_encoder: CommandEncoder) void; 205 | }; 206 | 207 | pub const ComputePassEncoder = *opaque { 208 | pub const beginPipelineStatisticsQuery = wgpuComputePassEncoderBeginPipelineStatisticsQuery; 209 | extern fn wgpuComputePassEncoderBeginPipelineStatisticsQuery( 210 | compute_pass_encoder: ComputePassEncoder, 211 | query_set: QuerySet, 212 | query_index: u32, 213 | ) void; 214 | 215 | pub const dispatch = wgpuComputePassEncoderDispatch; 216 | extern fn wgpuComputePassEncoderDispatch(compute_pass_encoder: ComputePassEncoder, x: u32, y: u32, z: u32) void; 217 | 218 | pub const dispatchIndirect = wgpuComputePassEncoderDispatchIndirect; 219 | extern fn wgpuComputePassEncoderDispatchIndirect( 220 | compute_pass_encoder: ComputePassEncoder, 221 | indirect_buffer: Buffer, 222 | indirect_offset: u64, 223 | ) void; 224 | 225 | pub const endPass = wgpuComputePassEncoderEndPass; 226 | extern fn wgpuComputePassEncoderEndPass(compute_pass_encoder: ComputePassEncoder) void; 227 | 228 | pub const endPipelineStatisticsQuery = wgpuComputePassEncoderEndPipelineStatisticsQuery; 229 | extern fn wgpuComputePassEncoderEndPipelineStatisticsQuery(compute_pass_encoder: ComputePassEncoder) void; 230 | 231 | pub const insertDebugMarker = wgpuComputePassEncoderInsertDebugMarker; 232 | extern fn wgpuComputePassEncoderInsertDebugMarker(compute_pass_encoder: ComputePassEncoder, marker_label: [*:0]const u8) void; 233 | 234 | pub const popDebugGroup = wgpuComputePassEncoderPopDebugGroup; 235 | extern fn wgpuComputePassEncoderPopDebugGroup(compute_pass_encoder: ComputePassEncoder) void; 236 | 237 | pub const pushDebugGroup = wgpuComputePassEncoderPushDebugGroup; 238 | extern fn wgpuComputePassEncoderPushDebugGroup(compute_pass_encoder: ComputePassEncoder, group_label: [*:0]const u8) void; 239 | 240 | pub const setBindGroup = wgpuComputePassEncoderSetBindGroup; 241 | extern fn wgpuComputePassEncoderSetBindGroup( 242 | compute_pass_encoder: ComputePassEncoder, 243 | group_index: u32, 244 | group: BindGroup, 245 | dynamic_offset_count: u32, 246 | dynamic_offsets: [*]const u32, 247 | ) void; 248 | 249 | pub const setPipeline = wgpuComputePassEncoderSetPipeline; 250 | extern fn wgpuComputePassEncoderSetPipeline(compute_pass_encoder: ComputePassEncoder, pipeline: ComputePipeline) void; 251 | 252 | pub const writeTimestamp = wgpuComputePassEncoderWriteTimestamp; 253 | extern fn wgpuComputePassEncoderWriteTimestamp( 254 | compute_pass_encoder: ComputePassEncoder, 255 | query_set: QuerySet, 256 | query_index: u32, 257 | ) void; 258 | }; 259 | 260 | pub const ComputePipeline = *opaque { 261 | pub const getBindGroupLayout = wgpuComputePipelineGetBindGroupLayout; 262 | extern fn wgpuComputePipelineGetBindGroupLayout(compute_pipeline: ComputePipeline, group_index: u32) BindGroupLayout; 263 | 264 | pub const setLabel = wgpuComputePipelineSetLabel; 265 | extern fn wgpuComputePipelineSetLabel(compute_pipeline: ComputePipeline, label: ?[*:0]const u8) void; 266 | 267 | // WGPU extras 268 | pub const drop = wgpuComputePipelineDrop; 269 | extern fn wgpuComputePipelineDrop(compute_pipeline: ComputePipeline) void; 270 | }; 271 | 272 | pub const Device = *opaque { 273 | pub const createBindGroup = wgpuDeviceCreateBindGroup; 274 | extern fn wgpuDeviceCreateBindGroup(device: Device, descriptor: *const BindGroupDescriptor) BindGroup; 275 | 276 | pub const createBindGroupLayout = wgpuDeviceCreateBindGroupLayout; 277 | extern fn wgpuDeviceCreateBindGroupLayout( 278 | device: Device, 279 | descriptor: *const BindGroupLayoutDescriptor, 280 | ) BindGroupLayout; 281 | 282 | pub const createBuffer = wgpuDeviceCreateBuffer; 283 | extern fn wgpuDeviceCreateBuffer(device: Device, descriptor: *const BufferDescriptor) Buffer; 284 | 285 | pub const createCommandEncoder = wgpuDeviceCreateCommandEncoder; 286 | extern fn wgpuDeviceCreateCommandEncoder( 287 | device: Device, 288 | descriptor: *const CommandEncoderDescriptor, 289 | ) CommandEncoder; 290 | 291 | pub const createComputePipeline = wgpuDeviceCreateComputePipeline; 292 | extern fn wgpuDeviceCreateComputePipeline( 293 | device: Device, 294 | descriptor: *const ComputePipelineDescriptor, 295 | ) ComputePipeline; 296 | 297 | pub const createComputePipelineAsync = wgpuDeviceCreateComputePipelineAsync; 298 | extern fn wgpuDeviceCreateComputePipelineAsync( 299 | device: Device, 300 | descriptor: *const ComputePipelineDescriptor, 301 | callback: CreateComputePipelineAsyncCallback, 302 | userdata: *c_void, 303 | ) void; 304 | 305 | pub const createPipelineLayout = wgpuDeviceCreatePipelineLayout; 306 | extern fn wgpuDeviceCreatePipelineLayout( 307 | device: Device, 308 | descriptor: *const PipelineLayoutDescriptor, 309 | ) PipelineLayout; 310 | 311 | pub const createQuerySet = wgpuDeviceCreateQuerySet; 312 | extern fn wgpuDeviceCreateQuerySet(device: Device, descriptor: *const QuerySetDescriptor) QuerySet; 313 | 314 | pub const createRenderBundleEncoder = wgpuDeviceCreateRenderBundleEncoder; 315 | extern fn wgpuDeviceCreateRenderBundleEncoder( 316 | device: Device, 317 | descriptor: *const RenderBundleEncoderDescriptor, 318 | ) RenderBundleEncoder; 319 | 320 | pub const createRenderPipeline = wgpuDeviceCreateRenderPipeline; 321 | extern fn wgpuDeviceCreateRenderPipeline( 322 | device: Device, 323 | descriptor: *const RenderPipelineDescriptor, 324 | ) RenderPipeline; 325 | 326 | pub const createRenderPipelineAsync = wgpuDeviceCreateRenderPipelineAsync; 327 | extern fn wgpuDeviceCreateRenderPipelineAsync( 328 | device: Device, 329 | descriptor: *const RenderPipelineDescriptor, 330 | callback: CreateRenderPipelineAsyncCallback, 331 | userdata: *c_void, 332 | ) void; 333 | 334 | pub const createSampler = wgpuDeviceCreateSampler; 335 | extern fn wgpuDeviceCreateSampler(device: Device, descriptor: *const SamplerDescriptor) Sampler; 336 | 337 | pub const createShaderModule = wgpuDeviceCreateShaderModule; 338 | extern fn wgpuDeviceCreateShaderModule(device: Device, descriptor: *const ShaderModuleDescriptor) ShaderModule; 339 | 340 | pub const createSwapChain = wgpuDeviceCreateSwapChain; 341 | extern fn wgpuDeviceCreateSwapChain( 342 | device: Device, 343 | surface: Surface, 344 | descriptor: *const SwapChainDescriptor, 345 | ) SwapChain; 346 | 347 | pub const createTexture = wgpuDeviceCreateTexture; 348 | extern fn wgpuDeviceCreateTexture(device: Device, descriptor: *const TextureDescriptor) Texture; 349 | 350 | pub const destroy = wgpuDeviceDestroy; 351 | extern fn wgpuDeviceDestroy(device: Device) void; 352 | pub const getLimits = wgpuDeviceGetLimits; 353 | extern fn wgpuDeviceGetLimits(device: Device, limits: *SupportedLimits) bool; 354 | 355 | pub const getQueue = wgpuDeviceGetQueue; 356 | extern fn wgpuDeviceGetQueue(device: Device) Queue; 357 | 358 | pub const popErrorScope = wgpuDevicePopErrorScope; 359 | extern fn wgpuDevicePopErrorScope(device: Device, callback: ErrorCallback, userdata: *c_void) bool; 360 | 361 | pub const pushErrorScope = wgpuDevicePushErrorScope; 362 | extern fn wgpuDevicePushErrorScope(device: Device, filter: ErrorFilter) void; 363 | 364 | pub const setDeviceLostCallback = wgpuDeviceSetDeviceLostCallback; 365 | extern fn wgpuDeviceSetDeviceLostCallback( 366 | device: Device, 367 | callback: DeviceLostCallback, 368 | userdata: *c_void, 369 | ) void; 370 | 371 | pub const setUncapturedErrorCallback = wgpuDeviceSetUncapturedErrorCallback; 372 | extern fn wgpuDeviceSetUncapturedErrorCallback( 373 | device: Device, 374 | callback: ErrorCallback, 375 | userdata: *c_void, 376 | ) void; 377 | 378 | // WGPU extras 379 | pub const poll = wgpuDevicePoll; 380 | extern fn wgpuDevicePoll(device: Device, force_wait: bool) void; 381 | 382 | pub const drop = wgpuDeviceDrop; 383 | extern fn wgpuDeviceDrop(device: Device) void; 384 | }; 385 | 386 | pub const Instance = *allowzero opaque { 387 | pub const createSurface = wgpuInstanceCreateSurface; 388 | extern fn wgpuInstanceCreateSurface(instance: Instance, descriptor: *const SurfaceDescriptor) Surface; 389 | 390 | pub const processEvents = wgpuInstanceProcessEvents; 391 | extern fn wgpuInstanceProcessEvents(instance: Instance) void; 392 | 393 | pub const requestAdapter = wgpuInstanceRequestAdapter; 394 | extern fn wgpuInstanceRequestAdapter( 395 | instance: Instance, 396 | options: *const RequestAdapterOptions, 397 | callback: RequestAdapterCallback, 398 | userdata: ?*c_void, 399 | ) void; 400 | }; 401 | pub const base = @intToPtr(Instance, 0); 402 | 403 | pub const PipelineLayout = *opaque { 404 | // WGPU extras 405 | pub const drop = wgpuPipelineLayoutDrop; 406 | extern fn wgpuPipelineLayoutDrop(pipeline_layout: PipelineLayout) void; 407 | }; 408 | 409 | pub const QuerySet = *opaque { 410 | pub const destroy = wgpuQuerySetDestroy; 411 | extern fn wgpuQuerySetDestroy(query_set: QuerySet) void; 412 | 413 | // WGPU extras 414 | pub const drop = wgpuQuerySetDrop; 415 | extern fn wgpuQuerySetDrop(query_set: QuerySet) void; 416 | }; 417 | 418 | pub const Queue = *opaque { 419 | pub const onSubmittedWorkDone = wgpuQueueOnSubmittedWorkDone; 420 | extern fn wgpuQueueOnSubmittedWorkDone( 421 | queue: Queue, 422 | signal_value: u64, 423 | callback: QueueWorkDoneCallback, 424 | userdata: *c_void, 425 | ) void; 426 | 427 | pub const submit = wgpuQueueSubmit; 428 | extern fn wgpuQueueSubmit(queue: Queue, command_count: u32, commands: [*]const CommandBuffer) void; 429 | 430 | pub const writeBuffer = wgpuQueueWriteBuffer; 431 | extern fn wgpuQueueWriteBuffer( 432 | queue: Queue, 433 | buffer: Buffer, 434 | buffer_offset: u64, 435 | data: *const c_void, 436 | size: usize, 437 | ) void; 438 | 439 | pub const writeTexture = wgpuQueueWriteTexture; 440 | extern fn wgpuQueueWriteTexture( 441 | queue: Queue, 442 | destination: *const ImageCopyTexture, 443 | data: *const c_void, 444 | data_size: usize, 445 | data_layout: *const TextureDataLayout, 446 | write_size: *const Extent3D, 447 | ) void; 448 | }; 449 | 450 | pub const RenderBundle = *opaque { 451 | // WGPU extras 452 | pub const drop = wgpuRenderBundleDrop; 453 | extern fn wgpuRenderBundleDrop(render_bundle: RenderBundle) void; 454 | }; 455 | 456 | pub const RenderBundleEncoder = *opaque { 457 | pub const draw = wgpuRenderBundleEncoderDraw; 458 | extern fn wgpuRenderBundleEncoderDraw( 459 | render_bundle_encoder: RenderBundleEncoder, 460 | vertex_count: u32, 461 | instance_count: u32, 462 | first_vertex: u32, 463 | first_instance: u32, 464 | ) void; 465 | 466 | pub const drawIndexed = wgpuRenderBundleEncoderDrawIndexed; 467 | extern fn wgpuRenderBundleEncoderDrawIndexed( 468 | render_bundle_encoder: RenderBundleEncoder, 469 | index_count: u32, 470 | instance_count: u32, 471 | first_index: u32, 472 | base_vertex: i32, 473 | first_instance: u32, 474 | ) void; 475 | 476 | pub const drawIndexedIndirect = wgpuRenderBundleEncoderDrawIndexedIndirect; 477 | extern fn wgpuRenderBundleEncoderDrawIndexedIndirect( 478 | render_bundle_encoder: RenderBundleEncoder, 479 | indirect_buffer: Buffer, 480 | indirect_offset: u64, 481 | ) void; 482 | 483 | pub const drawIndirect = wgpuRenderBundleEncoderDrawIndirect; 484 | extern fn wgpuRenderBundleEncoderDrawIndirect( 485 | render_bundle_encoder: RenderBundleEncoder, 486 | indirect_buffer: Buffer, 487 | indirect_offset: u64, 488 | ) void; 489 | 490 | pub const finish = wgpuRenderBundleEncoderFinish; 491 | extern fn wgpuRenderBundleEncoderFinish( 492 | render_bundle_encoder: RenderBundleEncoder, 493 | descriptor: *const RenderBundleDescriptor, 494 | ) RenderBundle; 495 | 496 | pub const insertDebugMarker = wgpuRenderBundleEncoderInsertDebugMarker; 497 | extern fn wgpuRenderBundleEncoderInsertDebugMarker( 498 | render_bundle_encoder: RenderBundleEncoder, 499 | marker_label: [*:0]const u8, 500 | ) void; 501 | 502 | pub const popDebugGroup = wgpuRenderBundleEncoderPopDebugGroup; 503 | extern fn wgpuRenderBundleEncoderPopDebugGroup(render_bundle_encoder: RenderBundleEncoder) void; 504 | 505 | pub const pushDebugGroup = wgpuRenderBundleEncoderPushDebugGroup; 506 | extern fn wgpuRenderBundleEncoderPushDebugGroup( 507 | render_bundle_encoder: RenderBundleEncoder, 508 | group_label: [*:0]const u8, 509 | ) void; 510 | 511 | pub const setBindGroup = wgpuRenderBundleEncoderSetBindGroup; 512 | extern fn wgpuRenderBundleEncoderSetBindGroup( 513 | render_bundle_encoder: RenderBundleEncoder, 514 | group_index: u32, 515 | group: BindGroup, 516 | dynamic_offset_count: u32, 517 | dynamic_offsets: [*]const u32, 518 | ) void; 519 | 520 | pub const setIndexBuffer = wgpuRenderBundleEncoderSetIndexBuffer; 521 | extern fn wgpuRenderBundleEncoderSetIndexBuffer( 522 | render_bundle_encoder: RenderBundleEncoder, 523 | buffer: Buffer, 524 | format: IndexFormat, 525 | offset: u64, 526 | size: u64, 527 | ) void; 528 | 529 | pub const setPipeline = wgpuRenderBundleEncoderSetPipeline; 530 | extern fn wgpuRenderBundleEncoderSetPipeline(render_bundle_encoder: RenderBundleEncoder, pipeline: RenderPipeline) void; 531 | 532 | pub const setVertexBuffer = wgpuRenderBundleEncoderSetVertexBuffer; 533 | extern fn wgpuRenderBundleEncoderSetVertexBuffer( 534 | render_bundle_encoder: RenderBundleEncoder, 535 | slot: u32, 536 | buffer: Buffer, 537 | offset: u64, 538 | size: u64, 539 | ) void; 540 | }; 541 | 542 | pub const RenderPassEncoder = *opaque { 543 | pub const beginOcclusionQuery = wgpuRenderPassEncoderBeginOcclusionQuery; 544 | extern fn wgpuRenderPassEncoderBeginOcclusionQuery(render_pass_encoder: RenderPassEncoder, query_index: u32) void; 545 | 546 | pub const beginPipelineStatisticsQuery = wgpuRenderPassEncoderBeginPipelineStatisticsQuery; 547 | extern fn wgpuRenderPassEncoderBeginPipelineStatisticsQuery( 548 | render_pass_encoder: RenderPassEncoder, 549 | query_set: QuerySet, 550 | query_index: u32, 551 | ) void; 552 | 553 | pub const draw = wgpuRenderPassEncoderDraw; 554 | extern fn wgpuRenderPassEncoderDraw( 555 | render_pass_encoder: RenderPassEncoder, 556 | vertex_count: u32, 557 | instance_count: u32, 558 | first_vertex: u32, 559 | first_instance: u32, 560 | ) void; 561 | 562 | pub const drawIndexed = wgpuRenderPassEncoderDrawIndexed; 563 | extern fn wgpuRenderPassEncoderDrawIndexed( 564 | render_pass_encoder: RenderPassEncoder, 565 | index_count: u32, 566 | instance_count: u32, 567 | first_index: u32, 568 | base_vertex: i32, 569 | first_instance: u32, 570 | ) void; 571 | 572 | pub const drawIndexedIndirect = wgpuRenderPassEncoderDrawIndexedIndirect; 573 | extern fn wgpuRenderPassEncoderDrawIndexedIndirect( 574 | render_pass_encoder: RenderPassEncoder, 575 | indirect_buffer: Buffer, 576 | indirect_offset: u64, 577 | ) void; 578 | 579 | pub const drawIndirect = wgpuRenderPassEncoderDrawIndirect; 580 | extern fn wgpuRenderPassEncoderDrawIndirect( 581 | render_pass_encoder: RenderPassEncoder, 582 | indirect_buffer: Buffer, 583 | indirect_offset: u64, 584 | ) void; 585 | 586 | pub const endOcclusionQuery = wgpuRenderPassEncoderEndOcclusionQuery; 587 | extern fn wgpuRenderPassEncoderEndOcclusionQuery(render_pass_encoder: RenderPassEncoder) void; 588 | 589 | pub const endPass = wgpuRenderPassEncoderEndPass; 590 | extern fn wgpuRenderPassEncoderEndPass(render_pass_encoder: RenderPassEncoder) void; 591 | 592 | pub const endPipelineStatisticsQuery = wgpuRenderPassEncoderEndPipelineStatisticsQuery; 593 | extern fn wgpuRenderPassEncoderEndPipelineStatisticsQuery(render_pass_encoder: RenderPassEncoder) void; 594 | 595 | pub const executeBundles = wgpuRenderPassEncoderExecuteBundles; 596 | extern fn wgpuRenderPassEncoderExecuteBundles( 597 | render_pass_encoder: RenderPassEncoder, 598 | bundles_count: u32, 599 | bundles: *RenderBundle, 600 | ) void; 601 | 602 | pub const insertDebugMarker = wgpuRenderPassEncoderInsertDebugMarker; 603 | extern fn wgpuRenderPassEncoderInsertDebugMarker(render_pass_encoder: RenderPassEncoder, marker_label: [*:0]const u8) void; 604 | 605 | pub const popDebugGroup = wgpuRenderPassEncoderPopDebugGroup; 606 | extern fn wgpuRenderPassEncoderPopDebugGroup(render_pass_encoder: RenderPassEncoder) void; 607 | 608 | pub const pushDebugGroup = wgpuRenderPassEncoderPushDebugGroup; 609 | extern fn wgpuRenderPassEncoderPushDebugGroup(render_pass_encoder: RenderPassEncoder, group_label: [*:0]const u8) void; 610 | 611 | pub const setBindGroup = wgpuRenderPassEncoderSetBindGroup; 612 | extern fn wgpuRenderPassEncoderSetBindGroup( 613 | render_pass_encoder: RenderPassEncoder, 614 | group_index: u32, 615 | group: BindGroup, 616 | dynamic_offset_count: u32, 617 | dynamic_offsets: *u32, 618 | ) void; 619 | 620 | pub const setBlendConstant = wgpuRenderPassEncoderSetBlendConstant; 621 | extern fn wgpuRenderPassEncoderSetBlendConstant(render_pass_encoder: RenderPassEncoder, color: *Color) void; 622 | 623 | pub const setIndexBuffer = wgpuRenderPassEncoderSetIndexBuffer; 624 | extern fn wgpuRenderPassEncoderSetIndexBuffer( 625 | render_pass_encoder: RenderPassEncoder, 626 | buffer: Buffer, 627 | format: IndexFormat, 628 | offset: u64, 629 | size: u64, 630 | ) void; 631 | 632 | pub const setPipeline = wgpuRenderPassEncoderSetPipeline; 633 | extern fn wgpuRenderPassEncoderSetPipeline(render_pass_encoder: RenderPassEncoder, pipeline: RenderPipeline) void; 634 | 635 | pub const setScissorRect = wgpuRenderPassEncoderSetScissorRect; 636 | extern fn wgpuRenderPassEncoderSetScissorRect( 637 | render_pass_encoder: RenderPassEncoder, 638 | x: u32, 639 | y: u32, 640 | width: u32, 641 | height: u32, 642 | ) void; 643 | 644 | pub const setStencilReference = wgpuRenderPassEncoderSetStencilReference; 645 | extern fn wgpuRenderPassEncoderSetStencilReference(render_pass_encoder: RenderPassEncoder, reference: u32) void; 646 | 647 | pub const setVertexBuffer = wgpuRenderPassEncoderSetVertexBuffer; 648 | extern fn wgpuRenderPassEncoderSetVertexBuffer( 649 | render_pass_encoder: RenderPassEncoder, 650 | slot: u32, 651 | buffer: Buffer, 652 | offset: u64, 653 | size: u64, 654 | ) void; 655 | 656 | pub const setViewport = wgpuRenderPassEncoderSetViewport; 657 | extern fn wgpuRenderPassEncoderSetViewport( 658 | render_pass_encoder: RenderPassEncoder, 659 | x: f32, 660 | y: f32, 661 | width: f32, 662 | height: f32, 663 | min_depth: f32, 664 | max_depth: f32, 665 | ) void; 666 | 667 | pub const writeTimestamp = wgpuRenderPassEncoderWriteTimestamp; 668 | extern fn wgpuRenderPassEncoderWriteTimestamp( 669 | render_pass_encoder: RenderPassEncoder, 670 | query_set: QuerySet, 671 | query_index: u32, 672 | ) void; 673 | 674 | // WGPU extras 675 | pub const setPushConstants = wgpuRenderPassEncoderSetPushConstants; 676 | extern fn wgpuRenderPassEncoderSetPushConstants( 677 | encoder: RenderPassEncoder, 678 | stages: ShaderStage, 679 | offset: u32, 680 | sizeBytes: u32, 681 | data: *const c_void, 682 | ) void; 683 | }; 684 | 685 | pub const RenderPipeline = *opaque { 686 | pub const getBindGroupLayout = wgpuRenderPipelineGetBindGroupLayout; 687 | extern fn wgpuRenderPipelineGetBindGroupLayout(render_pipeline: RenderPipeline, group_index: u32) BindGroupLayout; 688 | 689 | pub const setLabel = wgpuRenderPipelineSetLabel; 690 | extern fn wgpuRenderPipelineSetLabel(render_pipeline: RenderPipeline, label: ?[*:0]const u8) void; 691 | 692 | // WGPU extras 693 | pub const drop = wgpuRenderPipelineDrop; 694 | extern fn wgpuRenderPipelineDrop(render_pipeline: RenderPipeline) void; 695 | }; 696 | 697 | pub const Sampler = *opaque { 698 | // WGPU extras 699 | pub const drop = wgpuSamplerDrop; 700 | extern fn wgpuSamplerDrop(sampler: Sampler) void; 701 | }; 702 | 703 | pub const ShaderModule = *opaque { 704 | pub const setLabel = wgpuShaderModuleSetLabel; 705 | extern fn wgpuShaderModuleSetLabel(shader_module: ShaderModule, label: ?[*:0]const u8) void; 706 | 707 | // WGPU extras 708 | pub const drop = wgpuShaderModuleDrop; 709 | extern fn wgpuShaderModuleDrop(shader_module: ShaderModule) void; 710 | }; 711 | 712 | pub const Surface = *opaque { 713 | pub const getPreferredFormat = wgpuSurfaceGetPreferredFormat; 714 | extern fn wgpuSurfaceGetPreferredFormat( 715 | surface: Surface, 716 | adapter: Adapter, 717 | ) TextureFormat; 718 | }; 719 | 720 | pub const SwapChain = *opaque { 721 | pub const getCurrentTextureView = wgpuSwapChainGetCurrentTextureView; 722 | extern fn wgpuSwapChainGetCurrentTextureView(swap_chain: SwapChain) ?TextureView; 723 | 724 | pub const present = wgpuSwapChainPresent; 725 | extern fn wgpuSwapChainPresent(swap_chain: SwapChain) void; 726 | }; 727 | 728 | pub const Texture = *opaque { 729 | pub const createView = wgpuTextureCreateView; 730 | extern fn wgpuTextureCreateView(texture: Texture, descriptor: *TextureViewDescriptor) TextureView; 731 | 732 | pub const destroy = wgpuTextureDestroy; 733 | extern fn wgpuTextureDestroy(texture: Texture) void; 734 | 735 | // WGPU extras 736 | pub const drop = wgpuTextureDrop; 737 | extern fn wgpuTextureDrop(texture: Texture) void; 738 | }; 739 | 740 | pub const TextureView = *opaque { 741 | // WGPU extras 742 | pub const drop = wgpuTextureViewDrop; 743 | extern fn wgpuTextureViewDrop(texture_view: TextureView) void; 744 | }; 745 | 746 | pub const AdapterType = enum(u32) { 747 | discrete_gpu = 0x00000000, 748 | integrated_gpu = 0x00000001, 749 | cpu = 0x00000002, 750 | unknown = 0x00000003, 751 | }; 752 | 753 | pub const AddressMode = enum(u32) { 754 | repeat = 0x00000000, 755 | mirror_repeat = 0x00000001, 756 | clamp_to_edge = 0x00000002, 757 | }; 758 | 759 | pub const BackendType = enum(u32) { 760 | none, 761 | webgpu, 762 | d3d11, 763 | d3d12, 764 | metal, 765 | vulkan, 766 | opengl, 767 | opengles, 768 | }; 769 | 770 | pub const BlendFactor = enum(u32) { 771 | zero = 0x00000000, 772 | one = 0x00000001, 773 | src = 0x00000002, 774 | one_minus_src = 0x00000003, 775 | src_alpha = 0x00000004, 776 | one_minus_src_alpha = 0x00000005, 777 | dst = 0x00000006, 778 | one_minus_dst = 0x00000007, 779 | dst_alpha = 0x00000008, 780 | one_minus_dst_alpha = 0x00000009, 781 | src_alpha_saturated = 0x0000000A, 782 | constant = 0x0000000B, 783 | one_minus_constant = 0x0000000C, 784 | }; 785 | 786 | pub const BlendOperation = enum(u32) { 787 | add = 0x00000000, 788 | subtract = 0x00000001, 789 | reverse_subtract = 0x00000002, 790 | min = 0x00000003, 791 | max = 0x00000004, 792 | }; 793 | 794 | pub const BufferBindingType = enum(u32) { 795 | uniform = 0x00000001, 796 | storage = 0x00000002, 797 | read_only_storage = 0x00000003, 798 | }; 799 | 800 | pub const BufferMapAsyncStatus = enum(u32) { 801 | success = 0x00000000, 802 | @"error" = 0x00000001, 803 | unknown = 0x00000002, 804 | device_lost = 0x00000003, 805 | destroyed_before_callback = 0x00000004, 806 | unmapped_before_callback = 0x00000005, 807 | }; 808 | 809 | pub const CompareFunction = enum(u32) { 810 | never = 0x00000001, 811 | less = 0x00000002, 812 | less_equal = 0x00000003, 813 | greater = 0x00000004, 814 | greater_equal = 0x00000005, 815 | equal = 0x00000006, 816 | not_equal = 0x00000007, 817 | always = 0x00000008, 818 | }; 819 | 820 | pub const CompilationMessageType = enum(u32) { 821 | @"error", 822 | warning, 823 | info, 824 | }; 825 | 826 | pub const CreatePipelineAsyncStatus = enum(u32) { 827 | success = 0x00000000, 828 | @"error" = 0x00000001, 829 | device_lost = 0x00000002, 830 | device_destroyed = 0x00000003, 831 | unknown = 0x00000004, 832 | }; 833 | 834 | pub const CullMode = enum(u32) { 835 | none = 0x00000000, 836 | front = 0x00000001, 837 | back = 0x00000002, 838 | }; 839 | 840 | pub const DeviceLostReason = enum(u32) { 841 | @"undefined", 842 | destroyed, 843 | }; 844 | 845 | pub const ErrorFilter = enum(u32) { 846 | none = 0x00000000, 847 | validation = 0x00000001, 848 | out_of_memory = 0x00000002, 849 | }; 850 | 851 | pub const ErrorType = enum(u32) { 852 | no_error = 0x00000000, 853 | validation = 0x00000001, 854 | out_of_memory = 0x00000002, 855 | unknown = 0x00000003, 856 | device_lost = 0x00000004, 857 | }; 858 | 859 | pub const FeatureName = enum(u32) { 860 | @"undefined", 861 | depth_clamping, 862 | depth24_unorm_stencil8, 863 | depth32_float_stencil8, 864 | timestamp_query, 865 | pipeline_statistics_query, 866 | texture_compression_bc, 867 | }; 868 | 869 | pub const FilterMode = enum(u32) { 870 | nearest = 0x00000000, 871 | linear = 0x00000001, 872 | }; 873 | 874 | pub const FrontFace = enum(u32) { 875 | ccw = 0x00000000, 876 | cw = 0x00000001, 877 | }; 878 | 879 | pub const IndexFormat = enum(u32) { 880 | unknown = 0, 881 | uint16 = 0x00000001, 882 | uint32 = 0x00000002, 883 | }; 884 | 885 | pub const LoadOp = enum(u32) { 886 | clear = 0x00000000, 887 | load = 0x00000001, 888 | }; 889 | 890 | pub const PipelineStatisticName = enum(u32) { 891 | vertex_shader_invocations = 0x00000000, 892 | clipper_invocations = 0x00000001, 893 | clipper_primitives_out = 0x00000002, 894 | fragment_shader_invocations = 0x00000003, 895 | compute_shader_invocations = 0x00000004, 896 | }; 897 | 898 | pub const PowerPreference = enum(u32) { 899 | low_power, 900 | high_performance, 901 | }; 902 | 903 | pub const PresentMode = enum(u32) { 904 | immediate = 0x00000000, 905 | mailbox = 0x00000001, 906 | fifo = 0x00000002, 907 | }; 908 | 909 | pub const PrimitiveTopology = enum(u32) { 910 | pointlist = 0x00000000, 911 | line_list = 0x00000001, 912 | line_strip = 0x00000002, 913 | triangle_list = 0x00000003, 914 | triangle_strip = 0x00000004, 915 | }; 916 | 917 | pub const QueryType = enum(u32) { 918 | occlusion = 0x00000000, 919 | pipeline_statistics = 0x00000001, 920 | timestamp = 0x00000002, 921 | }; 922 | 923 | pub const QueueWorkDoneStatus = enum(u32) { 924 | success = 0x00000000, 925 | @"error" = 0x00000001, 926 | unknown = 0x00000002, 927 | device_lost = 0x00000003, 928 | }; 929 | 930 | pub const RequestAdapterStatus = enum(u32) { 931 | success, 932 | unavailable, 933 | @"error", 934 | unknown, 935 | }; 936 | 937 | pub const RequestDeviceStatus = enum(u32) { 938 | success, 939 | @"error", 940 | unknown, 941 | }; 942 | 943 | pub const SType = enum(u32) { 944 | invalid = 0x00000000, 945 | surface_descriptor_from_metal_layer = 0x00000001, 946 | surface_descriptor_from_windows_hwnd = 0x00000002, 947 | surface_descriptor_from_xlib = 0x00000003, 948 | surface_descriptor_from_canvas_html_selector = 0x00000004, 949 | shader_module_spirv_descriptor = 0x00000005, 950 | shader_module_wgsl_descriptor = 0x00000006, 951 | primitive_depth_clamping_state = 0x00000007, 952 | 953 | // WGPU extras 954 | // Start at 6 to prevent collisions with webgpu STypes 955 | device_extras = 0x60000001, 956 | adapter_extras = 0x60000002, 957 | }; 958 | 959 | pub const SamplerBindingType = enum(u32) { 960 | filtering = 0x00000001, 961 | non_filtering = 0x00000002, 962 | comparison = 0x00000003, 963 | }; 964 | 965 | pub const StencilOperation = enum(u32) { 966 | keep = 0x00000000, 967 | zero = 0x00000001, 968 | replace = 0x00000002, 969 | invert = 0x00000003, 970 | increment_clamp = 0x00000004, 971 | decrement_clamp = 0x00000005, 972 | increment_wrap = 0x00000006, 973 | decrement_wrap = 0x00000007, 974 | }; 975 | 976 | pub const StorageTextureAccess = enum(u32) { 977 | @"undefined", 978 | write_only, 979 | }; 980 | 981 | pub const StoreOp = enum(u32) { 982 | store, 983 | discard, 984 | }; 985 | 986 | pub const TextureAspect = enum(u32) { 987 | all = 0x00000000, 988 | stencil_only = 0x00000001, 989 | depth_only = 0x00000002, 990 | }; 991 | 992 | pub const TextureComponentType = enum(u32) { 993 | float = 0x00000000, 994 | sint = 0x00000001, 995 | uint = 0x00000002, 996 | depth_comparison = 0x00000003, 997 | }; 998 | 999 | pub const TextureDimension = enum(u32) { 1000 | @"1d" = 0x00000000, 1001 | @"2d" = 0x00000001, 1002 | @"3d" = 0x00000002, 1003 | }; 1004 | 1005 | pub const TextureFormat = enum(u32) { 1006 | r8_unorm = 1, 1007 | r8_snorm, 1008 | r8_uint, 1009 | r8_sint, 1010 | r16_uint, 1011 | r16_sint, 1012 | r16_float, 1013 | rg8_unorm, 1014 | rg8_snorm, 1015 | rg8_uint, 1016 | rg8_sint, 1017 | r32_float, 1018 | r32_uint, 1019 | r32_sint, 1020 | rg16_uint, 1021 | rg16_sint, 1022 | rg16_float, 1023 | rgba8_unorm, 1024 | rgba8_unorm_srgb, 1025 | rgba8_snorm, 1026 | rgba8_uint, 1027 | rgba8_sint, 1028 | bgra8_unorm, 1029 | bgra8_unorm_srgb, 1030 | rgb10_a_2_unorm, 1031 | rg11b10_ufloat, 1032 | rgb9e5_ufloat, 1033 | rg32_float, 1034 | rg32_uint, 1035 | rg32_sint, 1036 | rgba16_uint, 1037 | rgba16_sint, 1038 | rgba16_float, 1039 | rgba32_float, 1040 | rgba32_uint, 1041 | rgba32_sint, 1042 | stencil8, 1043 | depth16_unorm, 1044 | depth24_plus, 1045 | depth24_plus_stencil_8, 1046 | depth32_float, 1047 | bc1_rgba_unorm, 1048 | bc1_rgba_unorm_srgb, 1049 | bc2_rgba_unorm, 1050 | bc2_rgba_unorm_srgb, 1051 | bc3_rgba_unorm, 1052 | bc3_rgba_unorm_srgb, 1053 | bc4_r_unorm, 1054 | bc4_r_snorm, 1055 | bc5_rg_unorm, 1056 | bc5_rg_snorm, 1057 | bc6h_rgb_ufloat, 1058 | bc6h_rgb_float, 1059 | bc7_rgba_unorm, 1060 | bc7_rgba_unorm_srgb, 1061 | }; 1062 | 1063 | pub const TextureSampleType = enum(u32) { 1064 | float = 0x00000001, 1065 | unfilterable_float = 0x00000002, 1066 | depth = 0x00000003, 1067 | sint = 0x00000004, 1068 | uint = 0x00000005, 1069 | }; 1070 | 1071 | pub const TextureViewDimension = enum(u32) { 1072 | @"1d" = 0x00000001, 1073 | @"2d" = 0x00000002, 1074 | @"2darray" = 0x00000003, 1075 | cube = 0x00000004, 1076 | cube_array = 0x00000005, 1077 | @"3d" = 0x00000006, 1078 | }; 1079 | 1080 | pub const VertexFormat = enum(u32) { 1081 | uint8x_2 = 0x00000001, 1082 | uint8x_4 = 0x00000002, 1083 | sint8x_2 = 0x00000003, 1084 | sint8x_4 = 0x00000004, 1085 | unorm_8x_2 = 0x00000005, 1086 | unorm_8x_4 = 0x00000006, 1087 | snorm_8x_2 = 0x00000007, 1088 | snorm_8x_4 = 0x00000008, 1089 | uint16x_2 = 0x00000009, 1090 | uint16x_4 = 0x0000000A, 1091 | sint16x_2 = 0x0000000B, 1092 | sint16x_4 = 0x0000000C, 1093 | unorm_16x_2 = 0x0000000D, 1094 | unorm_16x_4 = 0x0000000E, 1095 | snorm_16x_2 = 0x0000000F, 1096 | snorm_16x_4 = 0x00000010, 1097 | float_16x_2 = 0x00000011, 1098 | float_16x_4 = 0x00000012, 1099 | float_32 = 0x00000013, 1100 | float_32x_2 = 0x00000014, 1101 | float_32x_3 = 0x00000015, 1102 | float_32x_4 = 0x00000016, 1103 | uint32 = 0x00000017, 1104 | uint32x_2 = 0x00000018, 1105 | uint32x_3 = 0x00000019, 1106 | uint32x_4 = 0x0000001A, 1107 | sint32 = 0x0000001B, 1108 | sint32x_2 = 0x0000001C, 1109 | sint32x_3 = 0x0000001D, 1110 | sint32x_4 = 0x0000001E, 1111 | }; 1112 | 1113 | pub const VertexStepMode = enum(u32) { 1114 | vertex, 1115 | instance, 1116 | }; 1117 | 1118 | fn Flags(comptime names: []const []const u8, default: bool) type { 1119 | const std = @import("std"); 1120 | 1121 | var bool_fields: [names.len]std.builtin.TypeInfo.StructField = undefined; 1122 | for (names) |name, i| { 1123 | bool_fields[i] = .{ 1124 | .name = name, 1125 | .field_type = bool, 1126 | .alignment = 0, 1127 | .default_value = default, 1128 | .is_comptime = false, 1129 | }; 1130 | } 1131 | 1132 | var fields: []const std.builtin.TypeInfo.StructField = &bool_fields; 1133 | if (names.len % 8 != 0) { // Pad bits 1134 | const T = std.meta.Int(.unsigned, 8 - names.len % 8); 1135 | const pad_default: T = 0; 1136 | fields = fields ++ &[_]std.builtin.TypeInfo.StructField{.{ 1137 | .name = "_bit_pad", 1138 | .field_type = T, 1139 | .alignment = 0, 1140 | .default_value = pad_default, 1141 | .is_comptime = false, 1142 | }}; 1143 | } 1144 | 1145 | var byte_size = (names.len - 1) / 8 + 1; 1146 | while (byte_size < 4) : (byte_size += 1) { 1147 | const pad_default: u8 = 0; 1148 | fields = fields ++ &[_]std.builtin.TypeInfo.StructField{.{ 1149 | .name = std.fmt.comptimePrint("_byte_pad{}", .{byte_size}), 1150 | .field_type = u8, 1151 | .alignment = 0, 1152 | .default_value = pad_default, 1153 | .is_comptime = false, 1154 | }}; 1155 | } 1156 | 1157 | const T = @Type(.{ .Struct = .{ 1158 | .layout = .Packed, 1159 | .fields = fields, 1160 | .decls = &.{}, 1161 | .is_tuple = false, 1162 | } }); 1163 | std.debug.assert(@bitSizeOf(T) == 32 and @sizeOf(T) == 4); 1164 | return T; 1165 | } 1166 | 1167 | pub const BufferUsage = Flags(&.{ 1168 | "map_read", 1169 | "map_write", 1170 | "copy_src", 1171 | "copy_dst", 1172 | "index", 1173 | "vertex", 1174 | "uniform", 1175 | "storage", 1176 | "indirect", 1177 | "query_resolve", 1178 | }, false); 1179 | 1180 | pub const ColorWriteMask = Flags(&.{ 1181 | "red", "green", 1182 | "blue", "alpha", 1183 | }, true); 1184 | 1185 | pub const MapMode = Flags(&.{ "read", "write" }, false); 1186 | 1187 | pub const ShaderStage = Flags(&.{ "vertex", "fragment", "compute" }, false); 1188 | 1189 | pub const TextureUsage = Flags(&.{ 1190 | "copy_src", 1191 | "copy_dst", 1192 | "texture_binding", 1193 | "storage_binding", 1194 | "render_attachment", 1195 | }, false); 1196 | 1197 | pub const ChainedStruct = extern struct { 1198 | next: ?*const ChainedStruct, 1199 | s_type: SType, 1200 | }; 1201 | 1202 | pub const ChainedStructOut = extern struct { 1203 | next: ?*ChainedStructOut, 1204 | s_type: SType, 1205 | }; 1206 | 1207 | pub const AdapterProperties = extern struct { 1208 | next_in_chain: ?*ChainedStructOut = null, 1209 | vendor_id: u32, 1210 | device_id: u32, 1211 | name: [*:0]const u8, 1212 | driver_description: [*:0]const u8, 1213 | adapter_type: AdapterType, 1214 | backend_type: BackendType, 1215 | }; 1216 | 1217 | pub const BindGroupEntry = extern struct { 1218 | next_in_chain: ?*const ChainedStruct = null, 1219 | binding: u32, 1220 | buffer: Buffer, 1221 | offset: u64, 1222 | size: u64, 1223 | sampler: Sampler, 1224 | texture_view: TextureView, 1225 | }; 1226 | 1227 | pub const BlendComponent = extern struct { 1228 | operation: BlendOperation, 1229 | src_factor: BlendFactor, 1230 | dst_factor: BlendFactor, 1231 | }; 1232 | 1233 | pub const BufferBindingLayout = extern struct { 1234 | next_in_chain: ?*const ChainedStruct = null, 1235 | type: BufferBindingType, 1236 | has_dynamic_offset: bool, 1237 | min_binding_size: u64, 1238 | }; 1239 | 1240 | pub const BufferDescriptor = extern struct { 1241 | next_in_chain: ?*const ChainedStruct = null, 1242 | label: ?[*:0]const u8 = null, 1243 | usage: BufferUsage, 1244 | size: u64, 1245 | mapped_at_creation: bool, 1246 | }; 1247 | 1248 | pub const Color = extern struct { 1249 | r: f64, 1250 | g: f64, 1251 | b: f64, 1252 | a: f64, 1253 | }; 1254 | 1255 | pub const CommandBufferDescriptor = extern struct { 1256 | next_in_chain: ?*const ChainedStruct = null, 1257 | label: ?[*:0]const u8 = null, 1258 | }; 1259 | 1260 | pub const CommandEncoderDescriptor = extern struct { 1261 | next_in_chain: ?*const ChainedStruct = null, 1262 | label: ?[*:0]const u8 = null, 1263 | }; 1264 | 1265 | pub const CompilationMessage = extern struct { 1266 | next_in_chain: ?*const ChainedStruct = null, 1267 | message: [*:0]const u8, 1268 | type: CompilationMessageType, 1269 | line_num: u64, 1270 | line_pos: u64, 1271 | offset: u64, 1272 | length: u64, 1273 | }; 1274 | 1275 | pub const ComputePassDescriptor = extern struct { 1276 | next_in_chain: ?*const ChainedStruct = null, 1277 | label: ?[*:0]const u8 = null, 1278 | }; 1279 | 1280 | pub const ConstantEntry = extern struct { 1281 | next_in_chain: ?*const ChainedStruct = null, 1282 | key: [*:0]const u8, 1283 | value: f64, 1284 | }; 1285 | 1286 | pub const Extent3D = extern struct { 1287 | width: u32, 1288 | height: u32, 1289 | depth_or_array_layers: u32, 1290 | }; 1291 | 1292 | pub const InstanceDescriptor = extern struct { 1293 | next_in_chain: ?*const ChainedStruct = null, 1294 | }; 1295 | 1296 | pub const Limits = extern struct { 1297 | max_texture_dimension_1d: u32 = 0, 1298 | max_texture_dimension_2d: u32 = 0, 1299 | max_texture_dimension_3d: u32 = 0, 1300 | max_texture_array_layers: u32 = 0, 1301 | max_bind_groups: u32 = 0, 1302 | max_dynamic_uniform_buffers_per_pipeline_layout: u32 = 0, 1303 | max_dynamic_storage_buffers_per_pipeline_layout: u32 = 0, 1304 | max_sampled_textures_per_shader_stage: u32 = 0, 1305 | max_samplers_per_shader_stage: u32 = 0, 1306 | max_storage_buffers_per_shader_stage: u32 = 0, 1307 | max_storage_textures_per_shader_stage: u32 = 0, 1308 | max_uniform_buffers_per_shader_stage: u32 = 0, 1309 | max_uniform_buffer_binding_size: u64 = 0, 1310 | max_storage_buffer_binding_size: u64 = 0, 1311 | min_uniform_buffer_offset_alignment: u32 = 0, 1312 | min_storage_buffer_offset_alignment: u32 = 0, 1313 | max_vertex_buffers: u32 = 0, 1314 | max_vertex_attributes: u32 = 0, 1315 | max_vertex_buffer_array_stride: u32 = 0, 1316 | max_inter_stage_shader_components: u32 = 0, 1317 | max_compute_workgroup_storage_size: u32 = 0, 1318 | max_compute_invocations_per_workgroup: u32 = 0, 1319 | max_compute_workgroup_size_x: u32 = 0, 1320 | max_compute_workgroup_size_y: u32 = 0, 1321 | max_compute_workgroup_size_z: u32 = 0, 1322 | max_compute_workgroups_per_dimension: u32 = 0, 1323 | }; 1324 | 1325 | pub const MultisampleState = extern struct { 1326 | next_in_chain: ?*const ChainedStruct = null, 1327 | count: u32, 1328 | mask: u32, 1329 | alpha_to_coverage_enabled: bool, 1330 | }; 1331 | 1332 | pub const Origin3D = extern struct { 1333 | x: u32, 1334 | y: u32, 1335 | z: u32, 1336 | }; 1337 | 1338 | pub const PipelineLayoutDescriptor = extern struct { 1339 | next_in_chain: ?*const ChainedStruct = null, 1340 | label: ?[*:0]const u8 = null, 1341 | bind_group_layout_count: u32, 1342 | bind_group_layouts: ?*BindGroupLayout, 1343 | }; 1344 | 1345 | pub const PrimitiveDepthClampingState = extern struct { 1346 | chain: ChainedStruct, 1347 | clamp_depth: bool, 1348 | }; 1349 | 1350 | pub const PrimitiveState = extern struct { 1351 | next_in_chain: ?*const ChainedStruct = null, 1352 | topology: PrimitiveTopology, 1353 | strip_index_format: IndexFormat, 1354 | front_face: FrontFace, 1355 | cull_mode: CullMode, 1356 | }; 1357 | 1358 | pub const QuerySetDescriptor = extern struct { 1359 | next_in_chain: ?*const ChainedStruct = null, 1360 | label: ?[*:0]const u8 = null, 1361 | type: QueryType, 1362 | count: u32, 1363 | pipeline_statistics: *PipelineStatisticName, 1364 | pipeline_statistics_count: u32, 1365 | }; 1366 | 1367 | pub const RenderBundleDescriptor = extern struct { 1368 | next_in_chain: ?*const ChainedStruct = null, 1369 | label: ?[*:0]const u8 = null, 1370 | }; 1371 | 1372 | pub const RenderBundleEncoderDescriptor = extern struct { 1373 | next_in_chain: ?*const ChainedStruct = null, 1374 | label: ?[*:0]const u8 = null, 1375 | color_formats_count: u32, 1376 | color_formats: *TextureFormat, 1377 | depth_stencil_format: TextureFormat, 1378 | sample_count: u32, 1379 | }; 1380 | 1381 | pub const RenderPassDepthStencilAttachment = extern struct { 1382 | view: TextureView, 1383 | depth_load_op: LoadOp, 1384 | depth_store_op: StoreOp, 1385 | clear_depth: f32, 1386 | depth_read_only: bool, 1387 | stencil_load_op: LoadOp, 1388 | stencil_store_op: StoreOp, 1389 | clear_stencil: u32, 1390 | stencil_read_only: bool, 1391 | }; 1392 | 1393 | pub const RequestAdapterOptions = extern struct { 1394 | next_in_chain: ?*const ChainedStruct = null, 1395 | compatible_surface: Surface, 1396 | power_preference: PowerPreference, 1397 | force_fallback_adapter: bool, 1398 | }; 1399 | 1400 | pub const SamplerBindingLayout = extern struct { 1401 | next_in_chain: ?*const ChainedStruct = null, 1402 | type: SamplerBindingType, 1403 | }; 1404 | 1405 | pub const SamplerDescriptor = extern struct { 1406 | next_in_chain: ?*const ChainedStruct = null, 1407 | label: ?[*:0]const u8 = null, 1408 | address_mode_u: AddressMode, 1409 | address_mode_v: AddressMode, 1410 | address_mode_w: AddressMode, 1411 | mag_filter: FilterMode, 1412 | min_filter: FilterMode, 1413 | mipmap_filter: FilterMode, 1414 | lod_min_clamp: f32, 1415 | lod_max_clamp: f32, 1416 | compare: CompareFunction, 1417 | max_anisotropy: u16, 1418 | }; 1419 | 1420 | pub const ShaderModuleDescriptor = extern struct { 1421 | next_in_chain: ?*const ChainedStruct = null, 1422 | label: ?[*:0]const u8 = null, 1423 | }; 1424 | 1425 | pub const ShaderModuleSPIRVDescriptor = extern struct { 1426 | chain: ChainedStruct, 1427 | code_size: u32, 1428 | code: *u32, 1429 | }; 1430 | 1431 | pub const ShaderModuleWGSLDescriptor = extern struct { 1432 | chain: ChainedStruct = .{ 1433 | .next = null, 1434 | .s_type = .shader_module_wgsl_descriptor, 1435 | }, 1436 | source: [*:0]const u8, 1437 | }; 1438 | 1439 | pub const StencilFaceState = extern struct { 1440 | compare: CompareFunction, 1441 | fail_op: StencilOperation, 1442 | depth_fail_op: StencilOperation, 1443 | pass_op: StencilOperation, 1444 | }; 1445 | 1446 | pub const StorageTextureBindingLayout = extern struct { 1447 | next_in_chain: ?*const ChainedStruct = null, 1448 | access: StorageTextureAccess, 1449 | format: TextureFormat, 1450 | view_dimension: TextureViewDimension, 1451 | }; 1452 | 1453 | pub const SurfaceDescriptor = extern struct { 1454 | next_in_chain: ?*const ChainedStruct = null, 1455 | label: ?[*:0]const u8 = null, 1456 | }; 1457 | 1458 | pub const SurfaceDescriptorFromCanvasHTMLSelector = extern struct { 1459 | chain: ChainedStruct, 1460 | selector: [*:0]const u8, 1461 | }; 1462 | 1463 | pub const SurfaceDescriptorFromMetalLayer = extern struct { 1464 | chain: ChainedStruct, 1465 | layer: *c_void, 1466 | }; 1467 | 1468 | pub const SurfaceDescriptorFromWindowsHWND = extern struct { 1469 | chain: ChainedStruct, 1470 | hinstance: *c_void, 1471 | hwnd: *c_void, 1472 | }; 1473 | 1474 | pub const SurfaceDescriptorFromXlib = extern struct { 1475 | chain: ChainedStruct = .{ 1476 | .next = null, 1477 | .s_type = .surface_descriptor_from_xlib, 1478 | }, 1479 | display: *c_void, 1480 | window: u32, 1481 | }; 1482 | 1483 | pub const SwapChainDescriptor = extern struct { 1484 | next_in_chain: ?*const ChainedStruct = null, 1485 | label: ?[*:0]const u8 = null, 1486 | usage: TextureUsage, 1487 | format: TextureFormat, 1488 | width: u32, 1489 | height: u32, 1490 | present_mode: PresentMode, 1491 | }; 1492 | 1493 | pub const TextureBindingLayout = extern struct { 1494 | next_in_chain: ?*const ChainedStruct = null, 1495 | sample_type: TextureSampleType, 1496 | view_dimension: TextureViewDimension, 1497 | multisampled: bool, 1498 | }; 1499 | 1500 | pub const TextureDataLayout = extern struct { 1501 | next_in_chain: ?*const ChainedStruct = null, 1502 | offset: u64, 1503 | bytes_per_row: u32, 1504 | rows_per_image: u32, 1505 | }; 1506 | 1507 | pub const TextureViewDescriptor = extern struct { 1508 | next_in_chain: ?*const ChainedStruct = null, 1509 | label: ?[*:0]const u8 = null, 1510 | format: TextureFormat, 1511 | dimension: TextureViewDimension, 1512 | base_mip_level: u32, 1513 | mip_level_count: u32, 1514 | base_array_layer: u32, 1515 | array_layer_count: u32, 1516 | aspect: TextureAspect, 1517 | }; 1518 | 1519 | pub const VertexAttribute = extern struct { 1520 | format: VertexFormat, 1521 | offset: u64, 1522 | shader_location: u32, 1523 | }; 1524 | 1525 | pub const BindGroupDescriptor = extern struct { 1526 | next_in_chain: ?*const ChainedStruct = null, 1527 | label: ?[*:0]const u8 = null, 1528 | layout: BindGroupLayout, 1529 | entry_count: u32, 1530 | entries: *BindGroupEntry, 1531 | }; 1532 | 1533 | pub const BindGroupLayoutEntry = extern struct { 1534 | next_in_chain: ?*const ChainedStruct = null, 1535 | binding: u32, 1536 | visibility: ShaderStage, 1537 | buffer: BufferBindingLayout, 1538 | sampler: SamplerBindingLayout, 1539 | texture: TextureBindingLayout, 1540 | storage_texture: StorageTextureBindingLayout, 1541 | }; 1542 | 1543 | pub const BlendState = extern struct { 1544 | color: BlendComponent, 1545 | alpha: BlendComponent, 1546 | }; 1547 | 1548 | pub const CompilationInfo = extern struct { 1549 | next_in_chain: ?*const ChainedStruct = null, 1550 | message_count: u32, 1551 | messages: [*]const CompilationMessage, 1552 | }; 1553 | 1554 | pub const DepthStencilState = extern struct { 1555 | next_in_chain: ?*const ChainedStruct = null, 1556 | format: TextureFormat, 1557 | depth_write_enabled: bool, 1558 | depth_compare: CompareFunction, 1559 | stencil_front: StencilFaceState, 1560 | stencil_back: StencilFaceState, 1561 | stencil_read_mask: u32, 1562 | stencil_write_mask: u32, 1563 | depth_bias: i32, 1564 | depth_bias_slope_scale: f32, 1565 | depth_bias_clamp: f32, 1566 | }; 1567 | 1568 | pub const ImageCopyBuffer = extern struct { 1569 | next_in_chain: ?*const ChainedStruct = null, 1570 | layout: TextureDataLayout, 1571 | buffer: Buffer, 1572 | }; 1573 | 1574 | pub const ImageCopyTexture = extern struct { 1575 | next_in_chain: ?*const ChainedStruct = null, 1576 | texture: Texture, 1577 | mip_level: u32, 1578 | origin: Origin3D, 1579 | aspect: TextureAspect, 1580 | }; 1581 | 1582 | pub const ProgrammableStageDescriptor = extern struct { 1583 | next_in_chain: ?*const ChainedStruct = null, 1584 | module: ShaderModule, 1585 | entry_point: [*:0]const u8, 1586 | constant_count: u32, 1587 | constants: [*]const ConstantEntry, 1588 | }; 1589 | 1590 | pub const RenderPassColorAttachment = extern struct { 1591 | view: TextureView, 1592 | resolve_target: ?TextureView, 1593 | load_op: LoadOp, 1594 | store_op: StoreOp, 1595 | clear_color: Color, 1596 | }; 1597 | 1598 | pub const RequiredLimits = extern struct { 1599 | next_in_chain: ?*const ChainedStruct = null, 1600 | limits: Limits, 1601 | }; 1602 | 1603 | pub const SupportedLimits = extern struct { 1604 | next_in_chain: ?*ChainedStructOut = null, 1605 | limits: Limits, 1606 | }; 1607 | 1608 | pub const TextureDescriptor = extern struct { 1609 | next_in_chain: ?*const ChainedStruct = null, 1610 | label: ?[*:0]const u8 = null, 1611 | usage: TextureUsage, 1612 | dimension: TextureDimension, 1613 | size: Extent3D, 1614 | format: TextureFormat, 1615 | mip_level_count: u32, 1616 | sample_count: u32, 1617 | }; 1618 | 1619 | pub const VertexBufferLayout = extern struct { 1620 | array_stride: u64, 1621 | step_mode: VertexStepMode, 1622 | attribute_count: u32, 1623 | attributes: *VertexAttribute, 1624 | }; 1625 | 1626 | pub const BindGroupLayoutDescriptor = extern struct { 1627 | next_in_chain: ?*const ChainedStruct = null, 1628 | label: ?[*:0]const u8 = null, 1629 | entry_count: u32, 1630 | entries: *BindGroupLayoutEntry, 1631 | }; 1632 | 1633 | pub const ColorTargetState = extern struct { 1634 | next_in_chain: ?*const ChainedStruct = null, 1635 | format: TextureFormat, 1636 | blend: *const BlendState, 1637 | write_mask: ColorWriteMask, 1638 | }; 1639 | 1640 | pub const ComputePipelineDescriptor = extern struct { 1641 | next_in_chain: ?*const ChainedStruct = null, 1642 | label: ?[*:0]const u8 = null, 1643 | layout: PipelineLayout, 1644 | compute: ProgrammableStageDescriptor, 1645 | }; 1646 | 1647 | pub const DeviceDescriptor = extern struct { 1648 | next_in_chain: ?*const ChainedStruct = null, 1649 | required_features_count: u32, 1650 | required_features: [*]const FeatureName, 1651 | required_limits: ?*const RequiredLimits, 1652 | }; 1653 | 1654 | pub const RenderPassDescriptor = extern struct { 1655 | next_in_chain: ?*const ChainedStruct = null, 1656 | label: ?[*:0]const u8 = null, 1657 | color_attachment_count: u32, 1658 | color_attachments: ?[*]RenderPassColorAttachment, 1659 | depth_stencil_attachment: ?*RenderPassDepthStencilAttachment = null, 1660 | occlusion_query_set: ?QuerySet = null, 1661 | }; 1662 | 1663 | pub const VertexState = extern struct { 1664 | next_in_chain: ?*const ChainedStruct = null, 1665 | module: ShaderModule, 1666 | entry_point: [*:0]const u8, 1667 | constant_count: u32, 1668 | constants: [*]const ConstantEntry, 1669 | buffer_count: u32, 1670 | buffers: [*]const VertexBufferLayout, 1671 | }; 1672 | 1673 | pub const FragmentState = extern struct { 1674 | next_in_chain: ?*const ChainedStruct = null, 1675 | module: ShaderModule, 1676 | entry_point: [*:0]const u8, 1677 | constant_count: u32, 1678 | constants: [*]const ConstantEntry, 1679 | target_count: u32, 1680 | targets: *const ColorTargetState, 1681 | }; 1682 | 1683 | pub const RenderPipelineDescriptor = extern struct { 1684 | next_in_chain: ?*const ChainedStruct = null, 1685 | label: ?[*:0]const u8 = null, 1686 | layout: PipelineLayout, 1687 | vertex: VertexState, 1688 | primitive: PrimitiveState, 1689 | depth_stencil: ?*const DepthStencilState, 1690 | multisample: MultisampleState, 1691 | fragment: ?*const FragmentState, 1692 | }; 1693 | 1694 | // WGPU extras 1695 | pub const NativeFeature = enum(u32) { 1696 | none = 0, 1697 | texture_adapter_specific_format_features = 0x10000000, 1698 | }; 1699 | 1700 | pub const LogLevel = enum(u32) { 1701 | off = 0x00000000, 1702 | err = 0x00000001, 1703 | warn = 0x00000002, 1704 | info = 0x00000003, 1705 | debug = 0x00000004, 1706 | trace = 0x00000005, 1707 | }; 1708 | 1709 | pub const AdapterExtras = extern struct { 1710 | chain: ChainedStruct, 1711 | backend: BackendType, 1712 | }; 1713 | 1714 | pub const DeviceExtras = extern struct { 1715 | chain: ChainedStruct = .{ 1716 | .next = null, 1717 | .s_type = .device_extras, 1718 | }, 1719 | native_features: NativeFeature = .none, 1720 | label: ?[*:0]const u8 = null, 1721 | trace_path: ?[*:0]const u8 = null, 1722 | }; 1723 | 1724 | pub const LogCallback = fn (level: LogLevel, msg: [*:0]const u8) callconv(.C) void; 1725 | 1726 | pub const setLogCallback = wgpuSetLogCallback; 1727 | extern fn wgpuSetLogCallback(callback: LogCallback) void; 1728 | 1729 | pub const setLogLevel = wgpuSetLogLevel; 1730 | extern fn wgpuSetLogLevel(level: LogLevel) void; 1731 | 1732 | pub const getVersion = wgpuGetVersion; 1733 | extern fn wgpuGetVersion() u32; 1734 | --------------------------------------------------------------------------------