From b98288605b9841b28eb12dd53640f3d3428bd232 Mon Sep 17 00:00:00 2001 From: Szymon Nowakowski Date: Sun, 2 Feb 2025 16:41:39 +0100 Subject: [PATCH] Project template --- .gitignore | 2 + build.zig | 72 + build.zig.zon | 81 + src/main.zig | 136 + vendor/zgpu/LICENSE | 22 + vendor/zgpu/README.md | 183 + vendor/zgpu/build.zig | 253 ++ vendor/zgpu/build.zig.zon | 48 + .../dawn/include/dawn/EnumClassBitmasks.h | 148 + .../zgpu/libs/dawn/include/dawn/dawn_proc.h | 36 + .../libs/dawn/include/dawn/dawn_proc_table.h | 245 ++ .../include/dawn/dawn_thread_dispatch_proc.h | 33 + .../dawn/include/dawn/native/D3D11Backend.h | 41 + .../dawn/include/dawn/native/D3D12Backend.h | 52 + .../dawn/include/dawn/native/D3DBackend.h | 109 + .../dawn/include/dawn/native/DawnNative.h | 309 ++ .../dawn/include/dawn/native/MetalBackend.h | 95 + .../dawn/include/dawn/native/NullBackend.h | 26 + .../dawn/include/dawn/native/OpenGLBackend.h | 59 + .../dawn/include/dawn/native/VulkanBackend.h | 180 + .../include/dawn/native/dawn_native_export.h | 36 + .../dawn/include/dawn/platform/DawnPlatform.h | 128 + .../dawn/platform/dawn_platform_export.h | 36 + vendor/zgpu/libs/dawn/include/dawn/webgpu.h | 2034 +++++++++++ .../zgpu/libs/dawn/include/dawn/webgpu_cpp.h | 2012 +++++++++++ .../include/dawn/webgpu_cpp_chained_struct.h | 35 + .../libs/dawn/include/dawn/webgpu_cpp_print.h | 1825 ++++++++++ .../zgpu/libs/dawn/include/dawn/wire/Wire.h | 58 + .../libs/dawn/include/dawn/wire/WireClient.h | 181 + .../libs/dawn/include/dawn/wire/WireServer.h | 154 + .../dawn/include/dawn/wire/dawn_wire_export.h | 36 + .../zgpu/libs/dawn/include/tint/override_id.h | 66 + vendor/zgpu/libs/dawn/include/tint/tint.h | 82 + vendor/zgpu/libs/dawn/include/webgpu/webgpu.h | 20 + .../libs/dawn/include/webgpu/webgpu_cpp.h | 20 + .../libs/dawn/include/webgpu/webgpu_glfw.h | 58 + vendor/zgpu/src/common_wgsl.zig | 99 + vendor/zgpu/src/dawn.cpp | 37 + vendor/zgpu/src/dawn_proc.c | 667 ++++ vendor/zgpu/src/wgpu.zig | 2974 +++++++++++++++++ vendor/zgpu/src/zgpu.zig | 1868 +++++++++++ vendor/zpool/LICENSE | 21 + vendor/zpool/README.md | 96 + vendor/zpool/build.zig | 22 + vendor/zpool/build.zig.zon | 11 + vendor/zpool/src/embedded_ring_queue.zig | 174 + vendor/zpool/src/handle.zig | 278 ++ vendor/zpool/src/main.zig | 8 + vendor/zpool/src/pool.zig | 1430 ++++++++ vendor/zpool/src/utils.zig | 106 + 50 files changed, 16702 insertions(+) create mode 100644 .gitignore create mode 100644 build.zig create mode 100644 build.zig.zon create mode 100644 src/main.zig create mode 100644 vendor/zgpu/LICENSE create mode 100644 vendor/zgpu/README.md create mode 100644 vendor/zgpu/build.zig create mode 100644 vendor/zgpu/build.zig.zon create mode 100644 vendor/zgpu/libs/dawn/include/dawn/EnumClassBitmasks.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/dawn_proc.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/dawn_proc_table.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/dawn_thread_dispatch_proc.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/D3D11Backend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/D3D12Backend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/D3DBackend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/DawnNative.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/MetalBackend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/NullBackend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/OpenGLBackend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/VulkanBackend.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/native/dawn_native_export.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/platform/DawnPlatform.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/platform/dawn_platform_export.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/webgpu.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_chained_struct.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_print.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/wire/Wire.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/wire/WireClient.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/wire/WireServer.h create mode 100644 vendor/zgpu/libs/dawn/include/dawn/wire/dawn_wire_export.h create mode 100644 vendor/zgpu/libs/dawn/include/tint/override_id.h create mode 100644 vendor/zgpu/libs/dawn/include/tint/tint.h create mode 100644 vendor/zgpu/libs/dawn/include/webgpu/webgpu.h create mode 100644 vendor/zgpu/libs/dawn/include/webgpu/webgpu_cpp.h create mode 100644 vendor/zgpu/libs/dawn/include/webgpu/webgpu_glfw.h create mode 100644 vendor/zgpu/src/common_wgsl.zig create mode 100644 vendor/zgpu/src/dawn.cpp create mode 100644 vendor/zgpu/src/dawn_proc.c create mode 100644 vendor/zgpu/src/wgpu.zig create mode 100644 vendor/zgpu/src/zgpu.zig create mode 100644 vendor/zpool/LICENSE create mode 100644 vendor/zpool/README.md create mode 100644 vendor/zpool/build.zig create mode 100644 vendor/zpool/build.zig.zon create mode 100644 vendor/zpool/src/embedded_ring_queue.zig create mode 100644 vendor/zpool/src/handle.zig create mode 100644 vendor/zpool/src/main.zig create mode 100644 vendor/zpool/src/pool.zig create mode 100644 vendor/zpool/src/utils.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8c8979 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.zig-cache +zig-out diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..ddcf248 --- /dev/null +++ b/build.zig @@ -0,0 +1,72 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const zaudio = b.dependency("zaudio", .{}); + const zglfw = b.dependency("zglfw", .{}); + const zgpu = b.dependency("zgpu", .{}); + const zgui = b.dependency("zgui", .{ + .shared = false, + .backend = .glfw_wgpu, + .with_implot = true, + }); + const zmath = b.dependency("zmath", .{}); + const znoise = b.dependency("znoise", .{}); + const zpool = b.dependency("zpool", .{}); + const zstbi = b.dependency("zstbi", .{}); + const ztracy = b.dependency("ztracy", .{ + .enable_ztracy = b.option(bool, "enable_ztracy", "Enable Tracy profile markers") orelse false, + .enable_fibers = b.option(bool, "enable_fibers", "Enable Tracy fiber support") orelse false, + .on_demand = b.option(bool, "on_demand", "Build Tracy with TRACY_ON_DEMAND") orelse false, + }); + + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const exe_mod = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + + exe_mod.addImport("zaudio", zaudio.module("root")); + exe_mod.addImport("zglfw", zglfw.module("root")); + exe_mod.addImport("zgpu", zgpu.module("root")); + exe_mod.addImport("zgui", zgui.module("root")); + exe_mod.addImport("zmath", zmath.module("root")); + exe_mod.addImport("znoise", znoise.module("root")); + exe_mod.addImport("zpool", zpool.module("root")); + exe_mod.addImport("zstbi", zstbi.module("root")); + exe_mod.addImport("ztracy", ztracy.module("root")); + + const exe = b.addExecutable(.{ + .name = "voxel-game", + .root_module = exe_mod, + }); + + exe.linkLibrary(zaudio.artifact("miniaudio")); + exe.linkLibrary(zgui.artifact("imgui")); + exe.linkLibrary(znoise.artifact("FastNoiseLite")); + exe.linkLibrary(zstbi.artifact("zstbi")); + exe.linkLibrary(ztracy.artifact("tracy")); + if (target.result.os.tag != .emscripten) { + exe.linkLibrary(zglfw.artifact("glfw")); + exe.linkLibrary(zgpu.artifact("zdawn")); + } + + if (optimize != .Debug) { + exe.subsystem = .Windows; + } + + @import("zgpu").addLibraryPathsTo(exe); + + b.installArtifact(exe); + + const run_cmd = b.addRunArtifact(exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the game"); + run_step.dependOn(&run_cmd.step); +} diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..e3460f9 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,81 @@ +.{ + .name = "voxel-game", + .version = "0.0.0", + + .dependencies = .{ + .zaudio = .{ + .url = "https://github.com/zig-gamedev/zaudio/archive/496da32757767b31f389554e1e5c668796755fe2.tar.gz", + .hash = "12203f6ab72861cd7e36ebd1590f9cc7fd036366e2ff96122002a395f628e813d999", + }, + .zglfw = .{ + .url = "https://github.com/zig-gamedev/zglfw/archive/5aaf806521bbda4385b1041d9448bd0c40192a1c.tar.gz", + .hash = "12202db5d18aa92ae61b0e47c11ec517eeb5984d8e2647ff513807ff30a444fef49a", + }, + // Needed to be vendored, because it depends on zpool, which itself + // needs to be vendored. + .zgpu = .{ + .path = "vendor/zgpu", + }, + .zgui = .{ + .url = "https://github.com/zig-gamedev/zgui/archive/5fb1c3b935b311e88352b0ffee29e7ad56da9722.tar.gz", + .hash = "12204f82e0475ddfd6a57d97f74bcf9052452c0eb2fa863cf0e3bce1071d2603e9f4", + }, + .zjobs = .{ + .url = "https://github.com/zig-gamedev/zjobs/archive/19743327b06209a8041f7840ec13a9b794767d32.tar.gz", + .hash = "12203322a6cbf36b797c78833fae7391b736f3808ee59d7ce092981d02bbde941a07", + }, + .zmath = .{ + .url = "https://github.com/zig-gamedev/zmath/archive/24cdd20f9da09bd1ce7b552907eeaba9bafea59d.tar.gz", + .hash = "1220081d55b58b968d953db1afc2fb01b2f5733929144e69522461ce25fa6450d84e", + }, + .znoise = .{ + .url = "https://github.com/zig-gamedev/znoise/archive/b6e7a24c9bfa4bae63521664e191a728b5b18805.tar.gz", + .hash = "12208e16c80366e2a2f8bd3f1c676b09bf47c157f4d0f0d6440555f9b74d8a9d79f7", + }, + // Needed to be vendored due to breaking changes in zig's type info + // structs, which upstream hasn't caught up to. + .zpool = .{ + .path = "vendor/zpool", + }, + .zstbi = .{ + .url = "https://github.com/zig-gamedev/zstbi/archive/bcbd249f3f57fb84d6d76f1bc621c7bd3bfaa4a2.tar.gz", + .hash = "12208b7d15a730294a7d8ee3a9d3ef145e109f94d0a68be7f0ee282e0630ede093d5", + }, + .ztracy = .{ + .url = "https://github.com/zig-gamedev/ztracy/archive/5af60074f355ecda6114d08dcc8c931c3d163c94.tar.gz", + .hash = "1220293b509e9238e43828b00ee18e38eeace190ef844b74bf54e3db6e7da7398f4b", + }, + + .dawn_x86_64_windows_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-windows-gnu/archive/d3a68014e6b6b53fd330a0ccba99e4dcfffddae5.tar.gz", + .hash = "1220f9448cde02ef3cd51bde2e0850d4489daa0541571d748154e89c6eb46c76a267", + .lazy = true, + }, + .dawn_x86_64_linux_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-linux-gnu/archive/7d70db023bf254546024629cbec5ee6113e12a42.tar.gz", + .hash = "12204a3519efd49ea2d7cf63b544492a3a771d37eda320f86380813376801e4cfa73", + .lazy = true, + }, + .dawn_aarch64_linux_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-aarch64-linux-gnu/archive/c1f55e740a62f6942ff046e709ecd509a005dbeb.tar.gz", + .hash = "12205cd13f6849f94ef7688ee88c6b74c7918a5dfb514f8a403fcc2929a0aa342627", + .lazy = true, + }, + .dawn_aarch64_macos = .{ + .url = "https://github.com/michal-z/webgpu_dawn-aarch64-macos/archive/d2360cdfff0cf4a780cb77aa47c57aca03cc6dfe.tar.gz", + .hash = "12201fe677e9c7cfb8984a36446b329d5af23d03dc1e4f79a853399529e523a007fa", + .lazy = true, + }, + .dawn_x86_64_macos = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-macos/archive/901716b10b31ce3e0d3fe479326b41e91d59c661.tar.gz", + .hash = "1220b1f02f2f7edd98a078c64e3100907d90311d94880a3cc5927e1ac009d002667a", + .lazy = true, + }, + }, + + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + }, +} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..d0c771d --- /dev/null +++ b/src/main.zig @@ -0,0 +1,136 @@ +const std = @import("std"); + +const zaudio = @import("zaudio"); +const zglfw = @import("zglfw"); +const zgpu = @import("zgpu"); +const zgui = @import("zgui"); +const ztracy = @import("ztracy"); + +pub var allocator: std.mem.Allocator = undefined; +pub var audio_engine: *zaudio.Engine = undefined; +pub var gctx: *zgpu.GraphicsContext = undefined; +pub var temp_allocator: std.mem.Allocator = undefined; +pub var window: *zglfw.Window = undefined; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + var ta = ztracy.TracyAllocator.init(gpa.allocator()); + + var fba = std.heap.FixedBufferAllocator.init(&struct { + pub var buffer: [16 * 1024 * 1024]u8 = undefined; + }.buffer); + + allocator = ta.allocator(); + temp_allocator = fba.threadSafeAllocator(); + + // --- zaudio -------------------------------------------------------------- + + const zone_init_zaudio = ztracy.ZoneN(@src(), "Init zaudio"); + + zaudio.init(allocator); + defer zaudio.deinit(); + + audio_engine = try zaudio.Engine.create(null); + defer audio_engine.destroy(); + + zone_init_zaudio.End(); + + // --- zglfw --------------------------------------------------------------- + + const zone_init_zglfw = ztracy.ZoneN(@src(), "Init zglfw"); + + try zglfw.init(); + defer zglfw.terminate(); + + zglfw.windowHint(.client_api, .no_api); + window = try zglfw.Window.create(1280, 720, "voxel-game", null); + window.setSizeLimits(640, 360, -1, -1); + defer window.destroy(); + + zone_init_zglfw.End(); + + // --- zgpu ---------------------------------------------------------------- + + const zone_init_zgpu = ztracy.ZoneN(@src(), "Init zgpu"); + + gctx = try zgpu.GraphicsContext.create(allocator, .{ + .window = window, + .fn_getTime = @ptrCast(&zglfw.getTime), + .fn_getFramebufferSize = @ptrCast(&zglfw.Window.getFramebufferSize), + .fn_getWin32Window = @ptrCast(&zglfw.getWin32Window), + .fn_getX11Display = @ptrCast(&zglfw.getX11Display), + .fn_getX11Window = @ptrCast(&zglfw.getX11Window), + .fn_getWaylandDisplay = @ptrCast(&zglfw.getWaylandDisplay), + .fn_getWaylandSurface = @ptrCast(&zglfw.getWaylandWindow), + .fn_getCocoaWindow = @ptrCast(&zglfw.getCocoaWindow), + }, .{}); + defer gctx.destroy(allocator); + + zone_init_zgpu.End(); + + // --- zgui ---------------------------------------------------------------- + + const zone_init_zgui = ztracy.ZoneN(@src(), "Init zgui"); + + zgui.init(allocator); + defer zgui.deinit(); + + zgui.backend.init( + window, + gctx.device, + @intFromEnum(zgpu.GraphicsContext.swapchain_format), + @intFromEnum(zgpu.wgpu.TextureFormat.depth32_float), + ); + defer zgui.backend.deinit(); + + zgui.io.setIniFilename(null); + + zone_init_zgui.End(); + + // --- main loop ----------------------------------------------------------- + + const zone_main_loop = ztracy.ZoneN(@src(), "Main loop"); + + while (!window.shouldClose()) { + ztracy.FrameMark(); + + fba.reset(); + + zglfw.pollEvents(); + zgui.backend.newFrame( + gctx.swapchain_descriptor.width, + gctx.swapchain_descriptor.height, + ); + + const swapchain_texture_view = gctx.swapchain.getCurrentTextureView(); + defer swapchain_texture_view.release(); + + const commands = commands: { + const encoder = gctx.device.createCommandEncoder(null); + defer encoder.release(); + + { + const pass = zgpu.beginRenderPassSimple( + encoder, + .load, + swapchain_texture_view, + null, + null, + null, + ); + defer zgpu.endReleasePass(pass); + zgui.backend.draw(pass); + } + + break :commands encoder.finish(null); + }; + defer commands.release(); + + gctx.submit(&.{commands}); + _ = gctx.present(); + } + + zone_main_loop.End(); +} diff --git a/vendor/zgpu/LICENSE b/vendor/zgpu/LICENSE new file mode 100644 index 0000000..5052cbe --- /dev/null +++ b/vendor/zgpu/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2022 Michal Ziulek +Copyright (c) 2024 zig-gamedev contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/zgpu/README.md b/vendor/zgpu/README.md new file mode 100644 index 0000000..6d9a6a0 --- /dev/null +++ b/vendor/zgpu/README.md @@ -0,0 +1,183 @@ +# [zgpu](https://github.com/zig-gamedev/zgpu) + +Cross-platform graphics lib for Zig built on top of [Dawn](https://github.com/zig-gamedev/dawn) native WebGPU implementation. + +Supports Windows 10+ (DirectX 12), macOS 12+ (Metal) and Linux (Vulkan). + +## Features + +- Zero-overhead wgpu API bindings ([source code](https://github.com/zig-gamedev/zgpu/blob/main/src/wgpu.zig)) +- Uniform buffer pool for fast CPU->GPU transfers +- Resource pools and handle-based GPU resources +- Async shader compilation +- GPU mipmap generator + +## Getting started + +Example `build.zig`: + +```zig +pub fn build(b: *std.Build) void { + const exe = b.addExecutable(.{ ... }); + + @import("zgpu").addLibraryPathsTo(exe); + + const zgpu = b.dependency("zgpu", .{}); + exe.root_module.addImport("zgpu", zgpu.module("root")); + + if (target.result.os.tag != .emscripten) { + exe.linkLibrary(zgpu.artifact("zdawn")); + } +} +``` + +## Sample applications + +- [gui test (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/gui_test_wgpu) +- [physically based rendering (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/physically_based_rendering_wgpu) +- [bullet physics test (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/bullet_physics_test_wgpu) +- [procedural mesh (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/procedural_mesh_wgpu) +- [textured quad (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/textured_quad_wgpu) +- [triangle (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/triangle_wgpu) + +## Library overview + +Below you can find an overview of main `zgpu` features. + +### Compile-time options + +You can override default options in your `build.zig`: + +```zig +pub fn build(b: *std.Build) void { + ... + + const zgpu = @import("zgpu").package(b, target, optimize, .{ + .options = .{ + .uniforms_buffer_size = 4 * 1024 * 1024, + .dawn_skip_validation = false, + .buffer_pool_size = 256, + .texture_pool_size = 256, + .texture_view_pool_size = 256, + .sampler_pool_size = 16, + .render_pipeline_pool_size = 128, + .compute_pipeline_pool_size = 128, + .bind_group_pool_size = 32, + .bind_group_layout_pool_size = 32, + .pipeline_layout_pool_size = 32, + }, + }); + + zgpu.link(exe); + + ... +} +``` + +### Graphics Context + +Create a `GraphicsContext` using a `WindowProvider`. For example, using [zglfw](https://github.com/zig-gamedev/zglfw): + +```zig +const gctx = try zgpu.GraphicsContext.create( + allocator, + .{ + .window = window, + .fn_getTime = @ptrCast(&zglfw.getTime), + .fn_getFramebufferSize = @ptrCast(&zglfw.Window.getFramebufferSize), + + // optional fields + .fn_getWin32Window = @ptrCast(&zglfw.getWin32Window), + .fn_getX11Display = @ptrCast(&zglfw.getX11Display), + .fn_getX11Window = @ptrCast(&zglfw.getX11Window), + .fn_getWaylandDisplay = @ptrCast(&zglfw.getWaylandDisplay), + .fn_getWaylandSurface = @ptrCast(&zglfw.getWaylandWindow), + .fn_getCocoaWindow = @ptrCast(&zglfw.getCocoaWindow), + }, + .{}, // default context creation options +); +``` + +### Uniforms + +- Implemented as a uniform buffer pool +- Easy to use +- Efficient - only one copy operation per frame + +```zig +struct DrawUniforms = extern struct { + object_to_world: zm.Mat, +}; +const mem = gctx.uniformsAllocate(DrawUniforms, 1); +mem.slice[0] = .{ .object_to_world = zm.transpose(zm.translation(...)) }; + +pass.setBindGroup(0, bind_group, &.{mem.offset}); +pass.drawIndexed(...); + +// When you are done encoding all commands for a frame: +gctx.submit(...); // Injects *one* copy operation to transfer *all* allocated uniforms +``` + +### Resource pools + +- Every GPU resource is identified by 32-bit integer handle +- All resources are stored in one system +- We keep basic info about each resource (size of the buffer, format of the texture, etc.) +- You can always check if resource is valid (very useful for async operations) +- System keeps basic info about resource dependencies, for example, `TextureViewHandle` knows about its + parent texture and becomes invalid when parent texture becomes invalid; `BindGroupHandle` knows + about all resources it binds so it becomes invalid if any of those resources become invalid + +```zig +const buffer_handle = gctx.createBuffer(...); + +if (gctx.isResourceValid(buffer_handle)) { + const buffer = gctx.lookupResource(buffer_handle).?; // Returns `wgpu.Buffer` + + const buffer_info = gctx.lookupResourceInfo(buffer_handle).?; // Returns `zgpu.BufferInfo` + std.debug.print("Buffer size is: {d}", .{buffer_info.size}); +} + +// If you want to destroy a resource before shutting down graphics context: +gctx.destroyResource(buffer_handle); + +``` + +### Async shader compilation + +- Thanks to resource pools and resources identified by handles we can easily async compile all our shaders + +```zig +const DemoState = struct { + pipeline_handle: zgpu.PipelineLayoutHandle = .{}, + ... +}; +const demo = try allocator.create(DemoState); + +// Below call schedules pipeline compilation and returns immediately. When compilation is complete +// valid pipeline handle will be stored in `demo.pipeline_handle`. +gctx.createRenderPipelineAsync(allocator, pipeline_layout, pipeline_descriptor, &demo.pipeline_handle); + +// Pass using our pipeline will be skipped until compilation is ready +pass: { + const pipeline = gctx.lookupResource(demo.pipeline_handle) orelse break :pass; + ... + + pass.setPipeline(pipeline); + pass.drawIndexed(...); +} +``` + +### Mipmap generation on the GPU + +- wgpu API does not provide mipmap generator +- zgpu provides decent mipmap generator implemented in a compute shader +- It supports 2D textures, array textures and cubemap textures of any format + (`rgba8_unorm`, `rg16_float`, `rgba32_float`, etc.) +- Currently it requires that: `texture_width == texture_height and isPowerOfTwo(texture_width)` +- It takes ~260 microsec to generate all mips for 1024x1024 `rgba8_unorm` texture on GTX 1660 + +```zig +// Usage: +gctx.generateMipmaps(arena, command_encoder, texture_handle); +``` diff --git a/vendor/zgpu/build.zig b/vendor/zgpu/build.zig new file mode 100644 index 0000000..28fb619 --- /dev/null +++ b/vendor/zgpu/build.zig @@ -0,0 +1,253 @@ +const std = @import("std"); +const log = std.log.scoped(.zgpu); + +const default_options = struct { + const uniforms_buffer_size = 4 * 1024 * 1024; + const dawn_skip_validation = false; + const dawn_allow_unsafe_apis = false; + const buffer_pool_size = 256; + const texture_pool_size = 256; + const texture_view_pool_size = 256; + const sampler_pool_size = 16; + const render_pipeline_pool_size = 128; + const compute_pipeline_pool_size = 128; + const bind_group_pool_size = 32; + const bind_group_layout_pool_size = 32; + const pipeline_layout_pool_size = 32; + const max_num_bindings_per_group = 10; + const max_num_bind_groups_per_pipeline = 4; +}; + +pub fn build(b: *std.Build) void { + const optimize = b.standardOptimizeOption(.{}); + const target = b.standardTargetOptions(.{}); + + const options = .{ + .uniforms_buffer_size = b.option( + u64, + "uniforms_buffer_size", + "Set uniforms buffer size", + ) orelse default_options.uniforms_buffer_size, + .dawn_skip_validation = b.option( + bool, + "dawn_skip_validation", + "Disable Dawn validation", + ) orelse default_options.dawn_skip_validation, + .dawn_allow_unsafe_apis = b.option( + bool, + "dawn_allow_unsafe_apis", + "Allow unsafe WebGPU APIs (e.g. timestamp queries)", + ) orelse default_options.dawn_allow_unsafe_apis, + .buffer_pool_size = b.option( + u32, + "buffer_pool_size", + "Set buffer pool size", + ) orelse default_options.buffer_pool_size, + .texture_pool_size = b.option( + u32, + "texture_pool_size", + "Set texture pool size", + ) orelse default_options.texture_pool_size, + .texture_view_pool_size = b.option( + u32, + "texture_view_pool_size", + "Set texture view pool size", + ) orelse default_options.texture_view_pool_size, + .sampler_pool_size = b.option( + u32, + "sampler_pool_size", + "Set sample pool size", + ) orelse default_options.sampler_pool_size, + .render_pipeline_pool_size = b.option( + u32, + "render_pipeline_pool_size", + "Set render pipeline pool size", + ) orelse default_options.render_pipeline_pool_size, + .compute_pipeline_pool_size = b.option( + u32, + "compute_pipeline_pool_size", + "Set compute pipeline pool size", + ) orelse default_options.compute_pipeline_pool_size, + .bind_group_pool_size = b.option( + u32, + "bind_group_pool_size", + "Set bind group pool size", + ) orelse default_options.bind_group_pool_size, + .bind_group_layout_pool_size = b.option( + u32, + "bind_group_layout_pool_size", + "Set bind group layout pool size", + ) orelse default_options.bind_group_layout_pool_size, + .pipeline_layout_pool_size = b.option( + u32, + "pipeline_layout_pool_size", + "Set pipeline layout pool size", + ) orelse default_options.pipeline_layout_pool_size, + .max_num_bindings_per_group = b.option( + u32, + "max_num_bindings_per_group", + "Set maximum number of bindings per bind group", + ) orelse default_options.max_num_bindings_per_group, + .max_num_bind_groups_per_pipeline = b.option( + u32, + "max_num_bind_groups_per_pipeline", + "Set maximum number of bindings groups per pipeline", + ) orelse default_options.max_num_bind_groups_per_pipeline, + }; + + const options_step = b.addOptions(); + inline for (std.meta.fields(@TypeOf(options))) |field| { + options_step.addOption(field.type, field.name, @field(options, field.name)); + } + + const options_module = options_step.createModule(); + + _ = b.addModule("root", .{ + .root_source_file = b.path("src/zgpu.zig"), + .imports = &.{ + .{ .name = "zgpu_options", .module = options_module }, + .{ .name = "zpool", .module = b.dependency("zpool", .{}).module("root") }, + }, + }); + + const zdawn = b.addStaticLibrary(.{ + .name = "zdawn", + .target = target, + .optimize = optimize, + }); + b.installArtifact(zdawn); + + linkSystemDeps(b, zdawn); + addLibraryPathsTo(zdawn); + + zdawn.linkSystemLibrary("dawn"); + zdawn.linkLibC(); + if (target.result.abi != .msvc) + zdawn.linkLibCpp(); + + zdawn.addIncludePath(b.path("libs/dawn/include")); + zdawn.addIncludePath(b.path("src")); + + zdawn.addCSourceFile(.{ + .file = b.path("src/dawn.cpp"), + .flags = &.{ "-std=c++17", "-fno-sanitize=undefined" }, + }); + zdawn.addCSourceFile(.{ + .file = b.path("src/dawn_proc.c"), + .flags = &.{"-fno-sanitize=undefined"}, + }); + + const test_step = b.step("test", "Run zgpu tests"); + + const tests = b.addTest(.{ + .name = "zgpu-tests", + .root_source_file = b.path("src/zgpu.zig"), + .target = target, + .optimize = optimize, + }); + tests.addIncludePath(b.path("libs/dawn/include")); + tests.linkLibrary(zdawn); + linkSystemDeps(b, tests); + addLibraryPathsTo(tests); + b.installArtifact(tests); + + test_step.dependOn(&b.addRunArtifact(tests).step); +} + +pub fn linkSystemDeps(b: *std.Build, compile_step: *std.Build.Step.Compile) void { + switch (compile_step.rootModuleTarget().os.tag) { + .windows => { + if (b.lazyDependency("system_sdk", .{})) |system_sdk| { + compile_step.addLibraryPath(system_sdk.path("windows/lib/x86_64-windows-gnu")); + } + compile_step.linkSystemLibrary("ole32"); + compile_step.linkSystemLibrary("dxguid"); + }, + .macos => { + if (b.lazyDependency("system_sdk", .{})) |system_sdk| { + compile_step.addLibraryPath(system_sdk.path("macos12/usr/lib")); + compile_step.addFrameworkPath(system_sdk.path("macos12/System/Library/Frameworks")); + } + compile_step.linkSystemLibrary("objc"); + compile_step.linkFramework("Metal"); + compile_step.linkFramework("CoreGraphics"); + compile_step.linkFramework("Foundation"); + compile_step.linkFramework("IOKit"); + compile_step.linkFramework("IOSurface"); + compile_step.linkFramework("QuartzCore"); + }, + else => {}, + } +} + +pub fn addLibraryPathsTo(compile_step: *std.Build.Step.Compile) void { + const b = compile_step.step.owner; + const target = compile_step.rootModuleTarget(); + switch (target.os.tag) { + .windows => { + if (b.lazyDependency("dawn_x86_64_windows_gnu", .{})) |dawn_prebuilt| { + compile_step.addLibraryPath(dawn_prebuilt.path("")); + } + }, + .linux => { + if (target.cpu.arch.isX86()) { + if (b.lazyDependency("dawn_x86_64_linux_gnu", .{})) |dawn_prebuilt| { + compile_step.addLibraryPath(dawn_prebuilt.path("")); + } + } else if (target.cpu.arch.isAARCH64()) { + if (b.lazyDependency("dawn_aarch64_linux_gnu", .{})) |dawn_prebuilt| { + compile_step.addLibraryPath(dawn_prebuilt.path("")); + } + } + }, + .macos => { + if (target.cpu.arch.isX86()) { + if (b.lazyDependency("dawn_x86_64_macos", .{})) |dawn_prebuilt| { + compile_step.addLibraryPath(dawn_prebuilt.path("")); + } + } else if (target.cpu.arch.isAARCH64()) { + if (b.lazyDependency("dawn_aarch64_macos", .{})) |dawn_prebuilt| { + compile_step.addLibraryPath(dawn_prebuilt.path("")); + } + } + }, + else => {}, + } +} + +pub fn checkTargetSupported(target: std.Target) bool { + const supported = switch (target.os.tag) { + .windows => target.cpu.arch.isX86() and target.abi.isGnu(), + .linux => (target.cpu.arch.isX86() or target.cpu.arch.isAARCH64()) and target.abi.isGnu(), + .macos => blk: { + if (!target.cpu.arch.isX86() and !target.cpu.arch.isAARCH64()) break :blk false; + + // If min. target macOS version is lesser than the min version we have available, then + // our Dawn binary is incompatible with the target. + if (target.os.version_range.semver.min.order( + .{ .major = 12, .minor = 0, .patch = 0 }, + ) == .lt) break :blk false; + break :blk true; + }, + else => false, + }; + if (supported == false) { + log.warn("\n" ++ + \\--------------------------------------------------------------------------- + \\ + \\Dawn/WebGPU binary for this target is not available. + \\ + \\Following targets are supported: + \\ + \\x86_64-windows-gnu + \\x86_64-linux-gnu + \\x86_64-macos.12.0.0-none + \\aarch64-linux-gnu + \\aarch64-macos.12.0.0-none + \\ + \\--------------------------------------------------------------------------- + \\ + , .{}); + } + return supported; +} diff --git a/vendor/zgpu/build.zig.zon b/vendor/zgpu/build.zig.zon new file mode 100644 index 0000000..8fa46fd --- /dev/null +++ b/vendor/zgpu/build.zig.zon @@ -0,0 +1,48 @@ +.{ + .name = "zgpu", + .version = "0.12.0-dev", + .paths = .{ + "build.zig", + "build.zig.zon", + "libs", + "src", + "README.md", + "LICENSE", + }, + .dependencies = .{ + // Needed to be vendored due to breaking changes in zig's type info + // structs, which upstream hasn't caught up to. + .zpool = .{ + .path = "../zpool", + }, + .system_sdk = .{ + .url = "https://github.com/zig-gamedev/system_sdk/archive/bf49d627a191e339f70e72668c8333717fb969b0.tar.gz", + .hash = "122047a9298c4c9dd43389d418d6826d469b192246ba0944102964cdc57f94c562df", + }, + .dawn_x86_64_windows_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-windows-gnu/archive/d3a68014e6b6b53fd330a0ccba99e4dcfffddae5.tar.gz", + .hash = "1220f9448cde02ef3cd51bde2e0850d4489daa0541571d748154e89c6eb46c76a267", + .lazy = true, + }, + .dawn_x86_64_linux_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-linux-gnu/archive/7d70db023bf254546024629cbec5ee6113e12a42.tar.gz", + .hash = "12204a3519efd49ea2d7cf63b544492a3a771d37eda320f86380813376801e4cfa73", + .lazy = true, + }, + .dawn_aarch64_linux_gnu = .{ + .url = "https://github.com/michal-z/webgpu_dawn-aarch64-linux-gnu/archive/c1f55e740a62f6942ff046e709ecd509a005dbeb.tar.gz", + .hash = "12205cd13f6849f94ef7688ee88c6b74c7918a5dfb514f8a403fcc2929a0aa342627", + .lazy = true, + }, + .dawn_aarch64_macos = .{ + .url = "https://github.com/michal-z/webgpu_dawn-aarch64-macos/archive/d2360cdfff0cf4a780cb77aa47c57aca03cc6dfe.tar.gz", + .hash = "12201fe677e9c7cfb8984a36446b329d5af23d03dc1e4f79a853399529e523a007fa", + .lazy = true, + }, + .dawn_x86_64_macos = .{ + .url = "https://github.com/michal-z/webgpu_dawn-x86_64-macos/archive/901716b10b31ce3e0d3fe479326b41e91d59c661.tar.gz", + .hash = "1220b1f02f2f7edd98a078c64e3100907d90311d94880a3cc5927e1ac009d002667a", + .lazy = true, + }, + }, +} diff --git a/vendor/zgpu/libs/dawn/include/dawn/EnumClassBitmasks.h b/vendor/zgpu/libs/dawn/include/dawn/EnumClassBitmasks.h new file mode 100644 index 0000000..252c7dd --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/EnumClassBitmasks.h @@ -0,0 +1,148 @@ +// Copyright 2017 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_ENUMCLASSBITMASKS_H_ +#define INCLUDE_DAWN_ENUMCLASSBITMASKS_H_ + +#include + +// The operators in dawn:: namespace need be introduced into other namespaces with +// using-declarations for C++ Argument Dependent Lookup to work. +#define DAWN_IMPORT_BITMASK_OPERATORS \ + using dawn::operator|; \ + using dawn::operator&; \ + using dawn::operator^; \ + using dawn::operator~; \ + using dawn::operator&=; \ + using dawn::operator|=; \ + using dawn::operator^=; \ + using dawn::HasZeroOrOneBits; + +namespace dawn { + +template +struct IsDawnBitmask { + static constexpr bool enable = false; +}; + +template +struct LowerBitmask { + static constexpr bool enable = false; +}; + +template +struct LowerBitmask::enable>::type> { + static constexpr bool enable = true; + using type = T; + constexpr static T Lower(T t) { return t; } +}; + +template +struct BoolConvertible { + using Integral = typename std::underlying_type::type; + + // NOLINTNEXTLINE(runtime/explicit) + explicit constexpr BoolConvertible(Integral value) : value(value) {} + constexpr operator bool() const { return value != 0; } + constexpr operator T() const { return static_cast(value); } + + Integral value; +}; + +template +struct LowerBitmask> { + static constexpr bool enable = true; + using type = T; + static constexpr type Lower(BoolConvertible t) { return t; } +}; + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator|(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) | + static_cast(LowerBitmask::Lower(right))); +} + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator&(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) & + static_cast(LowerBitmask::Lower(right))); +} + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator^(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) ^ + static_cast(LowerBitmask::Lower(right))); +} + +template +constexpr BoolConvertible::type> operator~(T1 t) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(~static_cast(LowerBitmask::Lower(t))); +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator&=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l & r; + return l; +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator|=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l | r; + return l; +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator^=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l ^ r; + return l; +} + +template +constexpr bool HasZeroOrOneBits(T value) { + using Integral = typename std::underlying_type::type; + return (static_cast(value) & (static_cast(value) - 1)) == 0; +} + +} // namespace dawn + +#endif // INCLUDE_DAWN_ENUMCLASSBITMASKS_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/dawn_proc.h b/vendor/zgpu/libs/dawn/include/dawn/dawn_proc.h new file mode 100644 index 0000000..94cc306 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/dawn_proc.h @@ -0,0 +1,36 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_DAWN_PROC_H_ +#define INCLUDE_DAWN_DAWN_PROC_H_ + +#include "dawn/dawn_proc_table.h" +#include "dawn/webgpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Sets the static proctable used by libdawn_proc to implement the Dawn entrypoints. Passing NULL +// for `procs` sets up the null proctable that contains only null function pointers. It is the +// default value of the proctable. Setting the proctable back to null is good practice when you +// are done using libdawn_proc since further usage will cause a segfault instead of calling an +// unexpected function. +WGPU_EXPORT void dawnProcSetProcs(const DawnProcTable* procs); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // INCLUDE_DAWN_DAWN_PROC_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/dawn_proc_table.h b/vendor/zgpu/libs/dawn/include/dawn/dawn_proc_table.h new file mode 100644 index 0000000..ff81d50 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/dawn_proc_table.h @@ -0,0 +1,245 @@ + +#ifndef DAWN_DAWN_PROC_TABLE_H_ +#define DAWN_DAWN_PROC_TABLE_H_ + +#include "dawn/webgpu.h" + +// Note: Often allocated as a static global. Do not add a complex constructor. +typedef struct DawnProcTable { + WGPUProcCreateInstance createInstance; + WGPUProcGetProcAddress getProcAddress; + + WGPUProcAdapterCreateDevice adapterCreateDevice; + WGPUProcAdapterEnumerateFeatures adapterEnumerateFeatures; + WGPUProcAdapterGetInstance adapterGetInstance; + WGPUProcAdapterGetLimits adapterGetLimits; + WGPUProcAdapterGetProperties adapterGetProperties; + WGPUProcAdapterHasFeature adapterHasFeature; + WGPUProcAdapterRequestDevice adapterRequestDevice; + WGPUProcAdapterReference adapterReference; + WGPUProcAdapterRelease adapterRelease; + + WGPUProcBindGroupSetLabel bindGroupSetLabel; + WGPUProcBindGroupReference bindGroupReference; + WGPUProcBindGroupRelease bindGroupRelease; + + WGPUProcBindGroupLayoutSetLabel bindGroupLayoutSetLabel; + WGPUProcBindGroupLayoutReference bindGroupLayoutReference; + WGPUProcBindGroupLayoutRelease bindGroupLayoutRelease; + + WGPUProcBufferDestroy bufferDestroy; + WGPUProcBufferGetConstMappedRange bufferGetConstMappedRange; + WGPUProcBufferGetMapState bufferGetMapState; + WGPUProcBufferGetMappedRange bufferGetMappedRange; + WGPUProcBufferGetSize bufferGetSize; + WGPUProcBufferGetUsage bufferGetUsage; + WGPUProcBufferMapAsync bufferMapAsync; + WGPUProcBufferSetLabel bufferSetLabel; + WGPUProcBufferUnmap bufferUnmap; + WGPUProcBufferReference bufferReference; + WGPUProcBufferRelease bufferRelease; + + WGPUProcCommandBufferSetLabel commandBufferSetLabel; + WGPUProcCommandBufferReference commandBufferReference; + WGPUProcCommandBufferRelease commandBufferRelease; + + WGPUProcCommandEncoderBeginComputePass commandEncoderBeginComputePass; + WGPUProcCommandEncoderBeginRenderPass commandEncoderBeginRenderPass; + WGPUProcCommandEncoderClearBuffer commandEncoderClearBuffer; + WGPUProcCommandEncoderCopyBufferToBuffer commandEncoderCopyBufferToBuffer; + WGPUProcCommandEncoderCopyBufferToTexture commandEncoderCopyBufferToTexture; + WGPUProcCommandEncoderCopyTextureToBuffer commandEncoderCopyTextureToBuffer; + WGPUProcCommandEncoderCopyTextureToTexture commandEncoderCopyTextureToTexture; + WGPUProcCommandEncoderCopyTextureToTextureInternal commandEncoderCopyTextureToTextureInternal; + WGPUProcCommandEncoderFinish commandEncoderFinish; + WGPUProcCommandEncoderInjectValidationError commandEncoderInjectValidationError; + WGPUProcCommandEncoderInsertDebugMarker commandEncoderInsertDebugMarker; + WGPUProcCommandEncoderPopDebugGroup commandEncoderPopDebugGroup; + WGPUProcCommandEncoderPushDebugGroup commandEncoderPushDebugGroup; + WGPUProcCommandEncoderResolveQuerySet commandEncoderResolveQuerySet; + WGPUProcCommandEncoderSetLabel commandEncoderSetLabel; + WGPUProcCommandEncoderWriteBuffer commandEncoderWriteBuffer; + WGPUProcCommandEncoderWriteTimestamp commandEncoderWriteTimestamp; + WGPUProcCommandEncoderReference commandEncoderReference; + WGPUProcCommandEncoderRelease commandEncoderRelease; + + WGPUProcComputePassEncoderDispatchWorkgroups computePassEncoderDispatchWorkgroups; + WGPUProcComputePassEncoderDispatchWorkgroupsIndirect computePassEncoderDispatchWorkgroupsIndirect; + WGPUProcComputePassEncoderEnd computePassEncoderEnd; + WGPUProcComputePassEncoderInsertDebugMarker computePassEncoderInsertDebugMarker; + WGPUProcComputePassEncoderPopDebugGroup computePassEncoderPopDebugGroup; + WGPUProcComputePassEncoderPushDebugGroup computePassEncoderPushDebugGroup; + WGPUProcComputePassEncoderSetBindGroup computePassEncoderSetBindGroup; + WGPUProcComputePassEncoderSetLabel computePassEncoderSetLabel; + WGPUProcComputePassEncoderSetPipeline computePassEncoderSetPipeline; + WGPUProcComputePassEncoderWriteTimestamp computePassEncoderWriteTimestamp; + WGPUProcComputePassEncoderReference computePassEncoderReference; + WGPUProcComputePassEncoderRelease computePassEncoderRelease; + + WGPUProcComputePipelineGetBindGroupLayout computePipelineGetBindGroupLayout; + WGPUProcComputePipelineSetLabel computePipelineSetLabel; + WGPUProcComputePipelineReference computePipelineReference; + WGPUProcComputePipelineRelease computePipelineRelease; + + WGPUProcDeviceCreateBindGroup deviceCreateBindGroup; + WGPUProcDeviceCreateBindGroupLayout deviceCreateBindGroupLayout; + WGPUProcDeviceCreateBuffer deviceCreateBuffer; + WGPUProcDeviceCreateCommandEncoder deviceCreateCommandEncoder; + WGPUProcDeviceCreateComputePipeline deviceCreateComputePipeline; + WGPUProcDeviceCreateComputePipelineAsync deviceCreateComputePipelineAsync; + WGPUProcDeviceCreateErrorBuffer deviceCreateErrorBuffer; + WGPUProcDeviceCreateErrorExternalTexture deviceCreateErrorExternalTexture; + WGPUProcDeviceCreateErrorShaderModule deviceCreateErrorShaderModule; + WGPUProcDeviceCreateErrorTexture deviceCreateErrorTexture; + WGPUProcDeviceCreateExternalTexture deviceCreateExternalTexture; + WGPUProcDeviceCreatePipelineLayout deviceCreatePipelineLayout; + WGPUProcDeviceCreateQuerySet deviceCreateQuerySet; + WGPUProcDeviceCreateRenderBundleEncoder deviceCreateRenderBundleEncoder; + WGPUProcDeviceCreateRenderPipeline deviceCreateRenderPipeline; + WGPUProcDeviceCreateRenderPipelineAsync deviceCreateRenderPipelineAsync; + WGPUProcDeviceCreateSampler deviceCreateSampler; + WGPUProcDeviceCreateShaderModule deviceCreateShaderModule; + WGPUProcDeviceCreateSwapChain deviceCreateSwapChain; + WGPUProcDeviceCreateTexture deviceCreateTexture; + WGPUProcDeviceDestroy deviceDestroy; + WGPUProcDeviceEnumerateFeatures deviceEnumerateFeatures; + WGPUProcDeviceForceLoss deviceForceLoss; + WGPUProcDeviceGetAdapter deviceGetAdapter; + WGPUProcDeviceGetLimits deviceGetLimits; + WGPUProcDeviceGetQueue deviceGetQueue; + WGPUProcDeviceGetSupportedSurfaceUsage deviceGetSupportedSurfaceUsage; + WGPUProcDeviceHasFeature deviceHasFeature; + WGPUProcDeviceInjectError deviceInjectError; + WGPUProcDevicePopErrorScope devicePopErrorScope; + WGPUProcDevicePushErrorScope devicePushErrorScope; + WGPUProcDeviceSetDeviceLostCallback deviceSetDeviceLostCallback; + WGPUProcDeviceSetLabel deviceSetLabel; + WGPUProcDeviceSetLoggingCallback deviceSetLoggingCallback; + WGPUProcDeviceSetUncapturedErrorCallback deviceSetUncapturedErrorCallback; + WGPUProcDeviceTick deviceTick; + WGPUProcDeviceValidateTextureDescriptor deviceValidateTextureDescriptor; + WGPUProcDeviceReference deviceReference; + WGPUProcDeviceRelease deviceRelease; + + WGPUProcExternalTextureDestroy externalTextureDestroy; + WGPUProcExternalTextureExpire externalTextureExpire; + WGPUProcExternalTextureRefresh externalTextureRefresh; + WGPUProcExternalTextureSetLabel externalTextureSetLabel; + WGPUProcExternalTextureReference externalTextureReference; + WGPUProcExternalTextureRelease externalTextureRelease; + + WGPUProcInstanceCreateSurface instanceCreateSurface; + WGPUProcInstanceProcessEvents instanceProcessEvents; + WGPUProcInstanceRequestAdapter instanceRequestAdapter; + WGPUProcInstanceReference instanceReference; + WGPUProcInstanceRelease instanceRelease; + + WGPUProcPipelineLayoutSetLabel pipelineLayoutSetLabel; + WGPUProcPipelineLayoutReference pipelineLayoutReference; + WGPUProcPipelineLayoutRelease pipelineLayoutRelease; + + WGPUProcQuerySetDestroy querySetDestroy; + WGPUProcQuerySetGetCount querySetGetCount; + WGPUProcQuerySetGetType querySetGetType; + WGPUProcQuerySetSetLabel querySetSetLabel; + WGPUProcQuerySetReference querySetReference; + WGPUProcQuerySetRelease querySetRelease; + + WGPUProcQueueCopyExternalTextureForBrowser queueCopyExternalTextureForBrowser; + WGPUProcQueueCopyTextureForBrowser queueCopyTextureForBrowser; + WGPUProcQueueOnSubmittedWorkDone queueOnSubmittedWorkDone; + WGPUProcQueueSetLabel queueSetLabel; + WGPUProcQueueSubmit queueSubmit; + WGPUProcQueueWriteBuffer queueWriteBuffer; + WGPUProcQueueWriteTexture queueWriteTexture; + WGPUProcQueueReference queueReference; + WGPUProcQueueRelease queueRelease; + + WGPUProcRenderBundleSetLabel renderBundleSetLabel; + WGPUProcRenderBundleReference renderBundleReference; + WGPUProcRenderBundleRelease renderBundleRelease; + + WGPUProcRenderBundleEncoderDraw renderBundleEncoderDraw; + WGPUProcRenderBundleEncoderDrawIndexed renderBundleEncoderDrawIndexed; + WGPUProcRenderBundleEncoderDrawIndexedIndirect renderBundleEncoderDrawIndexedIndirect; + WGPUProcRenderBundleEncoderDrawIndirect renderBundleEncoderDrawIndirect; + WGPUProcRenderBundleEncoderFinish renderBundleEncoderFinish; + WGPUProcRenderBundleEncoderInsertDebugMarker renderBundleEncoderInsertDebugMarker; + WGPUProcRenderBundleEncoderPopDebugGroup renderBundleEncoderPopDebugGroup; + WGPUProcRenderBundleEncoderPushDebugGroup renderBundleEncoderPushDebugGroup; + WGPUProcRenderBundleEncoderSetBindGroup renderBundleEncoderSetBindGroup; + WGPUProcRenderBundleEncoderSetIndexBuffer renderBundleEncoderSetIndexBuffer; + WGPUProcRenderBundleEncoderSetLabel renderBundleEncoderSetLabel; + WGPUProcRenderBundleEncoderSetPipeline renderBundleEncoderSetPipeline; + WGPUProcRenderBundleEncoderSetVertexBuffer renderBundleEncoderSetVertexBuffer; + WGPUProcRenderBundleEncoderReference renderBundleEncoderReference; + WGPUProcRenderBundleEncoderRelease renderBundleEncoderRelease; + + WGPUProcRenderPassEncoderBeginOcclusionQuery renderPassEncoderBeginOcclusionQuery; + WGPUProcRenderPassEncoderDraw renderPassEncoderDraw; + WGPUProcRenderPassEncoderDrawIndexed renderPassEncoderDrawIndexed; + WGPUProcRenderPassEncoderDrawIndexedIndirect renderPassEncoderDrawIndexedIndirect; + WGPUProcRenderPassEncoderDrawIndirect renderPassEncoderDrawIndirect; + WGPUProcRenderPassEncoderEnd renderPassEncoderEnd; + WGPUProcRenderPassEncoderEndOcclusionQuery renderPassEncoderEndOcclusionQuery; + WGPUProcRenderPassEncoderExecuteBundles renderPassEncoderExecuteBundles; + WGPUProcRenderPassEncoderInsertDebugMarker renderPassEncoderInsertDebugMarker; + WGPUProcRenderPassEncoderPopDebugGroup renderPassEncoderPopDebugGroup; + WGPUProcRenderPassEncoderPushDebugGroup renderPassEncoderPushDebugGroup; + WGPUProcRenderPassEncoderSetBindGroup renderPassEncoderSetBindGroup; + WGPUProcRenderPassEncoderSetBlendConstant renderPassEncoderSetBlendConstant; + WGPUProcRenderPassEncoderSetIndexBuffer renderPassEncoderSetIndexBuffer; + WGPUProcRenderPassEncoderSetLabel renderPassEncoderSetLabel; + WGPUProcRenderPassEncoderSetPipeline renderPassEncoderSetPipeline; + WGPUProcRenderPassEncoderSetScissorRect renderPassEncoderSetScissorRect; + WGPUProcRenderPassEncoderSetStencilReference renderPassEncoderSetStencilReference; + WGPUProcRenderPassEncoderSetVertexBuffer renderPassEncoderSetVertexBuffer; + WGPUProcRenderPassEncoderSetViewport renderPassEncoderSetViewport; + WGPUProcRenderPassEncoderWriteTimestamp renderPassEncoderWriteTimestamp; + WGPUProcRenderPassEncoderReference renderPassEncoderReference; + WGPUProcRenderPassEncoderRelease renderPassEncoderRelease; + + WGPUProcRenderPipelineGetBindGroupLayout renderPipelineGetBindGroupLayout; + WGPUProcRenderPipelineSetLabel renderPipelineSetLabel; + WGPUProcRenderPipelineReference renderPipelineReference; + WGPUProcRenderPipelineRelease renderPipelineRelease; + + WGPUProcSamplerSetLabel samplerSetLabel; + WGPUProcSamplerReference samplerReference; + WGPUProcSamplerRelease samplerRelease; + + WGPUProcShaderModuleGetCompilationInfo shaderModuleGetCompilationInfo; + WGPUProcShaderModuleSetLabel shaderModuleSetLabel; + WGPUProcShaderModuleReference shaderModuleReference; + WGPUProcShaderModuleRelease shaderModuleRelease; + + WGPUProcSurfaceReference surfaceReference; + WGPUProcSurfaceRelease surfaceRelease; + + WGPUProcSwapChainGetCurrentTexture swapChainGetCurrentTexture; + WGPUProcSwapChainGetCurrentTextureView swapChainGetCurrentTextureView; + WGPUProcSwapChainPresent swapChainPresent; + WGPUProcSwapChainReference swapChainReference; + WGPUProcSwapChainRelease swapChainRelease; + + WGPUProcTextureCreateView textureCreateView; + WGPUProcTextureDestroy textureDestroy; + WGPUProcTextureGetDepthOrArrayLayers textureGetDepthOrArrayLayers; + WGPUProcTextureGetDimension textureGetDimension; + WGPUProcTextureGetFormat textureGetFormat; + WGPUProcTextureGetHeight textureGetHeight; + WGPUProcTextureGetMipLevelCount textureGetMipLevelCount; + WGPUProcTextureGetSampleCount textureGetSampleCount; + WGPUProcTextureGetUsage textureGetUsage; + WGPUProcTextureGetWidth textureGetWidth; + WGPUProcTextureSetLabel textureSetLabel; + WGPUProcTextureReference textureReference; + WGPUProcTextureRelease textureRelease; + + WGPUProcTextureViewSetLabel textureViewSetLabel; + WGPUProcTextureViewReference textureViewReference; + WGPUProcTextureViewRelease textureViewRelease; + +} DawnProcTable; + +#endif // DAWN_DAWN_PROC_TABLE_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/dawn_thread_dispatch_proc.h b/vendor/zgpu/libs/dawn/include/dawn/dawn_thread_dispatch_proc.h new file mode 100644 index 0000000..7b12c67 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/dawn_thread_dispatch_proc.h @@ -0,0 +1,33 @@ +// Copyright 2020 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_DAWN_THREAD_DISPATCH_PROC_H_ +#define INCLUDE_DAWN_DAWN_THREAD_DISPATCH_PROC_H_ + +#include "dawn/dawn_proc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Call dawnProcSetProcs(&dawnThreadDispatchProcTable) and then use dawnProcSetPerThreadProcs +// to set per-thread procs. +WGPU_EXPORT extern DawnProcTable dawnThreadDispatchProcTable; +WGPU_EXPORT void dawnProcSetPerThreadProcs(const DawnProcTable* procs); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // INCLUDE_DAWN_DAWN_THREAD_DISPATCH_PROC_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/D3D11Backend.h b/vendor/zgpu/libs/dawn/include/dawn/native/D3D11Backend.h new file mode 100644 index 0000000..5fae956 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/D3D11Backend.h @@ -0,0 +1,41 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_ +#define INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_ + +#include +#include +#include + +#include + +#include "dawn/native/D3DBackend.h" + +namespace dawn::native::d3d11 { + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public d3d::PhysicalDeviceDiscoveryOptions { + PhysicalDeviceDiscoveryOptions(); + explicit PhysicalDeviceDiscoveryOptions(Microsoft::WRL::ComPtr adapter); +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr GetD3D11Device(WGPUDevice device); + +} // namespace dawn::native::d3d11 + +#endif // INCLUDE_DAWN_NATIVE_D3D11BACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/D3D12Backend.h b/vendor/zgpu/libs/dawn/include/dawn/native/D3D12Backend.h new file mode 100644 index 0000000..eb0ca2b --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/D3D12Backend.h @@ -0,0 +1,52 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_D3D12BACKEND_H_ +#define INCLUDE_DAWN_NATIVE_D3D12BACKEND_H_ + +#include +#include +#include +#include + +#include "dawn/native/D3DBackend.h" + +struct ID3D12Device; +struct ID3D12Resource; + +namespace dawn::native::d3d12 { + +class Device; + +enum MemorySegment { + Local, + NonLocal, +}; + +DAWN_NATIVE_EXPORT uint64_t SetExternalMemoryReservation(WGPUDevice device, + uint64_t requestedReservationSize, + MemorySegment memorySegment); + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public d3d::PhysicalDeviceDiscoveryOptions { + PhysicalDeviceDiscoveryOptions(); + explicit PhysicalDeviceDiscoveryOptions(Microsoft::WRL::ComPtr adapter); +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +} // namespace dawn::native::d3d12 + +#endif // INCLUDE_DAWN_NATIVE_D3D12BACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/D3DBackend.h b/vendor/zgpu/libs/dawn/include/dawn/native/D3DBackend.h new file mode 100644 index 0000000..9e134d3 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/D3DBackend.h @@ -0,0 +1,109 @@ +// Copyright 2023 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_D3DBACKEND_H_ +#define INCLUDE_DAWN_NATIVE_D3DBACKEND_H_ + +#include +#include +#include + +#include +#include + +#include "dawn/native/DawnNative.h" +#include "dawn/webgpu_cpp_chained_struct.h" + +namespace dawn::native::d3d { + +class ExternalImageDXGIImpl; + +DAWN_NATIVE_EXPORT Microsoft::WRL::ComPtr GetDXGIAdapter(WGPUAdapter adapter); + +// Can be chained in WGPURequestAdapterOptions +struct DAWN_NATIVE_EXPORT RequestAdapterOptionsLUID : wgpu::ChainedStruct { + RequestAdapterOptionsLUID(); + + ::LUID adapterLUID; +}; + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public PhysicalDeviceDiscoveryOptionsBase { + PhysicalDeviceDiscoveryOptions(WGPUBackendType type, + Microsoft::WRL::ComPtr adapter); + Microsoft::WRL::ComPtr dxgiAdapter; +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDXGISharedHandle : ExternalImageDescriptor { + public: + ExternalImageDescriptorDXGISharedHandle(); + + // Note: SharedHandle must be a handle to a texture object. + HANDLE sharedHandle = nullptr; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageDXGIFenceDescriptor { + // Shared handle for the fence. This never passes ownership to the callee (when used as an input + // parameter) or to the caller (when used as a return value or output parameter). + HANDLE fenceHandle = nullptr; + + // The value that was previously signaled on this fence and should be waited on. + uint64_t fenceValue = 0; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageDXGIBeginAccessDescriptor { + bool isInitialized = false; // Whether the texture is initialized on import + WGPUTextureUsageFlags usage = WGPUTextureUsage_None; + + // A list of fences to wait on before accessing the texture. + std::vector waitFences; + + // Whether the texture is for a WebGPU swap chain. + bool isSwapChainTexture = false; +}; + +class DAWN_NATIVE_EXPORT ExternalImageDXGI { + public: + ~ExternalImageDXGI(); + + static std::unique_ptr Create( + WGPUDevice device, + const ExternalImageDescriptorDXGISharedHandle* descriptor); + + // Returns true if the external image resources are still valid, otherwise BeginAccess() is + // guaranteed to fail e.g. after device destruction. + bool IsValid() const; + + // Creates WGPUTexture wrapping the DXGI shared handle. The provided wait fences will be + // synchronized before using the texture in any command lists. Empty fences (nullptr handle) are + // ignored for convenience (EndAccess can return such fences). + WGPUTexture BeginAccess(const ExternalImageDXGIBeginAccessDescriptor* descriptor); + + // Returns the signalFence that the client must wait on for correct synchronization. Can return + // an empty fence (nullptr handle) if the texture wasn't accessed by Dawn. + // Note that merely calling Destroy() on the WGPUTexture does not ensure synchronization. + void EndAccess(WGPUTexture texture, ExternalImageDXGIFenceDescriptor* signalFence); + + private: + explicit ExternalImageDXGI(std::unique_ptr impl); + + std::unique_ptr mImpl; +}; + +} // namespace dawn::native::d3d + +#endif // INCLUDE_DAWN_NATIVE_D3DBACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/DawnNative.h b/vendor/zgpu/libs/dawn/include/dawn/native/DawnNative.h new file mode 100644 index 0000000..81db699 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/DawnNative.h @@ -0,0 +1,309 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_ +#define INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_ + +#include +#include + +#include "dawn/dawn_proc_table.h" +#include "dawn/native/dawn_native_export.h" +#include "dawn/webgpu.h" +#include "dawn/webgpu_cpp_chained_struct.h" + +namespace dawn::platform { +class Platform; +} // namespace dawn::platform + +namespace wgpu { +struct AdapterProperties; +struct DeviceDescriptor; +struct RequestAdapterOptions; +} // namespace wgpu + +namespace dawn::native { + +class InstanceBase; +class AdapterBase; + +// Each toggle is assigned with a TogglesStage, indicating the validation and earliest usage +// time of the toggle. +enum class ToggleStage { Instance, Adapter, Device }; + +// A struct to record the information of a toggle. A toggle is a code path in Dawn device that +// can be manually configured to run or not outside Dawn, including workarounds, special +// features and optimizations. +struct ToggleInfo { + const char* name; + const char* description; + const char* url; + ToggleStage stage; +}; + +// A struct to record the information of a feature. A feature is a GPU feature that is not +// required to be supported by all Dawn backends and can only be used when it is enabled on the +// creation of device. +struct FeatureInfo { + const char* name; + const char* description; + const char* url; + // The enum of feature state, could be stable or experimental. Using an experimental feature + // requires the AllowUnsafeAPIs toggle to be enabled. + enum class FeatureState { Stable = 0, Experimental }; + FeatureState featureState; +}; + +// An adapter is an object that represent on possibility of creating devices in the system. +// Most of the time it will represent a combination of a physical GPU and an API. Not that the +// same GPU can be represented by multiple adapters but on different APIs. +// +// The underlying Dawn adapter is owned by the Dawn instance so this class is not RAII but just +// a reference to an underlying adapter. +class DAWN_NATIVE_EXPORT Adapter { + public: + Adapter(); + // NOLINTNEXTLINE(runtime/explicit) + Adapter(AdapterBase* impl); + ~Adapter(); + + Adapter(const Adapter& other); + Adapter& operator=(const Adapter& other); + + // Essentially webgpu.h's wgpuAdapterGetProperties while we don't have WGPUAdapter in + // dawn.json + void GetProperties(wgpu::AdapterProperties* properties) const; + void GetProperties(WGPUAdapterProperties* properties) const; + + std::vector GetSupportedExtensions() const; + std::vector GetSupportedFeatures() const; + bool GetLimits(WGPUSupportedLimits* limits) const; + + void SetUseTieredLimits(bool useTieredLimits); + + // Check that the Adapter is able to support importing external images. This is necessary + // to implement the swapchain and interop APIs in Chromium. + bool SupportsExternalImages() const; + + explicit operator bool() const; + + // Create a device on this adapter. On an error, nullptr is returned. + WGPUDevice CreateDevice(const wgpu::DeviceDescriptor* deviceDescriptor); + WGPUDevice CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor = nullptr); + + void RequestDevice(const wgpu::DeviceDescriptor* descriptor, + WGPURequestDeviceCallback callback, + void* userdata); + void RequestDevice(const WGPUDeviceDescriptor* descriptor, + WGPURequestDeviceCallback callback, + void* userdata); + void RequestDevice(std::nullptr_t descriptor, + WGPURequestDeviceCallback callback, + void* userdata) { + RequestDevice(static_cast(descriptor), callback, userdata); + } + + // Returns the underlying WGPUAdapter object. + WGPUAdapter Get() const; + + // Reset the backend device object for testing purposes. + void ResetInternalDeviceForTesting(); + + private: + AdapterBase* mImpl = nullptr; +}; + +// Base class for options passed to Instance::DiscoverPhysicalDevices. +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptionsBase { + public: + const WGPUBackendType backendType; + + protected: + explicit PhysicalDeviceDiscoveryOptionsBase(WGPUBackendType type); +}; + +// Deprecated, use PhysicalDeviceDiscoveryOptionsBase instead. +// TODO(dawn:1774): Remove this. +using AdapterDiscoveryOptionsBase = PhysicalDeviceDiscoveryOptionsBase; + +enum BackendValidationLevel { Full, Partial, Disabled }; + +// Can be chained in InstanceDescriptor +struct DAWN_NATIVE_EXPORT DawnInstanceDescriptor : wgpu::ChainedStruct { + DawnInstanceDescriptor(); + static constexpr size_t kFirstMemberAlignment = + wgpu::detail::ConstexprMax(alignof(wgpu::ChainedStruct), alignof(uint32_t)); + alignas(kFirstMemberAlignment) uint32_t additionalRuntimeSearchPathsCount = 0; + const char* const* additionalRuntimeSearchPaths; + dawn::platform::Platform* platform = nullptr; + + // Equality operators, mostly for testing. Note that this tests + // strict pointer-pointer equality if the struct contains member pointers. + bool operator==(const DawnInstanceDescriptor& rhs) const; +}; + +// Represents a connection to dawn_native and is used for dependency injection, discovering +// system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter). +// +// This is an RAII class for Dawn instances and also controls the lifetime of all adapters +// for this instance. +class DAWN_NATIVE_EXPORT Instance { + public: + explicit Instance(const WGPUInstanceDescriptor* desc = nullptr); + ~Instance(); + + Instance(const Instance& other) = delete; + Instance& operator=(const Instance& other) = delete; + + // Gather all physical devices in the system that can be accessed with no special options. + void DiscoverDefaultPhysicalDevices(); + + // Adds physical devices that can be discovered with the options provided (like a + // getProcAddress). The backend is chosen based on the type of the options used. Returns true on + // success. + bool DiscoverPhysicalDevices(const PhysicalDeviceDiscoveryOptionsBase* options); + + // Deprecated, use DiscoverDefaultPhysicalDevices and DiscoverPhysicalDevices instead. + // TODO(Dawn:1774): Remove these. + void DiscoverDefaultAdapters(); + bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options); + + // Discovers and returns a vector of adapters. + // All systems adapters that can be found are returned if no options are passed. + // Otherwise, returns adapters based on the `options`. Adapter toggles descriptor can chained + // after options. + std::vector EnumerateAdapters(const WGPURequestAdapterOptions* options) const; + std::vector EnumerateAdapters( + const wgpu::RequestAdapterOptions* options = nullptr) const; + + // Deprecated. Call EnumerateAdapters instead. + std::vector GetAdapters() const; + + const ToggleInfo* GetToggleInfo(const char* toggleName); + const FeatureInfo* GetFeatureInfo(WGPUFeatureName feature); + + // Enables backend validation layers + void EnableBackendValidation(bool enableBackendValidation); + void SetBackendValidationLevel(BackendValidationLevel validationLevel); + + // Enable debug capture on Dawn startup + void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup); + + // Enable / disable the adapter blocklist. + void EnableAdapterBlocklist(bool enable); + + uint64_t GetDeviceCountForTesting() const; + + // Returns the underlying WGPUInstance object. + WGPUInstance Get() const; + + private: + InstanceBase* mImpl = nullptr; +}; + +// Backend-agnostic API for dawn_native +DAWN_NATIVE_EXPORT const DawnProcTable& GetProcs(); + +// Query the names of all the toggles that are enabled in device +DAWN_NATIVE_EXPORT std::vector GetTogglesUsed(WGPUDevice device); + +// Backdoor to get the number of lazy clears for testing +DAWN_NATIVE_EXPORT size_t GetLazyClearCountForTesting(WGPUDevice device); + +// Backdoor to get the number of deprecation warnings for testing +DAWN_NATIVE_EXPORT size_t GetDeprecationWarningCountForTesting(WGPUDevice device); + +// Backdoor to get the number of physical devices an instance knows about for testing +DAWN_NATIVE_EXPORT size_t GetPhysicalDeviceCountForTesting(WGPUInstance instance); + +// Query if texture has been initialized +DAWN_NATIVE_EXPORT bool IsTextureSubresourceInitialized( + WGPUTexture texture, + uint32_t baseMipLevel, + uint32_t levelCount, + uint32_t baseArrayLayer, + uint32_t layerCount, + WGPUTextureAspect aspect = WGPUTextureAspect_All); + +// Backdoor to get the order of the ProcMap for testing +DAWN_NATIVE_EXPORT std::vector GetProcMapNamesForTesting(); + +DAWN_NATIVE_EXPORT bool DeviceTick(WGPUDevice device); + +DAWN_NATIVE_EXPORT bool InstanceProcessEvents(WGPUInstance instance); + +// ErrorInjector functions used for testing only. Defined in dawn_native/ErrorInjector.cpp +DAWN_NATIVE_EXPORT void EnableErrorInjector(); +DAWN_NATIVE_EXPORT void DisableErrorInjector(); +DAWN_NATIVE_EXPORT void ClearErrorInjector(); +DAWN_NATIVE_EXPORT uint64_t AcquireErrorInjectorCallCount(); +DAWN_NATIVE_EXPORT void InjectErrorAt(uint64_t index); + +// The different types of external images +enum ExternalImageType { + OpaqueFD, + DmaBuf, + IOSurface, + DXGISharedHandle, + EGLImage, + AHardwareBuffer, +}; + +// Common properties of external images +struct DAWN_NATIVE_EXPORT ExternalImageDescriptor { + public: + const WGPUTextureDescriptor* cTextureDescriptor; // Must match image creation params + bool isInitialized; // Whether the texture is initialized on import + ExternalImageType GetType() const; + + protected: + explicit ExternalImageDescriptor(ExternalImageType type); + + private: + ExternalImageType mType; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageExportInfo { + public: + bool isInitialized = false; // Whether the texture is initialized after export + ExternalImageType GetType() const; + + protected: + explicit ExternalImageExportInfo(ExternalImageType type); + + private: + ExternalImageType mType; +}; + +DAWN_NATIVE_EXPORT bool CheckIsErrorForTesting(void* objectHandle); + +DAWN_NATIVE_EXPORT const char* GetObjectLabelForTesting(void* objectHandle); + +DAWN_NATIVE_EXPORT uint64_t GetAllocatedSizeForTesting(WGPUBuffer buffer); + +DAWN_NATIVE_EXPORT bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a, + WGPUBindGroupLayout b); + +} // namespace dawn::native + +// Alias the DawnInstanceDescriptor up to wgpu. +// TODO(dawn:1374) Remove this aliasing once the usages are updated. +namespace wgpu { +using dawn::native::DawnInstanceDescriptor; +} // namespace wgpu + +// TODO(dawn:824): Remove once the deprecation period is passed. +namespace dawn_native = dawn::native; + +#endif // INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/MetalBackend.h b/vendor/zgpu/libs/dawn/include/dawn/native/MetalBackend.h new file mode 100644 index 0000000..c401d7d --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/MetalBackend.h @@ -0,0 +1,95 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_METALBACKEND_H_ +#define INCLUDE_DAWN_NATIVE_METALBACKEND_H_ + +#include + +#include "dawn/native/DawnNative.h" + +// The specifics of the Metal backend expose types in function signatures that might not be +// available in dependent's minimum supported SDK version. Suppress all availability errors using +// clang's pragmas. Dependents using the types without guarded availability will still get errors +// when using the types. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + +struct __IOSurface; +typedef __IOSurface* IOSurfaceRef; + +#ifdef __OBJC__ +#import +#endif // __OBJC__ + +namespace dawn::native::metal { + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public PhysicalDeviceDiscoveryOptionsBase { + PhysicalDeviceDiscoveryOptions(); +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +struct DAWN_NATIVE_EXPORT ExternalImageMTLSharedEventDescriptor { + // Shared event handle `id`. + // This never passes ownership to the callee (when used as an input + // parameter) or to the caller (when used as a return value or output parameter). +#ifdef __OBJC__ + id sharedEvent = nil; + static_assert(sizeof(id) == sizeof(void*)); + static_assert(alignof(id) == alignof(void*)); +#else + void* sharedEvent = nullptr; +#endif + + // The value that was previously signaled on this event and should be waited on. + uint64_t signaledValue = 0; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorIOSurface : ExternalImageDescriptor { + public: + ExternalImageDescriptorIOSurface(); + ~ExternalImageDescriptorIOSurface(); + + IOSurfaceRef ioSurface; + + // A list of events to wait on before accessing the texture. + std::vector waitEvents; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageIOSurfaceEndAccessDescriptor + : ExternalImageMTLSharedEventDescriptor { + bool isInitialized; +}; + +DAWN_NATIVE_EXPORT WGPUTexture WrapIOSurface(WGPUDevice device, + const ExternalImageDescriptorIOSurface* descriptor); + +DAWN_NATIVE_EXPORT void IOSurfaceEndAccess(WGPUTexture texture, + ExternalImageIOSurfaceEndAccessDescriptor* descriptor); + +// 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. +DAWN_NATIVE_EXPORT void WaitForCommandsToBeScheduled(WGPUDevice device); + +} // namespace dawn::native::metal + +#pragma clang diagnostic pop + +#endif // INCLUDE_DAWN_NATIVE_METALBACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/NullBackend.h b/vendor/zgpu/libs/dawn/include/dawn/native/NullBackend.h new file mode 100644 index 0000000..c28b90f --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/NullBackend.h @@ -0,0 +1,26 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_NULLBACKEND_H_ +#define INCLUDE_DAWN_NATIVE_NULLBACKEND_H_ + +#include "dawn/native/DawnNative.h" + +namespace dawn::native::null { + +// Nothing for now \o/ + +} // namespace dawn::native::null + +#endif // INCLUDE_DAWN_NATIVE_NULLBACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/OpenGLBackend.h b/vendor/zgpu/libs/dawn/include/dawn/native/OpenGLBackend.h new file mode 100644 index 0000000..2804f0f --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/OpenGLBackend.h @@ -0,0 +1,59 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_OPENGLBACKEND_H_ +#define INCLUDE_DAWN_NATIVE_OPENGLBACKEND_H_ + +typedef void* EGLImage; + +#include "dawn/native/DawnNative.h" +#include "dawn/webgpu_cpp_chained_struct.h" + +namespace dawn::native::opengl { + +// Can be chained in WGPURequestAdapterOptions +struct DAWN_NATIVE_EXPORT RequestAdapterOptionsGetGLProc : wgpu::ChainedStruct { + RequestAdapterOptionsGetGLProc(); + + void* (*getProc)(const char*); +}; + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public PhysicalDeviceDiscoveryOptionsBase { + explicit PhysicalDeviceDiscoveryOptions(WGPUBackendType type); + + void* (*getProc)(const char*); +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +// TODO(crbug.com/dawn/810): This struct can be removed once Chrome is no longer using it. +struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsES : public PhysicalDeviceDiscoveryOptions { + AdapterDiscoveryOptionsES(); +}; + +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorEGLImage : ExternalImageDescriptor { + public: + ExternalImageDescriptorEGLImage(); + + ::EGLImage image; +}; + +DAWN_NATIVE_EXPORT WGPUTexture +WrapExternalEGLImage(WGPUDevice device, const ExternalImageDescriptorEGLImage* descriptor); + +} // namespace dawn::native::opengl + +#endif // INCLUDE_DAWN_NATIVE_OPENGLBACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/VulkanBackend.h b/vendor/zgpu/libs/dawn/include/dawn/native/VulkanBackend.h new file mode 100644 index 0000000..a677388 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/VulkanBackend.h @@ -0,0 +1,180 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_ +#define INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_ + +#include + +#include +#include + +#include "dawn/native/DawnNative.h" + +namespace dawn::native::vulkan { + +DAWN_NATIVE_EXPORT VkInstance GetInstance(WGPUDevice device); + +DAWN_NATIVE_EXPORT PFN_vkVoidFunction GetInstanceProcAddr(WGPUDevice device, const char* pName); + +struct DAWN_NATIVE_EXPORT PhysicalDeviceDiscoveryOptions + : public PhysicalDeviceDiscoveryOptionsBase { + PhysicalDeviceDiscoveryOptions(); + + bool forceSwiftShader = false; +}; + +// TODO(dawn:1774): Deprecated. +using AdapterDiscoveryOptions = PhysicalDeviceDiscoveryOptions; + +enum class NeedsDedicatedAllocation { + Yes, + No, + // Use Vulkan reflection to detect whether a dedicated allocation is needed. + Detect, +}; + +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorVk : ExternalImageDescriptor { + public: + // The following members may be ignored if |ExternalImageDescriptor::isInitialized| is false + // since the import does not need to preserve texture contents. + + // See https://www.khronos.org/registry/vulkan/specs/1.1/html/chap7.html. The acquire + // operation old/new layouts must match exactly the layouts in the release operation. So + // we may need to issue two barriers releasedOldLayout -> releasedNewLayout -> + // cTextureDescriptor.usage if the new layout is not compatible with the desired usage. + // The first barrier is the queue transfer, the second is the layout transition to our + // desired usage. + VkImageLayout releasedOldLayout = VK_IMAGE_LAYOUT_GENERAL; + VkImageLayout releasedNewLayout = VK_IMAGE_LAYOUT_GENERAL; + + // Try to detect the need to use a dedicated allocation for imported images by default but let + // the application override this as drivers have bugs and forget to require a dedicated + // allocation. + NeedsDedicatedAllocation dedicatedAllocation = NeedsDedicatedAllocation::Detect; + + protected: + using ExternalImageDescriptor::ExternalImageDescriptor; +}; + +struct ExternalImageExportInfoVk : ExternalImageExportInfo { + public: + // See comments in |ExternalImageDescriptorVk| + // Contains the old/new layouts used in the queue release operation. + VkImageLayout releasedOldLayout; + VkImageLayout releasedNewLayout; + + protected: + using ExternalImageExportInfo::ExternalImageExportInfo; +}; + +// Can't use DAWN_PLATFORM_IS(LINUX) since header included in both Dawn and Chrome +#ifdef __linux__ + +// Common properties of external images represented by FDs. On successful import the file +// descriptor's ownership is transferred to the Dawn implementation and they shouldn't be +// used outside of Dawn again. TODO(enga): Also transfer ownership in the error case so the +// caller can assume the FD is always consumed. +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorFD : ExternalImageDescriptorVk { + public: + int memoryFD; // A file descriptor from an export of the memory of the image + std::vector waitFDs; // File descriptors of semaphores which will be waited on + + protected: + using ExternalImageDescriptorVk::ExternalImageDescriptorVk; +}; + +// Descriptor for opaque file descriptor image import +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorOpaqueFD : ExternalImageDescriptorFD { + ExternalImageDescriptorOpaqueFD(); + + VkDeviceSize allocationSize; // Must match VkMemoryAllocateInfo from image creation + uint32_t memoryTypeIndex; // Must match VkMemoryAllocateInfo from image creation +}; + +// The plane-wise offset and stride. +struct DAWN_NATIVE_EXPORT PlaneLayout { + uint64_t offset; + uint32_t stride; +}; + +// Descriptor for dma-buf file descriptor image import +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorDmaBuf : ExternalImageDescriptorFD { + ExternalImageDescriptorDmaBuf(); + + static constexpr uint32_t kMaxPlanes = 3; + std::array planeLayouts; + uint64_t drmModifier; // DRM modifier of the buffer +}; + +// Info struct that is written to in |ExportVulkanImage|. +struct DAWN_NATIVE_EXPORT ExternalImageExportInfoFD : ExternalImageExportInfoVk { + public: + // Contains the exported semaphore handles. + std::vector semaphoreHandles; + + protected: + using ExternalImageExportInfoVk::ExternalImageExportInfoVk; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageExportInfoOpaqueFD : ExternalImageExportInfoFD { + ExternalImageExportInfoOpaqueFD(); +}; + +struct DAWN_NATIVE_EXPORT ExternalImageExportInfoDmaBuf : ExternalImageExportInfoFD { + ExternalImageExportInfoDmaBuf(); +}; + +#ifdef __ANDROID__ + +// Descriptor for AHardwareBuffer image import +struct DAWN_NATIVE_EXPORT ExternalImageDescriptorAHardwareBuffer : ExternalImageDescriptorVk { + public: + ExternalImageDescriptorAHardwareBuffer(); + + struct AHardwareBuffer* handle; // The AHardwareBuffer which contains the memory of the image + std::vector waitFDs; // File descriptors of semaphores which will be waited on + + protected: + using ExternalImageDescriptorVk::ExternalImageDescriptorVk; +}; + +struct DAWN_NATIVE_EXPORT ExternalImageExportInfoAHardwareBuffer : ExternalImageExportInfoFD { + ExternalImageExportInfoAHardwareBuffer(); +}; + +#endif // __ANDROID__ + +#endif // __linux__ + +// Imports external memory into a Vulkan image. Internally, this uses external memory / +// semaphore extensions to import the image and wait on the provided synchronizaton +// primitives before the texture can be used. +// On failure, returns a nullptr. +DAWN_NATIVE_EXPORT WGPUTexture WrapVulkanImage(WGPUDevice device, + const ExternalImageDescriptorVk* descriptor); + +// Exports external memory from a Vulkan image. This must be called on wrapped textures +// before they are destroyed. It writes the semaphore to wait on and the old/new image +// layouts to |info|. Pass VK_IMAGE_LAYOUT_UNDEFINED as |desiredLayout| if you don't want to +// perform a layout transition. +DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture, + VkImageLayout desiredLayout, + ExternalImageExportInfoVk* info); +// |ExportVulkanImage| with default desiredLayout of VK_IMAGE_LAYOUT_UNDEFINED. +DAWN_NATIVE_EXPORT bool ExportVulkanImage(WGPUTexture texture, ExternalImageExportInfoVk* info); + +} // namespace dawn::native::vulkan + +#endif // INCLUDE_DAWN_NATIVE_VULKANBACKEND_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/native/dawn_native_export.h b/vendor/zgpu/libs/dawn/include/dawn/native/dawn_native_export.h new file mode 100644 index 0000000..c237720 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/native/dawn_native_export.h @@ -0,0 +1,36 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_NATIVE_DAWN_NATIVE_EXPORT_H_ +#define INCLUDE_DAWN_NATIVE_DAWN_NATIVE_EXPORT_H_ + +#if defined(DAWN_NATIVE_SHARED_LIBRARY) +#if defined(_WIN32) +#if defined(DAWN_NATIVE_IMPLEMENTATION) +#define DAWN_NATIVE_EXPORT __declspec(dllexport) +#else +#define DAWN_NATIVE_EXPORT __declspec(dllimport) +#endif +#else // defined(_WIN32) +#if defined(DAWN_NATIVE_IMPLEMENTATION) +#define DAWN_NATIVE_EXPORT __attribute__((visibility("default"))) +#else +#define DAWN_NATIVE_EXPORT +#endif +#endif // defined(_WIN32) +#else // defined(DAWN_NATIVE_SHARED_LIBRARY) +#define DAWN_NATIVE_EXPORT +#endif // defined(DAWN_NATIVE_SHARED_LIBRARY) + +#endif // INCLUDE_DAWN_NATIVE_DAWN_NATIVE_EXPORT_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/platform/DawnPlatform.h b/vendor/zgpu/libs/dawn/include/dawn/platform/DawnPlatform.h new file mode 100644 index 0000000..4d215bc --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/platform/DawnPlatform.h @@ -0,0 +1,128 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_PLATFORM_DAWNPLATFORM_H_ +#define INCLUDE_DAWN_PLATFORM_DAWNPLATFORM_H_ + +#include +#include +#include + +#include "dawn/platform/dawn_platform_export.h" +#include "dawn/webgpu.h" + +namespace dawn::platform { + +enum class TraceCategory { + General, // General trace events + Validation, // Dawn validation + Recording, // Native command recording + GPUWork, // Actual GPU work +}; + +class DAWN_PLATFORM_EXPORT CachingInterface { + public: + CachingInterface(); + virtual ~CachingInterface(); + + // LoadData has two modes. The first mode is used to get a value which + // corresponds to the |key|. The |valueOut| is a caller provided buffer + // allocated to the size |valueSize| which is loaded with data of the + // size returned. The second mode is used to query for the existence of + // the |key| where |valueOut| is nullptr and |valueSize| must be 0. + // The return size is non-zero if the |key| exists. + virtual size_t LoadData(const void* key, size_t keySize, void* valueOut, size_t valueSize) = 0; + + // StoreData puts a |value| in the cache which corresponds to the |key|. + virtual void StoreData(const void* key, + size_t keySize, + const void* value, + size_t valueSize) = 0; + + private: + CachingInterface(const CachingInterface&) = delete; + CachingInterface& operator=(const CachingInterface&) = delete; +}; + +class DAWN_PLATFORM_EXPORT WaitableEvent { + public: + WaitableEvent() = default; + virtual ~WaitableEvent() = default; + virtual void Wait() = 0; // Wait for completion + virtual bool IsComplete() = 0; // Non-blocking check if the event is complete +}; + +using PostWorkerTaskCallback = void (*)(void* userdata); + +class DAWN_PLATFORM_EXPORT WorkerTaskPool { + public: + WorkerTaskPool() = default; + virtual ~WorkerTaskPool() = default; + virtual std::unique_ptr PostWorkerTask(PostWorkerTaskCallback, + void* userdata) = 0; +}; + +class DAWN_PLATFORM_EXPORT Platform { + public: + Platform(); + virtual ~Platform(); + + virtual const unsigned char* GetTraceCategoryEnabledFlag(TraceCategory category); + + virtual double MonotonicallyIncreasingTime(); + + virtual uint64_t AddTraceEvent(char phase, + const unsigned char* categoryGroupEnabled, + const char* name, + uint64_t id, + double timestamp, + int numArgs, + const char** argNames, + const unsigned char* argTypes, + const uint64_t* argValues, + unsigned char flags); + + // Invoked to add a UMA histogram count-based sample + virtual void HistogramCustomCounts(const char* name, + int sample, + int min, + int max, + int bucketCount); + + // Invoked to add a UMA histogram enumeration sample + virtual void HistogramEnumeration(const char* name, int sample, int boundaryValue); + + // Invoked to add a UMA histogram sparse sample + virtual void HistogramSparse(const char* name, int sample); + + // Invoked to add a UMA histogram boolean sample + virtual void HistogramBoolean(const char* name, bool sample); + + // The returned CachingInterface is expected to outlive the device which uses it to persistently + // cache objects. + virtual CachingInterface* GetCachingInterface(); + + virtual std::unique_ptr CreateWorkerTaskPool(); + + private: + Platform(const Platform&) = delete; + Platform& operator=(const Platform&) = delete; +}; + +} // namespace dawn::platform + +// TODO(dawn:824): Remove once the deprecation period is passed. +namespace dawn_platform = dawn::platform; + +#endif // INCLUDE_DAWN_PLATFORM_DAWNPLATFORM_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/platform/dawn_platform_export.h b/vendor/zgpu/libs/dawn/include/dawn/platform/dawn_platform_export.h new file mode 100644 index 0000000..fbdb33c --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/platform/dawn_platform_export.h @@ -0,0 +1,36 @@ +// Copyright 2020 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_PLATFORM_DAWN_PLATFORM_EXPORT_H_ +#define INCLUDE_DAWN_PLATFORM_DAWN_PLATFORM_EXPORT_H_ + +#if defined(DAWN_PLATFORM_SHARED_LIBRARY) +#if defined(_WIN32) +#if defined(DAWN_PLATFORM_IMPLEMENTATION) +#define DAWN_PLATFORM_EXPORT __declspec(dllexport) +#else +#define DAWN_PLATFORM_EXPORT __declspec(dllimport) +#endif +#else // defined(_WIN32) +#if defined(DAWN_PLATFORM_IMPLEMENTATION) +#define DAWN_PLATFORM_EXPORT __attribute__((visibility("default"))) +#else +#define DAWN_PLATFORM_EXPORT +#endif +#endif // defined(_WIN32) +#else // defined(DAWN_PLATFORM_SHARED_LIBRARY) +#define DAWN_PLATFORM_EXPORT +#endif // defined(DAWN_PLATFORM_SHARED_LIBRARY) + +#endif // INCLUDE_DAWN_PLATFORM_DAWN_PLATFORM_EXPORT_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/webgpu.h b/vendor/zgpu/libs/dawn/include/dawn/webgpu.h new file mode 100644 index 0000000..1cd5bf4 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/webgpu.h @@ -0,0 +1,2034 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, "WebGPU native" developers +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifdef __EMSCRIPTEN__ +#error "Do not include this header. Emscripten already provides headers needed for WebGPU." +#endif +#ifndef WEBGPU_H_ +#define WEBGPU_H_ + +#if defined(WGPU_SHARED_LIBRARY) +# if defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __declspec(dllexport) +# else +# define WGPU_EXPORT __declspec(dllimport) +# endif +# else // defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __attribute__((visibility("default"))) +# else +# define WGPU_EXPORT +# endif +# endif // defined(_WIN32) +#else // defined(WGPU_SHARED_LIBRARY) +# define WGPU_EXPORT +#endif // defined(WGPU_SHARED_LIBRARY) + +#if !defined(WGPU_OBJECT_ATTRIBUTE) +#define WGPU_OBJECT_ATTRIBUTE +#endif +#if !defined(WGPU_ENUM_ATTRIBUTE) +#define WGPU_ENUM_ATTRIBUTE +#endif +#if !defined(WGPU_STRUCTURE_ATTRIBUTE) +#define WGPU_STRUCTURE_ATTRIBUTE +#endif +#if !defined(WGPU_FUNCTION_ATTRIBUTE) +#define WGPU_FUNCTION_ATTRIBUTE +#endif +#if !defined(WGPU_NULLABLE) +#define WGPU_NULLABLE +#endif + +#include +#include +#include + +#define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (0xffffffffUL) +#define WGPU_COPY_STRIDE_UNDEFINED (0xffffffffUL) +#define WGPU_LIMIT_U32_UNDEFINED (0xffffffffUL) +#define WGPU_LIMIT_U64_UNDEFINED (0xffffffffffffffffULL) +#define WGPU_MIP_LEVEL_COUNT_UNDEFINED (0xffffffffUL) +#define WGPU_WHOLE_MAP_SIZE SIZE_MAX +#define WGPU_WHOLE_SIZE (0xffffffffffffffffULL) + +typedef uint32_t WGPUFlags; + +typedef struct WGPUAdapterImpl* WGPUAdapter WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupImpl* WGPUBindGroup WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBufferImpl* WGPUBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandBufferImpl* WGPUCommandBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandEncoderImpl* WGPUCommandEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePassEncoderImpl* WGPUComputePassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePipelineImpl* WGPUComputePipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUDeviceImpl* WGPUDevice WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUExternalTextureImpl* WGPUExternalTexture WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUInstanceImpl* WGPUInstance WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUPipelineLayoutImpl* WGPUPipelineLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQuerySetImpl* WGPUQuerySet WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQueueImpl* WGPUQueue WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleImpl* WGPURenderBundle WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleEncoderImpl* WGPURenderBundleEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPipelineImpl* WGPURenderPipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSamplerImpl* WGPUSampler WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUShaderModuleImpl* WGPUShaderModule WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSurfaceImpl* WGPUSurface WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSwapChainImpl* WGPUSwapChain WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureImpl* WGPUTexture WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureViewImpl* WGPUTextureView WGPU_OBJECT_ATTRIBUTE; + +// Structure forward declarations +struct WGPUAdapterProperties; +struct WGPUBindGroupEntry; +struct WGPUBlendComponent; +struct WGPUBufferBindingLayout; +struct WGPUBufferDescriptor; +struct WGPUColor; +struct WGPUCommandBufferDescriptor; +struct WGPUCommandEncoderDescriptor; +struct WGPUCompilationMessage; +struct WGPUComputePassTimestampWrite; +struct WGPUConstantEntry; +struct WGPUCopyTextureForBrowserOptions; +struct WGPUDawnAdapterPropertiesPowerPreference; +struct WGPUDawnBufferDescriptorErrorInfoFromWireClient; +struct WGPUDawnCacheDeviceDescriptor; +struct WGPUDawnEncoderInternalUsageDescriptor; +struct WGPUDawnMultisampleStateRenderToSingleSampled; +struct WGPUDawnRenderPassColorAttachmentRenderToSingleSampled; +struct WGPUDawnShaderModuleSPIRVOptionsDescriptor; +struct WGPUDawnTextureInternalUsageDescriptor; +struct WGPUDawnTogglesDescriptor; +struct WGPUExtent2D; +struct WGPUExtent3D; +struct WGPUExternalTextureBindingEntry; +struct WGPUExternalTextureBindingLayout; +struct WGPUInstanceDescriptor; +struct WGPULimits; +struct WGPUMultisampleState; +struct WGPUOrigin2D; +struct WGPUOrigin3D; +struct WGPUPipelineLayoutDescriptor; +struct WGPUPrimitiveDepthClipControl; +struct WGPUPrimitiveState; +struct WGPUQuerySetDescriptor; +struct WGPUQueueDescriptor; +struct WGPURenderBundleDescriptor; +struct WGPURenderBundleEncoderDescriptor; +struct WGPURenderPassDepthStencilAttachment; +struct WGPURenderPassDescriptorMaxDrawCount; +struct WGPURenderPassTimestampWrite; +struct WGPURequestAdapterOptions; +struct WGPUSamplerBindingLayout; +struct WGPUSamplerDescriptor; +struct WGPUShaderModuleDescriptor; +struct WGPUShaderModuleSPIRVDescriptor; +struct WGPUShaderModuleWGSLDescriptor; +struct WGPUStencilFaceState; +struct WGPUStorageTextureBindingLayout; +struct WGPUSurfaceDescriptor; +struct WGPUSurfaceDescriptorFromAndroidNativeWindow; +struct WGPUSurfaceDescriptorFromCanvasHTMLSelector; +struct WGPUSurfaceDescriptorFromMetalLayer; +struct WGPUSurfaceDescriptorFromWaylandSurface; +struct WGPUSurfaceDescriptorFromWindowsCoreWindow; +struct WGPUSurfaceDescriptorFromWindowsHWND; +struct WGPUSurfaceDescriptorFromWindowsSwapChainPanel; +struct WGPUSurfaceDescriptorFromXlibWindow; +struct WGPUSwapChainDescriptor; +struct WGPUTextureBindingLayout; +struct WGPUTextureDataLayout; +struct WGPUTextureViewDescriptor; +struct WGPUVertexAttribute; +struct WGPUBindGroupDescriptor; +struct WGPUBindGroupLayoutEntry; +struct WGPUBlendState; +struct WGPUCompilationInfo; +struct WGPUComputePassDescriptor; +struct WGPUDepthStencilState; +struct WGPUExternalTextureDescriptor; +struct WGPUImageCopyBuffer; +struct WGPUImageCopyExternalTexture; +struct WGPUImageCopyTexture; +struct WGPUProgrammableStageDescriptor; +struct WGPURenderPassColorAttachment; +struct WGPURequiredLimits; +struct WGPUSupportedLimits; +struct WGPUTextureDescriptor; +struct WGPUVertexBufferLayout; +struct WGPUBindGroupLayoutDescriptor; +struct WGPUColorTargetState; +struct WGPUComputePipelineDescriptor; +struct WGPUDeviceDescriptor; +struct WGPURenderPassDescriptor; +struct WGPUVertexState; +struct WGPUFragmentState; +struct WGPURenderPipelineDescriptor; + +typedef enum WGPUAdapterType { + WGPUAdapterType_DiscreteGPU = 0x00000000, + WGPUAdapterType_IntegratedGPU = 0x00000001, + WGPUAdapterType_CPU = 0x00000002, + WGPUAdapterType_Unknown = 0x00000003, + WGPUAdapterType_Force32 = 0x7FFFFFFF +} WGPUAdapterType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUAddressMode { + WGPUAddressMode_Repeat = 0x00000000, + WGPUAddressMode_MirrorRepeat = 0x00000001, + WGPUAddressMode_ClampToEdge = 0x00000002, + WGPUAddressMode_Force32 = 0x7FFFFFFF +} WGPUAddressMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUAlphaMode { + WGPUAlphaMode_Premultiplied = 0x00000000, + WGPUAlphaMode_Unpremultiplied = 0x00000001, + WGPUAlphaMode_Opaque = 0x00000002, + WGPUAlphaMode_Force32 = 0x7FFFFFFF +} WGPUAlphaMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBackendType { + WGPUBackendType_Undefined = 0x00000000, + WGPUBackendType_Null = 0x00000001, + WGPUBackendType_WebGPU = 0x00000002, + WGPUBackendType_D3D11 = 0x00000003, + WGPUBackendType_D3D12 = 0x00000004, + WGPUBackendType_Metal = 0x00000005, + WGPUBackendType_Vulkan = 0x00000006, + WGPUBackendType_OpenGL = 0x00000007, + WGPUBackendType_OpenGLES = 0x00000008, + WGPUBackendType_Force32 = 0x7FFFFFFF +} WGPUBackendType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendFactor { + WGPUBlendFactor_Zero = 0x00000000, + WGPUBlendFactor_One = 0x00000001, + WGPUBlendFactor_Src = 0x00000002, + WGPUBlendFactor_OneMinusSrc = 0x00000003, + WGPUBlendFactor_SrcAlpha = 0x00000004, + WGPUBlendFactor_OneMinusSrcAlpha = 0x00000005, + WGPUBlendFactor_Dst = 0x00000006, + WGPUBlendFactor_OneMinusDst = 0x00000007, + WGPUBlendFactor_DstAlpha = 0x00000008, + WGPUBlendFactor_OneMinusDstAlpha = 0x00000009, + WGPUBlendFactor_SrcAlphaSaturated = 0x0000000A, + WGPUBlendFactor_Constant = 0x0000000B, + WGPUBlendFactor_OneMinusConstant = 0x0000000C, + WGPUBlendFactor_Force32 = 0x7FFFFFFF +} WGPUBlendFactor WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendOperation { + WGPUBlendOperation_Add = 0x00000000, + WGPUBlendOperation_Subtract = 0x00000001, + WGPUBlendOperation_ReverseSubtract = 0x00000002, + WGPUBlendOperation_Min = 0x00000003, + WGPUBlendOperation_Max = 0x00000004, + WGPUBlendOperation_Force32 = 0x7FFFFFFF +} WGPUBlendOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferBindingType { + WGPUBufferBindingType_Undefined = 0x00000000, + WGPUBufferBindingType_Uniform = 0x00000001, + WGPUBufferBindingType_Storage = 0x00000002, + WGPUBufferBindingType_ReadOnlyStorage = 0x00000003, + WGPUBufferBindingType_Force32 = 0x7FFFFFFF +} WGPUBufferBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferMapAsyncStatus { + WGPUBufferMapAsyncStatus_Success = 0x00000000, + WGPUBufferMapAsyncStatus_ValidationError = 0x00000001, + WGPUBufferMapAsyncStatus_Unknown = 0x00000002, + WGPUBufferMapAsyncStatus_DeviceLost = 0x00000003, + WGPUBufferMapAsyncStatus_DestroyedBeforeCallback = 0x00000004, + WGPUBufferMapAsyncStatus_UnmappedBeforeCallback = 0x00000005, + WGPUBufferMapAsyncStatus_MappingAlreadyPending = 0x00000006, + WGPUBufferMapAsyncStatus_OffsetOutOfRange = 0x00000007, + WGPUBufferMapAsyncStatus_SizeOutOfRange = 0x00000008, + WGPUBufferMapAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUBufferMapAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferMapState { + WGPUBufferMapState_Unmapped = 0x00000000, + WGPUBufferMapState_Pending = 0x00000001, + WGPUBufferMapState_Mapped = 0x00000002, + WGPUBufferMapState_Force32 = 0x7FFFFFFF +} WGPUBufferMapState WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompareFunction { + WGPUCompareFunction_Undefined = 0x00000000, + WGPUCompareFunction_Never = 0x00000001, + WGPUCompareFunction_Less = 0x00000002, + WGPUCompareFunction_LessEqual = 0x00000003, + WGPUCompareFunction_Greater = 0x00000004, + WGPUCompareFunction_GreaterEqual = 0x00000005, + WGPUCompareFunction_Equal = 0x00000006, + WGPUCompareFunction_NotEqual = 0x00000007, + WGPUCompareFunction_Always = 0x00000008, + WGPUCompareFunction_Force32 = 0x7FFFFFFF +} WGPUCompareFunction WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationInfoRequestStatus { + WGPUCompilationInfoRequestStatus_Success = 0x00000000, + WGPUCompilationInfoRequestStatus_Error = 0x00000001, + WGPUCompilationInfoRequestStatus_DeviceLost = 0x00000002, + WGPUCompilationInfoRequestStatus_Unknown = 0x00000003, + WGPUCompilationInfoRequestStatus_Force32 = 0x7FFFFFFF +} WGPUCompilationInfoRequestStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationMessageType { + WGPUCompilationMessageType_Error = 0x00000000, + WGPUCompilationMessageType_Warning = 0x00000001, + WGPUCompilationMessageType_Info = 0x00000002, + WGPUCompilationMessageType_Force32 = 0x7FFFFFFF +} WGPUCompilationMessageType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUComputePassTimestampLocation { + WGPUComputePassTimestampLocation_Beginning = 0x00000000, + WGPUComputePassTimestampLocation_End = 0x00000001, + WGPUComputePassTimestampLocation_Force32 = 0x7FFFFFFF +} WGPUComputePassTimestampLocation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCreatePipelineAsyncStatus { + WGPUCreatePipelineAsyncStatus_Success = 0x00000000, + WGPUCreatePipelineAsyncStatus_ValidationError = 0x00000001, + WGPUCreatePipelineAsyncStatus_InternalError = 0x00000002, + WGPUCreatePipelineAsyncStatus_DeviceLost = 0x00000003, + WGPUCreatePipelineAsyncStatus_DeviceDestroyed = 0x00000004, + WGPUCreatePipelineAsyncStatus_Unknown = 0x00000005, + WGPUCreatePipelineAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUCreatePipelineAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCullMode { + WGPUCullMode_None = 0x00000000, + WGPUCullMode_Front = 0x00000001, + WGPUCullMode_Back = 0x00000002, + WGPUCullMode_Force32 = 0x7FFFFFFF +} WGPUCullMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUDeviceLostReason { + WGPUDeviceLostReason_Undefined = 0x00000000, + WGPUDeviceLostReason_Destroyed = 0x00000001, + WGPUDeviceLostReason_Force32 = 0x7FFFFFFF +} WGPUDeviceLostReason WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorFilter { + WGPUErrorFilter_Validation = 0x00000000, + WGPUErrorFilter_OutOfMemory = 0x00000001, + WGPUErrorFilter_Internal = 0x00000002, + WGPUErrorFilter_Force32 = 0x7FFFFFFF +} WGPUErrorFilter WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorType { + WGPUErrorType_NoError = 0x00000000, + WGPUErrorType_Validation = 0x00000001, + WGPUErrorType_OutOfMemory = 0x00000002, + WGPUErrorType_Internal = 0x00000003, + WGPUErrorType_Unknown = 0x00000004, + WGPUErrorType_DeviceLost = 0x00000005, + WGPUErrorType_Force32 = 0x7FFFFFFF +} WGPUErrorType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUExternalTextureRotation { + WGPUExternalTextureRotation_Rotate0Degrees = 0x00000000, + WGPUExternalTextureRotation_Rotate90Degrees = 0x00000001, + WGPUExternalTextureRotation_Rotate180Degrees = 0x00000002, + WGPUExternalTextureRotation_Rotate270Degrees = 0x00000003, + WGPUExternalTextureRotation_Force32 = 0x7FFFFFFF +} WGPUExternalTextureRotation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFeatureName { + WGPUFeatureName_Undefined = 0x00000000, + WGPUFeatureName_DepthClipControl = 0x00000001, + WGPUFeatureName_Depth32FloatStencil8 = 0x00000002, + WGPUFeatureName_TimestampQuery = 0x00000003, + WGPUFeatureName_PipelineStatisticsQuery = 0x00000004, + WGPUFeatureName_TextureCompressionBC = 0x00000005, + WGPUFeatureName_TextureCompressionETC2 = 0x00000006, + WGPUFeatureName_TextureCompressionASTC = 0x00000007, + WGPUFeatureName_IndirectFirstInstance = 0x00000008, + WGPUFeatureName_ShaderF16 = 0x00000009, + WGPUFeatureName_RG11B10UfloatRenderable = 0x0000000A, + WGPUFeatureName_BGRA8UnormStorage = 0x0000000B, + WGPUFeatureName_Float32Filterable = 0x0000000C, + WGPUFeatureName_DawnShaderFloat16 = 0x000003E9, + WGPUFeatureName_DawnInternalUsages = 0x000003EA, + WGPUFeatureName_DawnMultiPlanarFormats = 0x000003EB, + WGPUFeatureName_DawnNative = 0x000003EC, + WGPUFeatureName_ChromiumExperimentalDp4a = 0x000003ED, + WGPUFeatureName_TimestampQueryInsidePasses = 0x000003EE, + WGPUFeatureName_ImplicitDeviceSynchronization = 0x000003EF, + WGPUFeatureName_SurfaceCapabilities = 0x000003F0, + WGPUFeatureName_TransientAttachments = 0x000003F1, + WGPUFeatureName_MSAARenderToSingleSampled = 0x000003F2, + WGPUFeatureName_Force32 = 0x7FFFFFFF +} WGPUFeatureName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFilterMode { + WGPUFilterMode_Nearest = 0x00000000, + WGPUFilterMode_Linear = 0x00000001, + WGPUFilterMode_Force32 = 0x7FFFFFFF +} WGPUFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFrontFace { + WGPUFrontFace_CCW = 0x00000000, + WGPUFrontFace_CW = 0x00000001, + WGPUFrontFace_Force32 = 0x7FFFFFFF +} WGPUFrontFace WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUIndexFormat { + WGPUIndexFormat_Undefined = 0x00000000, + WGPUIndexFormat_Uint16 = 0x00000001, + WGPUIndexFormat_Uint32 = 0x00000002, + WGPUIndexFormat_Force32 = 0x7FFFFFFF +} WGPUIndexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPULoadOp { + WGPULoadOp_Undefined = 0x00000000, + WGPULoadOp_Clear = 0x00000001, + WGPULoadOp_Load = 0x00000002, + WGPULoadOp_Force32 = 0x7FFFFFFF +} WGPULoadOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPULoggingType { + WGPULoggingType_Verbose = 0x00000000, + WGPULoggingType_Info = 0x00000001, + WGPULoggingType_Warning = 0x00000002, + WGPULoggingType_Error = 0x00000003, + WGPULoggingType_Force32 = 0x7FFFFFFF +} WGPULoggingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMipmapFilterMode { + WGPUMipmapFilterMode_Nearest = 0x00000000, + WGPUMipmapFilterMode_Linear = 0x00000001, + WGPUMipmapFilterMode_Force32 = 0x7FFFFFFF +} WGPUMipmapFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPipelineStatisticName { + WGPUPipelineStatisticName_VertexShaderInvocations = 0x00000000, + WGPUPipelineStatisticName_ClipperInvocations = 0x00000001, + WGPUPipelineStatisticName_ClipperPrimitivesOut = 0x00000002, + WGPUPipelineStatisticName_FragmentShaderInvocations = 0x00000003, + WGPUPipelineStatisticName_ComputeShaderInvocations = 0x00000004, + WGPUPipelineStatisticName_Force32 = 0x7FFFFFFF +} WGPUPipelineStatisticName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPowerPreference { + WGPUPowerPreference_Undefined = 0x00000000, + WGPUPowerPreference_LowPower = 0x00000001, + WGPUPowerPreference_HighPerformance = 0x00000002, + WGPUPowerPreference_Force32 = 0x7FFFFFFF +} WGPUPowerPreference WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPresentMode { + WGPUPresentMode_Immediate = 0x00000000, + WGPUPresentMode_Mailbox = 0x00000001, + WGPUPresentMode_Fifo = 0x00000002, + WGPUPresentMode_Force32 = 0x7FFFFFFF +} WGPUPresentMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPrimitiveTopology { + WGPUPrimitiveTopology_PointList = 0x00000000, + WGPUPrimitiveTopology_LineList = 0x00000001, + WGPUPrimitiveTopology_LineStrip = 0x00000002, + WGPUPrimitiveTopology_TriangleList = 0x00000003, + WGPUPrimitiveTopology_TriangleStrip = 0x00000004, + WGPUPrimitiveTopology_Force32 = 0x7FFFFFFF +} WGPUPrimitiveTopology WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueryType { + WGPUQueryType_Occlusion = 0x00000000, + WGPUQueryType_PipelineStatistics = 0x00000001, + WGPUQueryType_Timestamp = 0x00000002, + WGPUQueryType_Force32 = 0x7FFFFFFF +} WGPUQueryType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueueWorkDoneStatus { + WGPUQueueWorkDoneStatus_Success = 0x00000000, + WGPUQueueWorkDoneStatus_Error = 0x00000001, + WGPUQueueWorkDoneStatus_Unknown = 0x00000002, + WGPUQueueWorkDoneStatus_DeviceLost = 0x00000003, + WGPUQueueWorkDoneStatus_Force32 = 0x7FFFFFFF +} WGPUQueueWorkDoneStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURenderPassTimestampLocation { + WGPURenderPassTimestampLocation_Beginning = 0x00000000, + WGPURenderPassTimestampLocation_End = 0x00000001, + WGPURenderPassTimestampLocation_Force32 = 0x7FFFFFFF +} WGPURenderPassTimestampLocation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestAdapterStatus { + WGPURequestAdapterStatus_Success = 0x00000000, + WGPURequestAdapterStatus_Unavailable = 0x00000001, + WGPURequestAdapterStatus_Error = 0x00000002, + WGPURequestAdapterStatus_Unknown = 0x00000003, + WGPURequestAdapterStatus_Force32 = 0x7FFFFFFF +} WGPURequestAdapterStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestDeviceStatus { + WGPURequestDeviceStatus_Success = 0x00000000, + WGPURequestDeviceStatus_Error = 0x00000001, + WGPURequestDeviceStatus_Unknown = 0x00000002, + WGPURequestDeviceStatus_Force32 = 0x7FFFFFFF +} WGPURequestDeviceStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSType { + WGPUSType_Invalid = 0x00000000, + WGPUSType_SurfaceDescriptorFromMetalLayer = 0x00000001, + WGPUSType_SurfaceDescriptorFromWindowsHWND = 0x00000002, + WGPUSType_SurfaceDescriptorFromXlibWindow = 0x00000003, + WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, + WGPUSType_ShaderModuleSPIRVDescriptor = 0x00000005, + WGPUSType_ShaderModuleWGSLDescriptor = 0x00000006, + WGPUSType_PrimitiveDepthClipControl = 0x00000007, + WGPUSType_SurfaceDescriptorFromWaylandSurface = 0x00000008, + WGPUSType_SurfaceDescriptorFromAndroidNativeWindow = 0x00000009, + WGPUSType_SurfaceDescriptorFromWindowsCoreWindow = 0x0000000B, + WGPUSType_ExternalTextureBindingEntry = 0x0000000C, + WGPUSType_ExternalTextureBindingLayout = 0x0000000D, + WGPUSType_SurfaceDescriptorFromWindowsSwapChainPanel = 0x0000000E, + WGPUSType_RenderPassDescriptorMaxDrawCount = 0x0000000F, + WGPUSType_DawnTextureInternalUsageDescriptor = 0x000003E8, + WGPUSType_DawnEncoderInternalUsageDescriptor = 0x000003EB, + WGPUSType_DawnInstanceDescriptor = 0x000003EC, + WGPUSType_DawnCacheDeviceDescriptor = 0x000003ED, + WGPUSType_DawnAdapterPropertiesPowerPreference = 0x000003EE, + WGPUSType_DawnBufferDescriptorErrorInfoFromWireClient = 0x000003EF, + WGPUSType_DawnTogglesDescriptor = 0x000003F0, + WGPUSType_DawnShaderModuleSPIRVOptionsDescriptor = 0x000003F1, + WGPUSType_RequestAdapterOptionsLUID = 0x000003F2, + WGPUSType_RequestAdapterOptionsGetGLProc = 0x000003F3, + WGPUSType_DawnMultisampleStateRenderToSingleSampled = 0x000003F4, + WGPUSType_DawnRenderPassColorAttachmentRenderToSingleSampled = 0x000003F5, + WGPUSType_Force32 = 0x7FFFFFFF +} WGPUSType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSamplerBindingType { + WGPUSamplerBindingType_Undefined = 0x00000000, + WGPUSamplerBindingType_Filtering = 0x00000001, + WGPUSamplerBindingType_NonFiltering = 0x00000002, + WGPUSamplerBindingType_Comparison = 0x00000003, + WGPUSamplerBindingType_Force32 = 0x7FFFFFFF +} WGPUSamplerBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStencilOperation { + WGPUStencilOperation_Keep = 0x00000000, + WGPUStencilOperation_Zero = 0x00000001, + WGPUStencilOperation_Replace = 0x00000002, + WGPUStencilOperation_Invert = 0x00000003, + WGPUStencilOperation_IncrementClamp = 0x00000004, + WGPUStencilOperation_DecrementClamp = 0x00000005, + WGPUStencilOperation_IncrementWrap = 0x00000006, + WGPUStencilOperation_DecrementWrap = 0x00000007, + WGPUStencilOperation_Force32 = 0x7FFFFFFF +} WGPUStencilOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStorageTextureAccess { + WGPUStorageTextureAccess_Undefined = 0x00000000, + WGPUStorageTextureAccess_WriteOnly = 0x00000001, + WGPUStorageTextureAccess_Force32 = 0x7FFFFFFF +} WGPUStorageTextureAccess WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStoreOp { + WGPUStoreOp_Undefined = 0x00000000, + WGPUStoreOp_Store = 0x00000001, + WGPUStoreOp_Discard = 0x00000002, + WGPUStoreOp_Force32 = 0x7FFFFFFF +} WGPUStoreOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureAspect { + WGPUTextureAspect_All = 0x00000000, + WGPUTextureAspect_StencilOnly = 0x00000001, + WGPUTextureAspect_DepthOnly = 0x00000002, + WGPUTextureAspect_Plane0Only = 0x00000003, + WGPUTextureAspect_Plane1Only = 0x00000004, + WGPUTextureAspect_Force32 = 0x7FFFFFFF +} WGPUTextureAspect WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureDimension { + WGPUTextureDimension_1D = 0x00000000, + WGPUTextureDimension_2D = 0x00000001, + WGPUTextureDimension_3D = 0x00000002, + WGPUTextureDimension_Force32 = 0x7FFFFFFF +} WGPUTextureDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureFormat { + WGPUTextureFormat_Undefined = 0x00000000, + WGPUTextureFormat_R8Unorm = 0x00000001, + WGPUTextureFormat_R8Snorm = 0x00000002, + WGPUTextureFormat_R8Uint = 0x00000003, + WGPUTextureFormat_R8Sint = 0x00000004, + WGPUTextureFormat_R16Uint = 0x00000005, + WGPUTextureFormat_R16Sint = 0x00000006, + WGPUTextureFormat_R16Float = 0x00000007, + WGPUTextureFormat_RG8Unorm = 0x00000008, + WGPUTextureFormat_RG8Snorm = 0x00000009, + WGPUTextureFormat_RG8Uint = 0x0000000A, + WGPUTextureFormat_RG8Sint = 0x0000000B, + WGPUTextureFormat_R32Float = 0x0000000C, + WGPUTextureFormat_R32Uint = 0x0000000D, + WGPUTextureFormat_R32Sint = 0x0000000E, + WGPUTextureFormat_RG16Uint = 0x0000000F, + WGPUTextureFormat_RG16Sint = 0x00000010, + WGPUTextureFormat_RG16Float = 0x00000011, + WGPUTextureFormat_RGBA8Unorm = 0x00000012, + WGPUTextureFormat_RGBA8UnormSrgb = 0x00000013, + WGPUTextureFormat_RGBA8Snorm = 0x00000014, + WGPUTextureFormat_RGBA8Uint = 0x00000015, + WGPUTextureFormat_RGBA8Sint = 0x00000016, + WGPUTextureFormat_BGRA8Unorm = 0x00000017, + WGPUTextureFormat_BGRA8UnormSrgb = 0x00000018, + WGPUTextureFormat_RGB10A2Unorm = 0x00000019, + WGPUTextureFormat_RG11B10Ufloat = 0x0000001A, + WGPUTextureFormat_RGB9E5Ufloat = 0x0000001B, + WGPUTextureFormat_RG32Float = 0x0000001C, + WGPUTextureFormat_RG32Uint = 0x0000001D, + WGPUTextureFormat_RG32Sint = 0x0000001E, + WGPUTextureFormat_RGBA16Uint = 0x0000001F, + WGPUTextureFormat_RGBA16Sint = 0x00000020, + WGPUTextureFormat_RGBA16Float = 0x00000021, + WGPUTextureFormat_RGBA32Float = 0x00000022, + WGPUTextureFormat_RGBA32Uint = 0x00000023, + WGPUTextureFormat_RGBA32Sint = 0x00000024, + WGPUTextureFormat_Stencil8 = 0x00000025, + WGPUTextureFormat_Depth16Unorm = 0x00000026, + WGPUTextureFormat_Depth24Plus = 0x00000027, + WGPUTextureFormat_Depth24PlusStencil8 = 0x00000028, + WGPUTextureFormat_Depth32Float = 0x00000029, + WGPUTextureFormat_Depth32FloatStencil8 = 0x0000002A, + WGPUTextureFormat_BC1RGBAUnorm = 0x0000002B, + WGPUTextureFormat_BC1RGBAUnormSrgb = 0x0000002C, + WGPUTextureFormat_BC2RGBAUnorm = 0x0000002D, + WGPUTextureFormat_BC2RGBAUnormSrgb = 0x0000002E, + WGPUTextureFormat_BC3RGBAUnorm = 0x0000002F, + WGPUTextureFormat_BC3RGBAUnormSrgb = 0x00000030, + WGPUTextureFormat_BC4RUnorm = 0x00000031, + WGPUTextureFormat_BC4RSnorm = 0x00000032, + WGPUTextureFormat_BC5RGUnorm = 0x00000033, + WGPUTextureFormat_BC5RGSnorm = 0x00000034, + WGPUTextureFormat_BC6HRGBUfloat = 0x00000035, + WGPUTextureFormat_BC6HRGBFloat = 0x00000036, + WGPUTextureFormat_BC7RGBAUnorm = 0x00000037, + WGPUTextureFormat_BC7RGBAUnormSrgb = 0x00000038, + WGPUTextureFormat_ETC2RGB8Unorm = 0x00000039, + WGPUTextureFormat_ETC2RGB8UnormSrgb = 0x0000003A, + WGPUTextureFormat_ETC2RGB8A1Unorm = 0x0000003B, + WGPUTextureFormat_ETC2RGB8A1UnormSrgb = 0x0000003C, + WGPUTextureFormat_ETC2RGBA8Unorm = 0x0000003D, + WGPUTextureFormat_ETC2RGBA8UnormSrgb = 0x0000003E, + WGPUTextureFormat_EACR11Unorm = 0x0000003F, + WGPUTextureFormat_EACR11Snorm = 0x00000040, + WGPUTextureFormat_EACRG11Unorm = 0x00000041, + WGPUTextureFormat_EACRG11Snorm = 0x00000042, + WGPUTextureFormat_ASTC4x4Unorm = 0x00000043, + WGPUTextureFormat_ASTC4x4UnormSrgb = 0x00000044, + WGPUTextureFormat_ASTC5x4Unorm = 0x00000045, + WGPUTextureFormat_ASTC5x4UnormSrgb = 0x00000046, + WGPUTextureFormat_ASTC5x5Unorm = 0x00000047, + WGPUTextureFormat_ASTC5x5UnormSrgb = 0x00000048, + WGPUTextureFormat_ASTC6x5Unorm = 0x00000049, + WGPUTextureFormat_ASTC6x5UnormSrgb = 0x0000004A, + WGPUTextureFormat_ASTC6x6Unorm = 0x0000004B, + WGPUTextureFormat_ASTC6x6UnormSrgb = 0x0000004C, + WGPUTextureFormat_ASTC8x5Unorm = 0x0000004D, + WGPUTextureFormat_ASTC8x5UnormSrgb = 0x0000004E, + WGPUTextureFormat_ASTC8x6Unorm = 0x0000004F, + WGPUTextureFormat_ASTC8x6UnormSrgb = 0x00000050, + WGPUTextureFormat_ASTC8x8Unorm = 0x00000051, + WGPUTextureFormat_ASTC8x8UnormSrgb = 0x00000052, + WGPUTextureFormat_ASTC10x5Unorm = 0x00000053, + WGPUTextureFormat_ASTC10x5UnormSrgb = 0x00000054, + WGPUTextureFormat_ASTC10x6Unorm = 0x00000055, + WGPUTextureFormat_ASTC10x6UnormSrgb = 0x00000056, + WGPUTextureFormat_ASTC10x8Unorm = 0x00000057, + WGPUTextureFormat_ASTC10x8UnormSrgb = 0x00000058, + WGPUTextureFormat_ASTC10x10Unorm = 0x00000059, + WGPUTextureFormat_ASTC10x10UnormSrgb = 0x0000005A, + WGPUTextureFormat_ASTC12x10Unorm = 0x0000005B, + WGPUTextureFormat_ASTC12x10UnormSrgb = 0x0000005C, + WGPUTextureFormat_ASTC12x12Unorm = 0x0000005D, + WGPUTextureFormat_ASTC12x12UnormSrgb = 0x0000005E, + WGPUTextureFormat_R8BG8Biplanar420Unorm = 0x0000005F, + WGPUTextureFormat_Force32 = 0x7FFFFFFF +} WGPUTextureFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureSampleType { + WGPUTextureSampleType_Undefined = 0x00000000, + WGPUTextureSampleType_Float = 0x00000001, + WGPUTextureSampleType_UnfilterableFloat = 0x00000002, + WGPUTextureSampleType_Depth = 0x00000003, + WGPUTextureSampleType_Sint = 0x00000004, + WGPUTextureSampleType_Uint = 0x00000005, + WGPUTextureSampleType_Force32 = 0x7FFFFFFF +} WGPUTextureSampleType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureViewDimension { + WGPUTextureViewDimension_Undefined = 0x00000000, + WGPUTextureViewDimension_1D = 0x00000001, + WGPUTextureViewDimension_2D = 0x00000002, + WGPUTextureViewDimension_2DArray = 0x00000003, + WGPUTextureViewDimension_Cube = 0x00000004, + WGPUTextureViewDimension_CubeArray = 0x00000005, + WGPUTextureViewDimension_3D = 0x00000006, + WGPUTextureViewDimension_Force32 = 0x7FFFFFFF +} WGPUTextureViewDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexFormat { + WGPUVertexFormat_Undefined = 0x00000000, + WGPUVertexFormat_Uint8x2 = 0x00000001, + WGPUVertexFormat_Uint8x4 = 0x00000002, + WGPUVertexFormat_Sint8x2 = 0x00000003, + WGPUVertexFormat_Sint8x4 = 0x00000004, + WGPUVertexFormat_Unorm8x2 = 0x00000005, + WGPUVertexFormat_Unorm8x4 = 0x00000006, + WGPUVertexFormat_Snorm8x2 = 0x00000007, + WGPUVertexFormat_Snorm8x4 = 0x00000008, + WGPUVertexFormat_Uint16x2 = 0x00000009, + WGPUVertexFormat_Uint16x4 = 0x0000000A, + WGPUVertexFormat_Sint16x2 = 0x0000000B, + WGPUVertexFormat_Sint16x4 = 0x0000000C, + WGPUVertexFormat_Unorm16x2 = 0x0000000D, + WGPUVertexFormat_Unorm16x4 = 0x0000000E, + WGPUVertexFormat_Snorm16x2 = 0x0000000F, + WGPUVertexFormat_Snorm16x4 = 0x00000010, + WGPUVertexFormat_Float16x2 = 0x00000011, + WGPUVertexFormat_Float16x4 = 0x00000012, + WGPUVertexFormat_Float32 = 0x00000013, + WGPUVertexFormat_Float32x2 = 0x00000014, + WGPUVertexFormat_Float32x3 = 0x00000015, + WGPUVertexFormat_Float32x4 = 0x00000016, + WGPUVertexFormat_Uint32 = 0x00000017, + WGPUVertexFormat_Uint32x2 = 0x00000018, + WGPUVertexFormat_Uint32x3 = 0x00000019, + WGPUVertexFormat_Uint32x4 = 0x0000001A, + WGPUVertexFormat_Sint32 = 0x0000001B, + WGPUVertexFormat_Sint32x2 = 0x0000001C, + WGPUVertexFormat_Sint32x3 = 0x0000001D, + WGPUVertexFormat_Sint32x4 = 0x0000001E, + WGPUVertexFormat_Force32 = 0x7FFFFFFF +} WGPUVertexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexStepMode { + WGPUVertexStepMode_Vertex = 0x00000000, + WGPUVertexStepMode_Instance = 0x00000001, + WGPUVertexStepMode_VertexBufferNotUsed = 0x00000002, + WGPUVertexStepMode_Force32 = 0x7FFFFFFF +} WGPUVertexStepMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferUsage { + WGPUBufferUsage_None = 0x00000000, + WGPUBufferUsage_MapRead = 0x00000001, + WGPUBufferUsage_MapWrite = 0x00000002, + WGPUBufferUsage_CopySrc = 0x00000004, + WGPUBufferUsage_CopyDst = 0x00000008, + WGPUBufferUsage_Index = 0x00000010, + WGPUBufferUsage_Vertex = 0x00000020, + WGPUBufferUsage_Uniform = 0x00000040, + WGPUBufferUsage_Storage = 0x00000080, + WGPUBufferUsage_Indirect = 0x00000100, + WGPUBufferUsage_QueryResolve = 0x00000200, + WGPUBufferUsage_Force32 = 0x7FFFFFFF +} WGPUBufferUsage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUBufferUsageFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUColorWriteMask { + WGPUColorWriteMask_None = 0x00000000, + WGPUColorWriteMask_Red = 0x00000001, + WGPUColorWriteMask_Green = 0x00000002, + WGPUColorWriteMask_Blue = 0x00000004, + WGPUColorWriteMask_Alpha = 0x00000008, + WGPUColorWriteMask_All = 0x0000000F, + WGPUColorWriteMask_Force32 = 0x7FFFFFFF +} WGPUColorWriteMask WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUColorWriteMaskFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMapMode { + WGPUMapMode_None = 0x00000000, + WGPUMapMode_Read = 0x00000001, + WGPUMapMode_Write = 0x00000002, + WGPUMapMode_Force32 = 0x7FFFFFFF +} WGPUMapMode WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUMapModeFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUShaderStage { + WGPUShaderStage_None = 0x00000000, + WGPUShaderStage_Vertex = 0x00000001, + WGPUShaderStage_Fragment = 0x00000002, + WGPUShaderStage_Compute = 0x00000004, + WGPUShaderStage_Force32 = 0x7FFFFFFF +} WGPUShaderStage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUShaderStageFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureUsage { + WGPUTextureUsage_None = 0x00000000, + WGPUTextureUsage_CopySrc = 0x00000001, + WGPUTextureUsage_CopyDst = 0x00000002, + WGPUTextureUsage_TextureBinding = 0x00000004, + WGPUTextureUsage_StorageBinding = 0x00000008, + WGPUTextureUsage_RenderAttachment = 0x00000010, + WGPUTextureUsage_TransientAttachment = 0x00000020, + WGPUTextureUsage_Force32 = 0x7FFFFFFF +} WGPUTextureUsage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUTextureUsageFlags WGPU_ENUM_ATTRIBUTE; + +typedef void (*WGPUBufferMapCallback)(WGPUBufferMapAsyncStatus status, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCompilationInfoCallback)(WGPUCompilationInfoRequestStatus status, struct WGPUCompilationInfo const * compilationInfo, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCreateComputePipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCreateRenderPipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUDeviceLostCallback)(WGPUDeviceLostReason reason, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUErrorCallback)(WGPUErrorType type, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPULoggingCallback)(WGPULoggingType type, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProc)(void) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPURequestAdapterCallback)(WGPURequestAdapterStatus status, WGPUAdapter adapter, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPURequestDeviceCallback)(WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; + +typedef struct WGPUChainedStruct { + struct WGPUChainedStruct const * next; + WGPUSType sType; +} WGPUChainedStruct WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUChainedStructOut { + struct WGPUChainedStructOut * next; + WGPUSType sType; +} WGPUChainedStructOut WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUAdapterProperties { + WGPUChainedStructOut * nextInChain; + uint32_t vendorID; + char const * vendorName; + char const * architecture; + uint32_t deviceID; + char const * name; + char const * driverDescription; + WGPUAdapterType adapterType; + WGPUBackendType backendType; + bool compatibilityMode; +} WGPUAdapterProperties WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupEntry { + WGPUChainedStruct const * nextInChain; + uint32_t binding; + WGPU_NULLABLE WGPUBuffer buffer; + uint64_t offset; + uint64_t size; + WGPU_NULLABLE WGPUSampler sampler; + WGPU_NULLABLE WGPUTextureView textureView; +} WGPUBindGroupEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBlendComponent { + WGPUBlendOperation operation; + WGPUBlendFactor srcFactor; + WGPUBlendFactor dstFactor; +} WGPUBlendComponent WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBufferBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUBufferBindingType type; + bool hasDynamicOffset; + uint64_t minBindingSize; +} WGPUBufferBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBufferDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUBufferUsageFlags usage; + uint64_t size; + bool mappedAtCreation; +} WGPUBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUColor { + double r; + double g; + double b; + double a; +} WGPUColor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCommandBufferDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUCommandBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCommandEncoderDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUCommandEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCompilationMessage { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * message; + WGPUCompilationMessageType type; + uint64_t lineNum; + uint64_t linePos; + uint64_t offset; + uint64_t length; + uint64_t utf16LinePos; + uint64_t utf16Offset; + uint64_t utf16Length; +} WGPUCompilationMessage WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePassTimestampWrite { + WGPUQuerySet querySet; + uint32_t queryIndex; + WGPUComputePassTimestampLocation location; +} WGPUComputePassTimestampWrite WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUConstantEntry { + WGPUChainedStruct const * nextInChain; + char const * key; + double value; +} WGPUConstantEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCopyTextureForBrowserOptions { + WGPUChainedStruct const * nextInChain; + bool flipY; + bool needsColorSpaceConversion; + WGPUAlphaMode srcAlphaMode; + WGPU_NULLABLE float const * srcTransferFunctionParameters; + WGPU_NULLABLE float const * conversionMatrix; + WGPU_NULLABLE float const * dstTransferFunctionParameters; + WGPUAlphaMode dstAlphaMode; + bool internalUsage; +} WGPUCopyTextureForBrowserOptions WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUAdapterProperties +typedef struct WGPUDawnAdapterPropertiesPowerPreference { + WGPUChainedStructOut chain; + WGPUPowerPreference powerPreference; +} WGPUDawnAdapterPropertiesPowerPreference WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUBufferDescriptor +typedef struct WGPUDawnBufferDescriptorErrorInfoFromWireClient { + WGPUChainedStruct chain; + bool outOfMemory; +} WGPUDawnBufferDescriptorErrorInfoFromWireClient WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUDeviceDescriptor +typedef struct WGPUDawnCacheDeviceDescriptor { + WGPUChainedStruct chain; + char const * isolationKey; +} WGPUDawnCacheDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUCommandEncoderDescriptor +typedef struct WGPUDawnEncoderInternalUsageDescriptor { + WGPUChainedStruct chain; + bool useInternalUsages; +} WGPUDawnEncoderInternalUsageDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUMultisampleState +typedef struct WGPUDawnMultisampleStateRenderToSingleSampled { + WGPUChainedStruct chain; + bool enabled; +} WGPUDawnMultisampleStateRenderToSingleSampled WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPURenderPassColorAttachment +typedef struct WGPUDawnRenderPassColorAttachmentRenderToSingleSampled { + WGPUChainedStruct chain; + uint32_t implicitSampleCount; +} WGPUDawnRenderPassColorAttachmentRenderToSingleSampled WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUDawnShaderModuleSPIRVOptionsDescriptor { + WGPUChainedStruct chain; + bool allowNonUniformDerivatives; +} WGPUDawnShaderModuleSPIRVOptionsDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUTextureDescriptor +typedef struct WGPUDawnTextureInternalUsageDescriptor { + WGPUChainedStruct chain; + WGPUTextureUsageFlags internalUsage; +} WGPUDawnTextureInternalUsageDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUInstanceDescriptor +// Can be chained in WGPURequestAdapterOptions +// Can be chained in WGPUDeviceDescriptor +typedef struct WGPUDawnTogglesDescriptor { + WGPUChainedStruct chain; + size_t enabledTogglesCount; + const char* const * enabledToggles; + size_t disabledTogglesCount; + const char* const * disabledToggles; +} WGPUDawnTogglesDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUExtent2D { + uint32_t width; + uint32_t height; +} WGPUExtent2D WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUExtent3D { + uint32_t width; + uint32_t height; + uint32_t depthOrArrayLayers; +} WGPUExtent3D WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUBindGroupEntry +typedef struct WGPUExternalTextureBindingEntry { + WGPUChainedStruct chain; + WGPUExternalTexture externalTexture; +} WGPUExternalTextureBindingEntry WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUBindGroupLayoutEntry +typedef struct WGPUExternalTextureBindingLayout { + WGPUChainedStruct chain; +} WGPUExternalTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUInstanceDescriptor { + WGPUChainedStruct const * nextInChain; +} WGPUInstanceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPULimits { + uint32_t maxTextureDimension1D; + uint32_t maxTextureDimension2D; + uint32_t maxTextureDimension3D; + uint32_t maxTextureArrayLayers; + uint32_t maxBindGroups; + uint32_t maxBindGroupsPlusVertexBuffers; + uint32_t maxBindingsPerBindGroup; + uint32_t maxDynamicUniformBuffersPerPipelineLayout; + uint32_t maxDynamicStorageBuffersPerPipelineLayout; + uint32_t maxSampledTexturesPerShaderStage; + uint32_t maxSamplersPerShaderStage; + uint32_t maxStorageBuffersPerShaderStage; + uint32_t maxStorageTexturesPerShaderStage; + uint32_t maxUniformBuffersPerShaderStage; + uint64_t maxUniformBufferBindingSize; + uint64_t maxStorageBufferBindingSize; + uint32_t minUniformBufferOffsetAlignment; + uint32_t minStorageBufferOffsetAlignment; + uint32_t maxVertexBuffers; + uint64_t maxBufferSize; + uint32_t maxVertexAttributes; + uint32_t maxVertexBufferArrayStride; + uint32_t maxInterStageShaderComponents; + uint32_t maxInterStageShaderVariables; + uint32_t maxColorAttachments; + uint32_t maxColorAttachmentBytesPerSample; + uint32_t maxComputeWorkgroupStorageSize; + uint32_t maxComputeInvocationsPerWorkgroup; + uint32_t maxComputeWorkgroupSizeX; + uint32_t maxComputeWorkgroupSizeY; + uint32_t maxComputeWorkgroupSizeZ; + uint32_t maxComputeWorkgroupsPerDimension; +} WGPULimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUMultisampleState { + WGPUChainedStruct const * nextInChain; + uint32_t count; + uint32_t mask; + bool alphaToCoverageEnabled; +} WGPUMultisampleState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUOrigin2D { + uint32_t x; + uint32_t y; +} WGPUOrigin2D WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUOrigin3D { + uint32_t x; + uint32_t y; + uint32_t z; +} WGPUOrigin3D WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUPipelineLayoutDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t bindGroupLayoutCount; + WGPUBindGroupLayout const * bindGroupLayouts; +} WGPUPipelineLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUPrimitiveState +typedef struct WGPUPrimitiveDepthClipControl { + WGPUChainedStruct chain; + bool unclippedDepth; +} WGPUPrimitiveDepthClipControl WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUPrimitiveState { + WGPUChainedStruct const * nextInChain; + WGPUPrimitiveTopology topology; + WGPUIndexFormat stripIndexFormat; + WGPUFrontFace frontFace; + WGPUCullMode cullMode; +} WGPUPrimitiveState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUQuerySetDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUQueryType type; + uint32_t count; + WGPUPipelineStatisticName const * pipelineStatistics; + size_t pipelineStatisticsCount; +} WGPUQuerySetDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUQueueDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUQueueDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderBundleDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPURenderBundleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderBundleEncoderDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t colorFormatsCount; + WGPUTextureFormat const * colorFormats; + WGPUTextureFormat depthStencilFormat; + uint32_t sampleCount; + bool depthReadOnly; + bool stencilReadOnly; +} WGPURenderBundleEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassDepthStencilAttachment { + WGPUTextureView view; + WGPULoadOp depthLoadOp; + WGPUStoreOp depthStoreOp; + float depthClearValue; + bool depthReadOnly; + WGPULoadOp stencilLoadOp; + WGPUStoreOp stencilStoreOp; + uint32_t stencilClearValue; + bool stencilReadOnly; +} WGPURenderPassDepthStencilAttachment WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPURenderPassDescriptor +typedef struct WGPURenderPassDescriptorMaxDrawCount { + WGPUChainedStruct chain; + uint64_t maxDrawCount; +} WGPURenderPassDescriptorMaxDrawCount WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassTimestampWrite { + WGPUQuerySet querySet; + uint32_t queryIndex; + WGPURenderPassTimestampLocation location; +} WGPURenderPassTimestampWrite WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURequestAdapterOptions { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE WGPUSurface compatibleSurface; + WGPUPowerPreference powerPreference; + WGPUBackendType backendType; + bool forceFallbackAdapter; + bool compatibilityMode; +} WGPURequestAdapterOptions WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSamplerBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUSamplerBindingType type; +} WGPUSamplerBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSamplerDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUAddressMode addressModeU; + WGPUAddressMode addressModeV; + WGPUAddressMode addressModeW; + WGPUFilterMode magFilter; + WGPUFilterMode minFilter; + WGPUMipmapFilterMode mipmapFilter; + float lodMinClamp; + float lodMaxClamp; + WGPUCompareFunction compare; + uint16_t maxAnisotropy; +} WGPUSamplerDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUShaderModuleDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUShaderModuleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderModuleSPIRVDescriptor { + WGPUChainedStruct chain; + uint32_t codeSize; + uint32_t const * code; +} WGPUShaderModuleSPIRVDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderModuleWGSLDescriptor { + WGPUChainedStruct chain; + char const * code; +} WGPUShaderModuleWGSLDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUStencilFaceState { + WGPUCompareFunction compare; + WGPUStencilOperation failOp; + WGPUStencilOperation depthFailOp; + WGPUStencilOperation passOp; +} WGPUStencilFaceState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUStorageTextureBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUStorageTextureAccess access; + WGPUTextureFormat format; + WGPUTextureViewDimension viewDimension; +} WGPUStorageTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUSurfaceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromAndroidNativeWindow { + WGPUChainedStruct chain; + void * window; +} WGPUSurfaceDescriptorFromAndroidNativeWindow WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromCanvasHTMLSelector { + WGPUChainedStruct chain; + char const * selector; +} WGPUSurfaceDescriptorFromCanvasHTMLSelector WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromMetalLayer { + WGPUChainedStruct chain; + void * layer; +} WGPUSurfaceDescriptorFromMetalLayer WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWaylandSurface { + WGPUChainedStruct chain; + void * display; + void * surface; +} WGPUSurfaceDescriptorFromWaylandSurface WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWindowsCoreWindow { + WGPUChainedStruct chain; + void * coreWindow; +} WGPUSurfaceDescriptorFromWindowsCoreWindow WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWindowsHWND { + WGPUChainedStruct chain; + void * hinstance; + void * hwnd; +} WGPUSurfaceDescriptorFromWindowsHWND WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWindowsSwapChainPanel { + WGPUChainedStruct chain; + void * swapChainPanel; +} WGPUSurfaceDescriptorFromWindowsSwapChainPanel WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromXlibWindow { + WGPUChainedStruct chain; + void * display; + uint32_t window; +} WGPUSurfaceDescriptorFromXlibWindow WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSwapChainDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureUsageFlags usage; + WGPUTextureFormat format; + uint32_t width; + uint32_t height; + WGPUPresentMode presentMode; +} WGPUSwapChainDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUTextureSampleType sampleType; + WGPUTextureViewDimension viewDimension; + bool multisampled; +} WGPUTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureDataLayout { + WGPUChainedStruct const * nextInChain; + uint64_t offset; + uint32_t bytesPerRow; + uint32_t rowsPerImage; +} WGPUTextureDataLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureViewDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureFormat format; + WGPUTextureViewDimension dimension; + uint32_t baseMipLevel; + uint32_t mipLevelCount; + uint32_t baseArrayLayer; + uint32_t arrayLayerCount; + WGPUTextureAspect aspect; +} WGPUTextureViewDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexAttribute { + WGPUVertexFormat format; + uint64_t offset; + uint32_t shaderLocation; +} WGPUVertexAttribute WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUBindGroupLayout layout; + size_t entryCount; + WGPUBindGroupEntry const * entries; +} WGPUBindGroupDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupLayoutEntry { + WGPUChainedStruct const * nextInChain; + uint32_t binding; + WGPUShaderStageFlags visibility; + WGPUBufferBindingLayout buffer; + WGPUSamplerBindingLayout sampler; + WGPUTextureBindingLayout texture; + WGPUStorageTextureBindingLayout storageTexture; +} WGPUBindGroupLayoutEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBlendState { + WGPUBlendComponent color; + WGPUBlendComponent alpha; +} WGPUBlendState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCompilationInfo { + WGPUChainedStruct const * nextInChain; + size_t messageCount; + WGPUCompilationMessage const * messages; +} WGPUCompilationInfo WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePassDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t timestampWriteCount; + WGPUComputePassTimestampWrite const * timestampWrites; +} WGPUComputePassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUDepthStencilState { + WGPUChainedStruct const * nextInChain; + WGPUTextureFormat format; + bool depthWriteEnabled; + WGPUCompareFunction depthCompare; + WGPUStencilFaceState stencilFront; + WGPUStencilFaceState stencilBack; + uint32_t stencilReadMask; + uint32_t stencilWriteMask; + int32_t depthBias; + float depthBiasSlopeScale; + float depthBiasClamp; +} WGPUDepthStencilState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUExternalTextureDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureView plane0; + WGPU_NULLABLE WGPUTextureView plane1; + WGPUOrigin2D visibleOrigin; + WGPUExtent2D visibleSize; + bool doYuvToRgbConversionOnly; + WGPU_NULLABLE float const * yuvToRgbConversionMatrix; + float const * srcTransferFunctionParameters; + float const * dstTransferFunctionParameters; + float const * gamutConversionMatrix; + bool flipY; + WGPUExternalTextureRotation rotation; +} WGPUExternalTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUImageCopyBuffer { + WGPUChainedStruct const * nextInChain; + WGPUTextureDataLayout layout; + WGPUBuffer buffer; +} WGPUImageCopyBuffer WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUImageCopyExternalTexture { + WGPUChainedStruct const * nextInChain; + WGPUExternalTexture externalTexture; + WGPUOrigin3D origin; + WGPUExtent2D naturalSize; +} WGPUImageCopyExternalTexture WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUImageCopyTexture { + WGPUChainedStruct const * nextInChain; + WGPUTexture texture; + uint32_t mipLevel; + WGPUOrigin3D origin; + WGPUTextureAspect aspect; +} WGPUImageCopyTexture WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUProgrammableStageDescriptor { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; +} WGPUProgrammableStageDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassColorAttachment { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE WGPUTextureView view; + WGPU_NULLABLE WGPUTextureView resolveTarget; + WGPULoadOp loadOp; + WGPUStoreOp storeOp; + WGPUColor clearValue; +} WGPURenderPassColorAttachment WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURequiredLimits { + WGPUChainedStruct const * nextInChain; + WGPULimits limits; +} WGPURequiredLimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSupportedLimits { + WGPUChainedStructOut * nextInChain; + WGPULimits limits; +} WGPUSupportedLimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureUsageFlags usage; + WGPUTextureDimension dimension; + WGPUExtent3D size; + WGPUTextureFormat format; + uint32_t mipLevelCount; + uint32_t sampleCount; + size_t viewFormatCount; + WGPUTextureFormat const * viewFormats; +} WGPUTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexBufferLayout { + uint64_t arrayStride; + WGPUVertexStepMode stepMode; + size_t attributeCount; + WGPUVertexAttribute const * attributes; +} WGPUVertexBufferLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupLayoutDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t entryCount; + WGPUBindGroupLayoutEntry const * entries; +} WGPUBindGroupLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUColorTargetState { + WGPUChainedStruct const * nextInChain; + WGPUTextureFormat format; + WGPU_NULLABLE WGPUBlendState const * blend; + WGPUColorWriteMaskFlags writeMask; +} WGPUColorTargetState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePipelineDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUProgrammableStageDescriptor compute; +} WGPUComputePipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUDeviceDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t requiredFeaturesCount; + WGPUFeatureName const * requiredFeatures; + WGPU_NULLABLE WGPURequiredLimits const * requiredLimits; + WGPUQueueDescriptor defaultQueue; + WGPUDeviceLostCallback deviceLostCallback; + void * deviceLostUserdata; +} WGPUDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t colorAttachmentCount; + WGPURenderPassColorAttachment const * colorAttachments; + WGPU_NULLABLE WGPURenderPassDepthStencilAttachment const * depthStencilAttachment; + WGPU_NULLABLE WGPUQuerySet occlusionQuerySet; + size_t timestampWriteCount; + WGPURenderPassTimestampWrite const * timestampWrites; +} WGPURenderPassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexState { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t bufferCount; + WGPUVertexBufferLayout const * buffers; +} WGPUVertexState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUFragmentState { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t targetCount; + WGPUColorTargetState const * targets; +} WGPUFragmentState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPipelineDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUVertexState vertex; + WGPUPrimitiveState primitive; + WGPU_NULLABLE WGPUDepthStencilState const * depthStencil; + WGPUMultisampleState multisample; + WGPU_NULLABLE WGPUFragmentState const * fragment; +} WGPURenderPipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(WGPU_SKIP_PROCS) + +typedef WGPUInstance (*WGPUProcCreateInstance)(WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Adapter +typedef WGPUDevice (*WGPUProcAdapterCreateDevice)(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef size_t (*WGPUProcAdapterEnumerateFeatures)(WGPUAdapter adapter, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUInstance (*WGPUProcAdapterGetInstance)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +typedef bool (*WGPUProcAdapterGetLimits)(WGPUAdapter adapter, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterGetProperties)(WGPUAdapter adapter, WGPUAdapterProperties * properties) WGPU_FUNCTION_ATTRIBUTE; +typedef bool (*WGPUProcAdapterHasFeature)(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterRequestDevice)(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterReference)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterRelease)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroup +typedef void (*WGPUProcBindGroupSetLabel)(WGPUBindGroup bindGroup, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupReference)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupRelease)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroupLayout +typedef void (*WGPUProcBindGroupLayoutSetLabel)(WGPUBindGroupLayout bindGroupLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutReference)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutRelease)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Buffer +typedef void (*WGPUProcBufferDestroy)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void const * (*WGPUProcBufferGetConstMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferMapState (*WGPUProcBufferGetMapState)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void * (*WGPUProcBufferGetMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef uint64_t (*WGPUProcBufferGetSize)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferUsageFlags (*WGPUProcBufferGetUsage)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferMapAsync)(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferSetLabel)(WGPUBuffer buffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferUnmap)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferReference)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferRelease)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandBuffer +typedef void (*WGPUProcCommandBufferSetLabel)(WGPUCommandBuffer commandBuffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferReference)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferRelease)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandEncoder +typedef WGPUComputePassEncoder (*WGPUProcCommandEncoderBeginComputePass)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPassEncoder (*WGPUProcCommandEncoderBeginRenderPass)(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderClearBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToTexture)(WGPUCommandEncoder commandEncoder, WGPUImageCopyBuffer const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToBuffer)(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyBuffer const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToTexture)(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToTextureInternal)(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandBuffer (*WGPUProcCommandEncoderFinish)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderInjectValidationError)(WGPUCommandEncoder commandEncoder, char const * message) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderInsertDebugMarker)(WGPUCommandEncoder commandEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPopDebugGroup)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPushDebugGroup)(WGPUCommandEncoder commandEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderResolveQuerySet)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderSetLabel)(WGPUCommandEncoder commandEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderWriteBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderWriteTimestamp)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderReference)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderRelease)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePassEncoder +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroups)(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroupsIndirect)(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderEnd)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderInsertDebugMarker)(WGPUComputePassEncoder computePassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPopDebugGroup)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPushDebugGroup)(WGPUComputePassEncoder computePassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetBindGroup)(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetLabel)(WGPUComputePassEncoder computePassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetPipeline)(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderWriteTimestamp)(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderReference)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderRelease)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePipeline +typedef WGPUBindGroupLayout (*WGPUProcComputePipelineGetBindGroupLayout)(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineSetLabel)(WGPUComputePipeline computePipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineReference)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineRelease)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Device +typedef WGPUBindGroup (*WGPUProcDeviceCreateBindGroup)(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBindGroupLayout (*WGPUProcDeviceCreateBindGroupLayout)(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBuffer (*WGPUProcDeviceCreateBuffer)(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandEncoder (*WGPUProcDeviceCreateCommandEncoder)(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUComputePipeline (*WGPUProcDeviceCreateComputePipeline)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceCreateComputePipelineAsync)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBuffer (*WGPUProcDeviceCreateErrorBuffer)(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUExternalTexture (*WGPUProcDeviceCreateErrorExternalTexture)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUShaderModule (*WGPUProcDeviceCreateErrorShaderModule)(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, char const * errorMessage) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTexture (*WGPUProcDeviceCreateErrorTexture)(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUExternalTexture (*WGPUProcDeviceCreateExternalTexture)(WGPUDevice device, WGPUExternalTextureDescriptor const * externalTextureDescriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUPipelineLayout (*WGPUProcDeviceCreatePipelineLayout)(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQuerySet (*WGPUProcDeviceCreateQuerySet)(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundleEncoder (*WGPUProcDeviceCreateRenderBundleEncoder)(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPipeline (*WGPUProcDeviceCreateRenderPipeline)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceCreateRenderPipelineAsync)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUSampler (*WGPUProcDeviceCreateSampler)(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUShaderModule (*WGPUProcDeviceCreateShaderModule)(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUSwapChain (*WGPUProcDeviceCreateSwapChain)(WGPUDevice device, WGPUSurface surface, WGPUSwapChainDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTexture (*WGPUProcDeviceCreateTexture)(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceDestroy)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef size_t (*WGPUProcDeviceEnumerateFeatures)(WGPUDevice device, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceForceLoss)(WGPUDevice device, WGPUDeviceLostReason type, char const * message) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUAdapter (*WGPUProcDeviceGetAdapter)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef bool (*WGPUProcDeviceGetLimits)(WGPUDevice device, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueue (*WGPUProcDeviceGetQueue)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureUsageFlags (*WGPUProcDeviceGetSupportedSurfaceUsage)(WGPUDevice device, WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef bool (*WGPUProcDeviceHasFeature)(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceInjectError)(WGPUDevice device, WGPUErrorType type, char const * message) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDevicePopErrorScope)(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDevicePushErrorScope)(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetDeviceLostCallback)(WGPUDevice device, WGPUDeviceLostCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetLabel)(WGPUDevice device, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetLoggingCallback)(WGPUDevice device, WGPULoggingCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetUncapturedErrorCallback)(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceTick)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceValidateTextureDescriptor)(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceReference)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceRelease)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ExternalTexture +typedef void (*WGPUProcExternalTextureDestroy)(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcExternalTextureExpire)(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcExternalTextureRefresh)(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcExternalTextureSetLabel)(WGPUExternalTexture externalTexture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcExternalTextureReference)(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcExternalTextureRelease)(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Instance +typedef WGPUSurface (*WGPUProcInstanceCreateSurface)(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceProcessEvents)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceRequestAdapter)(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceReference)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceRelease)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of PipelineLayout +typedef void (*WGPUProcPipelineLayoutSetLabel)(WGPUPipelineLayout pipelineLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutReference)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutRelease)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of QuerySet +typedef void (*WGPUProcQuerySetDestroy)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcQuerySetGetCount)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueryType (*WGPUProcQuerySetGetType)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetSetLabel)(WGPUQuerySet querySet, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetReference)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetRelease)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Queue +typedef void (*WGPUProcQueueCopyExternalTextureForBrowser)(WGPUQueue queue, WGPUImageCopyExternalTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueCopyTextureForBrowser)(WGPUQueue queue, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueOnSubmittedWorkDone)(WGPUQueue queue, uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSetLabel)(WGPUQueue queue, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSubmit)(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteBuffer)(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteTexture)(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueReference)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueRelease)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundle +typedef void (*WGPUProcRenderBundleSetLabel)(WGPURenderBundle renderBundle, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleReference)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleRelease)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundleEncoder +typedef void (*WGPUProcRenderBundleEncoderDraw)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexed)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexedIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundle (*WGPUProcRenderBundleEncoderFinish)(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderInsertDebugMarker)(WGPURenderBundleEncoder renderBundleEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPopDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPushDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetBindGroup)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetIndexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetLabel)(WGPURenderBundleEncoder renderBundleEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetPipeline)(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetVertexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderReference)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderRelease)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPassEncoder +typedef void (*WGPUProcRenderPassEncoderBeginOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDraw)(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexed)(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexedIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEnd)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEndOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderExecuteBundles)(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderInsertDebugMarker)(WGPURenderPassEncoder renderPassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPopDebugGroup)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPushDebugGroup)(WGPURenderPassEncoder renderPassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBindGroup)(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBlendConstant)(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetIndexBuffer)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetLabel)(WGPURenderPassEncoder renderPassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetPipeline)(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetScissorRect)(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetStencilReference)(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetVertexBuffer)(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetViewport)(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderWriteTimestamp)(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderReference)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderRelease)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPipeline +typedef WGPUBindGroupLayout (*WGPUProcRenderPipelineGetBindGroupLayout)(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineSetLabel)(WGPURenderPipeline renderPipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineReference)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineRelease)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Sampler +typedef void (*WGPUProcSamplerSetLabel)(WGPUSampler sampler, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerReference)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerRelease)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ShaderModule +typedef void (*WGPUProcShaderModuleGetCompilationInfo)(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleSetLabel)(WGPUShaderModule shaderModule, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleReference)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleRelease)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Surface +typedef void (*WGPUProcSurfaceReference)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceRelease)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SwapChain +typedef WGPUTexture (*WGPUProcSwapChainGetCurrentTexture)(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureView (*WGPUProcSwapChainGetCurrentTextureView)(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSwapChainPresent)(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSwapChainReference)(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSwapChainRelease)(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Texture +typedef WGPUTextureView (*WGPUProcTextureCreateView)(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureDestroy)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetDepthOrArrayLayers)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureDimension (*WGPUProcTextureGetDimension)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureFormat (*WGPUProcTextureGetFormat)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetHeight)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetMipLevelCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetSampleCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureUsageFlags (*WGPUProcTextureGetUsage)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetWidth)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureSetLabel)(WGPUTexture texture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureReference)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureRelease)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of TextureView +typedef void (*WGPUProcTextureViewSetLabel)(WGPUTextureView textureView, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewReference)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewRelease)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_PROCS) + +#if !defined(WGPU_SKIP_DECLARATIONS) + +WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Adapter +WGPU_EXPORT WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT size_t wgpuAdapterEnumerateFeatures(WGPUAdapter adapter, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUInstance wgpuAdapterGetInstance(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT bool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterGetProperties(WGPUAdapter adapter, WGPUAdapterProperties * properties) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT bool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterReference(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterRelease(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroup +WGPU_EXPORT void wgpuBindGroupSetLabel(WGPUBindGroup bindGroup, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupReference(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupRelease(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroupLayout +WGPU_EXPORT void wgpuBindGroupLayoutSetLabel(WGPUBindGroupLayout bindGroupLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutReference(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutRelease(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Buffer +WGPU_EXPORT void wgpuBufferDestroy(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferMapState wgpuBufferGetMapState(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint64_t wgpuBufferGetSize(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferUsageFlags wgpuBufferGetUsage(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferSetLabel(WGPUBuffer buffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferUnmap(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferReference(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferRelease(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandBuffer +WGPU_EXPORT void wgpuCommandBufferSetLabel(WGPUCommandBuffer commandBuffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferReference(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferRelease(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandEncoder +WGPU_EXPORT WGPUComputePassEncoder wgpuCommandEncoderBeginComputePass(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPassEncoder wgpuCommandEncoderBeginRenderPass(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderClearBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyBuffer const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToBuffer(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyBuffer const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToTextureInternal(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandBuffer wgpuCommandEncoderFinish(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderInjectValidationError(WGPUCommandEncoder commandEncoder, char const * message) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderInsertDebugMarker(WGPUCommandEncoder commandEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPopDebugGroup(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPushDebugGroup(WGPUCommandEncoder commandEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderResolveQuerySet(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderSetLabel(WGPUCommandEncoder commandEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderWriteBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderWriteTimestamp(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderReference(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderRelease(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePassEncoder +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroups(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroupsIndirect(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderEnd(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderInsertDebugMarker(WGPUComputePassEncoder computePassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPopDebugGroup(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPushDebugGroup(WGPUComputePassEncoder computePassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetBindGroup(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetLabel(WGPUComputePassEncoder computePassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetPipeline(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderWriteTimestamp(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderReference(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderRelease(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuComputePipelineGetBindGroupLayout(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineSetLabel(WGPUComputePipeline computePipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineReference(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineRelease(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Device +WGPU_EXPORT WGPUBindGroup wgpuDeviceCreateBindGroup(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBindGroupLayout wgpuDeviceCreateBindGroupLayout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandEncoder wgpuDeviceCreateCommandEncoder(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUComputePipeline wgpuDeviceCreateComputePipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceCreateComputePipelineAsync(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBuffer wgpuDeviceCreateErrorBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUExternalTexture wgpuDeviceCreateErrorExternalTexture(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUShaderModule wgpuDeviceCreateErrorShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, char const * errorMessage) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTexture wgpuDeviceCreateErrorTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUExternalTexture wgpuDeviceCreateExternalTexture(WGPUDevice device, WGPUExternalTextureDescriptor const * externalTextureDescriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQuerySet wgpuDeviceCreateQuerySet(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundleEncoder wgpuDeviceCreateRenderBundleEncoder(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceCreateRenderPipelineAsync(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUSwapChain wgpuDeviceCreateSwapChain(WGPUDevice device, WGPUSurface surface, WGPUSwapChainDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT size_t wgpuDeviceEnumerateFeatures(WGPUDevice device, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceForceLoss(WGPUDevice device, WGPUDeviceLostReason type, char const * message) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUAdapter wgpuDeviceGetAdapter(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT bool wgpuDeviceGetLimits(WGPUDevice device, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueue wgpuDeviceGetQueue(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureUsageFlags wgpuDeviceGetSupportedSurfaceUsage(WGPUDevice device, WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT bool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceInjectError(WGPUDevice device, WGPUErrorType type, char const * message) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDevicePopErrorScope(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDevicePushErrorScope(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetDeviceLostCallback(WGPUDevice device, WGPUDeviceLostCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetLabel(WGPUDevice device, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetLoggingCallback(WGPUDevice device, WGPULoggingCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetUncapturedErrorCallback(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceTick(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceValidateTextureDescriptor(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceReference(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceRelease(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ExternalTexture +WGPU_EXPORT void wgpuExternalTextureDestroy(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuExternalTextureExpire(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuExternalTextureRefresh(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuExternalTextureSetLabel(WGPUExternalTexture externalTexture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuExternalTextureReference(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuExternalTextureRelease(WGPUExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Instance +WGPU_EXPORT WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceProcessEvents(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceRequestAdapter(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceReference(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceRelease(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of PipelineLayout +WGPU_EXPORT void wgpuPipelineLayoutSetLabel(WGPUPipelineLayout pipelineLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutReference(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutRelease(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of QuerySet +WGPU_EXPORT void wgpuQuerySetDestroy(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuQuerySetGetCount(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueryType wgpuQuerySetGetType(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetSetLabel(WGPUQuerySet querySet, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetReference(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetRelease(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Queue +WGPU_EXPORT void wgpuQueueCopyExternalTextureForBrowser(WGPUQueue queue, WGPUImageCopyExternalTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueCopyTextureForBrowser(WGPUQueue queue, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSetLabel(WGPUQueue queue, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueReference(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueRelease(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundle +WGPU_EXPORT void wgpuRenderBundleSetLabel(WGPURenderBundle renderBundle, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleReference(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleRelease(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundleEncoder +WGPU_EXPORT void wgpuRenderBundleEncoderDraw(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexed(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexedIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundle wgpuRenderBundleEncoderFinish(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderInsertDebugMarker(WGPURenderBundleEncoder renderBundleEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPopDebugGroup(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPushDebugGroup(WGPURenderBundleEncoder renderBundleEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetBindGroup(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetIndexBuffer(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetLabel(WGPURenderBundleEncoder renderBundleEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetPipeline(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetVertexBuffer(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderReference(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderRelease(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPassEncoder +WGPU_EXPORT void wgpuRenderPassEncoderBeginOcclusionQuery(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDraw(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexed(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexedIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEnd(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEndOcclusionQuery(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderExecuteBundles(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderInsertDebugMarker(WGPURenderPassEncoder renderPassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPopDebugGroup(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPushDebugGroup(WGPURenderPassEncoder renderPassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBindGroup(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBlendConstant(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetIndexBuffer(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetLabel(WGPURenderPassEncoder renderPassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetPipeline(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetScissorRect(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetStencilReference(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetVertexBuffer(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetViewport(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderWriteTimestamp(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderReference(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderRelease(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuRenderPipelineGetBindGroupLayout(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineSetLabel(WGPURenderPipeline renderPipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineReference(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineRelease(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Sampler +WGPU_EXPORT void wgpuSamplerSetLabel(WGPUSampler sampler, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerReference(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerRelease(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ShaderModule +WGPU_EXPORT void wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleReference(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Surface +WGPU_EXPORT void wgpuSurfaceReference(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceRelease(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SwapChain +WGPU_EXPORT WGPUTexture wgpuSwapChainGetCurrentTexture(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureView wgpuSwapChainGetCurrentTextureView(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSwapChainPresent(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSwapChainReference(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSwapChainRelease(WGPUSwapChain swapChain) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Texture +WGPU_EXPORT WGPUTextureView wgpuTextureCreateView(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureDestroy(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetDepthOrArrayLayers(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureDimension wgpuTextureGetDimension(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuTextureGetFormat(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetHeight(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetMipLevelCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetSampleCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureUsageFlags wgpuTextureGetUsage(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetWidth(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureSetLabel(WGPUTexture texture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureReference(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureRelease(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of TextureView +WGPU_EXPORT void wgpuTextureViewSetLabel(WGPUTextureView textureView, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewReference(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewRelease(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_DECLARATIONS) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // WEBGPU_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp.h b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp.h new file mode 100644 index 0000000..5181bb2 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp.h @@ -0,0 +1,2012 @@ +#ifdef __EMSCRIPTEN__ +#error "Do not include this header. Emscripten already provides headers needed for WebGPU." +#endif +#ifndef WEBGPU_CPP_H_ +#define WEBGPU_CPP_H_ + +#include "dawn/webgpu.h" +#include "dawn/webgpu_cpp_chained_struct.h" +#include "dawn/EnumClassBitmasks.h" +#include +#include +#include + +namespace wgpu { + + static constexpr uint32_t kArrayLayerCountUndefined = WGPU_ARRAY_LAYER_COUNT_UNDEFINED; + static constexpr uint32_t kCopyStrideUndefined = WGPU_COPY_STRIDE_UNDEFINED; + static constexpr uint32_t kLimitU32Undefined = WGPU_LIMIT_U32_UNDEFINED; + static constexpr uint64_t kLimitU64Undefined = WGPU_LIMIT_U64_UNDEFINED; + static constexpr uint32_t kMipLevelCountUndefined = WGPU_MIP_LEVEL_COUNT_UNDEFINED; + static constexpr size_t kWholeMapSize = WGPU_WHOLE_MAP_SIZE; + static constexpr uint64_t kWholeSize = WGPU_WHOLE_SIZE; + + enum class AdapterType : uint32_t { + DiscreteGPU = 0x00000000, + IntegratedGPU = 0x00000001, + CPU = 0x00000002, + Unknown = 0x00000003, + }; + + enum class AddressMode : uint32_t { + Repeat = 0x00000000, + MirrorRepeat = 0x00000001, + ClampToEdge = 0x00000002, + }; + + enum class AlphaMode : uint32_t { + Premultiplied = 0x00000000, + Unpremultiplied = 0x00000001, + Opaque = 0x00000002, + }; + + enum class BackendType : uint32_t { + Undefined = 0x00000000, + Null = 0x00000001, + WebGPU = 0x00000002, + D3D11 = 0x00000003, + D3D12 = 0x00000004, + Metal = 0x00000005, + Vulkan = 0x00000006, + OpenGL = 0x00000007, + OpenGLES = 0x00000008, + }; + + enum class BlendFactor : uint32_t { + Zero = 0x00000000, + One = 0x00000001, + Src = 0x00000002, + OneMinusSrc = 0x00000003, + SrcAlpha = 0x00000004, + OneMinusSrcAlpha = 0x00000005, + Dst = 0x00000006, + OneMinusDst = 0x00000007, + DstAlpha = 0x00000008, + OneMinusDstAlpha = 0x00000009, + SrcAlphaSaturated = 0x0000000A, + Constant = 0x0000000B, + OneMinusConstant = 0x0000000C, + }; + + enum class BlendOperation : uint32_t { + Add = 0x00000000, + Subtract = 0x00000001, + ReverseSubtract = 0x00000002, + Min = 0x00000003, + Max = 0x00000004, + }; + + enum class BufferBindingType : uint32_t { + Undefined = 0x00000000, + Uniform = 0x00000001, + Storage = 0x00000002, + ReadOnlyStorage = 0x00000003, + }; + + enum class BufferMapAsyncStatus : uint32_t { + Success = 0x00000000, + ValidationError = 0x00000001, + Unknown = 0x00000002, + DeviceLost = 0x00000003, + DestroyedBeforeCallback = 0x00000004, + UnmappedBeforeCallback = 0x00000005, + MappingAlreadyPending = 0x00000006, + OffsetOutOfRange = 0x00000007, + SizeOutOfRange = 0x00000008, + }; + + enum class BufferMapState : uint32_t { + Unmapped = 0x00000000, + Pending = 0x00000001, + Mapped = 0x00000002, + }; + + enum class CompareFunction : uint32_t { + Undefined = 0x00000000, + Never = 0x00000001, + Less = 0x00000002, + LessEqual = 0x00000003, + Greater = 0x00000004, + GreaterEqual = 0x00000005, + Equal = 0x00000006, + NotEqual = 0x00000007, + Always = 0x00000008, + }; + + enum class CompilationInfoRequestStatus : uint32_t { + Success = 0x00000000, + Error = 0x00000001, + DeviceLost = 0x00000002, + Unknown = 0x00000003, + }; + + enum class CompilationMessageType : uint32_t { + Error = 0x00000000, + Warning = 0x00000001, + Info = 0x00000002, + }; + + enum class ComputePassTimestampLocation : uint32_t { + Beginning = 0x00000000, + End = 0x00000001, + }; + + enum class CreatePipelineAsyncStatus : uint32_t { + Success = 0x00000000, + ValidationError = 0x00000001, + InternalError = 0x00000002, + DeviceLost = 0x00000003, + DeviceDestroyed = 0x00000004, + Unknown = 0x00000005, + }; + + enum class CullMode : uint32_t { + None = 0x00000000, + Front = 0x00000001, + Back = 0x00000002, + }; + + enum class DeviceLostReason : uint32_t { + Undefined = 0x00000000, + Destroyed = 0x00000001, + }; + + enum class ErrorFilter : uint32_t { + Validation = 0x00000000, + OutOfMemory = 0x00000001, + Internal = 0x00000002, + }; + + enum class ErrorType : uint32_t { + NoError = 0x00000000, + Validation = 0x00000001, + OutOfMemory = 0x00000002, + Internal = 0x00000003, + Unknown = 0x00000004, + DeviceLost = 0x00000005, + }; + + enum class ExternalTextureRotation : uint32_t { + Rotate0Degrees = 0x00000000, + Rotate90Degrees = 0x00000001, + Rotate180Degrees = 0x00000002, + Rotate270Degrees = 0x00000003, + }; + + enum class FeatureName : uint32_t { + Undefined = 0x00000000, + DepthClipControl = 0x00000001, + Depth32FloatStencil8 = 0x00000002, + TimestampQuery = 0x00000003, + PipelineStatisticsQuery = 0x00000004, + TextureCompressionBC = 0x00000005, + TextureCompressionETC2 = 0x00000006, + TextureCompressionASTC = 0x00000007, + IndirectFirstInstance = 0x00000008, + ShaderF16 = 0x00000009, + RG11B10UfloatRenderable = 0x0000000A, + BGRA8UnormStorage = 0x0000000B, + Float32Filterable = 0x0000000C, + DawnShaderFloat16 = 0x000003E9, + DawnInternalUsages = 0x000003EA, + DawnMultiPlanarFormats = 0x000003EB, + DawnNative = 0x000003EC, + ChromiumExperimentalDp4a = 0x000003ED, + TimestampQueryInsidePasses = 0x000003EE, + ImplicitDeviceSynchronization = 0x000003EF, + SurfaceCapabilities = 0x000003F0, + TransientAttachments = 0x000003F1, + MSAARenderToSingleSampled = 0x000003F2, + }; + + enum class FilterMode : uint32_t { + Nearest = 0x00000000, + Linear = 0x00000001, + }; + + enum class FrontFace : uint32_t { + CCW = 0x00000000, + CW = 0x00000001, + }; + + enum class IndexFormat : uint32_t { + Undefined = 0x00000000, + Uint16 = 0x00000001, + Uint32 = 0x00000002, + }; + + enum class LoadOp : uint32_t { + Undefined = 0x00000000, + Clear = 0x00000001, + Load = 0x00000002, + }; + + enum class LoggingType : uint32_t { + Verbose = 0x00000000, + Info = 0x00000001, + Warning = 0x00000002, + Error = 0x00000003, + }; + + enum class MipmapFilterMode : uint32_t { + Nearest = 0x00000000, + Linear = 0x00000001, + }; + + enum class PipelineStatisticName : uint32_t { + VertexShaderInvocations = 0x00000000, + ClipperInvocations = 0x00000001, + ClipperPrimitivesOut = 0x00000002, + FragmentShaderInvocations = 0x00000003, + ComputeShaderInvocations = 0x00000004, + }; + + enum class PowerPreference : uint32_t { + Undefined = 0x00000000, + LowPower = 0x00000001, + HighPerformance = 0x00000002, + }; + + enum class PresentMode : uint32_t { + Immediate = 0x00000000, + Mailbox = 0x00000001, + Fifo = 0x00000002, + }; + + enum class PrimitiveTopology : uint32_t { + PointList = 0x00000000, + LineList = 0x00000001, + LineStrip = 0x00000002, + TriangleList = 0x00000003, + TriangleStrip = 0x00000004, + }; + + enum class QueryType : uint32_t { + Occlusion = 0x00000000, + PipelineStatistics = 0x00000001, + Timestamp = 0x00000002, + }; + + enum class QueueWorkDoneStatus : uint32_t { + Success = 0x00000000, + Error = 0x00000001, + Unknown = 0x00000002, + DeviceLost = 0x00000003, + }; + + enum class RenderPassTimestampLocation : uint32_t { + Beginning = 0x00000000, + End = 0x00000001, + }; + + enum class RequestAdapterStatus : uint32_t { + Success = 0x00000000, + Unavailable = 0x00000001, + Error = 0x00000002, + Unknown = 0x00000003, + }; + + enum class RequestDeviceStatus : uint32_t { + Success = 0x00000000, + Error = 0x00000001, + Unknown = 0x00000002, + }; + + enum class SType : uint32_t { + Invalid = 0x00000000, + SurfaceDescriptorFromMetalLayer = 0x00000001, + SurfaceDescriptorFromWindowsHWND = 0x00000002, + SurfaceDescriptorFromXlibWindow = 0x00000003, + SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, + ShaderModuleSPIRVDescriptor = 0x00000005, + ShaderModuleWGSLDescriptor = 0x00000006, + PrimitiveDepthClipControl = 0x00000007, + SurfaceDescriptorFromWaylandSurface = 0x00000008, + SurfaceDescriptorFromAndroidNativeWindow = 0x00000009, + SurfaceDescriptorFromWindowsCoreWindow = 0x0000000B, + ExternalTextureBindingEntry = 0x0000000C, + ExternalTextureBindingLayout = 0x0000000D, + SurfaceDescriptorFromWindowsSwapChainPanel = 0x0000000E, + RenderPassDescriptorMaxDrawCount = 0x0000000F, + DawnTextureInternalUsageDescriptor = 0x000003E8, + DawnEncoderInternalUsageDescriptor = 0x000003EB, + DawnInstanceDescriptor = 0x000003EC, + DawnCacheDeviceDescriptor = 0x000003ED, + DawnAdapterPropertiesPowerPreference = 0x000003EE, + DawnBufferDescriptorErrorInfoFromWireClient = 0x000003EF, + DawnTogglesDescriptor = 0x000003F0, + DawnShaderModuleSPIRVOptionsDescriptor = 0x000003F1, + RequestAdapterOptionsLUID = 0x000003F2, + RequestAdapterOptionsGetGLProc = 0x000003F3, + DawnMultisampleStateRenderToSingleSampled = 0x000003F4, + DawnRenderPassColorAttachmentRenderToSingleSampled = 0x000003F5, + }; + + enum class SamplerBindingType : uint32_t { + Undefined = 0x00000000, + Filtering = 0x00000001, + NonFiltering = 0x00000002, + Comparison = 0x00000003, + }; + + enum class StencilOperation : uint32_t { + Keep = 0x00000000, + Zero = 0x00000001, + Replace = 0x00000002, + Invert = 0x00000003, + IncrementClamp = 0x00000004, + DecrementClamp = 0x00000005, + IncrementWrap = 0x00000006, + DecrementWrap = 0x00000007, + }; + + enum class StorageTextureAccess : uint32_t { + Undefined = 0x00000000, + WriteOnly = 0x00000001, + }; + + enum class StoreOp : uint32_t { + Undefined = 0x00000000, + Store = 0x00000001, + Discard = 0x00000002, + }; + + enum class TextureAspect : uint32_t { + All = 0x00000000, + StencilOnly = 0x00000001, + DepthOnly = 0x00000002, + Plane0Only = 0x00000003, + Plane1Only = 0x00000004, + }; + + enum class TextureDimension : uint32_t { + e1D = 0x00000000, + e2D = 0x00000001, + e3D = 0x00000002, + }; + + enum class TextureFormat : uint32_t { + Undefined = 0x00000000, + R8Unorm = 0x00000001, + R8Snorm = 0x00000002, + R8Uint = 0x00000003, + R8Sint = 0x00000004, + R16Uint = 0x00000005, + R16Sint = 0x00000006, + R16Float = 0x00000007, + RG8Unorm = 0x00000008, + RG8Snorm = 0x00000009, + RG8Uint = 0x0000000A, + RG8Sint = 0x0000000B, + R32Float = 0x0000000C, + R32Uint = 0x0000000D, + R32Sint = 0x0000000E, + RG16Uint = 0x0000000F, + RG16Sint = 0x00000010, + RG16Float = 0x00000011, + RGBA8Unorm = 0x00000012, + RGBA8UnormSrgb = 0x00000013, + RGBA8Snorm = 0x00000014, + RGBA8Uint = 0x00000015, + RGBA8Sint = 0x00000016, + BGRA8Unorm = 0x00000017, + BGRA8UnormSrgb = 0x00000018, + RGB10A2Unorm = 0x00000019, + RG11B10Ufloat = 0x0000001A, + RGB9E5Ufloat = 0x0000001B, + RG32Float = 0x0000001C, + RG32Uint = 0x0000001D, + RG32Sint = 0x0000001E, + RGBA16Uint = 0x0000001F, + RGBA16Sint = 0x00000020, + RGBA16Float = 0x00000021, + RGBA32Float = 0x00000022, + RGBA32Uint = 0x00000023, + RGBA32Sint = 0x00000024, + Stencil8 = 0x00000025, + Depth16Unorm = 0x00000026, + Depth24Plus = 0x00000027, + Depth24PlusStencil8 = 0x00000028, + Depth32Float = 0x00000029, + Depth32FloatStencil8 = 0x0000002A, + BC1RGBAUnorm = 0x0000002B, + BC1RGBAUnormSrgb = 0x0000002C, + BC2RGBAUnorm = 0x0000002D, + BC2RGBAUnormSrgb = 0x0000002E, + BC3RGBAUnorm = 0x0000002F, + BC3RGBAUnormSrgb = 0x00000030, + BC4RUnorm = 0x00000031, + BC4RSnorm = 0x00000032, + BC5RGUnorm = 0x00000033, + BC5RGSnorm = 0x00000034, + BC6HRGBUfloat = 0x00000035, + BC6HRGBFloat = 0x00000036, + BC7RGBAUnorm = 0x00000037, + BC7RGBAUnormSrgb = 0x00000038, + ETC2RGB8Unorm = 0x00000039, + ETC2RGB8UnormSrgb = 0x0000003A, + ETC2RGB8A1Unorm = 0x0000003B, + ETC2RGB8A1UnormSrgb = 0x0000003C, + ETC2RGBA8Unorm = 0x0000003D, + ETC2RGBA8UnormSrgb = 0x0000003E, + EACR11Unorm = 0x0000003F, + EACR11Snorm = 0x00000040, + EACRG11Unorm = 0x00000041, + EACRG11Snorm = 0x00000042, + ASTC4x4Unorm = 0x00000043, + ASTC4x4UnormSrgb = 0x00000044, + ASTC5x4Unorm = 0x00000045, + ASTC5x4UnormSrgb = 0x00000046, + ASTC5x5Unorm = 0x00000047, + ASTC5x5UnormSrgb = 0x00000048, + ASTC6x5Unorm = 0x00000049, + ASTC6x5UnormSrgb = 0x0000004A, + ASTC6x6Unorm = 0x0000004B, + ASTC6x6UnormSrgb = 0x0000004C, + ASTC8x5Unorm = 0x0000004D, + ASTC8x5UnormSrgb = 0x0000004E, + ASTC8x6Unorm = 0x0000004F, + ASTC8x6UnormSrgb = 0x00000050, + ASTC8x8Unorm = 0x00000051, + ASTC8x8UnormSrgb = 0x00000052, + ASTC10x5Unorm = 0x00000053, + ASTC10x5UnormSrgb = 0x00000054, + ASTC10x6Unorm = 0x00000055, + ASTC10x6UnormSrgb = 0x00000056, + ASTC10x8Unorm = 0x00000057, + ASTC10x8UnormSrgb = 0x00000058, + ASTC10x10Unorm = 0x00000059, + ASTC10x10UnormSrgb = 0x0000005A, + ASTC12x10Unorm = 0x0000005B, + ASTC12x10UnormSrgb = 0x0000005C, + ASTC12x12Unorm = 0x0000005D, + ASTC12x12UnormSrgb = 0x0000005E, + R8BG8Biplanar420Unorm = 0x0000005F, + }; + + enum class TextureSampleType : uint32_t { + Undefined = 0x00000000, + Float = 0x00000001, + UnfilterableFloat = 0x00000002, + Depth = 0x00000003, + Sint = 0x00000004, + Uint = 0x00000005, + }; + + enum class TextureViewDimension : uint32_t { + Undefined = 0x00000000, + e1D = 0x00000001, + e2D = 0x00000002, + e2DArray = 0x00000003, + Cube = 0x00000004, + CubeArray = 0x00000005, + e3D = 0x00000006, + }; + + enum class VertexFormat : uint32_t { + Undefined = 0x00000000, + Uint8x2 = 0x00000001, + Uint8x4 = 0x00000002, + Sint8x2 = 0x00000003, + Sint8x4 = 0x00000004, + Unorm8x2 = 0x00000005, + Unorm8x4 = 0x00000006, + Snorm8x2 = 0x00000007, + Snorm8x4 = 0x00000008, + Uint16x2 = 0x00000009, + Uint16x4 = 0x0000000A, + Sint16x2 = 0x0000000B, + Sint16x4 = 0x0000000C, + Unorm16x2 = 0x0000000D, + Unorm16x4 = 0x0000000E, + Snorm16x2 = 0x0000000F, + Snorm16x4 = 0x00000010, + Float16x2 = 0x00000011, + Float16x4 = 0x00000012, + Float32 = 0x00000013, + Float32x2 = 0x00000014, + Float32x3 = 0x00000015, + Float32x4 = 0x00000016, + Uint32 = 0x00000017, + Uint32x2 = 0x00000018, + Uint32x3 = 0x00000019, + Uint32x4 = 0x0000001A, + Sint32 = 0x0000001B, + Sint32x2 = 0x0000001C, + Sint32x3 = 0x0000001D, + Sint32x4 = 0x0000001E, + }; + + enum class VertexStepMode : uint32_t { + Vertex = 0x00000000, + Instance = 0x00000001, + VertexBufferNotUsed = 0x00000002, + }; + + + enum class BufferUsage : uint32_t { + None = 0x00000000, + MapRead = 0x00000001, + MapWrite = 0x00000002, + CopySrc = 0x00000004, + CopyDst = 0x00000008, + Index = 0x00000010, + Vertex = 0x00000020, + Uniform = 0x00000040, + Storage = 0x00000080, + Indirect = 0x00000100, + QueryResolve = 0x00000200, + }; + + enum class ColorWriteMask : uint32_t { + None = 0x00000000, + Red = 0x00000001, + Green = 0x00000002, + Blue = 0x00000004, + Alpha = 0x00000008, + All = 0x0000000F, + }; + + enum class MapMode : uint32_t { + None = 0x00000000, + Read = 0x00000001, + Write = 0x00000002, + }; + + enum class ShaderStage : uint32_t { + None = 0x00000000, + Vertex = 0x00000001, + Fragment = 0x00000002, + Compute = 0x00000004, + }; + + enum class TextureUsage : uint32_t { + None = 0x00000000, + CopySrc = 0x00000001, + CopyDst = 0x00000002, + TextureBinding = 0x00000004, + StorageBinding = 0x00000008, + RenderAttachment = 0x00000010, + TransientAttachment = 0x00000020, + }; + + + using BufferMapCallback = WGPUBufferMapCallback; + using CompilationInfoCallback = WGPUCompilationInfoCallback; + using CreateComputePipelineAsyncCallback = WGPUCreateComputePipelineAsyncCallback; + using CreateRenderPipelineAsyncCallback = WGPUCreateRenderPipelineAsyncCallback; + using DeviceLostCallback = WGPUDeviceLostCallback; + using ErrorCallback = WGPUErrorCallback; + using LoggingCallback = WGPULoggingCallback; + using Proc = WGPUProc; + using QueueWorkDoneCallback = WGPUQueueWorkDoneCallback; + using RequestAdapterCallback = WGPURequestAdapterCallback; + using RequestDeviceCallback = WGPURequestDeviceCallback; + + class Adapter; + class BindGroup; + class BindGroupLayout; + class Buffer; + class CommandBuffer; + class CommandEncoder; + class ComputePassEncoder; + class ComputePipeline; + class Device; + class ExternalTexture; + class Instance; + class PipelineLayout; + class QuerySet; + class Queue; + class RenderBundle; + class RenderBundleEncoder; + class RenderPassEncoder; + class RenderPipeline; + class Sampler; + class ShaderModule; + class Surface; + class SwapChain; + class Texture; + class TextureView; + + struct AdapterProperties; + struct BindGroupEntry; + struct BlendComponent; + struct BufferBindingLayout; + struct BufferDescriptor; + struct Color; + struct CommandBufferDescriptor; + struct CommandEncoderDescriptor; + struct CompilationMessage; + struct ComputePassTimestampWrite; + struct ConstantEntry; + struct CopyTextureForBrowserOptions; + struct DawnAdapterPropertiesPowerPreference; + struct DawnBufferDescriptorErrorInfoFromWireClient; + struct DawnCacheDeviceDescriptor; + struct DawnEncoderInternalUsageDescriptor; + struct DawnMultisampleStateRenderToSingleSampled; + struct DawnRenderPassColorAttachmentRenderToSingleSampled; + struct DawnShaderModuleSPIRVOptionsDescriptor; + struct DawnTextureInternalUsageDescriptor; + struct DawnTogglesDescriptor; + struct Extent2D; + struct Extent3D; + struct ExternalTextureBindingEntry; + struct ExternalTextureBindingLayout; + struct InstanceDescriptor; + struct Limits; + struct MultisampleState; + struct Origin2D; + struct Origin3D; + struct PipelineLayoutDescriptor; + struct PrimitiveDepthClipControl; + struct PrimitiveState; + struct QuerySetDescriptor; + struct QueueDescriptor; + struct RenderBundleDescriptor; + struct RenderBundleEncoderDescriptor; + struct RenderPassDepthStencilAttachment; + struct RenderPassDescriptorMaxDrawCount; + struct RenderPassTimestampWrite; + struct RequestAdapterOptions; + struct SamplerBindingLayout; + struct SamplerDescriptor; + struct ShaderModuleDescriptor; + struct ShaderModuleSPIRVDescriptor; + struct ShaderModuleWGSLDescriptor; + struct StencilFaceState; + struct StorageTextureBindingLayout; + struct SurfaceDescriptor; + struct SurfaceDescriptorFromAndroidNativeWindow; + struct SurfaceDescriptorFromCanvasHTMLSelector; + struct SurfaceDescriptorFromMetalLayer; + struct SurfaceDescriptorFromWaylandSurface; + struct SurfaceDescriptorFromWindowsCoreWindow; + struct SurfaceDescriptorFromWindowsHWND; + struct SurfaceDescriptorFromWindowsSwapChainPanel; + struct SurfaceDescriptorFromXlibWindow; + struct SwapChainDescriptor; + struct TextureBindingLayout; + struct TextureDataLayout; + struct TextureViewDescriptor; + struct VertexAttribute; + struct BindGroupDescriptor; + struct BindGroupLayoutEntry; + struct BlendState; + struct CompilationInfo; + struct ComputePassDescriptor; + struct DepthStencilState; + struct ExternalTextureDescriptor; + struct ImageCopyBuffer; + struct ImageCopyExternalTexture; + struct ImageCopyTexture; + struct ProgrammableStageDescriptor; + struct RenderPassColorAttachment; + struct RequiredLimits; + struct SupportedLimits; + struct TextureDescriptor; + struct VertexBufferLayout; + struct BindGroupLayoutDescriptor; + struct ColorTargetState; + struct ComputePipelineDescriptor; + struct DeviceDescriptor; + struct RenderPassDescriptor; + struct VertexState; + struct FragmentState; + struct RenderPipelineDescriptor; + + template + class ObjectBase { + public: + ObjectBase() = default; + ObjectBase(CType handle): mHandle(handle) { + if (mHandle) Derived::WGPUReference(mHandle); + } + ~ObjectBase() { + if (mHandle) Derived::WGPURelease(mHandle); + } + + ObjectBase(ObjectBase const& other) + : ObjectBase(other.Get()) { + } + Derived& operator=(ObjectBase const& other) { + if (&other != this) { + if (mHandle) Derived::WGPURelease(mHandle); + mHandle = other.mHandle; + if (mHandle) Derived::WGPUReference(mHandle); + } + + return static_cast(*this); + } + + ObjectBase(ObjectBase&& other) { + mHandle = other.mHandle; + other.mHandle = 0; + } + Derived& operator=(ObjectBase&& other) { + if (&other != this) { + if (mHandle) Derived::WGPURelease(mHandle); + mHandle = other.mHandle; + other.mHandle = 0; + } + + return static_cast(*this); + } + + ObjectBase(std::nullptr_t) {} + Derived& operator=(std::nullptr_t) { + if (mHandle != nullptr) { + Derived::WGPURelease(mHandle); + mHandle = nullptr; + } + return static_cast(*this); + } + + bool operator==(std::nullptr_t) const { + return mHandle == nullptr; + } + bool operator!=(std::nullptr_t) const { + return mHandle != nullptr; + } + + explicit operator bool() const { + return mHandle != nullptr; + } + CType Get() const { + return mHandle; + } + // TODO(dawn:1639) Deprecate Release after uses have been removed. + CType Release() { + CType result = mHandle; + mHandle = 0; + return result; + } + CType MoveToCHandle() { + CType result = mHandle; + mHandle = 0; + return result; + } + static Derived Acquire(CType handle) { + Derived result; + result.mHandle = handle; + return result; + } + + protected: + CType mHandle = nullptr; + }; + + + + class Adapter : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + Device CreateDevice(DeviceDescriptor const * descriptor = nullptr) const; + size_t EnumerateFeatures(FeatureName * features) const; + Instance GetInstance() const; + bool GetLimits(SupportedLimits * limits) const; + void GetProperties(AdapterProperties * properties) const; + bool HasFeature(FeatureName feature) const; + void RequestDevice(DeviceDescriptor const * descriptor, RequestDeviceCallback callback, void * userdata) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUAdapter handle); + static void WGPURelease(WGPUAdapter handle); + }; + + class BindGroup : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUBindGroup handle); + static void WGPURelease(WGPUBindGroup handle); + }; + + class BindGroupLayout : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUBindGroupLayout handle); + static void WGPURelease(WGPUBindGroupLayout handle); + }; + + class Buffer : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void Destroy() const; + void const * GetConstMappedRange(size_t offset = 0, size_t size = WGPU_WHOLE_MAP_SIZE) const; + BufferMapState GetMapState() const; + void * GetMappedRange(size_t offset = 0, size_t size = WGPU_WHOLE_MAP_SIZE) const; + uint64_t GetSize() const; + BufferUsage GetUsage() const; + void MapAsync(MapMode mode, size_t offset, size_t size, BufferMapCallback callback, void * userdata) const; + void SetLabel(char const * label) const; + void Unmap() const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUBuffer handle); + static void WGPURelease(WGPUBuffer handle); + }; + + class CommandBuffer : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUCommandBuffer handle); + static void WGPURelease(WGPUCommandBuffer handle); + }; + + class CommandEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + ComputePassEncoder BeginComputePass(ComputePassDescriptor const * descriptor = nullptr) const; + RenderPassEncoder BeginRenderPass(RenderPassDescriptor const * descriptor) const; + void ClearBuffer(Buffer const& buffer, uint64_t offset = 0, uint64_t size = WGPU_WHOLE_SIZE) const; + void CopyBufferToBuffer(Buffer const& source, uint64_t sourceOffset, Buffer const& destination, uint64_t destinationOffset, uint64_t size) const; + void CopyBufferToTexture(ImageCopyBuffer const * source, ImageCopyTexture const * destination, Extent3D const * copySize) const; + void CopyTextureToBuffer(ImageCopyTexture const * source, ImageCopyBuffer const * destination, Extent3D const * copySize) const; + void CopyTextureToTexture(ImageCopyTexture const * source, ImageCopyTexture const * destination, Extent3D const * copySize) const; + void CopyTextureToTextureInternal(ImageCopyTexture const * source, ImageCopyTexture const * destination, Extent3D const * copySize) const; + CommandBuffer Finish(CommandBufferDescriptor const * descriptor = nullptr) const; + void InjectValidationError(char const * message) const; + void InsertDebugMarker(char const * markerLabel) const; + void PopDebugGroup() const; + void PushDebugGroup(char const * groupLabel) const; + void ResolveQuerySet(QuerySet const& querySet, uint32_t firstQuery, uint32_t queryCount, Buffer const& destination, uint64_t destinationOffset) const; + void SetLabel(char const * label) const; + void WriteBuffer(Buffer const& buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size) const; + void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUCommandEncoder handle); + static void WGPURelease(WGPUCommandEncoder handle); + }; + + class ComputePassEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void DispatchWorkgroups(uint32_t workgroupCountX, uint32_t workgroupCountY = 1, uint32_t workgroupCountZ = 1) const; + void DispatchWorkgroupsIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + void End() const; + void InsertDebugMarker(char const * markerLabel) const; + void PopDebugGroup() const; + void PushDebugGroup(char const * groupLabel) const; + void SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + void SetLabel(char const * label) const; + void SetPipeline(ComputePipeline const& pipeline) const; + void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUComputePassEncoder handle); + static void WGPURelease(WGPUComputePassEncoder handle); + }; + + class ComputePipeline : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + BindGroupLayout GetBindGroupLayout(uint32_t groupIndex) const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUComputePipeline handle); + static void WGPURelease(WGPUComputePipeline handle); + }; + + class Device : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + BindGroup CreateBindGroup(BindGroupDescriptor const * descriptor) const; + BindGroupLayout CreateBindGroupLayout(BindGroupLayoutDescriptor const * descriptor) const; + Buffer CreateBuffer(BufferDescriptor const * descriptor) const; + CommandEncoder CreateCommandEncoder(CommandEncoderDescriptor const * descriptor = nullptr) const; + ComputePipeline CreateComputePipeline(ComputePipelineDescriptor const * descriptor) const; + void CreateComputePipelineAsync(ComputePipelineDescriptor const * descriptor, CreateComputePipelineAsyncCallback callback, void * userdata) const; + Buffer CreateErrorBuffer(BufferDescriptor const * descriptor) const; + ExternalTexture CreateErrorExternalTexture() const; + ShaderModule CreateErrorShaderModule(ShaderModuleDescriptor const * descriptor, char const * errorMessage) const; + Texture CreateErrorTexture(TextureDescriptor const * descriptor) const; + ExternalTexture CreateExternalTexture(ExternalTextureDescriptor const * externalTextureDescriptor) const; + PipelineLayout CreatePipelineLayout(PipelineLayoutDescriptor const * descriptor) const; + QuerySet CreateQuerySet(QuerySetDescriptor const * descriptor) const; + RenderBundleEncoder CreateRenderBundleEncoder(RenderBundleEncoderDescriptor const * descriptor) const; + RenderPipeline CreateRenderPipeline(RenderPipelineDescriptor const * descriptor) const; + void CreateRenderPipelineAsync(RenderPipelineDescriptor const * descriptor, CreateRenderPipelineAsyncCallback callback, void * userdata) const; + Sampler CreateSampler(SamplerDescriptor const * descriptor = nullptr) const; + ShaderModule CreateShaderModule(ShaderModuleDescriptor const * descriptor) const; + SwapChain CreateSwapChain(Surface const& surface, SwapChainDescriptor const * descriptor) const; + Texture CreateTexture(TextureDescriptor const * descriptor) const; + void Destroy() const; + size_t EnumerateFeatures(FeatureName * features) const; + void ForceLoss(DeviceLostReason type, char const * message) const; + Adapter GetAdapter() const; + bool GetLimits(SupportedLimits * limits) const; + Queue GetQueue() const; + TextureUsage GetSupportedSurfaceUsage(Surface const& surface) const; + bool HasFeature(FeatureName feature) const; + void InjectError(ErrorType type, char const * message) const; + void PopErrorScope(ErrorCallback callback, void * userdata) const; + void PushErrorScope(ErrorFilter filter) const; + void SetDeviceLostCallback(DeviceLostCallback callback, void * userdata) const; + void SetLabel(char const * label) const; + void SetLoggingCallback(LoggingCallback callback, void * userdata) const; + void SetUncapturedErrorCallback(ErrorCallback callback, void * userdata) const; + void Tick() const; + void ValidateTextureDescriptor(TextureDescriptor const * descriptor) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUDevice handle); + static void WGPURelease(WGPUDevice handle); + }; + + class ExternalTexture : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void Destroy() const; + void Expire() const; + void Refresh() const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUExternalTexture handle); + static void WGPURelease(WGPUExternalTexture handle); + }; + + class Instance : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + Surface CreateSurface(SurfaceDescriptor const * descriptor) const; + void ProcessEvents() const; + void RequestAdapter(RequestAdapterOptions const * options, RequestAdapterCallback callback, void * userdata) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUInstance handle); + static void WGPURelease(WGPUInstance handle); + }; + + class PipelineLayout : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUPipelineLayout handle); + static void WGPURelease(WGPUPipelineLayout handle); + }; + + class QuerySet : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void Destroy() const; + uint32_t GetCount() const; + QueryType GetType() const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUQuerySet handle); + static void WGPURelease(WGPUQuerySet handle); + }; + + class Queue : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void CopyExternalTextureForBrowser(ImageCopyExternalTexture const * source, ImageCopyTexture const * destination, Extent3D const * copySize, CopyTextureForBrowserOptions const * options) const; + void CopyTextureForBrowser(ImageCopyTexture const * source, ImageCopyTexture const * destination, Extent3D const * copySize, CopyTextureForBrowserOptions const * options) const; + void OnSubmittedWorkDone(uint64_t signalValue, QueueWorkDoneCallback callback, void * userdata) const; + void SetLabel(char const * label) const; + void Submit(size_t commandCount, CommandBuffer const * commands) const; + void WriteBuffer(Buffer const& buffer, uint64_t bufferOffset, void const * data, size_t size) const; + void WriteTexture(ImageCopyTexture const * destination, void const * data, size_t dataSize, TextureDataLayout const * dataLayout, Extent3D const * writeSize) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUQueue handle); + static void WGPURelease(WGPUQueue handle); + }; + + class RenderBundle : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPURenderBundle handle); + static void WGPURelease(WGPURenderBundle handle); + }; + + class RenderBundleEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t firstVertex = 0, uint32_t firstInstance = 0) const; + void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) const; + void DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + void DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + RenderBundle Finish(RenderBundleDescriptor const * descriptor = nullptr) const; + void InsertDebugMarker(char const * markerLabel) const; + void PopDebugGroup() const; + void PushDebugGroup(char const * groupLabel) const; + void SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + void SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset = 0, uint64_t size = WGPU_WHOLE_SIZE) const; + void SetLabel(char const * label) const; + void SetPipeline(RenderPipeline const& pipeline) const; + void SetVertexBuffer(uint32_t slot, Buffer const& buffer, uint64_t offset = 0, uint64_t size = WGPU_WHOLE_SIZE) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPURenderBundleEncoder handle); + static void WGPURelease(WGPURenderBundleEncoder handle); + }; + + class RenderPassEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void BeginOcclusionQuery(uint32_t queryIndex) const; + void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t firstVertex = 0, uint32_t firstInstance = 0) const; + void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) const; + void DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + void DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + void End() const; + void EndOcclusionQuery() const; + void ExecuteBundles(size_t bundleCount, RenderBundle const * bundles) const; + void InsertDebugMarker(char const * markerLabel) const; + void PopDebugGroup() const; + void PushDebugGroup(char const * groupLabel) const; + void SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + void SetBlendConstant(Color const * color) const; + void SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset = 0, uint64_t size = WGPU_WHOLE_SIZE) const; + void SetLabel(char const * label) const; + void SetPipeline(RenderPipeline const& pipeline) const; + void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) const; + void SetStencilReference(uint32_t reference) const; + void SetVertexBuffer(uint32_t slot, Buffer const& buffer, uint64_t offset = 0, uint64_t size = WGPU_WHOLE_SIZE) const; + void SetViewport(float x, float y, float width, float height, float minDepth, float maxDepth) const; + void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPURenderPassEncoder handle); + static void WGPURelease(WGPURenderPassEncoder handle); + }; + + class RenderPipeline : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + BindGroupLayout GetBindGroupLayout(uint32_t groupIndex) const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPURenderPipeline handle); + static void WGPURelease(WGPURenderPipeline handle); + }; + + class Sampler : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUSampler handle); + static void WGPURelease(WGPUSampler handle); + }; + + class ShaderModule : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void GetCompilationInfo(CompilationInfoCallback callback, void * userdata) const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUShaderModule handle); + static void WGPURelease(WGPUShaderModule handle); + }; + + class Surface : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + + private: + friend ObjectBase; + static void WGPUReference(WGPUSurface handle); + static void WGPURelease(WGPUSurface handle); + }; + + class SwapChain : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + Texture GetCurrentTexture() const; + TextureView GetCurrentTextureView() const; + void Present() const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUSwapChain handle); + static void WGPURelease(WGPUSwapChain handle); + }; + + class Texture : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + TextureView CreateView(TextureViewDescriptor const * descriptor = nullptr) const; + void Destroy() const; + uint32_t GetDepthOrArrayLayers() const; + TextureDimension GetDimension() const; + TextureFormat GetFormat() const; + uint32_t GetHeight() const; + uint32_t GetMipLevelCount() const; + uint32_t GetSampleCount() const; + TextureUsage GetUsage() const; + uint32_t GetWidth() const; + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUTexture handle); + static void WGPURelease(WGPUTexture handle); + }; + + class TextureView : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + void SetLabel(char const * label) const; + + private: + friend ObjectBase; + static void WGPUReference(WGPUTextureView handle); + static void WGPURelease(WGPUTextureView handle); + }; + + + Instance CreateInstance(InstanceDescriptor const * descriptor = nullptr); + Proc GetProcAddress(Device device, char const * procName); + + struct AdapterProperties { + ChainedStructOut * nextInChain = nullptr; + uint32_t vendorID; + char const * vendorName; + char const * architecture; + uint32_t deviceID; + char const * name; + char const * driverDescription; + AdapterType adapterType; + BackendType backendType; + bool compatibilityMode = false; + }; + + struct BindGroupEntry { + ChainedStruct const * nextInChain = nullptr; + uint32_t binding; + Buffer buffer = nullptr; + uint64_t offset = 0; + uint64_t size = WGPU_WHOLE_SIZE; + Sampler sampler = nullptr; + TextureView textureView = nullptr; + }; + + struct BlendComponent { + BlendOperation operation = BlendOperation::Add; + BlendFactor srcFactor = BlendFactor::One; + BlendFactor dstFactor = BlendFactor::Zero; + }; + + struct BufferBindingLayout { + ChainedStruct const * nextInChain = nullptr; + BufferBindingType type = BufferBindingType::Undefined; + bool hasDynamicOffset = false; + uint64_t minBindingSize = 0; + }; + + struct BufferDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + BufferUsage usage; + uint64_t size; + bool mappedAtCreation = false; + }; + + struct Color { + double r; + double g; + double b; + double a; + }; + + struct CommandBufferDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + struct CommandEncoderDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + struct CompilationMessage { + ChainedStruct const * nextInChain = nullptr; + char const * message = nullptr; + CompilationMessageType type; + uint64_t lineNum; + uint64_t linePos; + uint64_t offset; + uint64_t length; + uint64_t utf16LinePos; + uint64_t utf16Offset; + uint64_t utf16Length; + }; + + struct ComputePassTimestampWrite { + QuerySet querySet; + uint32_t queryIndex; + ComputePassTimestampLocation location; + }; + + struct ConstantEntry { + ChainedStruct const * nextInChain = nullptr; + char const * key; + double value; + }; + + struct CopyTextureForBrowserOptions { + ChainedStruct const * nextInChain = nullptr; + bool flipY = false; + bool needsColorSpaceConversion = false; + AlphaMode srcAlphaMode = AlphaMode::Unpremultiplied; + float const * srcTransferFunctionParameters = nullptr; + float const * conversionMatrix = nullptr; + float const * dstTransferFunctionParameters = nullptr; + AlphaMode dstAlphaMode = AlphaMode::Unpremultiplied; + bool internalUsage = false; + }; + + // Can be chained in AdapterProperties + struct DawnAdapterPropertiesPowerPreference : ChainedStructOut { + DawnAdapterPropertiesPowerPreference() { + sType = SType::DawnAdapterPropertiesPowerPreference; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(PowerPreference )); + alignas(kFirstMemberAlignment) PowerPreference powerPreference = PowerPreference::Undefined; + }; + + // Can be chained in BufferDescriptor + struct DawnBufferDescriptorErrorInfoFromWireClient : ChainedStruct { + DawnBufferDescriptorErrorInfoFromWireClient() { + sType = SType::DawnBufferDescriptorErrorInfoFromWireClient; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(bool )); + alignas(kFirstMemberAlignment) bool outOfMemory = false; + }; + + // Can be chained in DeviceDescriptor + struct DawnCacheDeviceDescriptor : ChainedStruct { + DawnCacheDeviceDescriptor() { + sType = SType::DawnCacheDeviceDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(char const * )); + alignas(kFirstMemberAlignment) char const * isolationKey = ""; + }; + + // Can be chained in CommandEncoderDescriptor + struct DawnEncoderInternalUsageDescriptor : ChainedStruct { + DawnEncoderInternalUsageDescriptor() { + sType = SType::DawnEncoderInternalUsageDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(bool )); + alignas(kFirstMemberAlignment) bool useInternalUsages = false; + }; + + // Can be chained in MultisampleState + struct DawnMultisampleStateRenderToSingleSampled : ChainedStruct { + DawnMultisampleStateRenderToSingleSampled() { + sType = SType::DawnMultisampleStateRenderToSingleSampled; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(bool )); + alignas(kFirstMemberAlignment) bool enabled = false; + }; + + // Can be chained in RenderPassColorAttachment + struct DawnRenderPassColorAttachmentRenderToSingleSampled : ChainedStruct { + DawnRenderPassColorAttachmentRenderToSingleSampled() { + sType = SType::DawnRenderPassColorAttachmentRenderToSingleSampled; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint32_t )); + alignas(kFirstMemberAlignment) uint32_t implicitSampleCount = 1; + }; + + // Can be chained in ShaderModuleDescriptor + struct DawnShaderModuleSPIRVOptionsDescriptor : ChainedStruct { + DawnShaderModuleSPIRVOptionsDescriptor() { + sType = SType::DawnShaderModuleSPIRVOptionsDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(bool )); + alignas(kFirstMemberAlignment) bool allowNonUniformDerivatives = false; + }; + + // Can be chained in TextureDescriptor + struct DawnTextureInternalUsageDescriptor : ChainedStruct { + DawnTextureInternalUsageDescriptor() { + sType = SType::DawnTextureInternalUsageDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(TextureUsage )); + alignas(kFirstMemberAlignment) TextureUsage internalUsage = TextureUsage::None; + }; + + // Can be chained in InstanceDescriptor + // Can be chained in RequestAdapterOptions + // Can be chained in DeviceDescriptor + struct DawnTogglesDescriptor : ChainedStruct { + DawnTogglesDescriptor() { + sType = SType::DawnTogglesDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(size_t )); + alignas(kFirstMemberAlignment) size_t enabledTogglesCount = 0; + const char* const * enabledToggles; + size_t disabledTogglesCount = 0; + const char* const * disabledToggles; + }; + + struct Extent2D { + uint32_t width = 0; + uint32_t height = 1; + }; + + struct Extent3D { + uint32_t width; + uint32_t height = 1; + uint32_t depthOrArrayLayers = 1; + }; + + // Can be chained in BindGroupEntry + struct ExternalTextureBindingEntry : ChainedStruct { + ExternalTextureBindingEntry() { + sType = SType::ExternalTextureBindingEntry; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(ExternalTexture )); + alignas(kFirstMemberAlignment) ExternalTexture externalTexture; + }; + + // Can be chained in BindGroupLayoutEntry + struct ExternalTextureBindingLayout : ChainedStruct { + ExternalTextureBindingLayout() { + sType = SType::ExternalTextureBindingLayout; + } + }; + + struct InstanceDescriptor { + ChainedStruct const * nextInChain = nullptr; + }; + + struct Limits { + uint32_t maxTextureDimension1D = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxTextureDimension2D = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxTextureDimension3D = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxTextureArrayLayers = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxBindGroups = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxBindGroupsPlusVertexBuffers = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxBindingsPerBindGroup = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxDynamicUniformBuffersPerPipelineLayout = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxDynamicStorageBuffersPerPipelineLayout = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxSampledTexturesPerShaderStage = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxSamplersPerShaderStage = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxStorageBuffersPerShaderStage = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxStorageTexturesPerShaderStage = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxUniformBuffersPerShaderStage = WGPU_LIMIT_U32_UNDEFINED; + uint64_t maxUniformBufferBindingSize = WGPU_LIMIT_U64_UNDEFINED; + uint64_t maxStorageBufferBindingSize = WGPU_LIMIT_U64_UNDEFINED; + uint32_t minUniformBufferOffsetAlignment = WGPU_LIMIT_U32_UNDEFINED; + uint32_t minStorageBufferOffsetAlignment = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxVertexBuffers = WGPU_LIMIT_U32_UNDEFINED; + uint64_t maxBufferSize = WGPU_LIMIT_U64_UNDEFINED; + uint32_t maxVertexAttributes = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxVertexBufferArrayStride = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxInterStageShaderComponents = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxInterStageShaderVariables = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxColorAttachments = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxColorAttachmentBytesPerSample = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeWorkgroupStorageSize = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeInvocationsPerWorkgroup = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeWorkgroupSizeX = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeWorkgroupSizeY = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeWorkgroupSizeZ = WGPU_LIMIT_U32_UNDEFINED; + uint32_t maxComputeWorkgroupsPerDimension = WGPU_LIMIT_U32_UNDEFINED; + }; + + struct MultisampleState { + ChainedStruct const * nextInChain = nullptr; + uint32_t count = 1; + uint32_t mask = 0xFFFFFFFF; + bool alphaToCoverageEnabled = false; + }; + + struct Origin2D { + uint32_t x = 0; + uint32_t y = 0; + }; + + struct Origin3D { + uint32_t x = 0; + uint32_t y = 0; + uint32_t z = 0; + }; + + struct PipelineLayoutDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t bindGroupLayoutCount; + BindGroupLayout const * bindGroupLayouts; + }; + + // Can be chained in PrimitiveState + struct PrimitiveDepthClipControl : ChainedStruct { + PrimitiveDepthClipControl() { + sType = SType::PrimitiveDepthClipControl; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(bool )); + alignas(kFirstMemberAlignment) bool unclippedDepth = false; + }; + + struct PrimitiveState { + ChainedStruct const * nextInChain = nullptr; + PrimitiveTopology topology = PrimitiveTopology::TriangleList; + IndexFormat stripIndexFormat = IndexFormat::Undefined; + FrontFace frontFace = FrontFace::CCW; + CullMode cullMode = CullMode::None; + }; + + struct QuerySetDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + QueryType type; + uint32_t count; + PipelineStatisticName const * pipelineStatistics; + size_t pipelineStatisticsCount = 0; + }; + + struct QueueDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + struct RenderBundleDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + struct RenderBundleEncoderDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t colorFormatsCount; + TextureFormat const * colorFormats; + TextureFormat depthStencilFormat = TextureFormat::Undefined; + uint32_t sampleCount = 1; + bool depthReadOnly = false; + bool stencilReadOnly = false; + }; + + struct RenderPassDepthStencilAttachment { + TextureView view; + LoadOp depthLoadOp = LoadOp::Undefined; + StoreOp depthStoreOp = StoreOp::Undefined; + float depthClearValue = NAN; + bool depthReadOnly = false; + LoadOp stencilLoadOp = LoadOp::Undefined; + StoreOp stencilStoreOp = StoreOp::Undefined; + uint32_t stencilClearValue = 0; + bool stencilReadOnly = false; + }; + + // Can be chained in RenderPassDescriptor + struct RenderPassDescriptorMaxDrawCount : ChainedStruct { + RenderPassDescriptorMaxDrawCount() { + sType = SType::RenderPassDescriptorMaxDrawCount; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint64_t )); + alignas(kFirstMemberAlignment) uint64_t maxDrawCount = 50000000; + }; + + struct RenderPassTimestampWrite { + QuerySet querySet; + uint32_t queryIndex; + RenderPassTimestampLocation location; + }; + + struct RequestAdapterOptions { + ChainedStruct const * nextInChain = nullptr; + Surface compatibleSurface = nullptr; + PowerPreference powerPreference = PowerPreference::Undefined; + BackendType backendType = BackendType::Undefined; + bool forceFallbackAdapter = false; + bool compatibilityMode = false; + }; + + struct SamplerBindingLayout { + ChainedStruct const * nextInChain = nullptr; + SamplerBindingType type = SamplerBindingType::Undefined; + }; + + struct SamplerDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + AddressMode addressModeU = AddressMode::ClampToEdge; + AddressMode addressModeV = AddressMode::ClampToEdge; + AddressMode addressModeW = AddressMode::ClampToEdge; + FilterMode magFilter = FilterMode::Nearest; + FilterMode minFilter = FilterMode::Nearest; + MipmapFilterMode mipmapFilter = MipmapFilterMode::Nearest; + float lodMinClamp = 0.0f; + float lodMaxClamp = 32.0f; + CompareFunction compare = CompareFunction::Undefined; + uint16_t maxAnisotropy = 1; + }; + + struct ShaderModuleDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + // Can be chained in ShaderModuleDescriptor + struct ShaderModuleSPIRVDescriptor : ChainedStruct { + ShaderModuleSPIRVDescriptor() { + sType = SType::ShaderModuleSPIRVDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint32_t )); + alignas(kFirstMemberAlignment) uint32_t codeSize; + uint32_t const * code; + }; + + // Can be chained in ShaderModuleDescriptor + struct ShaderModuleWGSLDescriptor : ChainedStruct { + ShaderModuleWGSLDescriptor() { + sType = SType::ShaderModuleWGSLDescriptor; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(char const * )); + alignas(kFirstMemberAlignment) char const * code; + }; + + struct StencilFaceState { + CompareFunction compare = CompareFunction::Always; + StencilOperation failOp = StencilOperation::Keep; + StencilOperation depthFailOp = StencilOperation::Keep; + StencilOperation passOp = StencilOperation::Keep; + }; + + struct StorageTextureBindingLayout { + ChainedStruct const * nextInChain = nullptr; + StorageTextureAccess access = StorageTextureAccess::Undefined; + TextureFormat format = TextureFormat::Undefined; + TextureViewDimension viewDimension = TextureViewDimension::Undefined; + }; + + struct SurfaceDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromAndroidNativeWindow : ChainedStruct { + SurfaceDescriptorFromAndroidNativeWindow() { + sType = SType::SurfaceDescriptorFromAndroidNativeWindow; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * window; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromCanvasHTMLSelector : ChainedStruct { + SurfaceDescriptorFromCanvasHTMLSelector() { + sType = SType::SurfaceDescriptorFromCanvasHTMLSelector; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(char const * )); + alignas(kFirstMemberAlignment) char const * selector; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromMetalLayer : ChainedStruct { + SurfaceDescriptorFromMetalLayer() { + sType = SType::SurfaceDescriptorFromMetalLayer; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * layer; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromWaylandSurface : ChainedStruct { + SurfaceDescriptorFromWaylandSurface() { + sType = SType::SurfaceDescriptorFromWaylandSurface; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * display; + void * surface; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromWindowsCoreWindow : ChainedStruct { + SurfaceDescriptorFromWindowsCoreWindow() { + sType = SType::SurfaceDescriptorFromWindowsCoreWindow; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * coreWindow; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromWindowsHWND : ChainedStruct { + SurfaceDescriptorFromWindowsHWND() { + sType = SType::SurfaceDescriptorFromWindowsHWND; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * hinstance; + void * hwnd; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromWindowsSwapChainPanel : ChainedStruct { + SurfaceDescriptorFromWindowsSwapChainPanel() { + sType = SType::SurfaceDescriptorFromWindowsSwapChainPanel; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * swapChainPanel; + }; + + // Can be chained in SurfaceDescriptor + struct SurfaceDescriptorFromXlibWindow : ChainedStruct { + SurfaceDescriptorFromXlibWindow() { + sType = SType::SurfaceDescriptorFromXlibWindow; + } + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(void * )); + alignas(kFirstMemberAlignment) void * display; + uint32_t window; + }; + + struct SwapChainDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + TextureUsage usage; + TextureFormat format; + uint32_t width; + uint32_t height; + PresentMode presentMode; + }; + + struct TextureBindingLayout { + ChainedStruct const * nextInChain = nullptr; + TextureSampleType sampleType = TextureSampleType::Undefined; + TextureViewDimension viewDimension = TextureViewDimension::Undefined; + bool multisampled = false; + }; + + struct TextureDataLayout { + ChainedStruct const * nextInChain = nullptr; + uint64_t offset = 0; + uint32_t bytesPerRow = WGPU_COPY_STRIDE_UNDEFINED; + uint32_t rowsPerImage = WGPU_COPY_STRIDE_UNDEFINED; + }; + + struct TextureViewDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + TextureFormat format = TextureFormat::Undefined; + TextureViewDimension dimension = TextureViewDimension::Undefined; + uint32_t baseMipLevel = 0; + uint32_t mipLevelCount = WGPU_MIP_LEVEL_COUNT_UNDEFINED; + uint32_t baseArrayLayer = 0; + uint32_t arrayLayerCount = WGPU_ARRAY_LAYER_COUNT_UNDEFINED; + TextureAspect aspect = TextureAspect::All; + }; + + struct VertexAttribute { + VertexFormat format; + uint64_t offset; + uint32_t shaderLocation; + }; + + struct BindGroupDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + BindGroupLayout layout; + size_t entryCount; + BindGroupEntry const * entries; + }; + + struct BindGroupLayoutEntry { + ChainedStruct const * nextInChain = nullptr; + uint32_t binding; + ShaderStage visibility; + BufferBindingLayout buffer; + SamplerBindingLayout sampler; + TextureBindingLayout texture; + StorageTextureBindingLayout storageTexture; + }; + + struct BlendState { + BlendComponent color; + BlendComponent alpha; + }; + + struct CompilationInfo { + ChainedStruct const * nextInChain = nullptr; + size_t messageCount; + CompilationMessage const * messages; + }; + + struct ComputePassDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t timestampWriteCount = 0; + ComputePassTimestampWrite const * timestampWrites; + }; + + struct DepthStencilState { + ChainedStruct const * nextInChain = nullptr; + TextureFormat format; + bool depthWriteEnabled; + CompareFunction depthCompare; + StencilFaceState stencilFront; + StencilFaceState stencilBack; + uint32_t stencilReadMask = 0xFFFFFFFF; + uint32_t stencilWriteMask = 0xFFFFFFFF; + int32_t depthBias = 0; + float depthBiasSlopeScale = 0.0f; + float depthBiasClamp = 0.0f; + }; + + struct ExternalTextureDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + TextureView plane0; + TextureView plane1 = nullptr; + Origin2D visibleOrigin; + Extent2D visibleSize; + bool doYuvToRgbConversionOnly = false; + float const * yuvToRgbConversionMatrix = nullptr; + float const * srcTransferFunctionParameters; + float const * dstTransferFunctionParameters; + float const * gamutConversionMatrix; + bool flipY = false; + ExternalTextureRotation rotation = ExternalTextureRotation::Rotate0Degrees; + }; + + struct ImageCopyBuffer { + ChainedStruct const * nextInChain = nullptr; + TextureDataLayout layout; + Buffer buffer; + }; + + struct ImageCopyExternalTexture { + ChainedStruct const * nextInChain = nullptr; + ExternalTexture externalTexture; + Origin3D origin; + Extent2D naturalSize; + }; + + struct ImageCopyTexture { + ChainedStruct const * nextInChain = nullptr; + Texture texture; + uint32_t mipLevel = 0; + Origin3D origin; + TextureAspect aspect = TextureAspect::All; + }; + + struct ProgrammableStageDescriptor { + ChainedStruct const * nextInChain = nullptr; + ShaderModule module; + char const * entryPoint; + size_t constantCount = 0; + ConstantEntry const * constants; + }; + + struct RenderPassColorAttachment { + ChainedStruct const * nextInChain = nullptr; + TextureView view = nullptr; + TextureView resolveTarget = nullptr; + LoadOp loadOp; + StoreOp storeOp; + Color clearValue; + }; + + struct RequiredLimits { + ChainedStruct const * nextInChain = nullptr; + Limits limits; + }; + + struct SupportedLimits { + ChainedStructOut * nextInChain = nullptr; + Limits limits; + }; + + struct TextureDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + TextureUsage usage; + TextureDimension dimension = TextureDimension::e2D; + Extent3D size; + TextureFormat format; + uint32_t mipLevelCount = 1; + uint32_t sampleCount = 1; + size_t viewFormatCount = 0; + TextureFormat const * viewFormats; + }; + + struct VertexBufferLayout { + uint64_t arrayStride; + VertexStepMode stepMode = VertexStepMode::Vertex; + size_t attributeCount; + VertexAttribute const * attributes; + }; + + struct BindGroupLayoutDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t entryCount; + BindGroupLayoutEntry const * entries; + }; + + struct ColorTargetState { + ChainedStruct const * nextInChain = nullptr; + TextureFormat format; + BlendState const * blend = nullptr; + ColorWriteMask writeMask = ColorWriteMask::All; + }; + + struct ComputePipelineDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + PipelineLayout layout = nullptr; + ProgrammableStageDescriptor compute; + }; + + struct DeviceDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t requiredFeaturesCount = 0; + FeatureName const * requiredFeatures = nullptr; + RequiredLimits const * requiredLimits = nullptr; + QueueDescriptor defaultQueue; + DeviceLostCallback deviceLostCallback = nullptr; + void * deviceLostUserdata = nullptr; + }; + + struct RenderPassDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + size_t colorAttachmentCount; + RenderPassColorAttachment const * colorAttachments; + RenderPassDepthStencilAttachment const * depthStencilAttachment = nullptr; + QuerySet occlusionQuerySet = nullptr; + size_t timestampWriteCount = 0; + RenderPassTimestampWrite const * timestampWrites; + }; + + struct VertexState { + ChainedStruct const * nextInChain = nullptr; + ShaderModule module; + char const * entryPoint; + size_t constantCount = 0; + ConstantEntry const * constants; + size_t bufferCount = 0; + VertexBufferLayout const * buffers; + }; + + struct FragmentState { + ChainedStruct const * nextInChain = nullptr; + ShaderModule module; + char const * entryPoint; + size_t constantCount = 0; + ConstantEntry const * constants; + size_t targetCount; + ColorTargetState const * targets; + }; + + struct RenderPipelineDescriptor { + ChainedStruct const * nextInChain = nullptr; + char const * label = nullptr; + PipelineLayout layout = nullptr; + VertexState vertex; + PrimitiveState primitive; + DepthStencilState const * depthStencil = nullptr; + MultisampleState multisample; + FragmentState const * fragment = nullptr; + }; + + + // The operators of EnumClassBitmmasks in the dawn:: namespace need to be imported + // in the wgpu namespace for Argument Dependent Lookup. + DAWN_IMPORT_BITMASK_OPERATORS +} // namespace wgpu + +namespace dawn { + template<> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + + template<> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + + template<> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + + template<> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + + template<> + struct IsDawnBitmask { + static constexpr bool enable = true; + }; + +} // namespace dawn + +#endif // WEBGPU_CPP_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_chained_struct.h b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_chained_struct.h new file mode 100644 index 0000000..7067902 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_chained_struct.h @@ -0,0 +1,35 @@ +#ifdef __EMSCRIPTEN__ +#error "Do not include this header. Emscripten already provides headers needed for WebGPU." +#endif +#ifndef WEBGPU_CPP_CHAINED_STRUCT_H_ +#define WEBGPU_CPP_CHAINED_STRUCT_H_ + +#include +#include + +// This header file declares the ChainedStruct structures separately from the WebGPU +// headers so that dependencies can directly extend structures without including the larger header +// which exposes capabilities that may require correctly set proc tables. +namespace wgpu { + + namespace detail { + constexpr size_t ConstexprMax(size_t a, size_t b) { + return a > b ? a : b; + } + } // namespace detail + + enum class SType : uint32_t; + + struct ChainedStruct { + ChainedStruct const * nextInChain = nullptr; + SType sType = SType(0u); + }; + + struct ChainedStructOut { + ChainedStructOut * nextInChain = nullptr; + SType sType = SType(0u); + }; + +} // namespace wgpu} + +#endif // WEBGPU_CPP_CHAINED_STRUCT_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_print.h b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_print.h new file mode 100644 index 0000000..8eea521 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/webgpu_cpp_print.h @@ -0,0 +1,1825 @@ + +#ifndef WEBGPU_CPP_PRINT_H_ +#define WEBGPU_CPP_PRINT_H_ + +#include "dawn/webgpu_cpp.h" + +#include +#include +#include +#include + +namespace wgpu { + + template + std::basic_ostream& operator<<(std::basic_ostream& o, AdapterType value) { + switch (value) { + case AdapterType::DiscreteGPU: + o << "AdapterType::DiscreteGPU"; + break; + case AdapterType::IntegratedGPU: + o << "AdapterType::IntegratedGPU"; + break; + case AdapterType::CPU: + o << "AdapterType::CPU"; + break; + case AdapterType::Unknown: + o << "AdapterType::Unknown"; + break; + default: + o << "AdapterType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, AddressMode value) { + switch (value) { + case AddressMode::Repeat: + o << "AddressMode::Repeat"; + break; + case AddressMode::MirrorRepeat: + o << "AddressMode::MirrorRepeat"; + break; + case AddressMode::ClampToEdge: + o << "AddressMode::ClampToEdge"; + break; + default: + o << "AddressMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, AlphaMode value) { + switch (value) { + case AlphaMode::Premultiplied: + o << "AlphaMode::Premultiplied"; + break; + case AlphaMode::Unpremultiplied: + o << "AlphaMode::Unpremultiplied"; + break; + case AlphaMode::Opaque: + o << "AlphaMode::Opaque"; + break; + default: + o << "AlphaMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BackendType value) { + switch (value) { + case BackendType::Undefined: + o << "BackendType::Undefined"; + break; + case BackendType::Null: + o << "BackendType::Null"; + break; + case BackendType::WebGPU: + o << "BackendType::WebGPU"; + break; + case BackendType::D3D11: + o << "BackendType::D3D11"; + break; + case BackendType::D3D12: + o << "BackendType::D3D12"; + break; + case BackendType::Metal: + o << "BackendType::Metal"; + break; + case BackendType::Vulkan: + o << "BackendType::Vulkan"; + break; + case BackendType::OpenGL: + o << "BackendType::OpenGL"; + break; + case BackendType::OpenGLES: + o << "BackendType::OpenGLES"; + break; + default: + o << "BackendType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BlendFactor value) { + switch (value) { + case BlendFactor::Zero: + o << "BlendFactor::Zero"; + break; + case BlendFactor::One: + o << "BlendFactor::One"; + break; + case BlendFactor::Src: + o << "BlendFactor::Src"; + break; + case BlendFactor::OneMinusSrc: + o << "BlendFactor::OneMinusSrc"; + break; + case BlendFactor::SrcAlpha: + o << "BlendFactor::SrcAlpha"; + break; + case BlendFactor::OneMinusSrcAlpha: + o << "BlendFactor::OneMinusSrcAlpha"; + break; + case BlendFactor::Dst: + o << "BlendFactor::Dst"; + break; + case BlendFactor::OneMinusDst: + o << "BlendFactor::OneMinusDst"; + break; + case BlendFactor::DstAlpha: + o << "BlendFactor::DstAlpha"; + break; + case BlendFactor::OneMinusDstAlpha: + o << "BlendFactor::OneMinusDstAlpha"; + break; + case BlendFactor::SrcAlphaSaturated: + o << "BlendFactor::SrcAlphaSaturated"; + break; + case BlendFactor::Constant: + o << "BlendFactor::Constant"; + break; + case BlendFactor::OneMinusConstant: + o << "BlendFactor::OneMinusConstant"; + break; + default: + o << "BlendFactor::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BlendOperation value) { + switch (value) { + case BlendOperation::Add: + o << "BlendOperation::Add"; + break; + case BlendOperation::Subtract: + o << "BlendOperation::Subtract"; + break; + case BlendOperation::ReverseSubtract: + o << "BlendOperation::ReverseSubtract"; + break; + case BlendOperation::Min: + o << "BlendOperation::Min"; + break; + case BlendOperation::Max: + o << "BlendOperation::Max"; + break; + default: + o << "BlendOperation::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BufferBindingType value) { + switch (value) { + case BufferBindingType::Undefined: + o << "BufferBindingType::Undefined"; + break; + case BufferBindingType::Uniform: + o << "BufferBindingType::Uniform"; + break; + case BufferBindingType::Storage: + o << "BufferBindingType::Storage"; + break; + case BufferBindingType::ReadOnlyStorage: + o << "BufferBindingType::ReadOnlyStorage"; + break; + default: + o << "BufferBindingType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BufferMapAsyncStatus value) { + switch (value) { + case BufferMapAsyncStatus::Success: + o << "BufferMapAsyncStatus::Success"; + break; + case BufferMapAsyncStatus::ValidationError: + o << "BufferMapAsyncStatus::ValidationError"; + break; + case BufferMapAsyncStatus::Unknown: + o << "BufferMapAsyncStatus::Unknown"; + break; + case BufferMapAsyncStatus::DeviceLost: + o << "BufferMapAsyncStatus::DeviceLost"; + break; + case BufferMapAsyncStatus::DestroyedBeforeCallback: + o << "BufferMapAsyncStatus::DestroyedBeforeCallback"; + break; + case BufferMapAsyncStatus::UnmappedBeforeCallback: + o << "BufferMapAsyncStatus::UnmappedBeforeCallback"; + break; + case BufferMapAsyncStatus::MappingAlreadyPending: + o << "BufferMapAsyncStatus::MappingAlreadyPending"; + break; + case BufferMapAsyncStatus::OffsetOutOfRange: + o << "BufferMapAsyncStatus::OffsetOutOfRange"; + break; + case BufferMapAsyncStatus::SizeOutOfRange: + o << "BufferMapAsyncStatus::SizeOutOfRange"; + break; + default: + o << "BufferMapAsyncStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, BufferMapState value) { + switch (value) { + case BufferMapState::Unmapped: + o << "BufferMapState::Unmapped"; + break; + case BufferMapState::Pending: + o << "BufferMapState::Pending"; + break; + case BufferMapState::Mapped: + o << "BufferMapState::Mapped"; + break; + default: + o << "BufferMapState::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, CompareFunction value) { + switch (value) { + case CompareFunction::Undefined: + o << "CompareFunction::Undefined"; + break; + case CompareFunction::Never: + o << "CompareFunction::Never"; + break; + case CompareFunction::Less: + o << "CompareFunction::Less"; + break; + case CompareFunction::LessEqual: + o << "CompareFunction::LessEqual"; + break; + case CompareFunction::Greater: + o << "CompareFunction::Greater"; + break; + case CompareFunction::GreaterEqual: + o << "CompareFunction::GreaterEqual"; + break; + case CompareFunction::Equal: + o << "CompareFunction::Equal"; + break; + case CompareFunction::NotEqual: + o << "CompareFunction::NotEqual"; + break; + case CompareFunction::Always: + o << "CompareFunction::Always"; + break; + default: + o << "CompareFunction::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, CompilationInfoRequestStatus value) { + switch (value) { + case CompilationInfoRequestStatus::Success: + o << "CompilationInfoRequestStatus::Success"; + break; + case CompilationInfoRequestStatus::Error: + o << "CompilationInfoRequestStatus::Error"; + break; + case CompilationInfoRequestStatus::DeviceLost: + o << "CompilationInfoRequestStatus::DeviceLost"; + break; + case CompilationInfoRequestStatus::Unknown: + o << "CompilationInfoRequestStatus::Unknown"; + break; + default: + o << "CompilationInfoRequestStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, CompilationMessageType value) { + switch (value) { + case CompilationMessageType::Error: + o << "CompilationMessageType::Error"; + break; + case CompilationMessageType::Warning: + o << "CompilationMessageType::Warning"; + break; + case CompilationMessageType::Info: + o << "CompilationMessageType::Info"; + break; + default: + o << "CompilationMessageType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ComputePassTimestampLocation value) { + switch (value) { + case ComputePassTimestampLocation::Beginning: + o << "ComputePassTimestampLocation::Beginning"; + break; + case ComputePassTimestampLocation::End: + o << "ComputePassTimestampLocation::End"; + break; + default: + o << "ComputePassTimestampLocation::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, CreatePipelineAsyncStatus value) { + switch (value) { + case CreatePipelineAsyncStatus::Success: + o << "CreatePipelineAsyncStatus::Success"; + break; + case CreatePipelineAsyncStatus::ValidationError: + o << "CreatePipelineAsyncStatus::ValidationError"; + break; + case CreatePipelineAsyncStatus::InternalError: + o << "CreatePipelineAsyncStatus::InternalError"; + break; + case CreatePipelineAsyncStatus::DeviceLost: + o << "CreatePipelineAsyncStatus::DeviceLost"; + break; + case CreatePipelineAsyncStatus::DeviceDestroyed: + o << "CreatePipelineAsyncStatus::DeviceDestroyed"; + break; + case CreatePipelineAsyncStatus::Unknown: + o << "CreatePipelineAsyncStatus::Unknown"; + break; + default: + o << "CreatePipelineAsyncStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, CullMode value) { + switch (value) { + case CullMode::None: + o << "CullMode::None"; + break; + case CullMode::Front: + o << "CullMode::Front"; + break; + case CullMode::Back: + o << "CullMode::Back"; + break; + default: + o << "CullMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, DeviceLostReason value) { + switch (value) { + case DeviceLostReason::Undefined: + o << "DeviceLostReason::Undefined"; + break; + case DeviceLostReason::Destroyed: + o << "DeviceLostReason::Destroyed"; + break; + default: + o << "DeviceLostReason::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ErrorFilter value) { + switch (value) { + case ErrorFilter::Validation: + o << "ErrorFilter::Validation"; + break; + case ErrorFilter::OutOfMemory: + o << "ErrorFilter::OutOfMemory"; + break; + case ErrorFilter::Internal: + o << "ErrorFilter::Internal"; + break; + default: + o << "ErrorFilter::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ErrorType value) { + switch (value) { + case ErrorType::NoError: + o << "ErrorType::NoError"; + break; + case ErrorType::Validation: + o << "ErrorType::Validation"; + break; + case ErrorType::OutOfMemory: + o << "ErrorType::OutOfMemory"; + break; + case ErrorType::Internal: + o << "ErrorType::Internal"; + break; + case ErrorType::Unknown: + o << "ErrorType::Unknown"; + break; + case ErrorType::DeviceLost: + o << "ErrorType::DeviceLost"; + break; + default: + o << "ErrorType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ExternalTextureRotation value) { + switch (value) { + case ExternalTextureRotation::Rotate0Degrees: + o << "ExternalTextureRotation::Rotate0Degrees"; + break; + case ExternalTextureRotation::Rotate90Degrees: + o << "ExternalTextureRotation::Rotate90Degrees"; + break; + case ExternalTextureRotation::Rotate180Degrees: + o << "ExternalTextureRotation::Rotate180Degrees"; + break; + case ExternalTextureRotation::Rotate270Degrees: + o << "ExternalTextureRotation::Rotate270Degrees"; + break; + default: + o << "ExternalTextureRotation::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, FeatureName value) { + switch (value) { + case FeatureName::Undefined: + o << "FeatureName::Undefined"; + break; + case FeatureName::DepthClipControl: + o << "FeatureName::DepthClipControl"; + break; + case FeatureName::Depth32FloatStencil8: + o << "FeatureName::Depth32FloatStencil8"; + break; + case FeatureName::TimestampQuery: + o << "FeatureName::TimestampQuery"; + break; + case FeatureName::PipelineStatisticsQuery: + o << "FeatureName::PipelineStatisticsQuery"; + break; + case FeatureName::TextureCompressionBC: + o << "FeatureName::TextureCompressionBC"; + break; + case FeatureName::TextureCompressionETC2: + o << "FeatureName::TextureCompressionETC2"; + break; + case FeatureName::TextureCompressionASTC: + o << "FeatureName::TextureCompressionASTC"; + break; + case FeatureName::IndirectFirstInstance: + o << "FeatureName::IndirectFirstInstance"; + break; + case FeatureName::ShaderF16: + o << "FeatureName::ShaderF16"; + break; + case FeatureName::RG11B10UfloatRenderable: + o << "FeatureName::RG11B10UfloatRenderable"; + break; + case FeatureName::BGRA8UnormStorage: + o << "FeatureName::BGRA8UnormStorage"; + break; + case FeatureName::Float32Filterable: + o << "FeatureName::Float32Filterable"; + break; + case FeatureName::DawnShaderFloat16: + o << "FeatureName::DawnShaderFloat16"; + break; + case FeatureName::DawnInternalUsages: + o << "FeatureName::DawnInternalUsages"; + break; + case FeatureName::DawnMultiPlanarFormats: + o << "FeatureName::DawnMultiPlanarFormats"; + break; + case FeatureName::DawnNative: + o << "FeatureName::DawnNative"; + break; + case FeatureName::ChromiumExperimentalDp4a: + o << "FeatureName::ChromiumExperimentalDp4a"; + break; + case FeatureName::TimestampQueryInsidePasses: + o << "FeatureName::TimestampQueryInsidePasses"; + break; + case FeatureName::ImplicitDeviceSynchronization: + o << "FeatureName::ImplicitDeviceSynchronization"; + break; + case FeatureName::SurfaceCapabilities: + o << "FeatureName::SurfaceCapabilities"; + break; + case FeatureName::TransientAttachments: + o << "FeatureName::TransientAttachments"; + break; + case FeatureName::MSAARenderToSingleSampled: + o << "FeatureName::MSAARenderToSingleSampled"; + break; + default: + o << "FeatureName::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, FilterMode value) { + switch (value) { + case FilterMode::Nearest: + o << "FilterMode::Nearest"; + break; + case FilterMode::Linear: + o << "FilterMode::Linear"; + break; + default: + o << "FilterMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, FrontFace value) { + switch (value) { + case FrontFace::CCW: + o << "FrontFace::CCW"; + break; + case FrontFace::CW: + o << "FrontFace::CW"; + break; + default: + o << "FrontFace::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, IndexFormat value) { + switch (value) { + case IndexFormat::Undefined: + o << "IndexFormat::Undefined"; + break; + case IndexFormat::Uint16: + o << "IndexFormat::Uint16"; + break; + case IndexFormat::Uint32: + o << "IndexFormat::Uint32"; + break; + default: + o << "IndexFormat::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, LoadOp value) { + switch (value) { + case LoadOp::Undefined: + o << "LoadOp::Undefined"; + break; + case LoadOp::Clear: + o << "LoadOp::Clear"; + break; + case LoadOp::Load: + o << "LoadOp::Load"; + break; + default: + o << "LoadOp::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, LoggingType value) { + switch (value) { + case LoggingType::Verbose: + o << "LoggingType::Verbose"; + break; + case LoggingType::Info: + o << "LoggingType::Info"; + break; + case LoggingType::Warning: + o << "LoggingType::Warning"; + break; + case LoggingType::Error: + o << "LoggingType::Error"; + break; + default: + o << "LoggingType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, MipmapFilterMode value) { + switch (value) { + case MipmapFilterMode::Nearest: + o << "MipmapFilterMode::Nearest"; + break; + case MipmapFilterMode::Linear: + o << "MipmapFilterMode::Linear"; + break; + default: + o << "MipmapFilterMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, PipelineStatisticName value) { + switch (value) { + case PipelineStatisticName::VertexShaderInvocations: + o << "PipelineStatisticName::VertexShaderInvocations"; + break; + case PipelineStatisticName::ClipperInvocations: + o << "PipelineStatisticName::ClipperInvocations"; + break; + case PipelineStatisticName::ClipperPrimitivesOut: + o << "PipelineStatisticName::ClipperPrimitivesOut"; + break; + case PipelineStatisticName::FragmentShaderInvocations: + o << "PipelineStatisticName::FragmentShaderInvocations"; + break; + case PipelineStatisticName::ComputeShaderInvocations: + o << "PipelineStatisticName::ComputeShaderInvocations"; + break; + default: + o << "PipelineStatisticName::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, PowerPreference value) { + switch (value) { + case PowerPreference::Undefined: + o << "PowerPreference::Undefined"; + break; + case PowerPreference::LowPower: + o << "PowerPreference::LowPower"; + break; + case PowerPreference::HighPerformance: + o << "PowerPreference::HighPerformance"; + break; + default: + o << "PowerPreference::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, PresentMode value) { + switch (value) { + case PresentMode::Immediate: + o << "PresentMode::Immediate"; + break; + case PresentMode::Mailbox: + o << "PresentMode::Mailbox"; + break; + case PresentMode::Fifo: + o << "PresentMode::Fifo"; + break; + default: + o << "PresentMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, PrimitiveTopology value) { + switch (value) { + case PrimitiveTopology::PointList: + o << "PrimitiveTopology::PointList"; + break; + case PrimitiveTopology::LineList: + o << "PrimitiveTopology::LineList"; + break; + case PrimitiveTopology::LineStrip: + o << "PrimitiveTopology::LineStrip"; + break; + case PrimitiveTopology::TriangleList: + o << "PrimitiveTopology::TriangleList"; + break; + case PrimitiveTopology::TriangleStrip: + o << "PrimitiveTopology::TriangleStrip"; + break; + default: + o << "PrimitiveTopology::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, QueryType value) { + switch (value) { + case QueryType::Occlusion: + o << "QueryType::Occlusion"; + break; + case QueryType::PipelineStatistics: + o << "QueryType::PipelineStatistics"; + break; + case QueryType::Timestamp: + o << "QueryType::Timestamp"; + break; + default: + o << "QueryType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, QueueWorkDoneStatus value) { + switch (value) { + case QueueWorkDoneStatus::Success: + o << "QueueWorkDoneStatus::Success"; + break; + case QueueWorkDoneStatus::Error: + o << "QueueWorkDoneStatus::Error"; + break; + case QueueWorkDoneStatus::Unknown: + o << "QueueWorkDoneStatus::Unknown"; + break; + case QueueWorkDoneStatus::DeviceLost: + o << "QueueWorkDoneStatus::DeviceLost"; + break; + default: + o << "QueueWorkDoneStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, RenderPassTimestampLocation value) { + switch (value) { + case RenderPassTimestampLocation::Beginning: + o << "RenderPassTimestampLocation::Beginning"; + break; + case RenderPassTimestampLocation::End: + o << "RenderPassTimestampLocation::End"; + break; + default: + o << "RenderPassTimestampLocation::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, RequestAdapterStatus value) { + switch (value) { + case RequestAdapterStatus::Success: + o << "RequestAdapterStatus::Success"; + break; + case RequestAdapterStatus::Unavailable: + o << "RequestAdapterStatus::Unavailable"; + break; + case RequestAdapterStatus::Error: + o << "RequestAdapterStatus::Error"; + break; + case RequestAdapterStatus::Unknown: + o << "RequestAdapterStatus::Unknown"; + break; + default: + o << "RequestAdapterStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, RequestDeviceStatus value) { + switch (value) { + case RequestDeviceStatus::Success: + o << "RequestDeviceStatus::Success"; + break; + case RequestDeviceStatus::Error: + o << "RequestDeviceStatus::Error"; + break; + case RequestDeviceStatus::Unknown: + o << "RequestDeviceStatus::Unknown"; + break; + default: + o << "RequestDeviceStatus::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, SType value) { + switch (value) { + case SType::Invalid: + o << "SType::Invalid"; + break; + case SType::SurfaceDescriptorFromMetalLayer: + o << "SType::SurfaceDescriptorFromMetalLayer"; + break; + case SType::SurfaceDescriptorFromWindowsHWND: + o << "SType::SurfaceDescriptorFromWindowsHWND"; + break; + case SType::SurfaceDescriptorFromXlibWindow: + o << "SType::SurfaceDescriptorFromXlibWindow"; + break; + case SType::SurfaceDescriptorFromCanvasHTMLSelector: + o << "SType::SurfaceDescriptorFromCanvasHTMLSelector"; + break; + case SType::ShaderModuleSPIRVDescriptor: + o << "SType::ShaderModuleSPIRVDescriptor"; + break; + case SType::ShaderModuleWGSLDescriptor: + o << "SType::ShaderModuleWGSLDescriptor"; + break; + case SType::PrimitiveDepthClipControl: + o << "SType::PrimitiveDepthClipControl"; + break; + case SType::SurfaceDescriptorFromWaylandSurface: + o << "SType::SurfaceDescriptorFromWaylandSurface"; + break; + case SType::SurfaceDescriptorFromAndroidNativeWindow: + o << "SType::SurfaceDescriptorFromAndroidNativeWindow"; + break; + case SType::SurfaceDescriptorFromWindowsCoreWindow: + o << "SType::SurfaceDescriptorFromWindowsCoreWindow"; + break; + case SType::ExternalTextureBindingEntry: + o << "SType::ExternalTextureBindingEntry"; + break; + case SType::ExternalTextureBindingLayout: + o << "SType::ExternalTextureBindingLayout"; + break; + case SType::SurfaceDescriptorFromWindowsSwapChainPanel: + o << "SType::SurfaceDescriptorFromWindowsSwapChainPanel"; + break; + case SType::RenderPassDescriptorMaxDrawCount: + o << "SType::RenderPassDescriptorMaxDrawCount"; + break; + case SType::DawnTextureInternalUsageDescriptor: + o << "SType::DawnTextureInternalUsageDescriptor"; + break; + case SType::DawnEncoderInternalUsageDescriptor: + o << "SType::DawnEncoderInternalUsageDescriptor"; + break; + case SType::DawnInstanceDescriptor: + o << "SType::DawnInstanceDescriptor"; + break; + case SType::DawnCacheDeviceDescriptor: + o << "SType::DawnCacheDeviceDescriptor"; + break; + case SType::DawnAdapterPropertiesPowerPreference: + o << "SType::DawnAdapterPropertiesPowerPreference"; + break; + case SType::DawnBufferDescriptorErrorInfoFromWireClient: + o << "SType::DawnBufferDescriptorErrorInfoFromWireClient"; + break; + case SType::DawnTogglesDescriptor: + o << "SType::DawnTogglesDescriptor"; + break; + case SType::DawnShaderModuleSPIRVOptionsDescriptor: + o << "SType::DawnShaderModuleSPIRVOptionsDescriptor"; + break; + case SType::RequestAdapterOptionsLUID: + o << "SType::RequestAdapterOptionsLUID"; + break; + case SType::RequestAdapterOptionsGetGLProc: + o << "SType::RequestAdapterOptionsGetGLProc"; + break; + case SType::DawnMultisampleStateRenderToSingleSampled: + o << "SType::DawnMultisampleStateRenderToSingleSampled"; + break; + case SType::DawnRenderPassColorAttachmentRenderToSingleSampled: + o << "SType::DawnRenderPassColorAttachmentRenderToSingleSampled"; + break; + default: + o << "SType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, SamplerBindingType value) { + switch (value) { + case SamplerBindingType::Undefined: + o << "SamplerBindingType::Undefined"; + break; + case SamplerBindingType::Filtering: + o << "SamplerBindingType::Filtering"; + break; + case SamplerBindingType::NonFiltering: + o << "SamplerBindingType::NonFiltering"; + break; + case SamplerBindingType::Comparison: + o << "SamplerBindingType::Comparison"; + break; + default: + o << "SamplerBindingType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, StencilOperation value) { + switch (value) { + case StencilOperation::Keep: + o << "StencilOperation::Keep"; + break; + case StencilOperation::Zero: + o << "StencilOperation::Zero"; + break; + case StencilOperation::Replace: + o << "StencilOperation::Replace"; + break; + case StencilOperation::Invert: + o << "StencilOperation::Invert"; + break; + case StencilOperation::IncrementClamp: + o << "StencilOperation::IncrementClamp"; + break; + case StencilOperation::DecrementClamp: + o << "StencilOperation::DecrementClamp"; + break; + case StencilOperation::IncrementWrap: + o << "StencilOperation::IncrementWrap"; + break; + case StencilOperation::DecrementWrap: + o << "StencilOperation::DecrementWrap"; + break; + default: + o << "StencilOperation::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, StorageTextureAccess value) { + switch (value) { + case StorageTextureAccess::Undefined: + o << "StorageTextureAccess::Undefined"; + break; + case StorageTextureAccess::WriteOnly: + o << "StorageTextureAccess::WriteOnly"; + break; + default: + o << "StorageTextureAccess::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, StoreOp value) { + switch (value) { + case StoreOp::Undefined: + o << "StoreOp::Undefined"; + break; + case StoreOp::Store: + o << "StoreOp::Store"; + break; + case StoreOp::Discard: + o << "StoreOp::Discard"; + break; + default: + o << "StoreOp::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureAspect value) { + switch (value) { + case TextureAspect::All: + o << "TextureAspect::All"; + break; + case TextureAspect::StencilOnly: + o << "TextureAspect::StencilOnly"; + break; + case TextureAspect::DepthOnly: + o << "TextureAspect::DepthOnly"; + break; + case TextureAspect::Plane0Only: + o << "TextureAspect::Plane0Only"; + break; + case TextureAspect::Plane1Only: + o << "TextureAspect::Plane1Only"; + break; + default: + o << "TextureAspect::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureDimension value) { + switch (value) { + case TextureDimension::e1D: + o << "TextureDimension::e1D"; + break; + case TextureDimension::e2D: + o << "TextureDimension::e2D"; + break; + case TextureDimension::e3D: + o << "TextureDimension::e3D"; + break; + default: + o << "TextureDimension::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureFormat value) { + switch (value) { + case TextureFormat::Undefined: + o << "TextureFormat::Undefined"; + break; + case TextureFormat::R8Unorm: + o << "TextureFormat::R8Unorm"; + break; + case TextureFormat::R8Snorm: + o << "TextureFormat::R8Snorm"; + break; + case TextureFormat::R8Uint: + o << "TextureFormat::R8Uint"; + break; + case TextureFormat::R8Sint: + o << "TextureFormat::R8Sint"; + break; + case TextureFormat::R16Uint: + o << "TextureFormat::R16Uint"; + break; + case TextureFormat::R16Sint: + o << "TextureFormat::R16Sint"; + break; + case TextureFormat::R16Float: + o << "TextureFormat::R16Float"; + break; + case TextureFormat::RG8Unorm: + o << "TextureFormat::RG8Unorm"; + break; + case TextureFormat::RG8Snorm: + o << "TextureFormat::RG8Snorm"; + break; + case TextureFormat::RG8Uint: + o << "TextureFormat::RG8Uint"; + break; + case TextureFormat::RG8Sint: + o << "TextureFormat::RG8Sint"; + break; + case TextureFormat::R32Float: + o << "TextureFormat::R32Float"; + break; + case TextureFormat::R32Uint: + o << "TextureFormat::R32Uint"; + break; + case TextureFormat::R32Sint: + o << "TextureFormat::R32Sint"; + break; + case TextureFormat::RG16Uint: + o << "TextureFormat::RG16Uint"; + break; + case TextureFormat::RG16Sint: + o << "TextureFormat::RG16Sint"; + break; + case TextureFormat::RG16Float: + o << "TextureFormat::RG16Float"; + break; + case TextureFormat::RGBA8Unorm: + o << "TextureFormat::RGBA8Unorm"; + break; + case TextureFormat::RGBA8UnormSrgb: + o << "TextureFormat::RGBA8UnormSrgb"; + break; + case TextureFormat::RGBA8Snorm: + o << "TextureFormat::RGBA8Snorm"; + break; + case TextureFormat::RGBA8Uint: + o << "TextureFormat::RGBA8Uint"; + break; + case TextureFormat::RGBA8Sint: + o << "TextureFormat::RGBA8Sint"; + break; + case TextureFormat::BGRA8Unorm: + o << "TextureFormat::BGRA8Unorm"; + break; + case TextureFormat::BGRA8UnormSrgb: + o << "TextureFormat::BGRA8UnormSrgb"; + break; + case TextureFormat::RGB10A2Unorm: + o << "TextureFormat::RGB10A2Unorm"; + break; + case TextureFormat::RG11B10Ufloat: + o << "TextureFormat::RG11B10Ufloat"; + break; + case TextureFormat::RGB9E5Ufloat: + o << "TextureFormat::RGB9E5Ufloat"; + break; + case TextureFormat::RG32Float: + o << "TextureFormat::RG32Float"; + break; + case TextureFormat::RG32Uint: + o << "TextureFormat::RG32Uint"; + break; + case TextureFormat::RG32Sint: + o << "TextureFormat::RG32Sint"; + break; + case TextureFormat::RGBA16Uint: + o << "TextureFormat::RGBA16Uint"; + break; + case TextureFormat::RGBA16Sint: + o << "TextureFormat::RGBA16Sint"; + break; + case TextureFormat::RGBA16Float: + o << "TextureFormat::RGBA16Float"; + break; + case TextureFormat::RGBA32Float: + o << "TextureFormat::RGBA32Float"; + break; + case TextureFormat::RGBA32Uint: + o << "TextureFormat::RGBA32Uint"; + break; + case TextureFormat::RGBA32Sint: + o << "TextureFormat::RGBA32Sint"; + break; + case TextureFormat::Stencil8: + o << "TextureFormat::Stencil8"; + break; + case TextureFormat::Depth16Unorm: + o << "TextureFormat::Depth16Unorm"; + break; + case TextureFormat::Depth24Plus: + o << "TextureFormat::Depth24Plus"; + break; + case TextureFormat::Depth24PlusStencil8: + o << "TextureFormat::Depth24PlusStencil8"; + break; + case TextureFormat::Depth32Float: + o << "TextureFormat::Depth32Float"; + break; + case TextureFormat::Depth32FloatStencil8: + o << "TextureFormat::Depth32FloatStencil8"; + break; + case TextureFormat::BC1RGBAUnorm: + o << "TextureFormat::BC1RGBAUnorm"; + break; + case TextureFormat::BC1RGBAUnormSrgb: + o << "TextureFormat::BC1RGBAUnormSrgb"; + break; + case TextureFormat::BC2RGBAUnorm: + o << "TextureFormat::BC2RGBAUnorm"; + break; + case TextureFormat::BC2RGBAUnormSrgb: + o << "TextureFormat::BC2RGBAUnormSrgb"; + break; + case TextureFormat::BC3RGBAUnorm: + o << "TextureFormat::BC3RGBAUnorm"; + break; + case TextureFormat::BC3RGBAUnormSrgb: + o << "TextureFormat::BC3RGBAUnormSrgb"; + break; + case TextureFormat::BC4RUnorm: + o << "TextureFormat::BC4RUnorm"; + break; + case TextureFormat::BC4RSnorm: + o << "TextureFormat::BC4RSnorm"; + break; + case TextureFormat::BC5RGUnorm: + o << "TextureFormat::BC5RGUnorm"; + break; + case TextureFormat::BC5RGSnorm: + o << "TextureFormat::BC5RGSnorm"; + break; + case TextureFormat::BC6HRGBUfloat: + o << "TextureFormat::BC6HRGBUfloat"; + break; + case TextureFormat::BC6HRGBFloat: + o << "TextureFormat::BC6HRGBFloat"; + break; + case TextureFormat::BC7RGBAUnorm: + o << "TextureFormat::BC7RGBAUnorm"; + break; + case TextureFormat::BC7RGBAUnormSrgb: + o << "TextureFormat::BC7RGBAUnormSrgb"; + break; + case TextureFormat::ETC2RGB8Unorm: + o << "TextureFormat::ETC2RGB8Unorm"; + break; + case TextureFormat::ETC2RGB8UnormSrgb: + o << "TextureFormat::ETC2RGB8UnormSrgb"; + break; + case TextureFormat::ETC2RGB8A1Unorm: + o << "TextureFormat::ETC2RGB8A1Unorm"; + break; + case TextureFormat::ETC2RGB8A1UnormSrgb: + o << "TextureFormat::ETC2RGB8A1UnormSrgb"; + break; + case TextureFormat::ETC2RGBA8Unorm: + o << "TextureFormat::ETC2RGBA8Unorm"; + break; + case TextureFormat::ETC2RGBA8UnormSrgb: + o << "TextureFormat::ETC2RGBA8UnormSrgb"; + break; + case TextureFormat::EACR11Unorm: + o << "TextureFormat::EACR11Unorm"; + break; + case TextureFormat::EACR11Snorm: + o << "TextureFormat::EACR11Snorm"; + break; + case TextureFormat::EACRG11Unorm: + o << "TextureFormat::EACRG11Unorm"; + break; + case TextureFormat::EACRG11Snorm: + o << "TextureFormat::EACRG11Snorm"; + break; + case TextureFormat::ASTC4x4Unorm: + o << "TextureFormat::ASTC4x4Unorm"; + break; + case TextureFormat::ASTC4x4UnormSrgb: + o << "TextureFormat::ASTC4x4UnormSrgb"; + break; + case TextureFormat::ASTC5x4Unorm: + o << "TextureFormat::ASTC5x4Unorm"; + break; + case TextureFormat::ASTC5x4UnormSrgb: + o << "TextureFormat::ASTC5x4UnormSrgb"; + break; + case TextureFormat::ASTC5x5Unorm: + o << "TextureFormat::ASTC5x5Unorm"; + break; + case TextureFormat::ASTC5x5UnormSrgb: + o << "TextureFormat::ASTC5x5UnormSrgb"; + break; + case TextureFormat::ASTC6x5Unorm: + o << "TextureFormat::ASTC6x5Unorm"; + break; + case TextureFormat::ASTC6x5UnormSrgb: + o << "TextureFormat::ASTC6x5UnormSrgb"; + break; + case TextureFormat::ASTC6x6Unorm: + o << "TextureFormat::ASTC6x6Unorm"; + break; + case TextureFormat::ASTC6x6UnormSrgb: + o << "TextureFormat::ASTC6x6UnormSrgb"; + break; + case TextureFormat::ASTC8x5Unorm: + o << "TextureFormat::ASTC8x5Unorm"; + break; + case TextureFormat::ASTC8x5UnormSrgb: + o << "TextureFormat::ASTC8x5UnormSrgb"; + break; + case TextureFormat::ASTC8x6Unorm: + o << "TextureFormat::ASTC8x6Unorm"; + break; + case TextureFormat::ASTC8x6UnormSrgb: + o << "TextureFormat::ASTC8x6UnormSrgb"; + break; + case TextureFormat::ASTC8x8Unorm: + o << "TextureFormat::ASTC8x8Unorm"; + break; + case TextureFormat::ASTC8x8UnormSrgb: + o << "TextureFormat::ASTC8x8UnormSrgb"; + break; + case TextureFormat::ASTC10x5Unorm: + o << "TextureFormat::ASTC10x5Unorm"; + break; + case TextureFormat::ASTC10x5UnormSrgb: + o << "TextureFormat::ASTC10x5UnormSrgb"; + break; + case TextureFormat::ASTC10x6Unorm: + o << "TextureFormat::ASTC10x6Unorm"; + break; + case TextureFormat::ASTC10x6UnormSrgb: + o << "TextureFormat::ASTC10x6UnormSrgb"; + break; + case TextureFormat::ASTC10x8Unorm: + o << "TextureFormat::ASTC10x8Unorm"; + break; + case TextureFormat::ASTC10x8UnormSrgb: + o << "TextureFormat::ASTC10x8UnormSrgb"; + break; + case TextureFormat::ASTC10x10Unorm: + o << "TextureFormat::ASTC10x10Unorm"; + break; + case TextureFormat::ASTC10x10UnormSrgb: + o << "TextureFormat::ASTC10x10UnormSrgb"; + break; + case TextureFormat::ASTC12x10Unorm: + o << "TextureFormat::ASTC12x10Unorm"; + break; + case TextureFormat::ASTC12x10UnormSrgb: + o << "TextureFormat::ASTC12x10UnormSrgb"; + break; + case TextureFormat::ASTC12x12Unorm: + o << "TextureFormat::ASTC12x12Unorm"; + break; + case TextureFormat::ASTC12x12UnormSrgb: + o << "TextureFormat::ASTC12x12UnormSrgb"; + break; + case TextureFormat::R8BG8Biplanar420Unorm: + o << "TextureFormat::R8BG8Biplanar420Unorm"; + break; + default: + o << "TextureFormat::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureSampleType value) { + switch (value) { + case TextureSampleType::Undefined: + o << "TextureSampleType::Undefined"; + break; + case TextureSampleType::Float: + o << "TextureSampleType::Float"; + break; + case TextureSampleType::UnfilterableFloat: + o << "TextureSampleType::UnfilterableFloat"; + break; + case TextureSampleType::Depth: + o << "TextureSampleType::Depth"; + break; + case TextureSampleType::Sint: + o << "TextureSampleType::Sint"; + break; + case TextureSampleType::Uint: + o << "TextureSampleType::Uint"; + break; + default: + o << "TextureSampleType::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureViewDimension value) { + switch (value) { + case TextureViewDimension::Undefined: + o << "TextureViewDimension::Undefined"; + break; + case TextureViewDimension::e1D: + o << "TextureViewDimension::e1D"; + break; + case TextureViewDimension::e2D: + o << "TextureViewDimension::e2D"; + break; + case TextureViewDimension::e2DArray: + o << "TextureViewDimension::e2DArray"; + break; + case TextureViewDimension::Cube: + o << "TextureViewDimension::Cube"; + break; + case TextureViewDimension::CubeArray: + o << "TextureViewDimension::CubeArray"; + break; + case TextureViewDimension::e3D: + o << "TextureViewDimension::e3D"; + break; + default: + o << "TextureViewDimension::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, VertexFormat value) { + switch (value) { + case VertexFormat::Undefined: + o << "VertexFormat::Undefined"; + break; + case VertexFormat::Uint8x2: + o << "VertexFormat::Uint8x2"; + break; + case VertexFormat::Uint8x4: + o << "VertexFormat::Uint8x4"; + break; + case VertexFormat::Sint8x2: + o << "VertexFormat::Sint8x2"; + break; + case VertexFormat::Sint8x4: + o << "VertexFormat::Sint8x4"; + break; + case VertexFormat::Unorm8x2: + o << "VertexFormat::Unorm8x2"; + break; + case VertexFormat::Unorm8x4: + o << "VertexFormat::Unorm8x4"; + break; + case VertexFormat::Snorm8x2: + o << "VertexFormat::Snorm8x2"; + break; + case VertexFormat::Snorm8x4: + o << "VertexFormat::Snorm8x4"; + break; + case VertexFormat::Uint16x2: + o << "VertexFormat::Uint16x2"; + break; + case VertexFormat::Uint16x4: + o << "VertexFormat::Uint16x4"; + break; + case VertexFormat::Sint16x2: + o << "VertexFormat::Sint16x2"; + break; + case VertexFormat::Sint16x4: + o << "VertexFormat::Sint16x4"; + break; + case VertexFormat::Unorm16x2: + o << "VertexFormat::Unorm16x2"; + break; + case VertexFormat::Unorm16x4: + o << "VertexFormat::Unorm16x4"; + break; + case VertexFormat::Snorm16x2: + o << "VertexFormat::Snorm16x2"; + break; + case VertexFormat::Snorm16x4: + o << "VertexFormat::Snorm16x4"; + break; + case VertexFormat::Float16x2: + o << "VertexFormat::Float16x2"; + break; + case VertexFormat::Float16x4: + o << "VertexFormat::Float16x4"; + break; + case VertexFormat::Float32: + o << "VertexFormat::Float32"; + break; + case VertexFormat::Float32x2: + o << "VertexFormat::Float32x2"; + break; + case VertexFormat::Float32x3: + o << "VertexFormat::Float32x3"; + break; + case VertexFormat::Float32x4: + o << "VertexFormat::Float32x4"; + break; + case VertexFormat::Uint32: + o << "VertexFormat::Uint32"; + break; + case VertexFormat::Uint32x2: + o << "VertexFormat::Uint32x2"; + break; + case VertexFormat::Uint32x3: + o << "VertexFormat::Uint32x3"; + break; + case VertexFormat::Uint32x4: + o << "VertexFormat::Uint32x4"; + break; + case VertexFormat::Sint32: + o << "VertexFormat::Sint32"; + break; + case VertexFormat::Sint32x2: + o << "VertexFormat::Sint32x2"; + break; + case VertexFormat::Sint32x3: + o << "VertexFormat::Sint32x3"; + break; + case VertexFormat::Sint32x4: + o << "VertexFormat::Sint32x4"; + break; + default: + o << "VertexFormat::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, VertexStepMode value) { + switch (value) { + case VertexStepMode::Vertex: + o << "VertexStepMode::Vertex"; + break; + case VertexStepMode::Instance: + o << "VertexStepMode::Instance"; + break; + case VertexStepMode::VertexBufferNotUsed: + o << "VertexStepMode::VertexBufferNotUsed"; + break; + default: + o << "VertexStepMode::" << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + return o; + } + + template + std::basic_ostream& operator<<(std::basic_ostream& o, BufferUsage value) { + o << "BufferUsage::"; + if (!static_cast(value)) { + // 0 is often explicitly declared as None. + o << "None"; + return o; + } + + bool moreThanOneBit = !HasZeroOrOneBits(value); + if (moreThanOneBit) { + o << "("; + } + + bool first = true; + if (value & BufferUsage::MapRead) { + if (!first) { + o << "|"; + } + first = false; + o << "MapRead"; + value &= ~BufferUsage::MapRead; + } + if (value & BufferUsage::MapWrite) { + if (!first) { + o << "|"; + } + first = false; + o << "MapWrite"; + value &= ~BufferUsage::MapWrite; + } + if (value & BufferUsage::CopySrc) { + if (!first) { + o << "|"; + } + first = false; + o << "CopySrc"; + value &= ~BufferUsage::CopySrc; + } + if (value & BufferUsage::CopyDst) { + if (!first) { + o << "|"; + } + first = false; + o << "CopyDst"; + value &= ~BufferUsage::CopyDst; + } + if (value & BufferUsage::Index) { + if (!first) { + o << "|"; + } + first = false; + o << "Index"; + value &= ~BufferUsage::Index; + } + if (value & BufferUsage::Vertex) { + if (!first) { + o << "|"; + } + first = false; + o << "Vertex"; + value &= ~BufferUsage::Vertex; + } + if (value & BufferUsage::Uniform) { + if (!first) { + o << "|"; + } + first = false; + o << "Uniform"; + value &= ~BufferUsage::Uniform; + } + if (value & BufferUsage::Storage) { + if (!first) { + o << "|"; + } + first = false; + o << "Storage"; + value &= ~BufferUsage::Storage; + } + if (value & BufferUsage::Indirect) { + if (!first) { + o << "|"; + } + first = false; + o << "Indirect"; + value &= ~BufferUsage::Indirect; + } + if (value & BufferUsage::QueryResolve) { + if (!first) { + o << "|"; + } + first = false; + o << "QueryResolve"; + value &= ~BufferUsage::QueryResolve; + } + + if (static_cast(value)) { + if (!first) { + o << "|"; + } + o << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + + if (moreThanOneBit) { + o << ")"; + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ColorWriteMask value) { + o << "ColorWriteMask::"; + if (!static_cast(value)) { + // 0 is often explicitly declared as None. + o << "None"; + return o; + } + + bool moreThanOneBit = !HasZeroOrOneBits(value); + if (moreThanOneBit) { + o << "("; + } + + bool first = true; + if (value & ColorWriteMask::Red) { + if (!first) { + o << "|"; + } + first = false; + o << "Red"; + value &= ~ColorWriteMask::Red; + } + if (value & ColorWriteMask::Green) { + if (!first) { + o << "|"; + } + first = false; + o << "Green"; + value &= ~ColorWriteMask::Green; + } + if (value & ColorWriteMask::Blue) { + if (!first) { + o << "|"; + } + first = false; + o << "Blue"; + value &= ~ColorWriteMask::Blue; + } + if (value & ColorWriteMask::Alpha) { + if (!first) { + o << "|"; + } + first = false; + o << "Alpha"; + value &= ~ColorWriteMask::Alpha; + } + if (value & ColorWriteMask::All) { + if (!first) { + o << "|"; + } + first = false; + o << "All"; + value &= ~ColorWriteMask::All; + } + + if (static_cast(value)) { + if (!first) { + o << "|"; + } + o << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + + if (moreThanOneBit) { + o << ")"; + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, MapMode value) { + o << "MapMode::"; + if (!static_cast(value)) { + // 0 is often explicitly declared as None. + o << "None"; + return o; + } + + bool moreThanOneBit = !HasZeroOrOneBits(value); + if (moreThanOneBit) { + o << "("; + } + + bool first = true; + if (value & MapMode::Read) { + if (!first) { + o << "|"; + } + first = false; + o << "Read"; + value &= ~MapMode::Read; + } + if (value & MapMode::Write) { + if (!first) { + o << "|"; + } + first = false; + o << "Write"; + value &= ~MapMode::Write; + } + + if (static_cast(value)) { + if (!first) { + o << "|"; + } + o << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + + if (moreThanOneBit) { + o << ")"; + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, ShaderStage value) { + o << "ShaderStage::"; + if (!static_cast(value)) { + // 0 is often explicitly declared as None. + o << "None"; + return o; + } + + bool moreThanOneBit = !HasZeroOrOneBits(value); + if (moreThanOneBit) { + o << "("; + } + + bool first = true; + if (value & ShaderStage::Vertex) { + if (!first) { + o << "|"; + } + first = false; + o << "Vertex"; + value &= ~ShaderStage::Vertex; + } + if (value & ShaderStage::Fragment) { + if (!first) { + o << "|"; + } + first = false; + o << "Fragment"; + value &= ~ShaderStage::Fragment; + } + if (value & ShaderStage::Compute) { + if (!first) { + o << "|"; + } + first = false; + o << "Compute"; + value &= ~ShaderStage::Compute; + } + + if (static_cast(value)) { + if (!first) { + o << "|"; + } + o << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + + if (moreThanOneBit) { + o << ")"; + } + return o; + } + template + std::basic_ostream& operator<<(std::basic_ostream& o, TextureUsage value) { + o << "TextureUsage::"; + if (!static_cast(value)) { + // 0 is often explicitly declared as None. + o << "None"; + return o; + } + + bool moreThanOneBit = !HasZeroOrOneBits(value); + if (moreThanOneBit) { + o << "("; + } + + bool first = true; + if (value & TextureUsage::CopySrc) { + if (!first) { + o << "|"; + } + first = false; + o << "CopySrc"; + value &= ~TextureUsage::CopySrc; + } + if (value & TextureUsage::CopyDst) { + if (!first) { + o << "|"; + } + first = false; + o << "CopyDst"; + value &= ~TextureUsage::CopyDst; + } + if (value & TextureUsage::TextureBinding) { + if (!first) { + o << "|"; + } + first = false; + o << "TextureBinding"; + value &= ~TextureUsage::TextureBinding; + } + if (value & TextureUsage::StorageBinding) { + if (!first) { + o << "|"; + } + first = false; + o << "StorageBinding"; + value &= ~TextureUsage::StorageBinding; + } + if (value & TextureUsage::RenderAttachment) { + if (!first) { + o << "|"; + } + first = false; + o << "RenderAttachment"; + value &= ~TextureUsage::RenderAttachment; + } + if (value & TextureUsage::TransientAttachment) { + if (!first) { + o << "|"; + } + first = false; + o << "TransientAttachment"; + value &= ~TextureUsage::TransientAttachment; + } + + if (static_cast(value)) { + if (!first) { + o << "|"; + } + o << std::showbase << std::hex << std::setfill('0') << std::setw(4) << static_cast::type>(value); + } + + if (moreThanOneBit) { + o << ")"; + } + return o; + } + +} // namespace wgpu + +#endif // WEBGPU_CPP_PRINT_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/wire/Wire.h b/vendor/zgpu/libs/dawn/include/dawn/wire/Wire.h new file mode 100644 index 0000000..e866db3 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/wire/Wire.h @@ -0,0 +1,58 @@ +// Copyright 2017 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_WIRE_WIRE_H_ +#define INCLUDE_DAWN_WIRE_WIRE_H_ + +#include +#include + +#include "dawn/webgpu.h" +#include "dawn/wire/dawn_wire_export.h" + +namespace dawn::wire { + +class DAWN_WIRE_EXPORT CommandSerializer { + public: + CommandSerializer(); + virtual ~CommandSerializer(); + CommandSerializer(const CommandSerializer& rhs) = delete; + CommandSerializer& operator=(const CommandSerializer& rhs) = delete; + + // Get space for serializing commands. + // GetCmdSpace will never be called with a value larger than + // what GetMaximumAllocationSize returns. Return nullptr to indicate + // a fatal error. + virtual void* GetCmdSpace(size_t size) = 0; + virtual bool Flush() = 0; + virtual size_t GetMaximumAllocationSize() const = 0; + virtual void OnSerializeError(); +}; + +class DAWN_WIRE_EXPORT CommandHandler { + public: + CommandHandler(); + virtual ~CommandHandler(); + CommandHandler(const CommandHandler& rhs) = delete; + CommandHandler& operator=(const CommandHandler& rhs) = delete; + + virtual const volatile char* HandleCommands(const volatile char* commands, size_t size) = 0; +}; + +} // namespace dawn::wire + +// TODO(dawn:824): Remove once the deprecation period is passed. +namespace dawn_wire = dawn::wire; + +#endif // INCLUDE_DAWN_WIRE_WIRE_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/wire/WireClient.h b/vendor/zgpu/libs/dawn/include/dawn/wire/WireClient.h new file mode 100644 index 0000000..1139715 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/wire/WireClient.h @@ -0,0 +1,181 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_WIRE_WIRECLIENT_H_ +#define INCLUDE_DAWN_WIRE_WIRECLIENT_H_ + +#include +#include + +#include "dawn/dawn_proc_table.h" +#include "dawn/wire/Wire.h" + +namespace dawn::wire { + +namespace client { +class Client; +class MemoryTransferService; + +DAWN_WIRE_EXPORT const DawnProcTable& GetProcs(); +} // namespace client + +struct ReservedTexture { + WGPUTexture texture; + uint32_t id; + uint32_t generation; + uint32_t deviceId; + uint32_t deviceGeneration; +}; + +struct ReservedSwapChain { + WGPUSwapChain swapchain; + uint32_t id; + uint32_t generation; + uint32_t deviceId; + uint32_t deviceGeneration; +}; + +struct ReservedDevice { + WGPUDevice device; + uint32_t id; + uint32_t generation; +}; + +struct ReservedInstance { + WGPUInstance instance; + uint32_t id; + uint32_t generation; +}; + +struct DAWN_WIRE_EXPORT WireClientDescriptor { + CommandSerializer* serializer; + client::MemoryTransferService* memoryTransferService = nullptr; +}; + +class DAWN_WIRE_EXPORT WireClient : public CommandHandler { + public: + explicit WireClient(const WireClientDescriptor& descriptor); + ~WireClient() override; + + const volatile char* HandleCommands(const volatile char* commands, size_t size) override; + + ReservedTexture ReserveTexture(WGPUDevice device, const WGPUTextureDescriptor* descriptor); + ReservedSwapChain ReserveSwapChain(WGPUDevice device, + const WGPUSwapChainDescriptor* descriptor); + ReservedDevice ReserveDevice(); + ReservedInstance ReserveInstance(); + + void ReclaimTextureReservation(const ReservedTexture& reservation); + void ReclaimSwapChainReservation(const ReservedSwapChain& reservation); + void ReclaimDeviceReservation(const ReservedDevice& reservation); + void ReclaimInstanceReservation(const ReservedInstance& reservation); + + // Disconnects the client. + // Commands allocated after this point will not be sent. + void Disconnect(); + + private: + std::unique_ptr mImpl; +}; + +namespace client { +class DAWN_WIRE_EXPORT MemoryTransferService { + public: + MemoryTransferService(); + virtual ~MemoryTransferService(); + + class ReadHandle; + class WriteHandle; + + // Create a handle for reading server data. + // This may fail and return nullptr. + virtual ReadHandle* CreateReadHandle(size_t) = 0; + + // Create a handle for writing server data. + // This may fail and return nullptr. + virtual WriteHandle* CreateWriteHandle(size_t) = 0; + + class DAWN_WIRE_EXPORT ReadHandle { + public: + ReadHandle(); + virtual ~ReadHandle(); + + // Get the required serialization size for SerializeCreate + virtual size_t SerializeCreateSize() = 0; + + // Serialize the handle into |serializePointer| so it can be received by the server. + virtual void SerializeCreate(void* serializePointer) = 0; + + // Simply return the base address of the allocation (without applying any offset) + // Returns nullptr if the allocation failed. + // The data must live at least until the ReadHandle is destructued + virtual const void* GetData() = 0; + + // Gets called when a MapReadCallback resolves. + // deserialize the data update and apply + // it to the range (offset, offset + size) of allocation + // There could be nothing to be deserialized (if using shared memory) + // Needs to check potential offset/size OOB and overflow + virtual bool DeserializeDataUpdate(const void* deserializePointer, + size_t deserializeSize, + size_t offset, + size_t size) = 0; + + private: + ReadHandle(const ReadHandle&) = delete; + ReadHandle& operator=(const ReadHandle&) = delete; + }; + + class DAWN_WIRE_EXPORT WriteHandle { + public: + WriteHandle(); + virtual ~WriteHandle(); + + // Get the required serialization size for SerializeCreate + virtual size_t SerializeCreateSize() = 0; + + // Serialize the handle into |serializePointer| so it can be received by the server. + virtual void SerializeCreate(void* serializePointer) = 0; + + // Simply return the base address of the allocation (without applying any offset) + // The data returned should be zero-initialized. + // The data returned must live at least until the WriteHandle is destructed. + // On failure, the pointer returned should be null. + virtual void* GetData() = 0; + + // Get the required serialization size for SerializeDataUpdate + virtual size_t SizeOfSerializeDataUpdate(size_t offset, size_t size) = 0; + + // Serialize a command to send the modified contents of + // the subrange (offset, offset + size) of the allocation at buffer unmap + // This subrange is always the whole mapped region for now + // There could be nothing to be serialized (if using shared memory) + virtual void SerializeDataUpdate(void* serializePointer, size_t offset, size_t size) = 0; + + private: + WriteHandle(const WriteHandle&) = delete; + WriteHandle& operator=(const WriteHandle&) = delete; + }; + + private: + MemoryTransferService(const MemoryTransferService&) = delete; + MemoryTransferService& operator=(const MemoryTransferService&) = delete; +}; + +// Backdoor to get the order of the ProcMap for testing +DAWN_WIRE_EXPORT std::vector GetProcMapNamesForTesting(); +} // namespace client +} // namespace dawn::wire + +#endif // INCLUDE_DAWN_WIRE_WIRECLIENT_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/wire/WireServer.h b/vendor/zgpu/libs/dawn/include/dawn/wire/WireServer.h new file mode 100644 index 0000000..9fc2ab3 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/wire/WireServer.h @@ -0,0 +1,154 @@ +// Copyright 2019 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_WIRE_WIRESERVER_H_ +#define INCLUDE_DAWN_WIRE_WIRESERVER_H_ + +#include + +#include "dawn/wire/Wire.h" + +struct DawnProcTable; + +namespace dawn::wire { + +namespace server { +class Server; +class MemoryTransferService; +} // namespace server + +struct DAWN_WIRE_EXPORT WireServerDescriptor { + const DawnProcTable* procs; + CommandSerializer* serializer; + server::MemoryTransferService* memoryTransferService = nullptr; +}; + +class DAWN_WIRE_EXPORT WireServer : public CommandHandler { + public: + explicit WireServer(const WireServerDescriptor& descriptor); + ~WireServer() override; + + const volatile char* HandleCommands(const volatile char* commands, size_t size) override; + + bool InjectTexture(WGPUTexture texture, + uint32_t id, + uint32_t generation, + uint32_t deviceId, + uint32_t deviceGeneration); + bool InjectSwapChain(WGPUSwapChain swapchain, + uint32_t id, + uint32_t generation, + uint32_t deviceId, + uint32_t deviceGeneration); + + bool InjectDevice(WGPUDevice device, uint32_t id, uint32_t generation); + + bool InjectInstance(WGPUInstance instance, uint32_t id, uint32_t generation); + + // Look up a device by (id, generation) pair. Returns nullptr if the generation + // has expired or the id is not found. + // The Wire does not have destroy hooks to allow an embedder to observe when an object + // has been destroyed, but in Chrome, we need to know the list of live devices so we + // can call device.Tick() on all of them periodically to ensure progress on asynchronous + // work is made. Getting this list can be done by tracking the (id, generation) of + // previously injected devices, and observing if GetDevice(id, generation) returns non-null. + WGPUDevice GetDevice(uint32_t id, uint32_t generation); + + // Check if a device handle is known by the wire. + // In Chrome, we need to know the list of live devices so we can call device.Tick() on all of + // them periodically to ensure progress on asynchronous work is made. + bool IsDeviceKnown(WGPUDevice device) const; + + private: + std::unique_ptr mImpl; +}; + +namespace server { +class DAWN_WIRE_EXPORT MemoryTransferService { + public: + MemoryTransferService(); + virtual ~MemoryTransferService(); + + class ReadHandle; + class WriteHandle; + + // Deserialize data to create Read/Write handles. These handles are for the client + // to Read/Write data. + virtual bool DeserializeReadHandle(const void* deserializePointer, + size_t deserializeSize, + ReadHandle** readHandle) = 0; + virtual bool DeserializeWriteHandle(const void* deserializePointer, + size_t deserializeSize, + WriteHandle** writeHandle) = 0; + + class DAWN_WIRE_EXPORT ReadHandle { + public: + ReadHandle(); + virtual ~ReadHandle(); + + // Return the size of the command serialized if + // SerializeDataUpdate is called with the same offset/size args + virtual size_t SizeOfSerializeDataUpdate(size_t offset, size_t size) = 0; + + // Gets called when a MapReadCallback resolves. + // Serialize the data update for the range (offset, offset + size) into + // |serializePointer| to the client There could be nothing to be serialized (if + // using shared memory) + virtual void SerializeDataUpdate(const void* data, + size_t offset, + size_t size, + void* serializePointer) = 0; + + private: + ReadHandle(const ReadHandle&) = delete; + ReadHandle& operator=(const ReadHandle&) = delete; + }; + + class DAWN_WIRE_EXPORT WriteHandle { + public: + WriteHandle(); + virtual ~WriteHandle(); + + // Set the target for writes from the client. DeserializeFlush should copy data + // into the target. + void SetTarget(void* data); + // Set Staging data length for OOB check + void SetDataLength(size_t dataLength); + + // This function takes in the serialized result of + // client::MemoryTransferService::WriteHandle::SerializeDataUpdate. + // Needs to check potential offset/size OOB and overflow + virtual bool DeserializeDataUpdate(const void* deserializePointer, + size_t deserializeSize, + size_t offset, + size_t size) = 0; + + protected: + void* mTargetData = nullptr; + size_t mDataLength = 0; + + private: + WriteHandle(const WriteHandle&) = delete; + WriteHandle& operator=(const WriteHandle&) = delete; + }; + + private: + MemoryTransferService(const MemoryTransferService&) = delete; + MemoryTransferService& operator=(const MemoryTransferService&) = delete; +}; +} // namespace server + +} // namespace dawn::wire + +#endif // INCLUDE_DAWN_WIRE_WIRESERVER_H_ diff --git a/vendor/zgpu/libs/dawn/include/dawn/wire/dawn_wire_export.h b/vendor/zgpu/libs/dawn/include/dawn/wire/dawn_wire_export.h new file mode 100644 index 0000000..e5b2113 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/dawn/wire/dawn_wire_export.h @@ -0,0 +1,36 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_DAWN_WIRE_DAWN_WIRE_EXPORT_H_ +#define INCLUDE_DAWN_WIRE_DAWN_WIRE_EXPORT_H_ + +#if defined(DAWN_WIRE_SHARED_LIBRARY) +#if defined(_WIN32) +#if defined(DAWN_WIRE_IMPLEMENTATION) +#define DAWN_WIRE_EXPORT __declspec(dllexport) +#else +#define DAWN_WIRE_EXPORT __declspec(dllimport) +#endif +#else // defined(_WIN32) +#if defined(DAWN_WIRE_IMPLEMENTATION) +#define DAWN_WIRE_EXPORT __attribute__((visibility("default"))) +#else +#define DAWN_WIRE_EXPORT +#endif +#endif // defined(_WIN32) +#else // defined(DAWN_WIRE_SHARED_LIBRARY) +#define DAWN_WIRE_EXPORT +#endif // defined(DAWN_WIRE_SHARED_LIBRARY) + +#endif // INCLUDE_DAWN_WIRE_DAWN_WIRE_EXPORT_H_ diff --git a/vendor/zgpu/libs/dawn/include/tint/override_id.h b/vendor/zgpu/libs/dawn/include/tint/override_id.h new file mode 100644 index 0000000..c638117 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/tint/override_id.h @@ -0,0 +1,66 @@ +// Copyright 2022 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_TINT_OVERRIDE_ID_H_ +#define SRC_TINT_OVERRIDE_ID_H_ + +#include +#include + +#include "src/tint/reflection.h" + +namespace tint { + +/// OverrideId is a numerical identifier for an override variable, unique per program. +struct OverrideId { + uint16_t value = 0; + + /// Reflect the fields of this struct so that it can be used by tint::ForeachField() + TINT_REFLECT(value); +}; + +/// Equality operator for OverrideId +/// @param lhs the OverrideId on the left of the '=' operator +/// @param rhs the OverrideId on the right of the '=' operator +/// @returns true if `lhs` is equal to `rhs` +inline bool operator==(OverrideId lhs, OverrideId rhs) { + return lhs.value == rhs.value; +} + +/// Less-than operator for OverrideId +/// @param lhs the OverrideId on the left of the '<' operator +/// @param rhs the OverrideId on the right of the '<' operator +/// @returns true if `lhs` comes before `rhs` +inline bool operator<(OverrideId lhs, OverrideId rhs) { + return lhs.value < rhs.value; +} + +} // namespace tint + +namespace std { + +/// Custom std::hash specialization for tint::OverrideId. +template <> +class hash { + public: + /// @param id the override identifier + /// @return the hash of the override identifier + inline std::size_t operator()(tint::OverrideId id) const { + return std::hash()(id.value); + } +}; + +} // namespace std + +#endif // SRC_TINT_OVERRIDE_ID_H_ diff --git a/vendor/zgpu/libs/dawn/include/tint/tint.h b/vendor/zgpu/libs/dawn/include/tint/tint.h new file mode 100644 index 0000000..b5402b0 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/tint/tint.h @@ -0,0 +1,82 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_TINT_TINT_H_ +#define INCLUDE_TINT_TINT_H_ + +// Guard for accidental includes to private headers +#define CURRENTLY_IN_TINT_PUBLIC_HEADER + +// TODO(tint:88): When implementing support for an install target, all of these +// headers will need to be moved to include/tint/. + +#include "src/tint/ast/transform/first_index_offset.h" +#include "src/tint/ast/transform/renamer.h" +#include "src/tint/ast/transform/single_entry_point.h" +#include "src/tint/ast/transform/substitute_override.h" +#include "src/tint/ast/transform/vertex_pulling.h" +#include "src/tint/diagnostic/printer.h" +#include "src/tint/inspector/inspector.h" +#include "src/tint/reader/reader.h" +#include "src/tint/transform/manager.h" +#include "src/tint/type/manager.h" +#include "src/tint/utils/unicode.h" +#include "src/tint/writer/array_length_from_uniform_options.h" +#include "src/tint/writer/binding_point.h" +#include "src/tint/writer/binding_remapper_options.h" +#include "src/tint/writer/external_texture_options.h" +#include "src/tint/writer/flatten_bindings.h" +#include "src/tint/writer/writer.h" + +#if TINT_BUILD_SPV_READER +#include "src/tint/reader/spirv/parser.h" +#endif // TINT_BUILD_SPV_READER + +#if TINT_BUILD_WGSL_READER +#include "src/tint/reader/wgsl/parser.h" +#endif // TINT_BUILD_WGSL_READER + +#if TINT_BUILD_SPV_WRITER +#include "src/tint/writer/spirv/generator.h" +#endif // TINT_BUILD_SPV_WRITER + +#if TINT_BUILD_WGSL_WRITER +#include "src/tint/writer/wgsl/generator.h" +#endif // TINT_BUILD_WGSL_WRITER + +#if TINT_BUILD_MSL_WRITER +#include "src/tint/writer/msl/generator.h" +#endif // TINT_BUILD_MSL_WRITER + +#if TINT_BUILD_HLSL_WRITER +#include "src/tint/writer/hlsl/generator.h" +#endif // TINT_BUILD_HLSL_WRITER + +#if TINT_BUILD_GLSL_WRITER +#include "src/tint/writer/glsl/generator.h" +#endif // TINT_BUILD_GLSL_WRITER + +namespace tint { + +/// Initialize initializes the Tint library. Call before using the Tint API. +void Initialize(); + +/// Shutdown uninitializes the Tint library. Call after using the Tint API. +void Shutdown(); + +} // namespace tint + +#undef CURRENTLY_IN_TINT_PUBLIC_HEADER + +#endif // INCLUDE_TINT_TINT_H_ diff --git a/vendor/zgpu/libs/dawn/include/webgpu/webgpu.h b/vendor/zgpu/libs/dawn/include/webgpu/webgpu.h new file mode 100644 index 0000000..535045e --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/webgpu/webgpu.h @@ -0,0 +1,20 @@ +// Copyright 2022 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_WEBGPU_WEBGPU_H_ +#define INCLUDE_WEBGPU_WEBGPU_H_ + +#include "dawn/webgpu.h" + +#endif // INCLUDE_WEBGPU_WEBGPU_H_ diff --git a/vendor/zgpu/libs/dawn/include/webgpu/webgpu_cpp.h b/vendor/zgpu/libs/dawn/include/webgpu/webgpu_cpp.h new file mode 100644 index 0000000..f1a6333 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/webgpu/webgpu_cpp.h @@ -0,0 +1,20 @@ +// Copyright 2022 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_WEBGPU_WEBGPU_CPP_H_ +#define INCLUDE_WEBGPU_WEBGPU_CPP_H_ + +#include "dawn/webgpu_cpp.h" + +#endif // INCLUDE_WEBGPU_WEBGPU_CPP_H_ diff --git a/vendor/zgpu/libs/dawn/include/webgpu/webgpu_glfw.h b/vendor/zgpu/libs/dawn/include/webgpu/webgpu_glfw.h new file mode 100644 index 0000000..5d3f4e3 --- /dev/null +++ b/vendor/zgpu/libs/dawn/include/webgpu/webgpu_glfw.h @@ -0,0 +1,58 @@ +// Copyright 2022 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_WEBGPU_WEBGPU_GLFW_H_ +#define INCLUDE_WEBGPU_WEBGPU_GLFW_H_ + +#include + +#include "webgpu/webgpu_cpp.h" + +#if defined(WGPU_GLFW_SHARED_LIBRARY) +#if defined(_WIN32) +#if defined(WGPU_GLFW_IMPLEMENTATION) +#define WGPU_GLFW_EXPORT __declspec(dllexport) +#else +#define WGPU_GLFW_EXPORT __declspec(dllimport) +#endif +#else // defined(_WIN32) +#if defined(WGPU_GLFW_IMPLEMENTATION) +#define WGPU_GLFW_EXPORT __attribute__((visibility("default"))) +#else +#define WGPU_GLFW_EXPORT +#endif +#endif // defined(_WIN32) +#else // defined(WGPU_GLFW_SHARED_LIBRARY) +#define WGPU_GLFW_EXPORT +#endif // defined(WGPU_GLFW_SHARED_LIBRARY) + +struct GLFWwindow; + +namespace wgpu::glfw { + +// Does the necessary setup on the GLFWwindow to allow creating a wgpu::Surface with it and +// calls `instance.CreateSurface` with the correct descriptor for this window. +// Returns a null wgpu::Surface on failure. +WGPU_GLFW_EXPORT wgpu::Surface CreateSurfaceForWindow(const wgpu::Instance& instance, + GLFWwindow* window); + +// Use for testing only. Does everything that CreateSurfaceForWindow does except the call to +// CreateSurface. Useful to be able to modify the descriptor for testing, or when trying to +// avoid using the global proc table. +WGPU_GLFW_EXPORT std::unique_ptr SetupWindowAndGetSurfaceDescriptor( + GLFWwindow* window); + +} // namespace wgpu::glfw + +#endif // INCLUDE_WEBGPU_WEBGPU_GLFW_H_ diff --git a/vendor/zgpu/src/common_wgsl.zig b/vendor/zgpu/src/common_wgsl.zig new file mode 100644 index 0000000..8a4e485 --- /dev/null +++ b/vendor/zgpu/src/common_wgsl.zig @@ -0,0 +1,99 @@ +const std = @import("std"); + +pub fn csGenerateMipmaps(allocator: std.mem.Allocator, format: []const u8) [:0]const u8 { + const s0 = std.fmt.allocPrint( + allocator, + \\ @group(0) @binding(2) var dst_mipmap1: texture_storage_2d<{s}, write>; + \\ @group(0) @binding(3) var dst_mipmap2: texture_storage_2d<{s}, write>; + \\ @group(0) @binding(4) var dst_mipmap3: texture_storage_2d<{s}, write>; + \\ @group(0) @binding(5) var dst_mipmap4: texture_storage_2d<{s}, write>; + , + .{ format, format, format, format }, + ) catch unreachable; + defer allocator.free(s0); + return std.mem.joinZ(allocator, "\n\n", &.{ s0, cs_generate_mipmaps }) catch unreachable; +} + +// zig fmt: off +const cs_generate_mipmaps = +\\ struct Uniforms { +\\ src_mip_level: i32, +\\ num_mip_levels: u32, +\\ } +\\ @group(0) @binding(0) var uniforms: Uniforms; +\\ @group(0) @binding(1) var src_image: texture_2d; +\\ +\\ var red: array; +\\ var green: array; +\\ var blue: array; +\\ var alpha: array; +\\ +\\ fn storeColor(index: u32, color: vec4) { +\\ red[index] = color.x; +\\ green[index] = color.y; +\\ blue[index] = color.z; +\\ alpha[index] = color.w; +\\ } +\\ +\\ fn loadColor(index: u32) -> vec4 { +\\ return vec4(red[index], green[index], blue[index], alpha[index]); +\\ } +\\ +\\ @compute @workgroup_size(8, 8, 1) +\\ fn main( +\\ @builtin(global_invocation_id) global_invocation_id: vec3, +\\ @builtin(local_invocation_index) local_invocation_index : u32, +\\ ) { +\\ let x = i32(global_invocation_id.x * 2u); +\\ let y = i32(global_invocation_id.y * 2u); +\\ +\\ var s00 = textureLoad(src_image, vec2(x, y), uniforms.src_mip_level); +\\ var s10 = textureLoad(src_image, vec2(x + 1, y), uniforms.src_mip_level); +\\ var s01 = textureLoad(src_image, vec2(x, y + 1), uniforms.src_mip_level); +\\ var s11 = textureLoad(src_image, vec2(x + 1, y + 1), uniforms.src_mip_level); +\\ s00 = 0.25 * (s00 + s01 + s10 + s11); +\\ +\\ textureStore(dst_mipmap1, vec2(global_invocation_id.xy), s00); +\\ storeColor(local_invocation_index, s00); +\\ if (uniforms.num_mip_levels == 1u) { +\\ return; +\\ } +\\ workgroupBarrier(); +\\ +\\ if ((local_invocation_index & 0x9u) == 0u) { +\\ s10 = loadColor(local_invocation_index + 1u); +\\ s01 = loadColor(local_invocation_index + 8u); +\\ s11 = loadColor(local_invocation_index + 9u); +\\ s00 = 0.25 * (s00 + s01 + s10 + s11); +\\ textureStore(dst_mipmap2, vec2(global_invocation_id.xy / 2u), s00); +\\ storeColor(local_invocation_index, s00); +\\ } +\\ if (uniforms.num_mip_levels == 2u) { +\\ return; +\\ } +\\ workgroupBarrier(); +\\ +\\ if ((local_invocation_index & 0x1Bu) == 0u) { +\\ s10 = loadColor(local_invocation_index + 2u); +\\ s01 = loadColor(local_invocation_index + 16u); +\\ s11 = loadColor(local_invocation_index + 18u); +\\ s00 = 0.25 * (s00 + s01 + s10 + s11); +\\ textureStore(dst_mipmap3, vec2(global_invocation_id.xy / 4u), s00); +\\ storeColor(local_invocation_index, s00); +\\ } +\\ if (uniforms.num_mip_levels == 3u) { +\\ return; +\\ } +\\ workgroupBarrier(); +\\ +\\ if (local_invocation_index == 0u) { +\\ s10 = loadColor(local_invocation_index + 4u); +\\ s01 = loadColor(local_invocation_index + 32u); +\\ s11 = loadColor(local_invocation_index + 36u); +\\ s00 = 0.25 * (s00 + s01 + s10 + s11); +\\ textureStore(dst_mipmap4, vec2(global_invocation_id.xy / 8u), s00); +\\ storeColor(local_invocation_index, s00); +\\ } +\\ } +; +// zig fmt: on diff --git a/vendor/zgpu/src/dawn.cpp b/vendor/zgpu/src/dawn.cpp new file mode 100644 index 0000000..bc6210c --- /dev/null +++ b/vendor/zgpu/src/dawn.cpp @@ -0,0 +1,37 @@ +#include "dawn/native/DawnNative.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DawnNativeInstanceImpl* DawnNativeInstance; + +DawnNativeInstance dniCreate(void) { + return reinterpret_cast(new dawn::native::Instance()); +} + +void dniDestroy(DawnNativeInstance dni) { + assert(dni); + delete reinterpret_cast(dni); +} + +WGPUInstance dniGetWgpuInstance(DawnNativeInstance dni) { + assert(dni); + return reinterpret_cast(dni)->Get(); +} + +void dniDiscoverDefaultAdapters(DawnNativeInstance dni) { + assert(dni); + dawn::native::Instance* instance = reinterpret_cast(dni); + instance->DiscoverDefaultAdapters(); +} + +const DawnProcTable* dnGetProcs(void) { + return &dawn::native::GetProcs(); +} + +#ifdef __cplusplus +} +#endif diff --git a/vendor/zgpu/src/dawn_proc.c b/vendor/zgpu/src/dawn_proc.c new file mode 100644 index 0000000..826a735 --- /dev/null +++ b/vendor/zgpu/src/dawn_proc.c @@ -0,0 +1,667 @@ + +#include "dawn/dawn_proc.h" + +static DawnProcTable procs; + +static DawnProcTable nullProcs; + +void dawnProcSetProcs(const DawnProcTable* procs_) { + if (procs_) { + procs = *procs_; + } else { + procs = nullProcs; + } +} + +WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor) { +return procs.createInstance(descriptor); +} +WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName) { +return procs.getProcAddress(device, procName); +} + +WGPUDevice wgpuAdapterCreateDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor) { +return procs.adapterCreateDevice(adapter, descriptor); +} +size_t wgpuAdapterEnumerateFeatures(WGPUAdapter adapter, WGPUFeatureName * features) { +return procs.adapterEnumerateFeatures(adapter, features); +} +WGPUInstance wgpuAdapterGetInstance(WGPUAdapter adapter) { +return procs.adapterGetInstance(adapter); +} +bool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPUSupportedLimits * limits) { +return procs.adapterGetLimits(adapter, limits); +} +void wgpuAdapterGetProperties(WGPUAdapter adapter, WGPUAdapterProperties * properties) { + procs.adapterGetProperties(adapter, properties); +} +bool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature) { +return procs.adapterHasFeature(adapter, feature); +} +void wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata) { + procs.adapterRequestDevice(adapter, descriptor, callback, userdata); +} +void wgpuAdapterReference(WGPUAdapter adapter) { + procs.adapterReference(adapter); +} +void wgpuAdapterRelease(WGPUAdapter adapter) { + procs.adapterRelease(adapter); +} + +void wgpuBindGroupSetLabel(WGPUBindGroup bindGroup, char const * label) { + procs.bindGroupSetLabel(bindGroup, label); +} +void wgpuBindGroupReference(WGPUBindGroup bindGroup) { + procs.bindGroupReference(bindGroup); +} +void wgpuBindGroupRelease(WGPUBindGroup bindGroup) { + procs.bindGroupRelease(bindGroup); +} + +void wgpuBindGroupLayoutSetLabel(WGPUBindGroupLayout bindGroupLayout, char const * label) { + procs.bindGroupLayoutSetLabel(bindGroupLayout, label); +} +void wgpuBindGroupLayoutReference(WGPUBindGroupLayout bindGroupLayout) { + procs.bindGroupLayoutReference(bindGroupLayout); +} +void wgpuBindGroupLayoutRelease(WGPUBindGroupLayout bindGroupLayout) { + procs.bindGroupLayoutRelease(bindGroupLayout); +} + +void wgpuBufferDestroy(WGPUBuffer buffer) { + procs.bufferDestroy(buffer); +} +void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size) { +return procs.bufferGetConstMappedRange(buffer, offset, size); +} +WGPUBufferMapState wgpuBufferGetMapState(WGPUBuffer buffer) { +return procs.bufferGetMapState(buffer); +} +void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size) { +return procs.bufferGetMappedRange(buffer, offset, size); +} +uint64_t wgpuBufferGetSize(WGPUBuffer buffer) { +return procs.bufferGetSize(buffer); +} +WGPUBufferUsageFlags wgpuBufferGetUsage(WGPUBuffer buffer) { +return procs.bufferGetUsage(buffer); +} +void wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata) { + procs.bufferMapAsync(buffer, mode, offset, size, callback, userdata); +} +void wgpuBufferSetLabel(WGPUBuffer buffer, char const * label) { + procs.bufferSetLabel(buffer, label); +} +void wgpuBufferUnmap(WGPUBuffer buffer) { + procs.bufferUnmap(buffer); +} +void wgpuBufferReference(WGPUBuffer buffer) { + procs.bufferReference(buffer); +} +void wgpuBufferRelease(WGPUBuffer buffer) { + procs.bufferRelease(buffer); +} + +void wgpuCommandBufferSetLabel(WGPUCommandBuffer commandBuffer, char const * label) { + procs.commandBufferSetLabel(commandBuffer, label); +} +void wgpuCommandBufferReference(WGPUCommandBuffer commandBuffer) { + procs.commandBufferReference(commandBuffer); +} +void wgpuCommandBufferRelease(WGPUCommandBuffer commandBuffer) { + procs.commandBufferRelease(commandBuffer); +} + +WGPUComputePassEncoder wgpuCommandEncoderBeginComputePass(WGPUCommandEncoder commandEncoder, WGPUComputePassDescriptor const * descriptor) { +return procs.commandEncoderBeginComputePass(commandEncoder, descriptor); +} +WGPURenderPassEncoder wgpuCommandEncoderBeginRenderPass(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) { +return procs.commandEncoderBeginRenderPass(commandEncoder, descriptor); +} +void wgpuCommandEncoderClearBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) { + procs.commandEncoderClearBuffer(commandEncoder, buffer, offset, size); +} +void wgpuCommandEncoderCopyBufferToBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) { + procs.commandEncoderCopyBufferToBuffer(commandEncoder, source, sourceOffset, destination, destinationOffset, size); +} +void wgpuCommandEncoderCopyBufferToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyBuffer const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) { + procs.commandEncoderCopyBufferToTexture(commandEncoder, source, destination, copySize); +} +void wgpuCommandEncoderCopyTextureToBuffer(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyBuffer const * destination, WGPUExtent3D const * copySize) { + procs.commandEncoderCopyTextureToBuffer(commandEncoder, source, destination, copySize); +} +void wgpuCommandEncoderCopyTextureToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) { + procs.commandEncoderCopyTextureToTexture(commandEncoder, source, destination, copySize); +} +void wgpuCommandEncoderCopyTextureToTextureInternal(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) { + procs.commandEncoderCopyTextureToTextureInternal(commandEncoder, source, destination, copySize); +} +WGPUCommandBuffer wgpuCommandEncoderFinish(WGPUCommandEncoder commandEncoder, WGPUCommandBufferDescriptor const * descriptor) { +return procs.commandEncoderFinish(commandEncoder, descriptor); +} +void wgpuCommandEncoderInjectValidationError(WGPUCommandEncoder commandEncoder, char const * message) { + procs.commandEncoderInjectValidationError(commandEncoder, message); +} +void wgpuCommandEncoderInsertDebugMarker(WGPUCommandEncoder commandEncoder, char const * markerLabel) { + procs.commandEncoderInsertDebugMarker(commandEncoder, markerLabel); +} +void wgpuCommandEncoderPopDebugGroup(WGPUCommandEncoder commandEncoder) { + procs.commandEncoderPopDebugGroup(commandEncoder); +} +void wgpuCommandEncoderPushDebugGroup(WGPUCommandEncoder commandEncoder, char const * groupLabel) { + procs.commandEncoderPushDebugGroup(commandEncoder, groupLabel); +} +void wgpuCommandEncoderResolveQuerySet(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) { + procs.commandEncoderResolveQuerySet(commandEncoder, querySet, firstQuery, queryCount, destination, destinationOffset); +} +void wgpuCommandEncoderSetLabel(WGPUCommandEncoder commandEncoder, char const * label) { + procs.commandEncoderSetLabel(commandEncoder, label); +} +void wgpuCommandEncoderWriteBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t bufferOffset, uint8_t const * data, uint64_t size) { + procs.commandEncoderWriteBuffer(commandEncoder, buffer, bufferOffset, data, size); +} +void wgpuCommandEncoderWriteTimestamp(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) { + procs.commandEncoderWriteTimestamp(commandEncoder, querySet, queryIndex); +} +void wgpuCommandEncoderReference(WGPUCommandEncoder commandEncoder) { + procs.commandEncoderReference(commandEncoder); +} +void wgpuCommandEncoderRelease(WGPUCommandEncoder commandEncoder) { + procs.commandEncoderRelease(commandEncoder); +} + +void wgpuComputePassEncoderDispatchWorkgroups(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) { + procs.computePassEncoderDispatchWorkgroups(computePassEncoder, workgroupCountX, workgroupCountY, workgroupCountZ); +} +void wgpuComputePassEncoderDispatchWorkgroupsIndirect(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + procs.computePassEncoderDispatchWorkgroupsIndirect(computePassEncoder, indirectBuffer, indirectOffset); +} +void wgpuComputePassEncoderEnd(WGPUComputePassEncoder computePassEncoder) { + procs.computePassEncoderEnd(computePassEncoder); +} +void wgpuComputePassEncoderInsertDebugMarker(WGPUComputePassEncoder computePassEncoder, char const * markerLabel) { + procs.computePassEncoderInsertDebugMarker(computePassEncoder, markerLabel); +} +void wgpuComputePassEncoderPopDebugGroup(WGPUComputePassEncoder computePassEncoder) { + procs.computePassEncoderPopDebugGroup(computePassEncoder); +} +void wgpuComputePassEncoderPushDebugGroup(WGPUComputePassEncoder computePassEncoder, char const * groupLabel) { + procs.computePassEncoderPushDebugGroup(computePassEncoder, groupLabel); +} +void wgpuComputePassEncoderSetBindGroup(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) { + procs.computePassEncoderSetBindGroup(computePassEncoder, groupIndex, group, dynamicOffsetCount, dynamicOffsets); +} +void wgpuComputePassEncoderSetLabel(WGPUComputePassEncoder computePassEncoder, char const * label) { + procs.computePassEncoderSetLabel(computePassEncoder, label); +} +void wgpuComputePassEncoderSetPipeline(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) { + procs.computePassEncoderSetPipeline(computePassEncoder, pipeline); +} +void wgpuComputePassEncoderWriteTimestamp(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) { + procs.computePassEncoderWriteTimestamp(computePassEncoder, querySet, queryIndex); +} +void wgpuComputePassEncoderReference(WGPUComputePassEncoder computePassEncoder) { + procs.computePassEncoderReference(computePassEncoder); +} +void wgpuComputePassEncoderRelease(WGPUComputePassEncoder computePassEncoder) { + procs.computePassEncoderRelease(computePassEncoder); +} + +WGPUBindGroupLayout wgpuComputePipelineGetBindGroupLayout(WGPUComputePipeline computePipeline, uint32_t groupIndex) { +return procs.computePipelineGetBindGroupLayout(computePipeline, groupIndex); +} +void wgpuComputePipelineSetLabel(WGPUComputePipeline computePipeline, char const * label) { + procs.computePipelineSetLabel(computePipeline, label); +} +void wgpuComputePipelineReference(WGPUComputePipeline computePipeline) { + procs.computePipelineReference(computePipeline); +} +void wgpuComputePipelineRelease(WGPUComputePipeline computePipeline) { + procs.computePipelineRelease(computePipeline); +} + +WGPUBindGroup wgpuDeviceCreateBindGroup(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) { +return procs.deviceCreateBindGroup(device, descriptor); +} +WGPUBindGroupLayout wgpuDeviceCreateBindGroupLayout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) { +return procs.deviceCreateBindGroupLayout(device, descriptor); +} +WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) { +return procs.deviceCreateBuffer(device, descriptor); +} +WGPUCommandEncoder wgpuDeviceCreateCommandEncoder(WGPUDevice device, WGPUCommandEncoderDescriptor const * descriptor) { +return procs.deviceCreateCommandEncoder(device, descriptor); +} +WGPUComputePipeline wgpuDeviceCreateComputePipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) { +return procs.deviceCreateComputePipeline(device, descriptor); +} +void wgpuDeviceCreateComputePipelineAsync(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata) { + procs.deviceCreateComputePipelineAsync(device, descriptor, callback, userdata); +} +WGPUBuffer wgpuDeviceCreateErrorBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) { +return procs.deviceCreateErrorBuffer(device, descriptor); +} +WGPUExternalTexture wgpuDeviceCreateErrorExternalTexture(WGPUDevice device) { +return procs.deviceCreateErrorExternalTexture(device); +} +WGPUShaderModule wgpuDeviceCreateErrorShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, char const * errorMessage) { +return procs.deviceCreateErrorShaderModule(device, descriptor, errorMessage); +} +WGPUTexture wgpuDeviceCreateErrorTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) { +return procs.deviceCreateErrorTexture(device, descriptor); +} +WGPUExternalTexture wgpuDeviceCreateExternalTexture(WGPUDevice device, WGPUExternalTextureDescriptor const * externalTextureDescriptor) { +return procs.deviceCreateExternalTexture(device, externalTextureDescriptor); +} +WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) { +return procs.deviceCreatePipelineLayout(device, descriptor); +} +WGPUQuerySet wgpuDeviceCreateQuerySet(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) { +return procs.deviceCreateQuerySet(device, descriptor); +} +WGPURenderBundleEncoder wgpuDeviceCreateRenderBundleEncoder(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) { +return procs.deviceCreateRenderBundleEncoder(device, descriptor); +} +WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) { +return procs.deviceCreateRenderPipeline(device, descriptor); +} +void wgpuDeviceCreateRenderPipelineAsync(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata) { + procs.deviceCreateRenderPipelineAsync(device, descriptor, callback, userdata); +} +WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPUSamplerDescriptor const * descriptor) { +return procs.deviceCreateSampler(device, descriptor); +} +WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) { +return procs.deviceCreateShaderModule(device, descriptor); +} +WGPUSwapChain wgpuDeviceCreateSwapChain(WGPUDevice device, WGPUSurface surface, WGPUSwapChainDescriptor const * descriptor) { +return procs.deviceCreateSwapChain(device, surface, descriptor); +} +WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) { +return procs.deviceCreateTexture(device, descriptor); +} +void wgpuDeviceDestroy(WGPUDevice device) { + procs.deviceDestroy(device); +} +size_t wgpuDeviceEnumerateFeatures(WGPUDevice device, WGPUFeatureName * features) { +return procs.deviceEnumerateFeatures(device, features); +} +void wgpuDeviceForceLoss(WGPUDevice device, WGPUDeviceLostReason type, char const * message) { + procs.deviceForceLoss(device, type, message); +} +WGPUAdapter wgpuDeviceGetAdapter(WGPUDevice device) { +return procs.deviceGetAdapter(device); +} +bool wgpuDeviceGetLimits(WGPUDevice device, WGPUSupportedLimits * limits) { +return procs.deviceGetLimits(device, limits); +} +WGPUQueue wgpuDeviceGetQueue(WGPUDevice device) { +return procs.deviceGetQueue(device); +} +WGPUTextureUsageFlags wgpuDeviceGetSupportedSurfaceUsage(WGPUDevice device, WGPUSurface surface) { +return procs.deviceGetSupportedSurfaceUsage(device, surface); +} +bool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature) { +return procs.deviceHasFeature(device, feature); +} +void wgpuDeviceInjectError(WGPUDevice device, WGPUErrorType type, char const * message) { + procs.deviceInjectError(device, type, message); +} +void wgpuDevicePopErrorScope(WGPUDevice device, WGPUErrorCallback callback, void * userdata) { + procs.devicePopErrorScope(device, callback, userdata); +} +void wgpuDevicePushErrorScope(WGPUDevice device, WGPUErrorFilter filter) { + procs.devicePushErrorScope(device, filter); +} +void wgpuDeviceSetDeviceLostCallback(WGPUDevice device, WGPUDeviceLostCallback callback, void * userdata) { + procs.deviceSetDeviceLostCallback(device, callback, userdata); +} +void wgpuDeviceSetLabel(WGPUDevice device, char const * label) { + procs.deviceSetLabel(device, label); +} +void wgpuDeviceSetLoggingCallback(WGPUDevice device, WGPULoggingCallback callback, void * userdata) { + procs.deviceSetLoggingCallback(device, callback, userdata); +} +void wgpuDeviceSetUncapturedErrorCallback(WGPUDevice device, WGPUErrorCallback callback, void * userdata) { + procs.deviceSetUncapturedErrorCallback(device, callback, userdata); +} +void wgpuDeviceTick(WGPUDevice device) { + procs.deviceTick(device); +} +void wgpuDeviceValidateTextureDescriptor(WGPUDevice device, WGPUTextureDescriptor const * descriptor) { + procs.deviceValidateTextureDescriptor(device, descriptor); +} +void wgpuDeviceReference(WGPUDevice device) { + procs.deviceReference(device); +} +void wgpuDeviceRelease(WGPUDevice device) { + procs.deviceRelease(device); +} + +void wgpuExternalTextureDestroy(WGPUExternalTexture externalTexture) { + procs.externalTextureDestroy(externalTexture); +} +void wgpuExternalTextureExpire(WGPUExternalTexture externalTexture) { + procs.externalTextureExpire(externalTexture); +} +void wgpuExternalTextureRefresh(WGPUExternalTexture externalTexture) { + procs.externalTextureRefresh(externalTexture); +} +void wgpuExternalTextureSetLabel(WGPUExternalTexture externalTexture, char const * label) { + procs.externalTextureSetLabel(externalTexture, label); +} +void wgpuExternalTextureReference(WGPUExternalTexture externalTexture) { + procs.externalTextureReference(externalTexture); +} +void wgpuExternalTextureRelease(WGPUExternalTexture externalTexture) { + procs.externalTextureRelease(externalTexture); +} + +WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) { +return procs.instanceCreateSurface(instance, descriptor); +} +void wgpuInstanceProcessEvents(WGPUInstance instance) { + procs.instanceProcessEvents(instance); +} +void wgpuInstanceRequestAdapter(WGPUInstance instance, WGPURequestAdapterOptions const * options, WGPURequestAdapterCallback callback, void * userdata) { + procs.instanceRequestAdapter(instance, options, callback, userdata); +} +void wgpuInstanceReference(WGPUInstance instance) { + procs.instanceReference(instance); +} +void wgpuInstanceRelease(WGPUInstance instance) { + procs.instanceRelease(instance); +} + +void wgpuPipelineLayoutSetLabel(WGPUPipelineLayout pipelineLayout, char const * label) { + procs.pipelineLayoutSetLabel(pipelineLayout, label); +} +void wgpuPipelineLayoutReference(WGPUPipelineLayout pipelineLayout) { + procs.pipelineLayoutReference(pipelineLayout); +} +void wgpuPipelineLayoutRelease(WGPUPipelineLayout pipelineLayout) { + procs.pipelineLayoutRelease(pipelineLayout); +} + +void wgpuQuerySetDestroy(WGPUQuerySet querySet) { + procs.querySetDestroy(querySet); +} +uint32_t wgpuQuerySetGetCount(WGPUQuerySet querySet) { +return procs.querySetGetCount(querySet); +} +WGPUQueryType wgpuQuerySetGetType(WGPUQuerySet querySet) { +return procs.querySetGetType(querySet); +} +void wgpuQuerySetSetLabel(WGPUQuerySet querySet, char const * label) { + procs.querySetSetLabel(querySet, label); +} +void wgpuQuerySetReference(WGPUQuerySet querySet) { + procs.querySetReference(querySet); +} +void wgpuQuerySetRelease(WGPUQuerySet querySet) { + procs.querySetRelease(querySet); +} + +void wgpuQueueCopyExternalTextureForBrowser(WGPUQueue queue, WGPUImageCopyExternalTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) { + procs.queueCopyExternalTextureForBrowser(queue, source, destination, copySize, options); +} +void wgpuQueueCopyTextureForBrowser(WGPUQueue queue, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize, WGPUCopyTextureForBrowserOptions const * options) { + procs.queueCopyTextureForBrowser(queue, source, destination, copySize, options); +} +void wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, uint64_t signalValue, WGPUQueueWorkDoneCallback callback, void * userdata) { + procs.queueOnSubmittedWorkDone(queue, signalValue, callback, userdata); +} +void wgpuQueueSetLabel(WGPUQueue queue, char const * label) { + procs.queueSetLabel(queue, label); +} +void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) { + procs.queueSubmit(queue, commandCount, commands); +} +void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) { + procs.queueWriteBuffer(queue, buffer, bufferOffset, data, size); +} +void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) { + procs.queueWriteTexture(queue, destination, data, dataSize, dataLayout, writeSize); +} +void wgpuQueueReference(WGPUQueue queue) { + procs.queueReference(queue); +} +void wgpuQueueRelease(WGPUQueue queue) { + procs.queueRelease(queue); +} + +void wgpuRenderBundleSetLabel(WGPURenderBundle renderBundle, char const * label) { + procs.renderBundleSetLabel(renderBundle, label); +} +void wgpuRenderBundleReference(WGPURenderBundle renderBundle) { + procs.renderBundleReference(renderBundle); +} +void wgpuRenderBundleRelease(WGPURenderBundle renderBundle) { + procs.renderBundleRelease(renderBundle); +} + +void wgpuRenderBundleEncoderDraw(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { + procs.renderBundleEncoderDraw(renderBundleEncoder, vertexCount, instanceCount, firstVertex, firstInstance); +} +void wgpuRenderBundleEncoderDrawIndexed(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) { + procs.renderBundleEncoderDrawIndexed(renderBundleEncoder, indexCount, instanceCount, firstIndex, baseVertex, firstInstance); +} +void wgpuRenderBundleEncoderDrawIndexedIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + procs.renderBundleEncoderDrawIndexedIndirect(renderBundleEncoder, indirectBuffer, indirectOffset); +} +void wgpuRenderBundleEncoderDrawIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + procs.renderBundleEncoderDrawIndirect(renderBundleEncoder, indirectBuffer, indirectOffset); +} +WGPURenderBundle wgpuRenderBundleEncoderFinish(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderBundleDescriptor const * descriptor) { +return procs.renderBundleEncoderFinish(renderBundleEncoder, descriptor); +} +void wgpuRenderBundleEncoderInsertDebugMarker(WGPURenderBundleEncoder renderBundleEncoder, char const * markerLabel) { + procs.renderBundleEncoderInsertDebugMarker(renderBundleEncoder, markerLabel); +} +void wgpuRenderBundleEncoderPopDebugGroup(WGPURenderBundleEncoder renderBundleEncoder) { + procs.renderBundleEncoderPopDebugGroup(renderBundleEncoder); +} +void wgpuRenderBundleEncoderPushDebugGroup(WGPURenderBundleEncoder renderBundleEncoder, char const * groupLabel) { + procs.renderBundleEncoderPushDebugGroup(renderBundleEncoder, groupLabel); +} +void wgpuRenderBundleEncoderSetBindGroup(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) { + procs.renderBundleEncoderSetBindGroup(renderBundleEncoder, groupIndex, group, dynamicOffsetCount, dynamicOffsets); +} +void wgpuRenderBundleEncoderSetIndexBuffer(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) { + procs.renderBundleEncoderSetIndexBuffer(renderBundleEncoder, buffer, format, offset, size); +} +void wgpuRenderBundleEncoderSetLabel(WGPURenderBundleEncoder renderBundleEncoder, char const * label) { + procs.renderBundleEncoderSetLabel(renderBundleEncoder, label); +} +void wgpuRenderBundleEncoderSetPipeline(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) { + procs.renderBundleEncoderSetPipeline(renderBundleEncoder, pipeline); +} +void wgpuRenderBundleEncoderSetVertexBuffer(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPUBuffer buffer, uint64_t offset, uint64_t size) { + procs.renderBundleEncoderSetVertexBuffer(renderBundleEncoder, slot, buffer, offset, size); +} +void wgpuRenderBundleEncoderReference(WGPURenderBundleEncoder renderBundleEncoder) { + procs.renderBundleEncoderReference(renderBundleEncoder); +} +void wgpuRenderBundleEncoderRelease(WGPURenderBundleEncoder renderBundleEncoder) { + procs.renderBundleEncoderRelease(renderBundleEncoder); +} + +void wgpuRenderPassEncoderBeginOcclusionQuery(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) { + procs.renderPassEncoderBeginOcclusionQuery(renderPassEncoder, queryIndex); +} +void wgpuRenderPassEncoderDraw(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { + procs.renderPassEncoderDraw(renderPassEncoder, vertexCount, instanceCount, firstVertex, firstInstance); +} +void wgpuRenderPassEncoderDrawIndexed(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) { + procs.renderPassEncoderDrawIndexed(renderPassEncoder, indexCount, instanceCount, firstIndex, baseVertex, firstInstance); +} +void wgpuRenderPassEncoderDrawIndexedIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + procs.renderPassEncoderDrawIndexedIndirect(renderPassEncoder, indirectBuffer, indirectOffset); +} +void wgpuRenderPassEncoderDrawIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + procs.renderPassEncoderDrawIndirect(renderPassEncoder, indirectBuffer, indirectOffset); +} +void wgpuRenderPassEncoderEnd(WGPURenderPassEncoder renderPassEncoder) { + procs.renderPassEncoderEnd(renderPassEncoder); +} +void wgpuRenderPassEncoderEndOcclusionQuery(WGPURenderPassEncoder renderPassEncoder) { + procs.renderPassEncoderEndOcclusionQuery(renderPassEncoder); +} +void wgpuRenderPassEncoderExecuteBundles(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) { + procs.renderPassEncoderExecuteBundles(renderPassEncoder, bundleCount, bundles); +} +void wgpuRenderPassEncoderInsertDebugMarker(WGPURenderPassEncoder renderPassEncoder, char const * markerLabel) { + procs.renderPassEncoderInsertDebugMarker(renderPassEncoder, markerLabel); +} +void wgpuRenderPassEncoderPopDebugGroup(WGPURenderPassEncoder renderPassEncoder) { + procs.renderPassEncoderPopDebugGroup(renderPassEncoder); +} +void wgpuRenderPassEncoderPushDebugGroup(WGPURenderPassEncoder renderPassEncoder, char const * groupLabel) { + procs.renderPassEncoderPushDebugGroup(renderPassEncoder, groupLabel); +} +void wgpuRenderPassEncoderSetBindGroup(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) { + procs.renderPassEncoderSetBindGroup(renderPassEncoder, groupIndex, group, dynamicOffsetCount, dynamicOffsets); +} +void wgpuRenderPassEncoderSetBlendConstant(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) { + procs.renderPassEncoderSetBlendConstant(renderPassEncoder, color); +} +void wgpuRenderPassEncoderSetIndexBuffer(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) { + procs.renderPassEncoderSetIndexBuffer(renderPassEncoder, buffer, format, offset, size); +} +void wgpuRenderPassEncoderSetLabel(WGPURenderPassEncoder renderPassEncoder, char const * label) { + procs.renderPassEncoderSetLabel(renderPassEncoder, label); +} +void wgpuRenderPassEncoderSetPipeline(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) { + procs.renderPassEncoderSetPipeline(renderPassEncoder, pipeline); +} +void wgpuRenderPassEncoderSetScissorRect(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + procs.renderPassEncoderSetScissorRect(renderPassEncoder, x, y, width, height); +} +void wgpuRenderPassEncoderSetStencilReference(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) { + procs.renderPassEncoderSetStencilReference(renderPassEncoder, reference); +} +void wgpuRenderPassEncoderSetVertexBuffer(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPUBuffer buffer, uint64_t offset, uint64_t size) { + procs.renderPassEncoderSetVertexBuffer(renderPassEncoder, slot, buffer, offset, size); +} +void wgpuRenderPassEncoderSetViewport(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) { + procs.renderPassEncoderSetViewport(renderPassEncoder, x, y, width, height, minDepth, maxDepth); +} +void wgpuRenderPassEncoderWriteTimestamp(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) { + procs.renderPassEncoderWriteTimestamp(renderPassEncoder, querySet, queryIndex); +} +void wgpuRenderPassEncoderReference(WGPURenderPassEncoder renderPassEncoder) { + procs.renderPassEncoderReference(renderPassEncoder); +} +void wgpuRenderPassEncoderRelease(WGPURenderPassEncoder renderPassEncoder) { + procs.renderPassEncoderRelease(renderPassEncoder); +} + +WGPUBindGroupLayout wgpuRenderPipelineGetBindGroupLayout(WGPURenderPipeline renderPipeline, uint32_t groupIndex) { +return procs.renderPipelineGetBindGroupLayout(renderPipeline, groupIndex); +} +void wgpuRenderPipelineSetLabel(WGPURenderPipeline renderPipeline, char const * label) { + procs.renderPipelineSetLabel(renderPipeline, label); +} +void wgpuRenderPipelineReference(WGPURenderPipeline renderPipeline) { + procs.renderPipelineReference(renderPipeline); +} +void wgpuRenderPipelineRelease(WGPURenderPipeline renderPipeline) { + procs.renderPipelineRelease(renderPipeline); +} + +void wgpuSamplerSetLabel(WGPUSampler sampler, char const * label) { + procs.samplerSetLabel(sampler, label); +} +void wgpuSamplerReference(WGPUSampler sampler) { + procs.samplerReference(sampler); +} +void wgpuSamplerRelease(WGPUSampler sampler) { + procs.samplerRelease(sampler); +} + +void wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata) { + procs.shaderModuleGetCompilationInfo(shaderModule, callback, userdata); +} +void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char const * label) { + procs.shaderModuleSetLabel(shaderModule, label); +} +void wgpuShaderModuleReference(WGPUShaderModule shaderModule) { + procs.shaderModuleReference(shaderModule); +} +void wgpuShaderModuleRelease(WGPUShaderModule shaderModule) { + procs.shaderModuleRelease(shaderModule); +} + +void wgpuSurfaceReference(WGPUSurface surface) { + procs.surfaceReference(surface); +} +void wgpuSurfaceRelease(WGPUSurface surface) { + procs.surfaceRelease(surface); +} + +WGPUTexture wgpuSwapChainGetCurrentTexture(WGPUSwapChain swapChain) { +return procs.swapChainGetCurrentTexture(swapChain); +} +WGPUTextureView wgpuSwapChainGetCurrentTextureView(WGPUSwapChain swapChain) { +return procs.swapChainGetCurrentTextureView(swapChain); +} +void wgpuSwapChainPresent(WGPUSwapChain swapChain) { + procs.swapChainPresent(swapChain); +} +void wgpuSwapChainReference(WGPUSwapChain swapChain) { + procs.swapChainReference(swapChain); +} +void wgpuSwapChainRelease(WGPUSwapChain swapChain) { + procs.swapChainRelease(swapChain); +} + +WGPUTextureView wgpuTextureCreateView(WGPUTexture texture, WGPUTextureViewDescriptor const * descriptor) { +return procs.textureCreateView(texture, descriptor); +} +void wgpuTextureDestroy(WGPUTexture texture) { + procs.textureDestroy(texture); +} +uint32_t wgpuTextureGetDepthOrArrayLayers(WGPUTexture texture) { +return procs.textureGetDepthOrArrayLayers(texture); +} +WGPUTextureDimension wgpuTextureGetDimension(WGPUTexture texture) { +return procs.textureGetDimension(texture); +} +WGPUTextureFormat wgpuTextureGetFormat(WGPUTexture texture) { +return procs.textureGetFormat(texture); +} +uint32_t wgpuTextureGetHeight(WGPUTexture texture) { +return procs.textureGetHeight(texture); +} +uint32_t wgpuTextureGetMipLevelCount(WGPUTexture texture) { +return procs.textureGetMipLevelCount(texture); +} +uint32_t wgpuTextureGetSampleCount(WGPUTexture texture) { +return procs.textureGetSampleCount(texture); +} +WGPUTextureUsageFlags wgpuTextureGetUsage(WGPUTexture texture) { +return procs.textureGetUsage(texture); +} +uint32_t wgpuTextureGetWidth(WGPUTexture texture) { +return procs.textureGetWidth(texture); +} +void wgpuTextureSetLabel(WGPUTexture texture, char const * label) { + procs.textureSetLabel(texture, label); +} +void wgpuTextureReference(WGPUTexture texture) { + procs.textureReference(texture); +} +void wgpuTextureRelease(WGPUTexture texture) { + procs.textureRelease(texture); +} + +void wgpuTextureViewSetLabel(WGPUTextureView textureView, char const * label) { + procs.textureViewSetLabel(textureView, label); +} +void wgpuTextureViewReference(WGPUTextureView textureView) { + procs.textureViewReference(textureView); +} +void wgpuTextureViewRelease(WGPUTextureView textureView) { + procs.textureViewRelease(textureView); +} + diff --git a/vendor/zgpu/src/wgpu.zig b/vendor/zgpu/src/wgpu.zig new file mode 100644 index 0000000..7bf50e2 --- /dev/null +++ b/vendor/zgpu/src/wgpu.zig @@ -0,0 +1,2974 @@ +const std = @import("std"); +const emscripten = @import("builtin").target.os.tag == .emscripten; + +test "extern struct ABI compatibility" { + @setEvalBranchQuota(10_000); + const wgpu = @cImport(@cInclude("dawn/webgpu.h")); + inline for (comptime std.meta.declarations(@This())) |decl| { + const ZigType = @field(@This(), decl.name); + if (@TypeOf(ZigType) != type) { + continue; + } + if (comptime std.meta.activeTag(@typeInfo(ZigType)) == .@"struct" and + @typeInfo(ZigType).@"struct".layout == .@"extern") + { + const wgpu_name = "WGPU" ++ decl.name; + const CType = @field(wgpu, wgpu_name); + std.testing.expectEqual(@sizeOf(CType), @sizeOf(ZigType)) catch |err| { + std.log.err("@sizeOf({s}) != @sizeOf({s})", .{ wgpu_name, decl.name }); + return err; + }; + comptime var i: usize = 0; + inline for (comptime std.meta.fieldNames(CType)) |c_field_name| { + std.testing.expectEqual( + @offsetOf(CType, c_field_name), + @offsetOf(ZigType, std.meta.fieldNames(ZigType)[i]), + ) catch |err| { + std.log.err( + "@offsetOf({s}, {s}) != @offsetOf({s}, {s})", + .{ wgpu_name, c_field_name, decl.name, std.meta.fieldNames(ZigType)[i] }, + ); + return err; + }; + i += 1; + } + } + } +} + +pub const AdapterType = enum(u32) { + discrete_gpu, + integrated_gpu, + cpu, + unknown, +}; + +pub const AddressMode = enum(u32) { + repeat = 0x00000000, + mirror_repeat = 0x00000001, + clamp_to_edge = 0x00000002, +}; + +pub const AlphaMode = enum(u32) { + premultiplied = 0x00000000, + unpremultiplied = 0x00000001, + opaq = 0x00000002, +}; + +pub const BackendType = enum(u32) { + undef, + nul, + webgpu, + d3d11, + d3d12, + metal, + vulkan, + opengl, + opengles, +}; + +pub const BlendFactor = switch (emscripten) { + true => enum(u32) { + undef = 0x00000000, + zero = 0x00000001, + one = 0x00000002, + src = 0x00000003, + one_minus_src = 0x00000004, + src_alpha = 0x00000005, + one_minus_src_alpha = 0x00000006, + dst = 0x00000007, + one_minus_dst = 0x00000008, + dst_alpha = 0x00000009, + one_minus_dst_alpha = 0x0000000A, + src_alpha_saturated = 0x0000000B, + constant = 0x0000000C, + one_minus_constant = 0x0000000D, + }, + false => enum(u32) { + zero = 0x00000000, + one = 0x00000001, + src = 0x00000002, + one_minus_src = 0x00000003, + src_alpha = 0x00000004, + one_minus_src_alpha = 0x00000005, + dst = 0x00000006, + one_minus_dst = 0x00000007, + dst_alpha = 0x00000008, + one_minus_dst_alpha = 0x00000009, + src_alpha_saturated = 0x0000000A, + constant = 0x0000000B, + one_minus_constant = 0x0000000C, + }, +}; + +pub const BlendOperation = switch (emscripten) { + true => enum(u32) { + undef = 0x00000000, + add = 0x00000001, + subtract = 0x00000002, + reverse_subtract = 0x00000003, + min = 0x00000008, + max = 0x00000004, + }, + false => enum(u32) { + add = 0x00000000, + subtract = 0x00000001, + reverse_subtract = 0x00000002, + min = 0x00000003, + max = 0x00000004, + }, +}; + +pub const BufferBindingType = enum(u32) { + undef = 0x00000000, + uniform = 0x00000001, + storage = 0x00000002, + read_only_storage = 0x00000003, +}; + +pub const BufferMapAsyncStatus = enum(u32) { + success = 0x00000000, + validation_error = 0x00000001, + unknown = 0x00000002, + device_lost = 0x00000003, + destroyed_before_callback = 0x00000004, + unmapped_before_callback = 0x00000005, + mappingAlreadyPending = 0x00000006, + offset_out_of_range = 0x00000007, + size_out_of_range = 0x00000008, +}; + +pub const BufferMapState = switch (emscripten) { + true => enum(u32) { + unmapped = 0x00000001, + pending = 0x00000002, + mapped = 0x00000003, + }, + false => enum(u32) { + unmapped = 0x00000000, + pending = 0x00000001, + mapped = 0x00000002, + }, +}; + +pub const CompareFunction = enum(u32) { + undef = 0x00000000, + never = 0x00000001, + less = 0x00000002, + less_equal = 0x00000003, + greater = 0x00000004, + greater_equal = 0x00000005, + equal = 0x00000006, + not_equal = 0x00000007, + always = 0x00000008, +}; + +pub const CompilationInfoRequestStatus = enum(u32) { + success = 0x00000000, + err = 0x00000001, + device_lost = 0x00000002, + unknown = 0x00000003, +}; + +pub const CompilationMessageType = enum(u32) { + err = 0x00000000, + warning = 0x00000001, + info = 0x00000002, +}; + +pub const ComputePassTimestampLocation = enum(u32) { + beginning = 0x00000000, + end = 0x00000001, +}; + +pub const CreatePipelineAsyncStatus = enum(u32) { + success = 0x00000000, + validation_error = 0x00000001, + internal_error = 0x00000002, + device_lost = 0x00000003, + device_destroyed = 0x00000004, + unknown = 0x00000005, +}; + +pub const ExternalTextureRotation = enum(u32) { + rotate_0_degrees = 0x00000000, + rotate_90_degrees = 0x00000001, + rotate_180_degrees = 0x00000002, + rotate_270_degrees = 0x00000003, +}; + +pub const CullMode = enum(u32) { + none = 0x00000000, + front = 0x00000001, + back = 0x00000002, +}; + +pub const DeviceLostReason = enum(u32) { + undef = 0x00000000, + destroyed = 0x00000001, +}; + +pub const ErrorFilter = enum(u32) { + validation = 0x00000000, + out_of_memory = 0x00000001, + internal = 0x00000002, +}; + +pub const ErrorType = enum(u32) { + no_error = 0x00000000, + validation = 0x00000001, + out_of_memory = 0x00000002, + internal = 0x00000003, + unknown = 0x00000004, + device_lost = 0x00000005, +}; + +pub const FeatureName = enum(u32) { + undef = 0x00000000, + depth_clip_control = 0x00000001, + depth32_float_stencil8 = 0x00000002, + timestamp_query = 0x00000003, + pipeline_statistics_query = 0x00000004, + texture_compression_bc = 0x00000005, + texture_compression_etc2 = 0x00000006, + texture_compression_astc = 0x00000007, + indirect_first_instance = 0x00000008, + shader_f16 = 0x00000009, + rg11_b10_ufloat_renderable = 0x0000000A, + bgra8_unorm_storage = 0x0000000B, + float32_filterable = 0x0000000C, + depth_clamping = 0x000003E8, + dawn_shader_float16 = 0x000003E9, + dawn_internal_usages = 0x000003EA, + dawn_multi_planar_formats = 0x000003EB, + dawn_native = 0x000003EC, + chromium_experimental_dp4a = 0x000003ED, + timestamp_query_inside_passes = 0x000003EE, + implicit_device_synchronization = 0x000003EF, + surface_capabilities = 0x000003F0, + transient_attachments = 0x000003F1, + msaa_render_to_single_sampled = 0x000003F2, +}; + +pub const FilterMode = enum(u32) { + nearest = 0x00000000, + linear = 0x00000001, +}; + +pub const MipmapFilterMode = enum(u32) { + nearest = 0x00000000, + linear = 0x00000001, +}; + +pub const FrontFace = enum(u32) { + ccw = 0x00000000, + cw = 0x00000001, +}; + +pub const IndexFormat = enum(u32) { + undef = 0x00000000, + uint16 = 0x00000001, + uint32 = 0x00000002, +}; + +pub const LoadOp = enum(u32) { + undef = 0x00000000, + clear = 0x00000001, + load = 0x00000002, +}; + +pub const LoggingType = enum(u32) { + verbose = 0x00000000, + info = 0x00000001, + warning = 0x00000002, + err = 0x00000003, +}; + +pub const PipelineStatisticName = enum(u32) { + vertex_shader_invocations = 0x00000000, + clipper_invocations = 0x00000001, + clipper_primitives_out = 0x00000002, + fragment_shader_invocations = 0x00000003, + compute_shader_invocations = 0x00000004, +}; + +pub const PowerPreference = enum(u32) { + undef = 0x00000000, + low_power = 0x00000001, + high_performance = 0x00000002, +}; + +pub const PresentMode = switch (emscripten) { + true => enum(u32) { + fifo = 0x00000001, + immediate = 0x00000003, + mailbox = 0x00000004, + }, + false => enum(u32) { + immediate = 0x00000000, + mailbox = 0x00000001, + fifo = 0x00000002, + }, +}; + +pub const PrimitiveTopology = switch (emscripten) { + true => enum(u32) { + undefined = 0x00000000, + point_list = 0x00000001, + line_list = 0x00000002, + line_strip = 0x00000003, + triangle_list = 0x00000004, + triangle_strip = 0x00000005, + }, + false => enum(u32) { + point_list = 0x00000000, + line_list = 0x00000001, + line_strip = 0x00000002, + triangle_list = 0x00000003, + triangle_strip = 0x00000004, + }, +}; + +pub const QueryType = enum(u32) { + occlusion = 0x00000000, + pipeline_statistics = 0x00000001, + timestamp = 0x00000002, +}; + +pub const QueueWorkDoneStatus = enum(u32) { + success = 0x00000000, + err = 0x00000001, + unknown = 0x00000002, + device_lost = 0x00000003, +}; + +pub const RenderPassTimestampLocation = enum(u32) { + beginning = 0x00000000, + end = 0x00000001, +}; + +pub const RequestAdapterStatus = enum(u32) { + success = 0x00000000, + unavailable = 0x00000001, + err = 0x00000002, + unknown = 0x00000003, +}; + +pub const RequestDeviceStatus = enum(u32) { + success = 0x00000000, + err = 0x00000001, + unknown = 0x00000002, +}; + +pub const SurfaceDescriptorFromMetalLayer = extern struct { + chain: ChainedStruct, + layer: *anyopaque, +}; + +pub const SurfaceDescriptorFromWaylandSurface = extern struct { + chain: ChainedStruct, + display: *anyopaque, + surface: *anyopaque, +}; + +pub const SurfaceDescriptorFromWindowsHWND = extern struct { + chain: ChainedStruct, + hinstance: *anyopaque, + hwnd: *anyopaque, +}; + +pub const SurfaceDescriptorFromXlibWindow = extern struct { + chain: ChainedStruct, + display: *anyopaque, + window: u32, +}; + +pub const SurfaceDescriptorFromWindowsCoreWindow = extern struct { + chain: ChainedStruct, + core_window: *anyopaque, +}; + +pub const SurfaceDescriptorFromWindowsSwapChainPanel = extern struct { + chain: ChainedStruct, + swap_chain_panel: *anyopaque, +}; + +pub const SurfaceDescriptorFromCanvasHTMLSelector = extern struct { + chain: ChainedStruct, + selector: [*:0]const u8, +}; + +pub const StructType = enum(u32) { + invalid = 0x00000000, + surface_descriptor_from_metal_layer = 0x00000001, + surface_descriptor_from_windows_hwnd = 0x00000002, + surface_descriptor_from_xlib_window = 0x00000003, + surface_descriptor_from_canvas_html_selector = 0x00000004, + shader_module_spirv_descriptor = 0x00000005, + shader_module_wgsl_descriptor = 0x00000006, + surface_descriptor_from_wayland_surface = 0x00000008, + surface_descriptor_from_android_native_window = 0x00000009, + surface_descriptor_from_windows_core_window = 0x0000000B, + external_texture_binding_entry = 0x0000000C, + external_texture_binding_layout = 0x0000000D, + surface_descriptor_from_windows_swap_chain_panel = 0x0000000E, + dawn_texture_internal_usage_descriptor = 0x000003E8, + dawn_encoder_internal_usage_descriptor = 0x000003EB, + dawn_instance_descriptor = 0x000003EC, + dawn_cache_device_descriptor = 0x000003ED, + dawn_adapter_properties_power_preference = 0x000003EE, + dawn_buffer_descriptor_error_info_from_wire_client = 0x000003EF, + dawn_toggles_descriptor = 0x000003F0, + dawn_shader_module_spirv_options_descriptor = 0x000003F1, + request_adapter_options_luid = 0x000003F2, + request_adapter_options_get_gl_proc = 0x000003F3, + dawn_multisample_state_render_to_single_sampled = 0x000003F4, + dawn_render_pass_color_attachment_render_to_single_sampled = 0x000003F5, +}; + +pub const SamplerBindingType = enum(u32) { + undef = 0x00000000, + filtering = 0x00000001, + non_filtering = 0x00000002, + comparison = 0x00000003, +}; + +pub const StencilOperation = enum(u32) { + keep = 0x00000000, + zero = 0x00000001, + replace = 0x00000002, + invert = 0x00000003, + increment_lamp = 0x00000004, + decrement_clamp = 0x00000005, + increment_wrap = 0x00000006, + decrement_wrap = 0x00000007, +}; + +pub const StorageTextureAccess = enum(u32) { + undef = 0x00000000, + write_only = 0x00000001, +}; + +pub const StoreOp = enum(u32) { + undef = 0x00000000, + store = 0x00000001, + discard = 0x00000002, +}; + +pub const TextureAspect = enum(u32) { + all = 0x00000000, + stencil_only = 0x00000001, + depth_only = 0x00000002, + plane0_only = 0x00000003, + plane1_only = 0x00000004, +}; + +pub const TextureDimension = switch (emscripten) { + true => enum(u32) { + undef = 0x00000000, + tdim_1d = 0x00000001, + tdim_2d = 0x00000002, + tdim_3d = 0x00000003, + }, + false => enum(u32) { + tdim_1d = 0x00000000, + tdim_2d = 0x00000001, + tdim_3d = 0x00000002, + }, +}; + +pub const TextureFormat = enum(u32) { + undef = 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 TextureSampleType = enum(u32) { + undef = 0x00000000, + float = 0x00000001, + unfilterable_float = 0x00000002, + depth = 0x00000003, + sint = 0x00000004, + uint = 0x00000005, +}; + +pub const TextureViewDimension = enum(u32) { + undef = 0x00000000, + tvdim_1d = 0x00000001, + tvdim_2d = 0x00000002, + tvdim_2d_array = 0x00000003, + tvdim_cube = 0x00000004, + tvdim_cube_array = 0x00000005, + tvdim_3d = 0x00000006, +}; + +pub const VertexFormat = enum(u32) { + undef = 0x00000000, + uint8x2 = 0x00000001, + uint8x4 = 0x00000002, + sint8x2 = 0x00000003, + sint8x4 = 0x00000004, + unorm8x2 = 0x00000005, + unorm8x4 = 0x00000006, + snorm8x2 = 0x00000007, + snorm8x4 = 0x00000008, + uint16x2 = 0x00000009, + uint16x4 = 0x0000000A, + sint16x2 = 0x0000000B, + sint16x4 = 0x0000000C, + unorm16x2 = 0x0000000D, + unorm16x4 = 0x0000000E, + snorm16x2 = 0x0000000F, + snorm16x4 = 0x00000010, + float16x2 = 0x00000011, + float16x4 = 0x00000012, + float32 = 0x00000013, + float32x2 = 0x00000014, + float32x3 = 0x00000015, + float32x4 = 0x00000016, + uint32 = 0x00000017, + uint32x2 = 0x00000018, + uint32x3 = 0x00000019, + uint32x4 = 0x0000001A, + sint32 = 0x0000001B, + sint32x2 = 0x0000001C, + sint32x3 = 0x0000001D, + sint32x4 = 0x0000001E, +}; + +pub const VertexStepMode = switch (emscripten) { + true => enum(u32) { + undefined = 0x00000000, + vertex_buffer_not_used = 0x00000001, + vertex = 0x00000002, + instance = 0x00000003, + }, + false => enum(u32) { + vertex = 0x00000000, + instance = 0x00000001, + vertex_buffer_not_used = 0x00000002, + }, +}; + +pub const BufferUsage = 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, +}; + +pub const ColorWriteMask = packed struct(u32) { + red: bool = false, + green: bool = false, + blue: bool = false, + alpha: bool = false, + _padding: u28 = 0, + + pub const all = ColorWriteMask{ .red = true, .green = true, .blue = true, .alpha = true }; +}; + +pub const MapMode = packed struct(u32) { + read: bool = false, + write: bool = false, + _padding: u30 = 0, +}; + +pub const ShaderStage = packed struct(u32) { + vertex: bool = false, + fragment: bool = false, + compute: bool = false, + _padding: u29 = 0, +}; + +pub const TextureUsage = 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, +}; + +pub const ChainedStruct = extern struct { + next: ?*const ChainedStruct, + struct_type: StructType, +}; + +pub const ChainedStructOut = extern struct { + next: ?*ChainedStructOut, + struct_type: StructType, +}; + +pub const AdapterProperties = extern struct { + next_in_chain: ?*ChainedStructOut = 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: AdapterType, + backend_type: BackendType, + compatibility_mode: bool, +}; + +pub const BindGroupEntry = extern struct { + next_in_chain: ?*const ChainedStruct = null, + binding: u32, + buffer: ?Buffer = null, + offset: u64 = 0, + size: u64, + sampler: ?Sampler = null, + texture_view: ?TextureView = null, +}; + +pub const BindGroupDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + layout: BindGroupLayout, + entry_count: usize, + entries: ?[*]const BindGroupEntry, +}; + +pub const BufferBindingLayout = extern struct { + next_in_chain: ?*const ChainedStruct = null, + binding_type: BufferBindingType = .uniform, + has_dynamic_offset: U32Bool = .false, + min_binding_size: u64 = 0, +}; + +pub const SamplerBindingLayout = extern struct { + next_in_chain: ?*const ChainedStruct = null, + binding_type: SamplerBindingType = .filtering, +}; + +pub const TextureBindingLayout = extern struct { + next_in_chain: ?*const ChainedStruct = null, + sample_type: TextureSampleType = .float, + view_dimension: TextureViewDimension = .tvdim_2d, + multisampled: bool = false, +}; + +pub const StorageTextureBindingLayout = extern struct { + next_in_chain: ?*const ChainedStruct = null, + access: StorageTextureAccess = .write_only, + format: TextureFormat, + view_dimension: TextureViewDimension = .tvdim_2d, +}; + +pub const BindGroupLayoutEntry = extern struct { + next_in_chain: ?*const ChainedStruct = null, + binding: u32, + visibility: ShaderStage, + buffer: BufferBindingLayout = .{ .binding_type = .undef }, + sampler: SamplerBindingLayout = .{ .binding_type = .undef }, + texture: TextureBindingLayout = .{ .sample_type = .undef }, + storage_texture: StorageTextureBindingLayout = .{ .access = .undef, .format = .undef }, +}; + +pub const BindGroupLayoutDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + entry_count: usize, + entries: ?[*]const BindGroupLayoutEntry, +}; + +pub const U32Bool = enum(u32) { + false = 0, + true = 1, +}; + +pub const BufferDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + usage: BufferUsage, + size: u64, + mapped_at_creation: U32Bool = .false, +}; + +pub const CommandEncoderDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +pub const ConstantEntry = extern struct { + next_in_chain: ?*const ChainedStruct = null, + key: [*:0]const u8, + value: f64, +}; + +pub const ProgrammableStageDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + module: ShaderModule, + entry_point: [*:0]const u8, + constant_count: usize = 0, + constants: ?[*]const ConstantEntry = null, +}; + +pub const ComputePipelineDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + layout: ?PipelineLayout = null, + compute: ProgrammableStageDescriptor, +}; + +pub const ExternalTextureDescriptor = 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: bool, + yuv_to_rgb_conversion_matrix: ?[*]const f32, + src_transfer_function_parameters: [*]const f32, + dst_transfer_function_parameters: [*]const f32, + gamut_conversion_matrix: [*]const f32, + flip_y: bool, + rotation: ExternalTextureRotation, +}; + +pub const PipelineLayoutDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + bind_group_layout_count: usize, + bind_group_layouts: ?[*]const BindGroupLayout, +}; + +pub const QuerySetDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + query_type: QueryType, + count: u32, + pipeline_statistics: ?[*]const PipelineStatisticName, + pipeline_statistics_count: usize, +}; + +pub const RenderBundleEncoderDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + color_formats_count: usize, + color_formats: ?[*]const TextureFormat, + depth_stencil_format: TextureFormat, + sample_count: u32, + depth_read_only: bool, + stencil_read_only: bool, +}; + +pub const VertexAttribute = extern struct { + format: VertexFormat, + offset: u64, + shader_location: u32, +}; + +pub const VertexBufferLayout = extern struct { + array_stride: u64, + step_mode: VertexStepMode = .vertex, + attribute_count: usize, + attributes: [*]const VertexAttribute, +}; + +pub const VertexState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + module: ShaderModule, + entry_point: [*:0]const u8, + constant_count: usize = 0, + constants: ?[*]const ConstantEntry = null, + buffer_count: usize = 0, + buffers: ?[*]const VertexBufferLayout = null, +}; + +pub const BlendComponent = extern struct { + operation: BlendOperation = .add, + src_factor: BlendFactor = .one, + dst_factor: BlendFactor = .zero, +}; + +pub const BlendState = extern struct { + color: BlendComponent, + alpha: BlendComponent, +}; + +pub const ColorTargetState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + format: TextureFormat, + blend: ?*const BlendState = null, + write_mask: ColorWriteMask = ColorWriteMask.all, +}; + +pub const FragmentState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + module: ShaderModule, + entry_point: [*:0]const u8, + constant_count: usize = 0, + constants: ?[*]const ConstantEntry = null, + target_count: usize = 0, + targets: ?[*]const ColorTargetState = null, +}; + +pub const PrimitiveState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + topology: PrimitiveTopology = .triangle_list, + strip_index_format: IndexFormat = .undef, + front_face: FrontFace = .ccw, + cull_mode: CullMode = .none, +}; + +pub const StencilFaceState = extern struct { + compare: CompareFunction = .always, + fail_op: StencilOperation = .keep, + depth_fail_op: StencilOperation = .keep, + pass_op: StencilOperation = .keep, +}; + +pub const DepthStencilState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + format: TextureFormat, + depth_write_enabled: bool = false, + depth_compare: CompareFunction = .always, + stencil_front: StencilFaceState = .{}, + stencil_back: StencilFaceState = .{}, + stencil_read_mask: u32 = 0xffff_ffff, + stencil_write_mask: u32 = 0xffff_ffff, + depth_bias: i32 = 0, + depth_bias_slope_scale: f32 = 0.0, + depth_bias_clamp: f32 = 0.0, +}; + +pub const MultisampleState = extern struct { + next_in_chain: ?*const ChainedStruct = null, + count: u32 = 1, + mask: u32 = 0xffff_ffff, + alpha_to_coverage_enabled: bool = false, +}; + +pub const RenderPipelineDescriptor = 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 const SamplerDescriptor = 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 = .undef, + max_anisotropy: u16 = 1, +}; + +pub const ShaderModuleDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +pub const ShaderModuleWGSLDescriptor = extern struct { + chain: ChainedStruct, + code: [*:0]const u8, +}; + +pub const SwapChainDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + usage: TextureUsage, + format: TextureFormat, + width: u32, + height: u32, + present_mode: PresentMode, +}; + +pub const Extent2D = extern struct { + width: u32, + height: u32 = 1, +}; + +pub const Extent3D = extern struct { + width: u32, + height: u32 = 1, + depth_or_array_layers: u32 = 1, +}; + +pub const TextureDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + usage: TextureUsage, + dimension: TextureDimension = .tdim_2d, + size: Extent3D, + format: TextureFormat, + mip_level_count: u32 = 1, + sample_count: u32 = 1, + view_format_count: usize = 0, + view_formats: ?[*]const TextureFormat = null, +}; + +pub const Limits = extern struct { + const u32_undefined: u32 = 0xFFFFFFFF; + const u64_undefined: u64 = 0xFFFFFFFFFFFFFFFF; + + max_texture_dimension_1d: u32 = u32_undefined, + max_texture_dimension_2d: u32 = u32_undefined, + max_texture_dimension_3d: u32 = u32_undefined, + max_texture_array_layers: u32 = u32_undefined, + max_bind_groups: u32 = u32_undefined, + max_bind_groups_plus_vertex_buffers: u32 = u32_undefined, + max_bindings_per_bind_group: u32 = u32_undefined, + max_dynamic_uniform_buffers_per_pipeline_layout: u32 = u32_undefined, + max_dynamic_storage_buffers_per_pipeline_layout: u32 = u32_undefined, + max_sampled_textures_per_shader_stage: u32 = u32_undefined, + max_samplers_per_shader_stage: u32 = u32_undefined, + max_storage_buffers_per_shader_stage: u32 = u32_undefined, + max_storage_textures_per_shader_stage: u32 = u32_undefined, + max_uniform_buffers_per_shader_stage: u32 = u32_undefined, + max_uniform_buffer_binding_size: u64 = u64_undefined, + max_storage_buffer_binding_size: u64 = u64_undefined, + min_uniform_buffer_offset_alignment: u32 = u32_undefined, + min_storage_buffer_offset_alignment: u32 = u32_undefined, + max_vertex_buffers: u32 = u32_undefined, + max_buffer_size: u64 = u64_undefined, + max_vertex_attributes: u32 = u32_undefined, + max_vertex_buffer_array_stride: u32 = u32_undefined, + max_inter_stage_shader_components: u32 = u32_undefined, + max_inter_stage_shader_variables: u32 = u32_undefined, + max_color_attachments: u32 = u32_undefined, + max_color_attachment_bytes_per_sample: u32 = u32_undefined, + max_compute_workgroup_storage_size: u32 = u32_undefined, + max_compute_invocations_per_workgroup: u32 = u32_undefined, + max_compute_workgroup_size_x: u32 = u32_undefined, + max_compute_workgroup_size_y: u32 = u32_undefined, + max_compute_workgroup_size_z: u32 = u32_undefined, + max_compute_workgroups_per_dimension: u32 = u32_undefined, +}; + +pub const RequiredLimits = extern struct { + next_in_chain: ?*const ChainedStruct = null, + limits: Limits = .{}, +}; + +pub const SupportedLimits = extern struct { + next_in_chain: ?*ChainedStructOut = null, + limits: Limits = .{}, +}; + +pub const QueueDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +// Can be chained in InstanceDescriptor +// Can be chained in RequestAdapterOptions +// Can be chained in DeviceDescriptor +pub const DawnTogglesDescriptor = extern struct { + chain: ChainedStruct, + enabled_toggles_count: usize = 0, + enabled_toggles: ?[*]const [*:0]const u8 = null, + disabled_toggles_count: usize = 0, + disabled_toggles: ?[*]const [*:0]const u8 = null, +}; + +pub const DawnAdapterPropertiesPowerPreference = extern struct { + chain: ChainedStructOut, + power_preference: PowerPreference, +}; + +pub const DeviceDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + required_features_count: usize = 0, + required_features: ?[*]const FeatureName = null, + required_limits: ?[*]const RequiredLimits = null, + default_queue: QueueDescriptor = .{}, + device_lost_callback: ?DeviceLostCallback = null, + device_lost_user_data: ?*anyopaque = null, +}; + +pub const SurfaceDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +pub const RequestAdapterOptions = extern struct { + next_in_chain: ?*const ChainedStruct = null, + compatible_surface: ?Surface = null, + power_preference: PowerPreference, + backend_type: BackendType = .undef, + force_fallback_adapter: bool = false, + compatibility_mode: bool = false, +}; + +pub const ComputePassTimestampWrite = extern struct { + query_set: QuerySet, + query_index: u32, + location: ComputePassTimestampLocation, +}; + +pub const RenderPassTimestampWrite = extern struct { + query_set: QuerySet, + query_index: u32, + location: RenderPassTimestampLocation, +}; + +pub const ComputePassDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + timestamp_write_count: usize, + timestamp_writes: ?[*]const ComputePassTimestampWrite, +}; + +pub const Color = extern struct { + r: f64, + g: f64, + b: f64, + a: f64, +}; + +pub const RenderPassColorAttachment = switch (emscripten) { + true => extern struct { + next_in_chain: ?*const ChainedStruct = null, + view: ?TextureView, + depth_slice: u32 = std.math.maxInt(u32), + resolve_target: ?TextureView = null, + load_op: LoadOp, + store_op: StoreOp, + clear_value: Color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 }, + }, + false => extern struct { + next_in_chain: ?*const ChainedStruct = null, + view: ?TextureView, + resolve_target: ?TextureView = null, + load_op: LoadOp, + store_op: StoreOp, + clear_value: Color = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.0 }, + }, +}; + +pub const RenderPassDepthStencilAttachment = extern struct { + view: TextureView, + depth_load_op: LoadOp = .undef, + depth_store_op: StoreOp = .undef, + depth_clear_value: f32 = 0.0, + depth_read_only: U32Bool = .false, + stencil_load_op: LoadOp = .undef, + stencil_store_op: StoreOp = .undef, + stencil_clear_value: u32 = 0, + stencil_read_only: U32Bool = .false, +}; + +pub const RenderPassDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + color_attachment_count: usize, + color_attachments: ?[*]const RenderPassColorAttachment, + depth_stencil_attachment: ?*const RenderPassDepthStencilAttachment = null, + occlusion_query_set: ?QuerySet = null, + timestamp_write_count: usize = 0, + timestamp_writes: ?[*]const RenderPassTimestampWrite = null, +}; + +pub const TextureDataLayout = extern struct { + next_in_chain: ?*const ChainedStruct = null, + offset: u64 = 0, + bytes_per_row: u32, + rows_per_image: u32, +}; + +pub const Origin2D = extern struct { + x: u32 = 0, + y: u32 = 0, +}; + +pub const Origin3D = extern struct { + x: u32 = 0, + y: u32 = 0, + z: u32 = 0, +}; + +pub const ImageCopyBuffer = extern struct { + next_in_chain: ?*const ChainedStruct = null, + layout: TextureDataLayout, + buffer: Buffer, +}; + +pub const ImageCopyTexture = extern struct { + next_in_chain: ?*const ChainedStruct = null, + texture: Texture, + mip_level: u32 = 0, + origin: Origin3D = .{}, + aspect: TextureAspect = .all, +}; + +pub const ImageCopyExternalTexture = extern struct { + next_in_chain: ?*const ChainedStruct = null, + external_texture: ExternalTexture, + origin: Origin3D, + natural_size: Extent2D, +}; + +pub const CommandBufferDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +pub const CopyTextureForBrowserOptions = extern struct { + next_in_chain: ?*const ChainedStruct = null, + flip_y: bool, + needs_color_space_conversion: bool, + src_alpha_mode: AlphaMode, + src_transfer_function_parameters: ?[*]const f32, + conversion_matrix: ?[*]const f32, + dst_transfer_function_parameters: ?[*]const f32, + dst_alpha_mode: AlphaMode, + internal_usage: bool, +}; + +pub const TextureViewDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, + format: TextureFormat = .undef, + dimension: TextureViewDimension = .undef, + base_mip_level: u32 = 0, + mip_level_count: u32 = 0xffff_ffff, + base_array_layer: u32 = 0, + array_layer_count: u32 = 0xffff_ffff, + aspect: TextureAspect = .all, +}; + +pub const CompilationMessage = extern struct { + next_in_chain: ?*const ChainedStruct = null, + message: ?[*:0]const u8 = null, + message_type: CompilationMessageType, + line_num: u64, + line_pos: u64, + offset: u64, + length: u64, + utf16_line_pos: u64, + utf16_offset: u64, + utf16_length: u64, +}; + +pub const CompilationInfo = extern struct { + next_in_chain: ?*const ChainedStruct = null, + message_count: usize, + messages: ?[*]const CompilationMessage, +}; + +pub const RenderBundleDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, + label: ?[*:0]const u8 = null, +}; + +pub const CreateComputePipelineAsyncCallback = *const fn ( + status: CreatePipelineAsyncStatus, + pipeline: ComputePipeline, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const CreateRenderPipelineAsyncCallback = *const fn ( + status: CreatePipelineAsyncStatus, + pipeline: RenderPipeline, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const ErrorCallback = *const fn ( + err_type: ErrorType, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const LoggingCallback = *const fn ( + log_type: LoggingType, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const DeviceLostCallback = *const fn ( + reason: DeviceLostReason, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const RequestAdapterCallback = *const fn ( + status: RequestAdapterStatus, + adapter: Adapter, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const RequestDeviceCallback = *const fn ( + status: RequestDeviceStatus, + device: Device, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const BufferMapCallback = *const fn ( + status: BufferMapAsyncStatus, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const QueueWorkDoneCallback = *const fn ( + status: QueueWorkDoneStatus, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const CompilationInfoCallback = *const fn ( + status: CompilationInfoRequestStatus, + info: *const CompilationInfo, + userdata: ?*anyopaque, +) callconv(.C) void; + +pub const Adapter = *opaque { + pub fn createDevice(adapter: Adapter, descriptor: DeviceDescriptor) Device { + return wgpuAdapterCreateDevice(adapter, &descriptor); + } + extern fn wgpuAdapterCreateDevice(adapter: Adapter, descriptor: *const DeviceDescriptor) Device; + + pub fn enumerateFeatures(adapter: Adapter, features: ?[*]FeatureName) usize { + return wgpuAdapterEnumerateFeatures(adapter, features); + } + extern fn wgpuAdapterEnumerateFeatures(adapter: Adapter, features: ?[*]FeatureName) usize; + + pub fn getLimits(adapter: Adapter, limits: *SupportedLimits) bool { + return wgpuAdapterGetLimits(adapter, limits); + } + extern fn wgpuAdapterGetLimits(adapter: Adapter, limits: *SupportedLimits) bool; + + pub fn getProperties(adapter: Adapter, properties: *AdapterProperties) void { + wgpuAdapterGetProperties(adapter, properties); + } + extern fn wgpuAdapterGetProperties(adapter: Adapter, properties: *AdapterProperties) void; + + pub fn hasFeature(adapter: Adapter, feature: FeatureName) bool { + return wgpuAdapterHasFeature(adapter, feature); + } + extern fn wgpuAdapterHasFeature(adapter: Adapter, feature: FeatureName) bool; + + pub fn requestDevice( + adapter: Adapter, + descriptor: DeviceDescriptor, + callback: RequestDeviceCallback, + userdata: ?*anyopaque, + ) void { + wgpuAdapterRequestDevice(adapter, &descriptor, callback, userdata); + } + extern fn wgpuAdapterRequestDevice( + adapter: Adapter, + descriptor: *const DeviceDescriptor, + callback: RequestDeviceCallback, + userdata: ?*anyopaque, + ) void; + + pub fn reference(adapter: Adapter) void { + wgpuAdapterReference(adapter); + } + extern fn wgpuAdapterReference(adapter: Adapter) void; + + pub fn release(adapter: Adapter) void { + wgpuAdapterRelease(adapter); + } + extern fn wgpuAdapterRelease(adapter: Adapter) void; +}; + +pub const BindGroup = *opaque { + pub fn setLabel(bind_group: BindGroup, label: ?[*:0]const u8) void { + wgpuBindGroupSetLabel(bind_group, label); + } + extern fn wgpuBindGroupSetLabel(bind_group: BindGroup, label: ?[*:0]const u8) void; + + pub fn reference(bind_group: BindGroup) void { + wgpuBindGroupReference(bind_group); + } + extern fn wgpuBindGroupReference(bind_group: BindGroup) void; + + pub fn release(bind_group: BindGroup) void { + wgpuBindGroupRelease(bind_group); + } + extern fn wgpuBindGroupRelease(bind_group: BindGroup) void; +}; + +pub const BindGroupLayout = *opaque { + pub fn setLabel(bind_group_layout: BindGroupLayout, label: ?[*:0]const u8) void { + wgpuBindGroupLayoutSetLabel(bind_group_layout, label); + } + extern fn wgpuBindGroupLayoutSetLabel(bind_group_layout: BindGroupLayout, label: ?[*:0]const u8) void; + + pub fn reference(bind_group_layout: BindGroupLayout) void { + wgpuBindGroupLayoutReference(bind_group_layout); + } + extern fn wgpuBindGroupLayoutReference(bind_group_layout: BindGroupLayout) void; + + pub fn release(bind_group_layout: BindGroupLayout) void { + wgpuBindGroupLayoutRelease(bind_group_layout); + } + extern fn wgpuBindGroupLayoutRelease(bind_group_layout: BindGroupLayout) void; +}; + +pub const Buffer = *opaque { + pub fn destroy(buffer: Buffer) void { + wgpuBufferDestroy(buffer); + } + extern fn wgpuBufferDestroy(buffer: Buffer) void; + + // `offset` has to be a multiple of 8 (otherwise `null` will be returned). + // `@sizeOf(T) * len` has to be a multiple of 4 (otherwise `null` will be returned). + pub fn getConstMappedRange(buffer: Buffer, comptime T: type, offset: usize, len: usize) ?[]const T { + if (len == 0) return null; + const ptr = wgpuBufferGetConstMappedRange(buffer, offset, @sizeOf(T) * len); + if (ptr == null) return null; + return @as([*]const T, @ptrCast(@alignCast(ptr)))[0..len]; + } + extern fn wgpuBufferGetConstMappedRange(buffer: Buffer, offset: usize, size: usize) ?*const anyopaque; + + // `offset` - in bytes, has to be a multiple of 8 (otherwise `null` will be returned). + // `len` - length of slice to return, in elements of type T, `@sizeOf(T) * len` has to be a multiple of 4 (otherwise `null` will be returned). + pub fn getMappedRange(buffer: Buffer, comptime T: type, offset: usize, len: usize) ?[]T { + if (len == 0) return null; + const ptr = wgpuBufferGetMappedRange(buffer, offset, @sizeOf(T) * len); + if (ptr == null) return null; + return @as([*]T, @ptrCast(@alignCast(ptr)))[0..len]; + } + extern fn wgpuBufferGetMappedRange(buffer: Buffer, offset: usize, size: usize) ?*anyopaque; + + pub fn getMapState(buffer: Buffer) BufferMapState { + return wgpuBufferGetMapState(buffer); + } + extern fn wgpuBufferGetMapState(buffer: Buffer) BufferMapState; + + pub fn getSize(buffer: Buffer) usize { + return @intCast(wgpuBufferGetSize(buffer)); + } + extern fn wgpuBufferGetSize(buffer: Buffer) u64; + + pub fn getUsage(buffer: Buffer) BufferUsage { + return wgpuBufferGetUsage(buffer); + } + extern fn wgpuBufferGetUsage(buffer: Buffer) BufferUsage; + + // `offset` - in bytes, has to be a multiple of 8 (Dawn's validation layer will warn). + // `size` - size of buffer to map in bytes, has to be a multiple of 4 (Dawn's validation layer will warn). + pub fn mapAsync( + buffer: Buffer, + mode: MapMode, + offset: usize, + size: usize, + callback: BufferMapCallback, + userdata: ?*anyopaque, + ) void { + wgpuBufferMapAsync(buffer, mode, offset, size, callback, userdata); + } + extern fn wgpuBufferMapAsync( + buffer: Buffer, + mode: MapMode, + offset: usize, + size: usize, + callback: BufferMapCallback, + userdata: ?*anyopaque, + ) void; + + pub fn setLabel(buffer: Buffer, label: ?[*:0]const u8) void { + wgpuBufferSetLabel(buffer, label); + } + extern fn wgpuBufferSetLabel(buffer: Buffer, label: ?[*:0]const u8) void; + + pub fn unmap(buffer: Buffer) void { + wgpuBufferUnmap(buffer); + } + extern fn wgpuBufferUnmap(buffer: Buffer) void; + + pub fn reference(buffer: Buffer) void { + wgpuBufferReference(buffer); + } + extern fn wgpuBufferReference(buffer: Buffer) void; + + pub fn release(buffer: Buffer) void { + wgpuBufferRelease(buffer); + } + extern fn wgpuBufferRelease(buffer: Buffer) void; +}; + +pub const CommandBuffer = *opaque { + pub fn setLabel(command_buffer: CommandBuffer, label: ?[*:0]const u8) void { + wgpuCommandBufferSetLabel(command_buffer, label); + } + extern fn wgpuCommandBufferSetLabel(command_buffer: CommandBuffer, label: ?[*:0]const u8) void; + + pub fn reference(command_buffer: CommandBuffer) void { + wgpuCommandBufferReference(command_buffer); + } + extern fn wgpuCommandBufferReference(command_buffer: CommandBuffer) void; + + pub fn release(command_buffer: CommandBuffer) void { + wgpuCommandBufferRelease(command_buffer); + } + extern fn wgpuCommandBufferRelease(command_buffer: CommandBuffer) void; +}; + +pub const CommandEncoder = *opaque { + pub fn beginComputePass( + command_encoder: CommandEncoder, + descriptor: ?ComputePassDescriptor, + ) ComputePassEncoder { + return wgpuCommandEncoderBeginComputePass(command_encoder, if (descriptor) |d| &d else null); + } + extern fn wgpuCommandEncoderBeginComputePass( + command_encoder: CommandEncoder, + descriptor: ?*const ComputePassDescriptor, + ) ComputePassEncoder; + + pub fn beginRenderPass( + command_encoder: CommandEncoder, + descriptor: RenderPassDescriptor, + ) RenderPassEncoder { + return wgpuCommandEncoderBeginRenderPass(command_encoder, &descriptor); + } + extern fn wgpuCommandEncoderBeginRenderPass( + command_encoder: CommandEncoder, + descriptor: *const RenderPassDescriptor, + ) RenderPassEncoder; + + pub fn clearBuffer(command_encoder: CommandEncoder, buffer: Buffer, offset: usize, size: usize) void { + wgpuCommandEncoderClearBuffer(command_encoder, buffer, offset, size); + } + extern fn wgpuCommandEncoderClearBuffer( + command_encoder: CommandEncoder, + buffer: Buffer, + offset: usize, + size: usize, + ) void; + + pub fn copyBufferToBuffer( + command_encoder: CommandEncoder, + source: Buffer, + source_offset: u64, + destination: Buffer, + destination_offset: u64, + size: u64, + ) void { + wgpuCommandEncoderCopyBufferToBuffer( + command_encoder, + source, + source_offset, + destination, + destination_offset, + size, + ); + } + extern fn wgpuCommandEncoderCopyBufferToBuffer( + command_encoder: CommandEncoder, + source: Buffer, + source_offset: u64, + destination: Buffer, + destination_offset: u64, + size: u64, + ) void; + + pub fn copyBufferToTexture( + command_encoder: CommandEncoder, + source: ImageCopyBuffer, + destination: ImageCopyTexture, + copy_size: Extent3D, + ) void { + wgpuCommandEncoderCopyBufferToTexture(command_encoder, &source, &destination, ©_size); + } + extern fn wgpuCommandEncoderCopyBufferToTexture( + command_encoder: CommandEncoder, + source: *const ImageCopyBuffer, + destination: *const ImageCopyTexture, + copy_size: *const Extent3D, + ) void; + + pub fn copyTextureToBuffer( + command_encoder: CommandEncoder, + source: ImageCopyTexture, + destination: ImageCopyBuffer, + copy_size: Extent3D, + ) void { + wgpuCommandEncoderCopyTextureToBuffer(command_encoder, &source, &destination, ©_size); + } + extern fn wgpuCommandEncoderCopyTextureToBuffer( + command_encoder: CommandEncoder, + source: *const ImageCopyTexture, + destination: *const ImageCopyBuffer, + copy_size: *const Extent3D, + ) void; + + pub fn copyTextureToTexture( + command_encoder: CommandEncoder, + source: ImageCopyTexture, + destination: ImageCopyTexture, + copy_size: Extent3D, + ) void { + wgpuCommandEncoderCopyTextureToTexture(command_encoder, &source, &destination, ©_size); + } + extern fn wgpuCommandEncoderCopyTextureToTexture( + command_encoder: CommandEncoder, + source: *const ImageCopyTexture, + destination: *const ImageCopyTexture, + copy_size: *const Extent3D, + ) void; + + pub fn finish(command_encoder: CommandEncoder, descriptor: ?CommandBufferDescriptor) CommandBuffer { + return wgpuCommandEncoderFinish(command_encoder, if (descriptor) |d| &d else null); + } + extern fn wgpuCommandEncoderFinish( + command_encoder: CommandEncoder, + descriptor: ?*const CommandBufferDescriptor, + ) CommandBuffer; + + pub fn injectValidationError(command_encoder: CommandEncoder, message: [*:0]const u8) void { + wgpuCommandEncoderInjectValidationError(command_encoder, message); + } + extern fn wgpuCommandEncoderInjectValidationError(command_encoder: CommandEncoder, message: [*:0]const u8) void; + + pub fn insertDebugMarker(command_encoder: CommandEncoder, marker_label: [*:0]const u8) void { + wgpuCommandEncoderInsertDebugMarker(command_encoder, marker_label); + } + extern fn wgpuCommandEncoderInsertDebugMarker(command_encoder: CommandEncoder, marker_label: [*:0]const u8) void; + + pub fn popDebugGroup(command_encoder: CommandEncoder) void { + wgpuCommandEncoderPopDebugGroup(command_encoder); + } + extern fn wgpuCommandEncoderPopDebugGroup(command_encoder: CommandEncoder) void; + + pub fn pushDebugGroup(command_encoder: CommandEncoder, group_label: [*:0]const u8) void { + wgpuCommandEncoderPushDebugGroup(command_encoder, group_label); + } + extern fn wgpuCommandEncoderPushDebugGroup(command_encoder: CommandEncoder, group_label: [*:0]const u8) void; + + pub fn resolveQuerySet( + command_encoder: CommandEncoder, + query_set: QuerySet, + first_query: u32, + query_count: u32, + destination: Buffer, + destination_offset: u64, + ) void { + wgpuCommandEncoderResolveQuerySet( + command_encoder, + query_set, + first_query, + query_count, + destination, + destination_offset, + ); + } + extern fn wgpuCommandEncoderResolveQuerySet( + command_encoder: CommandEncoder, + query_set: QuerySet, + first_query: u32, + query_count: u32, + destination: Buffer, + destination_offset: u64, + ) void; + + pub fn setLabel(command_encoder: CommandEncoder, label: ?[*:0]const u8) void { + wgpuCommandEncoderSetLabel(command_encoder, label); + } + extern fn wgpuCommandEncoderSetLabel(command_encoder: CommandEncoder, label: ?[*:0]const u8) void; + + pub fn writeBuffer( + command_encoder: CommandEncoder, + buffer: Buffer, + buffer_offset: u64, + comptime T: type, + data: []const T, + ) void { + wgpuCommandEncoderWriteBuffer( + command_encoder, + buffer, + buffer_offset, + @as([*]const u8, @ptrCast(data.ptr)), + @as(u64, @intCast(data.len)) * @sizeOf(T), + ); + } + extern fn wgpuCommandEncoderWriteBuffer( + command_encoder: CommandEncoder, + buffer: Buffer, + buffer_offset: u64, + data: [*]const u8, + size: u64, + ) void; + + pub fn writeTimestamp(command_encoder: CommandEncoder, query_set: QuerySet, query_index: u32) void { + wgpuCommandEncoderWriteTimestamp(command_encoder, query_set, query_index); + } + extern fn wgpuCommandEncoderWriteTimestamp( + command_encoder: CommandEncoder, + query_set: QuerySet, + query_index: u32, + ) void; + + pub fn reference(command_encoder: CommandEncoder) void { + wgpuCommandEncoderReference(command_encoder); + } + extern fn wgpuCommandEncoderReference(command_encoder: CommandEncoder) void; + + pub fn release(command_encoder: CommandEncoder) void { + wgpuCommandEncoderRelease(command_encoder); + } + extern fn wgpuCommandEncoderRelease(command_encoder: CommandEncoder) void; +}; + +pub const ComputePassEncoder = *opaque { + pub fn dispatchWorkgroups( + compute_pass_encoder: ComputePassEncoder, + workgroup_count_x: u32, + workgroup_count_y: u32, + workgroup_count_z: u32, + ) void { + wgpuComputePassEncoderDispatchWorkgroups( + compute_pass_encoder, + workgroup_count_x, + workgroup_count_y, + workgroup_count_z, + ); + } + extern fn wgpuComputePassEncoderDispatchWorkgroups( + compute_pass_encoder: ComputePassEncoder, + workgroup_count_x: u32, + workgroup_count_y: u32, + workgroup_count_z: u32, + ) void; + + pub fn dispatchWorkgroupsIndirect( + compute_pass_encoder: ComputePassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void { + wgpuComputePassEncoderDispatchWorkgroupsIndirect(compute_pass_encoder, indirect_buffer, indirect_offset); + } + extern fn wgpuComputePassEncoderDispatchWorkgroupsIndirect( + compute_pass_encoder: ComputePassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void; + + pub fn end(compute_pass_encoder: ComputePassEncoder) void { + wgpuComputePassEncoderEnd(compute_pass_encoder); + } + extern fn wgpuComputePassEncoderEnd(compute_pass_encoder: ComputePassEncoder) void; + + pub fn insertDebugMarker(compute_pass_encoder: ComputePassEncoder, marker_label: [*:0]const u8) void { + wgpuComputePassEncoderInsertDebugMarker(compute_pass_encoder, marker_label); + } + extern fn wgpuComputePassEncoderInsertDebugMarker( + compute_pass_encoder: ComputePassEncoder, + marker_label: [*:0]const u8, + ) void; + + pub fn popDebugGroup(compute_pass_encoder: ComputePassEncoder) void { + wgpuComputePassEncoderPopDebugGroup(compute_pass_encoder); + } + extern fn wgpuComputePassEncoderPopDebugGroup(compute_pass_encoder: ComputePassEncoder) void; + + pub fn pushDebugGroup(compute_pass_encoder: ComputePassEncoder, group_label: [*:0]const u8) void { + wgpuComputePassEncoderPushDebugGroup(compute_pass_encoder, group_label); + } + extern fn wgpuComputePassEncoderPushDebugGroup( + compute_pass_encoder: ComputePassEncoder, + group_label: [*:0]const u8, + ) void; + + pub fn setBindGroup( + compute_pass_encoder: ComputePassEncoder, + group_index: u32, + bind_group: BindGroup, + dynamic_offsets: ?[]const u32, + ) void { + wgpuComputePassEncoderSetBindGroup( + compute_pass_encoder, + group_index, + bind_group, + if (dynamic_offsets) |dynoff| @as(u32, @intCast(dynoff.len)) else 0, + if (dynamic_offsets) |dynoff| dynoff.ptr else null, + ); + } + extern fn wgpuComputePassEncoderSetBindGroup( + compute_pass_encoder: ComputePassEncoder, + group_index: u32, + bind_group: BindGroup, + dynamic_offset_count: u32, + dynamic_offsets: ?[*]const u32, + ) void; + + pub fn setLabel(compute_pass_encoder: ComputePassEncoder, label: ?[*:0]const u8) void { + wgpuComputePassEncoderSetLabel(compute_pass_encoder, label); + } + extern fn wgpuComputePassEncoderSetLabel(compute_pass_encoder: ComputePassEncoder, label: ?[*:0]const u8) void; + + pub fn setPipeline(compute_pass_encoder: ComputePassEncoder, pipeline: ComputePipeline) void { + wgpuComputePassEncoderSetPipeline(compute_pass_encoder, pipeline); + } + extern fn wgpuComputePassEncoderSetPipeline( + compute_pass_encoder: ComputePassEncoder, + pipeline: ComputePipeline, + ) void; + + pub fn writeTimestamp( + compute_pass_encoder: ComputePassEncoder, + query_set: QuerySet, + query_index: u32, + ) void { + wgpuComputePassEncoderWriteTimestamp(compute_pass_encoder, query_set, query_index); + } + extern fn wgpuComputePassEncoderWriteTimestamp( + compute_pass_encoder: ComputePassEncoder, + query_set: QuerySet, + query_index: u32, + ) void; + + pub fn reference(compute_pass_encoder: ComputePassEncoder) void { + wgpuComputePassEncoderReference(compute_pass_encoder); + } + extern fn wgpuComputePassEncoderReference(compute_pass_encoder: ComputePassEncoder) void; + + pub fn release(compute_pass_encoder: ComputePassEncoder) void { + wgpuComputePassEncoderRelease(compute_pass_encoder); + } + extern fn wgpuComputePassEncoderRelease(compute_pass_encoder: ComputePassEncoder) void; +}; + +pub const ComputePipeline = *opaque { + pub fn getBindGroupLayout(compute_pipeline: ComputePipeline, group_index: u32) BindGroupLayout { + return wgpuComputePipelineGetBindGroupLayout(compute_pipeline, group_index); + } + extern fn wgpuComputePipelineGetBindGroupLayout( + compute_pipeline: ComputePipeline, + group_index: u32, + ) BindGroupLayout; + + pub fn setLabel(compute_pipeline: ComputePipeline, label: ?[*:0]const u8) void { + wgpuComputePipelineSetLabel(compute_pipeline, label); + } + extern fn wgpuComputePipelineSetLabel(compute_pipeline: ComputePipeline, label: ?[*:0]const u8) void; + + pub fn reference(compute_pipeline: ComputePipeline) void { + wgpuComputePipelineReference(compute_pipeline); + } + extern fn wgpuComputePipelineReference(compute_pipeline: ComputePipeline) void; + + pub fn release(compute_pipeline: ComputePipeline) void { + wgpuComputePipelineRelease(compute_pipeline); + } + extern fn wgpuComputePipelineRelease(compute_pipeline: ComputePipeline) void; +}; + +pub const Device = *opaque { + pub fn createBindGroup(device: Device, descriptor: BindGroupDescriptor) BindGroup { + return wgpuDeviceCreateBindGroup(device, &descriptor); + } + extern fn wgpuDeviceCreateBindGroup(device: Device, descriptor: *const BindGroupDescriptor) BindGroup; + + pub fn createBindGroupLayout(device: Device, descriptor: BindGroupLayoutDescriptor) BindGroupLayout { + return wgpuDeviceCreateBindGroupLayout(device, &descriptor); + } + extern fn wgpuDeviceCreateBindGroupLayout( + device: Device, + descriptor: *const BindGroupLayoutDescriptor, + ) BindGroupLayout; + + pub fn createBuffer(device: Device, descriptor: BufferDescriptor) Buffer { + return wgpuDeviceCreateBuffer(device, &descriptor); + } + extern fn wgpuDeviceCreateBuffer(device: Device, descriptor: *const BufferDescriptor) Buffer; + + pub fn createCommandEncoder(device: Device, descriptor: ?CommandEncoderDescriptor) CommandEncoder { + return wgpuDeviceCreateCommandEncoder(device, if (descriptor) |d| &d else null); + } + extern fn wgpuDeviceCreateCommandEncoder( + device: Device, + descriptor: ?*const CommandEncoderDescriptor, + ) CommandEncoder; + + pub fn createComputePipeline(device: Device, descriptor: ComputePipelineDescriptor) ComputePipeline { + return wgpuDeviceCreateComputePipeline(device, &descriptor); + } + extern fn wgpuDeviceCreateComputePipeline( + device: Device, + descriptor: *const ComputePipelineDescriptor, + ) ComputePipeline; + + pub fn createComputePipelineAsync( + device: Device, + descriptor: ComputePipelineDescriptor, + callback: CreateComputePipelineAsyncCallback, + userdata: ?*anyopaque, + ) void { + wgpuDeviceCreateComputePipelineAsync(device, &descriptor, callback, userdata); + } + extern fn wgpuDeviceCreateComputePipelineAsync( + device: Device, + descriptor: *const ComputePipelineDescriptor, + callback: CreateComputePipelineAsyncCallback, + userdata: ?*anyopaque, + ) void; + + pub fn createErrorBuffer(device: Device) Buffer { + return wgpuDeviceCreateErrorBuffer(device); + } + extern fn wgpuDeviceCreateErrorBuffer(device: Device) Buffer; + + pub fn createExternalTexture(device: Device, descriptor: ExternalTextureDescriptor) ExternalTexture { + return wgpuDeviceCreateExternalTexture(device, &descriptor); + } + extern fn wgpuDeviceCreateExternalTexture( + device: Device, + descriptor: *const ExternalTextureDescriptor, + ) ExternalTexture; + + pub fn createPipelineLayout(device: Device, descriptor: PipelineLayoutDescriptor) PipelineLayout { + return wgpuDeviceCreatePipelineLayout(device, &descriptor); + } + extern fn wgpuDeviceCreatePipelineLayout( + device: Device, + descriptor: *const PipelineLayoutDescriptor, + ) PipelineLayout; + + pub fn createQuerySet(device: Device, descriptor: QuerySetDescriptor) QuerySet { + return wgpuDeviceCreateQuerySet(device, &descriptor); + } + extern fn wgpuDeviceCreateQuerySet(device: Device, descriptor: *const QuerySetDescriptor) QuerySet; + + pub fn createRenderBundleEncoder( + device: Device, + descriptor: RenderBundleEncoderDescriptor, + ) RenderBundleEncoder { + return wgpuDeviceCreateRenderBundleEncoder(device, &descriptor); + } + extern fn wgpuDeviceCreateRenderBundleEncoder( + device: Device, + descriptor: *const RenderBundleEncoderDescriptor, + ) RenderBundleEncoder; + + pub fn createRenderPipeline(device: Device, descriptor: RenderPipelineDescriptor) RenderPipeline { + return wgpuDeviceCreateRenderPipeline(device, &descriptor); + } + extern fn wgpuDeviceCreateRenderPipeline( + device: Device, + descriptor: *const RenderPipelineDescriptor, + ) RenderPipeline; + + pub fn createRenderPipelineAsync( + device: Device, + descriptor: RenderPipelineDescriptor, + callback: CreateRenderPipelineAsyncCallback, + userdata: ?*anyopaque, + ) void { + wgpuDeviceCreateRenderPipelineAsync(device, &descriptor, callback, userdata); + } + extern fn wgpuDeviceCreateRenderPipelineAsync( + device: Device, + descriptor: *const RenderPipelineDescriptor, + callback: CreateRenderPipelineAsyncCallback, + userdata: ?*anyopaque, + ) void; + + pub fn createSampler(device: Device, descriptor: SamplerDescriptor) Sampler { + return wgpuDeviceCreateSampler(device, &descriptor); + } + extern fn wgpuDeviceCreateSampler(device: Device, descriptor: *const SamplerDescriptor) Sampler; + + pub fn createShaderModule(device: Device, descriptor: ShaderModuleDescriptor) ShaderModule { + return wgpuDeviceCreateShaderModule(device, &descriptor); + } + extern fn wgpuDeviceCreateShaderModule(device: Device, descriptor: *const ShaderModuleDescriptor) ShaderModule; + + pub fn createSwapChain(device: Device, surface: ?Surface, descriptor: SwapChainDescriptor) SwapChain { + return wgpuDeviceCreateSwapChain(device, surface, &descriptor); + } + extern fn wgpuDeviceCreateSwapChain( + device: Device, + surface: ?Surface, + descriptor: *const SwapChainDescriptor, + ) SwapChain; + + pub fn createTexture(device: Device, descriptor: TextureDescriptor) Texture { + return wgpuDeviceCreateTexture(device, &descriptor); + } + extern fn wgpuDeviceCreateTexture(device: Device, descriptor: *const TextureDescriptor) Texture; + + pub fn destroy(device: Device) void { + wgpuDeviceDestroy(device); + } + extern fn wgpuDeviceDestroy(device: Device) void; + + pub fn enumerateFeatures(device: Device, features: ?[*]FeatureName) usize { + return wgpuDeviceEnumerateFeatures(device, features); + } + extern fn wgpuDeviceEnumerateFeatures(device: Device, features: ?[*]FeatureName) usize; + + pub fn getLimits(device: Device, limits: *SupportedLimits) bool { + return wgpuDeviceGetLimits(device, limits); + } + extern fn wgpuDeviceGetLimits(device: Device, limits: *SupportedLimits) bool; + + pub fn getQueue(device: Device) Queue { + return wgpuDeviceGetQueue(device); + } + extern fn wgpuDeviceGetQueue(device: Device) Queue; + + pub fn hasFeature(device: Device, feature: FeatureName) bool { + return wgpuDeviceHasFeature(device, feature); + } + extern fn wgpuDeviceHasFeature(device: Device, feature: FeatureName) bool; + + pub fn injectError(device: Device, err_type: ErrorType, message: ?[*:0]const u8) void { + wgpuDeviceInjectError(device, err_type, message); + } + extern fn wgpuDeviceInjectError(device: Device, err_type: ErrorType, message: ?[*:0]const u8) void; + + pub fn forceLoss(device: Device, reason: DeviceLostReason, message: ?[*:0]const u8) void { + wgpuDeviceForceLoss(device, reason, message); + } + extern fn wgpuDeviceForceLoss(device: Device, reason: DeviceLostReason, message: ?[*:0]const u8) void; + + pub fn getAdapter(device: Device) Adapter { + return wgpuDeviceGetAdapter(device); + } + extern fn wgpuDeviceGetAdapter(device: Device) Adapter; + + pub fn popErrorScope(device: Device, callback: ErrorCallback, userdata: ?*anyopaque) bool { + return wgpuDevicePopErrorScope(device, callback, userdata); + } + extern fn wgpuDevicePopErrorScope(device: Device, callback: ErrorCallback, userdata: ?*anyopaque) bool; + + pub fn pushErrorScope(device: Device, filter: ErrorFilter) void { + wgpuDevicePushErrorScope(device, filter); + } + extern fn wgpuDevicePushErrorScope(device: Device, filter: ErrorFilter) void; + + pub fn setDeviceLostCallback( + device: Device, + callback: DeviceLostCallback, + userdata: ?*anyopaque, + ) void { + wgpuDeviceSetDeviceLostCallback(device, callback, userdata); + } + extern fn wgpuDeviceSetDeviceLostCallback( + device: Device, + callback: DeviceLostCallback, + userdata: ?*anyopaque, + ) void; + + pub fn setLabel(device: Device, label: ?[*:0]const u8) void { + wgpuDeviceSetLabel(device, label); + } + extern fn wgpuDeviceSetLabel(device: Device, label: ?[*:0]const u8) void; + + pub fn setLoggingCallback(device: Device, callback: LoggingCallback, userdata: ?*anyopaque) void { + wgpuDeviceSetLoggingCallback(device, callback, userdata); + } + extern fn wgpuDeviceSetLoggingCallback(device: Device, callback: LoggingCallback, userdata: ?*anyopaque) void; + + pub fn setUncapturedErrorCallback(device: Device, callback: ErrorCallback, userdata: ?*anyopaque) void { + wgpuDeviceSetUncapturedErrorCallback(device, callback, userdata); + } + extern fn wgpuDeviceSetUncapturedErrorCallback( + device: Device, + callback: ErrorCallback, + userdata: ?*anyopaque, + ) void; + + pub fn tick(device: Device) void { + wgpuDeviceTick(device); + } + extern fn wgpuDeviceTick(device: Device) void; + + pub fn reference(device: Device) void { + wgpuDeviceReference(device); + } + extern fn wgpuDeviceReference(device: Device) void; + + pub fn release(device: Device) void { + wgpuDeviceRelease(device); + } + extern fn wgpuDeviceRelease(device: Device) void; +}; + +pub const ExternalTexture = *opaque { + pub fn destroy(external_texture: ExternalTexture) void { + wgpuExternalTextureDestroy(external_texture); + } + extern fn wgpuExternalTextureDestroy(external_texture: ExternalTexture) void; + + pub fn setLabel(external_texture: ExternalTexture, label: ?[*:0]const u8) void { + wgpuExternalTextureSetLabel(external_texture, label); + } + extern fn wgpuExternalTextureSetLabel(external_texture: ExternalTexture, label: ?[*:0]const u8) void; + + pub fn reference(external_texture: ExternalTexture) void { + wgpuExternalTextureReference(external_texture); + } + extern fn wgpuExternalTextureReference(external_texture: ExternalTexture) void; + + pub fn release(external_texture: ExternalTexture) void { + wgpuExternalTextureRelease(external_texture); + } + extern fn wgpuExternalTextureRelease(external_texture: ExternalTexture) void; +}; + +pub const Instance = *opaque { + pub fn createSurface(instance: Instance, descriptor: SurfaceDescriptor) Surface { + return wgpuInstanceCreateSurface(instance, &descriptor); + } + extern fn wgpuInstanceCreateSurface(instance: Instance, descriptor: *const SurfaceDescriptor) Surface; + + pub fn requestAdapter( + instance: Instance, + options: RequestAdapterOptions, + callback: RequestAdapterCallback, + userdata: ?*anyopaque, + ) void { + wgpuInstanceRequestAdapter(instance, &options, callback, userdata); + } + extern fn wgpuInstanceRequestAdapter( + instance: Instance, + options: *const RequestAdapterOptions, + callback: RequestAdapterCallback, + userdata: ?*anyopaque, + ) void; + + pub fn reference(instance: Instance) void { + wgpuInstanceReference(instance); + } + extern fn wgpuInstanceReference(instance: Instance) void; + + pub fn release(instance: Instance) void { + wgpuInstanceRelease(instance); + } + extern fn wgpuInstanceRelease(instance: Instance) void; +}; + +pub const PipelineLayout = *opaque { + pub fn setLabel(pipeline_layout: PipelineLayout, label: ?[*:0]const u8) void { + wgpuPipelineLayoutSetLabel(pipeline_layout, label); + } + extern fn wgpuPipelineLayoutSetLabel(pipeline_layout: PipelineLayout, label: ?[*:0]const u8) void; + + pub fn reference(pipeline_layout: PipelineLayout) void { + wgpuPipelineLayoutReference(pipeline_layout); + } + extern fn wgpuPipelineLayoutReference(pipeline_layout: PipelineLayout) void; + + pub fn release(pipeline_layout: PipelineLayout) void { + wgpuPipelineLayoutRelease(pipeline_layout); + } + extern fn wgpuPipelineLayoutRelease(pipeline_layout: PipelineLayout) void; +}; + +pub const QuerySet = *opaque { + pub fn destroy(query_set: QuerySet) void { + wgpuQuerySetDestroy(query_set); + } + extern fn wgpuQuerySetDestroy(query_set: QuerySet) void; + + pub fn setLabel(query_set: QuerySet, label: ?[*:0]const u8) void { + wgpuQuerySetSetLabel(query_set, label); + } + extern fn wgpuQuerySetSetLabel(query_set: QuerySet, label: ?[*:0]const u8) void; + + pub fn reference(query_set: QuerySet) void { + wgpuQuerySetReference(query_set); + } + extern fn wgpuQuerySetReference(query_set: QuerySet) void; + + pub fn release(query_set: QuerySet) void { + wgpuQuerySetRelease(query_set); + } + extern fn wgpuQuerySetRelease(query_set: QuerySet) void; +}; + +pub const Queue = *opaque { + pub fn copyExternalTextureForBrowser( + queue: Queue, + source: ImageCopyExternalTexture, + destination: ImageCopyTexture, + copy_size: Extent3D, + options: CopyTextureForBrowserOptions, + ) void { + wgpuQueueCopyExternalTextureForBrowser(queue, &source, &destination, ©_size, &options); + } + extern fn wgpuQueueCopyExternalTextureForBrowser( + queue: Queue, + source: *const ImageCopyExternalTexture, + destination: *const ImageCopyTexture, + copy_size: *const Extent3D, + options: *const CopyTextureForBrowserOptions, + ) void; + + pub fn copyTextureForBrowser( + queue: Queue, + source: ImageCopyTexture, + destination: ImageCopyTexture, + copy_size: Extent3D, + options: CopyTextureForBrowserOptions, + ) void { + wgpuQueueCopyTextureForBrowser(queue, &source, &destination, ©_size, &options); + } + extern fn wgpuQueueCopyTextureForBrowser( + queue: Queue, + source: *const ImageCopyTexture, + destination: *const ImageCopyTexture, + copy_size: *const Extent3D, + options: *const CopyTextureForBrowserOptions, + ) void; + + pub fn onSubmittedWorkDone( + queue: Queue, + signal_value: u64, + callback: QueueWorkDoneCallback, + userdata: ?*anyopaque, + ) void { + if (emscripten) { + const oswd = @extern( + *const fn ( + queue: Queue, + callback: QueueWorkDoneCallback, + userdata: ?*anyopaque, + ) callconv(.C) void, + .{ .name = "wgpuQueueOnSubmittedWorkDone" }, + ); + oswd(queue, callback, userdata); + } else { + const oswd = @extern( + *const fn ( + queue: Queue, + signal_value: u64, + callback: QueueWorkDoneCallback, + userdata: ?*anyopaque, + ) callconv(.C) void, + .{ .name = "wgpuQueueOnSubmittedWorkDone" }, + ); + oswd(queue, signal_value, callback, userdata); + } + } + pub fn setLabel(queue: Queue, label: ?[*:0]const u8) void { + wgpuQueueSetLabel(queue, label); + } + extern fn wgpuQueueSetLabel(queue: Queue, label: ?[*:0]const u8) void; + + pub fn submit(queue: Queue, commands: []const CommandBuffer) void { + wgpuQueueSubmit(queue, @as(u32, @intCast(commands.len)), commands.ptr); + } + extern fn wgpuQueueSubmit(queue: Queue, command_count: u32, commands: [*]const CommandBuffer) void; + + pub fn writeBuffer( + queue: Queue, + buffer: Buffer, + buffer_offset: usize, + comptime T: type, + data: []const T, + ) void { + wgpuQueueWriteBuffer( + queue, + buffer, + @intCast(buffer_offset), + @as(*const anyopaque, @ptrCast(data.ptr)), + data.len * @sizeOf(T), + ); + } + extern fn wgpuQueueWriteBuffer( + queue: Queue, + buffer: Buffer, + buffer_offset: u64, + data: *const anyopaque, + size: usize, + ) void; + + pub fn writeTexture( + queue: Queue, + destination: ImageCopyTexture, + data_layout: TextureDataLayout, + write_size: Extent3D, + comptime T: type, + data: []const T, + ) void { + wgpuQueueWriteTexture( + queue, + &destination, + @as(*const anyopaque, @ptrCast(data.ptr)), + @as(usize, @intCast(data.len)) * @sizeOf(T), + &data_layout, + &write_size, + ); + } + extern fn wgpuQueueWriteTexture( + queue: Queue, + destination: *const ImageCopyTexture, + data: *const anyopaque, + data_size: usize, + data_layout: *const TextureDataLayout, + write_size: *const Extent3D, + ) void; + + pub fn reference(queue: Queue) void { + wgpuQueueReference(queue); + } + extern fn wgpuQueueReference(queue: Queue) void; + + pub fn release(queue: Queue) void { + wgpuQueueRelease(queue); + } + extern fn wgpuQueueRelease(queue: Queue) void; +}; + +pub const RenderBundle = *opaque { + pub fn reference(render_bundle: RenderBundle) void { + wgpuRenderBundleReference(render_bundle); + } + extern fn wgpuRenderBundleReference(render_bundle: RenderBundle) void; + + pub fn release(render_bundle: RenderBundle) void { + wgpuRenderBundleRelease(render_bundle); + } + extern fn wgpuRenderBundleRelease(render_bundle: RenderBundle) void; +}; + +pub const RenderBundleEncoder = *opaque { + pub fn draw( + render_bundle_encoder: RenderBundleEncoder, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, + ) void { + wgpuRenderBundleEncoderDraw( + render_bundle_encoder, + vertex_count, + instance_count, + first_vertex, + first_instance, + ); + } + extern fn wgpuRenderBundleEncoderDraw( + render_bundle_encoder: RenderBundleEncoder, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, + ) void; + + pub fn drawIndexed( + render_bundle_encoder: RenderBundleEncoder, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, + ) void { + wgpuRenderBundleEncoderDrawIndexed( + render_bundle_encoder, + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + ); + } + extern fn wgpuRenderBundleEncoderDrawIndexed( + render_bundle_encoder: RenderBundleEncoder, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, + ) void; + + pub fn drawIndexedIndirect( + render_bundle_encoder: RenderBundleEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void { + wgpuRenderBundleEncoderDrawIndexedIndirect(render_bundle_encoder, indirect_buffer, indirect_offset); + } + extern fn wgpuRenderBundleEncoderDrawIndexedIndirect( + render_bundle_encoder: RenderBundleEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void; + + pub fn drawIndirect( + render_bundle_encoder: RenderBundleEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void { + wgpuRenderBundleEncoderDrawIndirect(render_bundle_encoder, indirect_buffer, indirect_offset); + } + extern fn wgpuRenderBundleEncoderDrawIndirect( + render_bundle_encoder: RenderBundleEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void; + + pub fn finish( + render_bundle_encoder: RenderBundleEncoder, + descriptor: RenderBundleDescriptor, + ) RenderBundle { + return wgpuRenderBundleEncoderFinish(render_bundle_encoder, &descriptor); + } + extern fn wgpuRenderBundleEncoderFinish( + render_bundle_encoder: RenderBundleEncoder, + descriptor: *const RenderBundleDescriptor, + ) RenderBundle; + + pub fn insertDebugMarker( + render_bundle_encoder: RenderBundleEncoder, + marker_label: [*:0]const u8, + ) void { + wgpuRenderBundleEncoderInsertDebugMarker(render_bundle_encoder, marker_label); + } + extern fn wgpuRenderBundleEncoderInsertDebugMarker( + render_bundle_encoder: RenderBundleEncoder, + marker_label: [*:0]const u8, + ) void; + + pub fn popDebugGroup(render_bundle_encoder: RenderBundleEncoder) void { + wgpuRenderBundleEncoderPopDebugGroup(render_bundle_encoder); + } + extern fn wgpuRenderBundleEncoderPopDebugGroup(render_bundle_encoder: RenderBundleEncoder) void; + + pub fn pushDebugGroup(render_bundle_encoder: RenderBundleEncoder, group_label: [*:0]const u8) void { + wgpuRenderBundleEncoderPushDebugGroup(render_bundle_encoder, group_label); + } + extern fn wgpuRenderBundleEncoderPushDebugGroup( + render_bundle_encoder: RenderBundleEncoder, + group_label: [*:0]const u8, + ) void; + + pub fn setBindGroup( + render_bundle_encoder: RenderBundleEncoder, + group_index: u32, + group: BindGroup, + dynamic_offsets: ?[]const u32, + ) void { + wgpuRenderBundleEncoderSetBindGroup( + render_bundle_encoder, + group_index, + group, + if (dynamic_offsets) |dynoff| @as(u32, @intCast(dynoff.len)) else 0, + if (dynamic_offsets) |dynoff| dynoff.ptr else null, + ); + } + extern fn wgpuRenderBundleEncoderSetBindGroup( + render_bundle_encoder: RenderBundleEncoder, + group_index: u32, + group: BindGroup, + dynamic_offset_count: u32, + dynamic_offsets: ?[*]const u32, + ) void; + + pub fn setIndexBuffer( + render_bundle_encoder: RenderBundleEncoder, + buffer: Buffer, + format: IndexFormat, + offset: u64, + size: u64, + ) void { + wgpuRenderBundleEncoderSetIndexBuffer(render_bundle_encoder, buffer, format, offset, size); + } + extern fn wgpuRenderBundleEncoderSetIndexBuffer( + render_bundle_encoder: RenderBundleEncoder, + buffer: Buffer, + format: IndexFormat, + offset: u64, + size: u64, + ) void; + + pub fn setLabel(render_bundle_encoder: RenderBundleEncoder, label: ?[*:0]const u8) void { + wgpuRenderBundleEncoderSetLabel(render_bundle_encoder, label); + } + extern fn wgpuRenderBundleEncoderSetLabel( + render_bundle_encoder: RenderBundleEncoder, + label: ?[*:0]const u8, + ) void; + + pub fn setPipeline(render_bundle_encoder: RenderBundleEncoder, pipeline: RenderPipeline) void { + wgpuRenderBundleEncoderSetPipeline(render_bundle_encoder, pipeline); + } + extern fn wgpuRenderBundleEncoderSetPipeline( + render_bundle_encoder: RenderBundleEncoder, + pipeline: RenderPipeline, + ) void; + + pub fn setVertexBuffer( + render_bundle_encoder: RenderBundleEncoder, + slot: u32, + buffer: Buffer, + offset: u64, + size: u64, + ) void { + wgpuRenderBundleEncoderSetVertexBuffer(render_bundle_encoder, slot, buffer, offset, size); + } + extern fn wgpuRenderBundleEncoderSetVertexBuffer( + render_bundle_encoder: RenderBundleEncoder, + slot: u32, + buffer: Buffer, + offset: u64, + size: u64, + ) void; + + pub fn reference(render_bundle_encoder: RenderBundleEncoder) void { + wgpuRenderBundleEncoderReference(render_bundle_encoder); + } + extern fn wgpuRenderBundleEncoderReference(render_bundle_encoder: RenderBundleEncoder) void; + + pub fn release(render_bundle_encoder: RenderBundleEncoder) void { + wgpuRenderBundleEncoderRelease(render_bundle_encoder); + } + extern fn wgpuRenderBundleEncoderRelease(render_bundle_encoder: RenderBundleEncoder) void; +}; + +pub const RenderPassEncoder = *opaque { + pub fn beginOcclusionQuery(render_pass_encoder: RenderPassEncoder, query_index: u32) void { + wgpuRenderPassEncoderBeginOcclusionQuery(render_pass_encoder, query_index); + } + extern fn wgpuRenderPassEncoderBeginOcclusionQuery( + render_pass_encoder: RenderPassEncoder, + query_index: u32, + ) void; + + pub fn draw( + render_pass_encoder: RenderPassEncoder, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, + ) void { + wgpuRenderPassEncoderDraw(render_pass_encoder, vertex_count, instance_count, first_vertex, first_instance); + } + extern fn wgpuRenderPassEncoderDraw( + render_pass_encoder: RenderPassEncoder, + vertex_count: u32, + instance_count: u32, + first_vertex: u32, + first_instance: u32, + ) void; + + pub fn drawIndexed( + render_pass_encoder: RenderPassEncoder, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, + ) void { + wgpuRenderPassEncoderDrawIndexed( + render_pass_encoder, + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + ); + } + extern fn wgpuRenderPassEncoderDrawIndexed( + render_pass_encoder: RenderPassEncoder, + index_count: u32, + instance_count: u32, + first_index: u32, + base_vertex: i32, + first_instance: u32, + ) void; + + pub fn drawIndexedIndirect( + render_pass_encoder: RenderPassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void { + wgpuRenderPassEncoderDrawIndexedIndirect(render_pass_encoder, indirect_buffer, indirect_offset); + } + extern fn wgpuRenderPassEncoderDrawIndexedIndirect( + render_pass_encoder: RenderPassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void; + + pub fn drawIndirect( + render_pass_encoder: RenderPassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void { + wgpuRenderPassEncoderDrawIndirect(render_pass_encoder, indirect_buffer, indirect_offset); + } + extern fn wgpuRenderPassEncoderDrawIndirect( + render_pass_encoder: RenderPassEncoder, + indirect_buffer: Buffer, + indirect_offset: u64, + ) void; + + pub fn end(render_pass_encoder: RenderPassEncoder) void { + wgpuRenderPassEncoderEnd(render_pass_encoder); + } + extern fn wgpuRenderPassEncoderEnd(render_pass_encoder: RenderPassEncoder) void; + + pub fn endOcclusionQuery(render_pass_encoder: RenderPassEncoder) void { + wgpuRenderPassEncoderEndOcclusionQuery(render_pass_encoder); + } + extern fn wgpuRenderPassEncoderEndOcclusionQuery(render_pass_encoder: RenderPassEncoder) void; + + pub fn executeBundles( + render_pass_encoder: RenderPassEncoder, + bundle_count: u32, + bundles: [*]const RenderBundle, + ) void { + wgpuRenderPassEncoderExecuteBundles(render_pass_encoder, bundle_count, bundles); + } + extern fn wgpuRenderPassEncoderExecuteBundles( + render_pass_encoder: RenderPassEncoder, + bundle_count: u32, + bundles: [*]const RenderBundle, + ) void; + + pub fn insertDebugMarker(render_pass_encoder: RenderPassEncoder, marker_label: [*:0]const u8) void { + wgpuRenderPassEncoderInsertDebugMarker(render_pass_encoder, marker_label); + } + extern fn wgpuRenderPassEncoderInsertDebugMarker( + render_pass_encoder: RenderPassEncoder, + marker_label: [*:0]const u8, + ) void; + + pub fn popDebugGroup(render_pass_encoder: RenderPassEncoder) void { + wgpuRenderPassEncoderPopDebugGroup(render_pass_encoder); + } + extern fn wgpuRenderPassEncoderPopDebugGroup(render_pass_encoder: RenderPassEncoder) void; + + pub fn pushDebugGroup(render_pass_encoder: RenderPassEncoder, group_label: [*:0]const u8) void { + wgpuRenderPassEncoderPushDebugGroup(render_pass_encoder, group_label); + } + extern fn wgpuRenderPassEncoderPushDebugGroup( + render_pass_encoder: RenderPassEncoder, + group_label: [*:0]const u8, + ) void; + + pub fn setBindGroup( + render_pass_encoder: RenderPassEncoder, + group_index: u32, + group: BindGroup, + dynamic_offsets: ?[]const u32, + ) void { + wgpuRenderPassEncoderSetBindGroup( + render_pass_encoder, + group_index, + group, + if (dynamic_offsets) |dynoff| @as(u32, @intCast(dynoff.len)) else 0, + if (dynamic_offsets) |dynoff| dynoff.ptr else null, + ); + } + extern fn wgpuRenderPassEncoderSetBindGroup( + render_pass_encoder: RenderPassEncoder, + group_index: u32, + group: BindGroup, + dynamic_offset_count: u32, + dynamic_offsets: ?[*]const u32, + ) void; + + pub fn setBlendConstant(render_pass_encoder: RenderPassEncoder, color: Color) void { + wgpuRenderPassEncoderSetBlendConstant(render_pass_encoder, &color); + } + extern fn wgpuRenderPassEncoderSetBlendConstant( + render_pass_encoder: RenderPassEncoder, + color: *const Color, + ) void; + + pub fn setIndexBuffer( + render_pass_encoder: RenderPassEncoder, + buffer: Buffer, + format: IndexFormat, + offset: u64, + size: u64, + ) void { + wgpuRenderPassEncoderSetIndexBuffer(render_pass_encoder, buffer, format, offset, size); + } + extern fn wgpuRenderPassEncoderSetIndexBuffer( + render_pass_encoder: RenderPassEncoder, + buffer: Buffer, + format: IndexFormat, + offset: u64, + size: u64, + ) void; + + pub fn setLabel(render_pass_encoder: RenderPassEncoder, label: ?[*:0]const u8) void { + wgpuRenderPassEncoderSetLabel(render_pass_encoder, label); + } + extern fn wgpuRenderPassEncoderSetLabel(render_pass_encoder: RenderPassEncoder, label: ?[*:0]const u8) void; + + pub fn setPipeline(render_pass_encoder: RenderPassEncoder, pipeline: RenderPipeline) void { + wgpuRenderPassEncoderSetPipeline(render_pass_encoder, pipeline); + } + extern fn wgpuRenderPassEncoderSetPipeline( + render_pass_encoder: RenderPassEncoder, + pipeline: RenderPipeline, + ) void; + + pub fn setScissorRect( + render_pass_encoder: RenderPassEncoder, + x: u32, + y: u32, + width: u32, + height: u32, + ) void { + wgpuRenderPassEncoderSetScissorRect(render_pass_encoder, x, y, width, height); + } + extern fn wgpuRenderPassEncoderSetScissorRect( + render_pass_encoder: RenderPassEncoder, + x: u32, + y: u32, + width: u32, + height: u32, + ) void; + + pub fn setStencilReference(render_pass_encoder: RenderPassEncoder, ref: u32) void { + wgpuRenderPassEncoderSetStencilReference(render_pass_encoder, ref); + } + extern fn wgpuRenderPassEncoderSetStencilReference(render_pass_encoder: RenderPassEncoder, ref: u32) void; + + pub fn setVertexBuffer( + render_pass_encoder: RenderPassEncoder, + slot: u32, + buffer: Buffer, + offset: u64, + size: u64, + ) void { + wgpuRenderPassEncoderSetVertexBuffer(render_pass_encoder, slot, buffer, offset, size); + } + extern fn wgpuRenderPassEncoderSetVertexBuffer( + render_pass_encoder: RenderPassEncoder, + slot: u32, + buffer: Buffer, + offset: u64, + size: u64, + ) void; + + pub fn setViewport( + render_pass_encoder: RenderPassEncoder, + x: f32, + y: f32, + width: f32, + height: f32, + min_depth: f32, + max_depth: f32, + ) void { + wgpuRenderPassEncoderSetViewport(render_pass_encoder, x, y, width, height, min_depth, max_depth); + } + extern fn wgpuRenderPassEncoderSetViewport( + render_pass_encoder: RenderPassEncoder, + x: f32, + y: f32, + width: f32, + height: f32, + min_depth: f32, + max_depth: f32, + ) void; + + pub fn writeTimestamp( + render_pass_encoder: RenderPassEncoder, + query_set: QuerySet, + query_index: u32, + ) void { + wgpuRenderPassEncoderWriteTimestamp(render_pass_encoder, query_set, query_index); + } + extern fn wgpuRenderPassEncoderWriteTimestamp( + render_pass_encoder: RenderPassEncoder, + query_set: QuerySet, + query_index: u32, + ) void; + + pub fn reference(render_pass_encoder: RenderPassEncoder) void { + wgpuRenderPassEncoderReference(render_pass_encoder); + } + extern fn wgpuRenderPassEncoderReference(render_pass_encoder: RenderPassEncoder) void; + + pub fn release(render_pass_encoder: RenderPassEncoder) void { + wgpuRenderPassEncoderRelease(render_pass_encoder); + } + extern fn wgpuRenderPassEncoderRelease(render_pass_encoder: RenderPassEncoder) void; +}; + +pub const RenderPipeline = *opaque { + pub fn getBindGroupLayout(render_pipeline: RenderPipeline, group_index: u32) BindGroupLayout { + return wgpuRenderPipelineGetBindGroupLayout(render_pipeline, group_index); + } + extern fn wgpuRenderPipelineGetBindGroupLayout( + render_pipeline: RenderPipeline, + group_index: u32, + ) BindGroupLayout; + + pub fn setLabel(render_pipeline: RenderPipeline, label: ?[*:0]const u8) void { + wgpuRenderPipelineSetLabel(render_pipeline, label); + } + extern fn wgpuRenderPipelineSetLabel(render_pipeline: RenderPipeline, label: ?[*:0]const u8) void; + + pub fn reference(render_pipeline: RenderPipeline) void { + wgpuRenderPipelineReference(render_pipeline); + } + extern fn wgpuRenderPipelineReference(render_pipeline: RenderPipeline) void; + + pub fn release(render_pipeline: RenderPipeline) void { + wgpuRenderPipelineRelease(render_pipeline); + } + extern fn wgpuRenderPipelineRelease(render_pipeline: RenderPipeline) void; +}; + +pub const Sampler = *opaque { + pub fn setLabel(sampler: Sampler, label: ?[*:0]const u8) void { + wgpuSamplerSetLabel(sampler, label); + } + extern fn wgpuSamplerSetLabel(sampler: Sampler, label: ?[*:0]const u8) void; + + pub fn reference(sampler: Sampler) void { + wgpuSamplerReference(sampler); + } + extern fn wgpuSamplerReference(sampler: Sampler) void; + + pub fn release(sampler: Sampler) void { + wgpuSamplerRelease(sampler); + } + extern fn wgpuSamplerRelease(sampler: Sampler) void; +}; + +pub const ShaderModule = *opaque { + pub fn getCompilationInfo( + shader_module: ShaderModule, + callback: CompilationInfoCallback, + userdata: ?*anyopaque, + ) void { + wgpuShaderModuleGetCompilationInfo(shader_module, callback, userdata); + } + extern fn wgpuShaderModuleGetCompilationInfo( + shader_module: ShaderModule, + callback: CompilationInfoCallback, + userdata: ?*anyopaque, + ) void; + + pub fn setLabel(shader_module: ShaderModule, label: ?[*:0]const u8) void { + wgpuShaderModuleSetLabel(shader_module, label); + } + extern fn wgpuShaderModuleSetLabel(shader_module: ShaderModule, label: ?[*:0]const u8) void; + + pub fn reference(shader_module: ShaderModule) void { + wgpuShaderModuleReference(shader_module); + } + extern fn wgpuShaderModuleReference(shader_module: ShaderModule) void; + + pub fn release(shader_module: ShaderModule) void { + wgpuShaderModuleRelease(shader_module); + } + extern fn wgpuShaderModuleRelease(shader_module: ShaderModule) void; +}; + +pub const Surface = *opaque { + pub fn reference(surface: Surface) void { + wgpuSurfaceReference(surface); + } + extern fn wgpuSurfaceReference(surface: Surface) void; + + pub fn release(surface: Surface) void { + wgpuSurfaceRelease(surface); + } + extern fn wgpuSurfaceRelease(surface: Surface) void; +}; + +pub const SwapChain = *opaque { + pub fn configure( + swap_chain: SwapChain, + format: TextureFormat, + allowed_usage: TextureUsage, + width: u32, + height: u32, + ) void { + wgpuSwapChainConfigure(swap_chain, format, allowed_usage, width, height); + } + extern fn wgpuSwapChainConfigure( + swap_chain: SwapChain, + format: TextureFormat, + allowed_usage: TextureUsage, + width: u32, + height: u32, + ) void; + + pub fn getCurrentTextureView(swap_chain: SwapChain) TextureView { + return wgpuSwapChainGetCurrentTextureView(swap_chain); + } + extern fn wgpuSwapChainGetCurrentTextureView(swap_chain: SwapChain) TextureView; + + pub fn present(swap_chain: SwapChain) void { + wgpuSwapChainPresent(swap_chain); + } + extern fn wgpuSwapChainPresent(swap_chain: SwapChain) void; + + pub fn reference(swap_chain: SwapChain) void { + wgpuSwapChainReference(swap_chain); + } + extern fn wgpuSwapChainReference(swap_chain: SwapChain) void; + + pub fn release(swap_chain: SwapChain) void { + wgpuSwapChainRelease(swap_chain); + } + extern fn wgpuSwapChainRelease(swap_chain: SwapChain) void; +}; + +pub const Texture = *opaque { + pub fn createView(texture: Texture, descriptor: TextureViewDescriptor) TextureView { + return wgpuTextureCreateView(texture, &descriptor); + } + extern fn wgpuTextureCreateView(texture: Texture, descriptor: *const TextureViewDescriptor) TextureView; + + pub fn destroy(texture: Texture) void { + wgpuTextureDestroy(texture); + } + extern fn wgpuTextureDestroy(texture: Texture) void; + + pub fn setLabel(texture: Texture, label: ?[*:0]const u8) void { + wgpuTextureSetLabel(texture, label); + } + extern fn wgpuTextureSetLabel(texture: Texture, label: ?[*:0]const u8) void; + + pub fn reference(texture: Texture) void { + wgpuTextureReference(texture); + } + extern fn wgpuTextureReference(texture: Texture) void; + + pub fn release(texture: Texture) void { + wgpuTextureRelease(texture); + } + extern fn wgpuTextureRelease(texture: Texture) void; +}; + +pub const TextureView = *opaque { + pub fn setLabel(texture_view: TextureView, label: ?[*:0]const u8) void { + wgpuTextureViewSetLabel(texture_view, label); + } + extern fn wgpuTextureViewSetLabel(texture_view: TextureView, label: ?[*:0]const u8) void; + + pub fn reference(texture_view: TextureView) void { + wgpuTextureViewReference(texture_view); + } + extern fn wgpuTextureViewReference(texture_view: TextureView) void; + + pub fn release(texture_view: TextureView) void { + wgpuTextureViewRelease(texture_view); + } + extern fn wgpuTextureViewRelease(texture_view: TextureView) void; +}; + +pub const InstanceDescriptor = extern struct { + next_in_chain: ?*const ChainedStruct = null, +}; +pub inline fn createInstance(desc: InstanceDescriptor) Instance { + _ = desc; + return wgpuCreateInstance(null); +} +extern fn wgpuCreateInstance(desc: ?*const InstanceDescriptor) Instance; diff --git a/vendor/zgpu/src/zgpu.zig b/vendor/zgpu/src/zgpu.zig new file mode 100644 index 0000000..5ff631b --- /dev/null +++ b/vendor/zgpu/src/zgpu.zig @@ -0,0 +1,1868 @@ +//-------------------------------------------------------------------------------------------------- +// zgpu is a small helper library built on top of native wgpu implementation (Dawn). +// +// It supports Windows 10+ (DirectX 12), macOS 12+ (Metal) and Linux (Vulkan). +// +// https://github.com/michal-z/zig-gamedev/tree/main/libs/zgpu +//-------------------------------------------------------------------------------------------------- +const std = @import("std"); +const math = std.math; +const assert = std.debug.assert; +const wgsl = @import("common_wgsl.zig"); +const zgpu_options = @import("zgpu_options"); +pub const wgpu = @import("wgpu.zig"); +pub const slog = std.log.scoped(.zgpu); // scoped log that can be comptime processed in main logger +const emscripten = @import("builtin").target.os.tag == .emscripten; + +test { + _ = wgpu; +} + +pub const WindowProvider = struct { + window: *anyopaque, + fn_getTime: *const fn () f64, + fn_getFramebufferSize: *const fn (window: *const anyopaque) [2]u32, + fn_getWin32Window: *const fn (window: *const anyopaque) ?*anyopaque = undefined, + fn_getX11Display: *const fn () ?*anyopaque = undefined, + fn_getX11Window: *const fn (window: *const anyopaque) u32 = undefined, + fn_getWaylandDisplay: ?*const fn () ?*anyopaque = null, + fn_getWaylandSurface: ?*const fn (window: *const anyopaque) ?*anyopaque = null, + fn_getCocoaWindow: *const fn (window: *const anyopaque) ?*anyopaque = undefined, + + fn getTime(self: WindowProvider) f64 { + return self.fn_getTime(); + } + + fn getFramebufferSize(self: WindowProvider) [2]u32 { + return self.fn_getFramebufferSize(self.window); + } + + fn getWin32Window(self: WindowProvider) ?*anyopaque { + return self.fn_getWin32Window(self.window); + } + + fn getX11Display(self: WindowProvider) ?*anyopaque { + return self.fn_getX11Display(); + } + + fn getX11Window(self: WindowProvider) u32 { + return self.fn_getX11Window(self.window); + } + + fn getWaylandDisplay(self: WindowProvider) ?*anyopaque { + if (self.fn_getWaylandDisplay) |f| { + return f(); + } else { + return @as(?*anyopaque, null); + } + } + + fn getWaylandSurface(self: WindowProvider) ?*anyopaque { + if (self.fn_getWaylandSurface) |f| { + return f(self.window); + } else { + return @as(?*anyopaque, null); + } + } + + fn getCocoaWindow(self: WindowProvider) ?*anyopaque { + return self.fn_getCocoaWindow(self.window); + } +}; + +pub const GraphicsContextOptions = struct { + present_mode: wgpu.PresentMode = .fifo, + required_features: []const wgpu.FeatureName = &.{}, + required_limits: ?*const wgpu.RequiredLimits = null, +}; + +pub const GraphicsContext = struct { + pub const swapchain_format = wgpu.TextureFormat.bgra8_unorm; + + window_provider: WindowProvider, + + stats: FrameStats = .{}, + + native_instance: DawnNativeInstance, + instance: wgpu.Instance, + device: wgpu.Device, + queue: wgpu.Queue, + surface: wgpu.Surface, + swapchain: wgpu.SwapChain, + swapchain_descriptor: wgpu.SwapChainDescriptor, + + buffer_pool: BufferPool, + texture_pool: TexturePool, + texture_view_pool: TextureViewPool, + sampler_pool: SamplerPool, + render_pipeline_pool: RenderPipelinePool, + compute_pipeline_pool: ComputePipelinePool, + bind_group_pool: BindGroupPool, + bind_group_layout_pool: BindGroupLayoutPool, + pipeline_layout_pool: PipelineLayoutPool, + + mipgens: std.AutoHashMap(wgpu.TextureFormat, MipgenResources), + + uniforms: struct { + offset: u32 = 0, + buffer: BufferHandle = .{}, + stage: struct { + num: u32 = 0, + current: u32 = 0, + buffers: [uniforms_staging_pipeline_len]UniformsStagingBuffer = + [_]UniformsStagingBuffer{.{}} ** uniforms_staging_pipeline_len, + } = .{}, + } = .{}, + + pub fn create( + allocator: std.mem.Allocator, + window_provider: WindowProvider, + options: GraphicsContextOptions, + ) !*GraphicsContext { + if (!emscripten) dawnProcSetProcs(dnGetProcs()); + + const native_instance = if (!emscripten) dniCreate(); + errdefer if (!emscripten) dniDestroy(native_instance); + + const instance = if (emscripten) wgpu.createInstance(.{}) else dniGetWgpuInstance(native_instance).?; + + const adapter = adapter: { + const Response = struct { + status: wgpu.RequestAdapterStatus = .unknown, + adapter: wgpu.Adapter = undefined, + }; + + const callback = (struct { + fn callback( + status: wgpu.RequestAdapterStatus, + adapter: wgpu.Adapter, + message: ?[*:0]const u8, + userdata: ?*anyopaque, + ) callconv(.C) void { + _ = message; + const response = @as(*Response, @ptrCast(@alignCast(userdata))); + response.status = status; + response.adapter = adapter; + } + }).callback; + + var response = Response{}; + instance.requestAdapter( + .{ .power_preference = .high_performance }, + callback, + @ptrCast(&response), + ); + + if (emscripten) { + // wait for response. requires emscripten `-sASYNC` flag + // otherwise whole api would need to be changed in a way that allows whole program to return from main and wait to js to call back + std.log.debug("wait for instance.requestAdapter...", .{}); + while (response.status == .unknown) emscripten_sleep(5); + std.log.debug("{}", .{response.status}); + } + + if (response.status != .success) { + std.log.err("Failed to request GPU adapter (status: {s}).", .{@tagName(response.status)}); + return error.NoGraphicsAdapter; + } + break :adapter response.adapter; + }; + errdefer adapter.release(); + + var properties: wgpu.AdapterProperties = undefined; + properties.next_in_chain = null; + adapter.getProperties(&properties); + + if (emscripten) { + properties.name = "emscripten"; + properties.driver_description = "emscripten"; + properties.adapter_type = .unknown; + properties.backend_type = .undef; + } + std.log.info("[zgpu] High-performance device has been selected:", .{}); + std.log.info("[zgpu] Name: {s}", .{properties.name}); + std.log.info("[zgpu] Driver: {s}", .{properties.driver_description}); + std.log.info("[zgpu] Adapter type: {s}", .{@tagName(properties.adapter_type)}); + std.log.info("[zgpu] Backend type: {s}", .{@tagName(properties.backend_type)}); + + const device = device: { + const Response = struct { + status: wgpu.RequestDeviceStatus = .unknown, + device: wgpu.Device = undefined, + }; + + const callback = (struct { + fn callback( + status: wgpu.RequestDeviceStatus, + device: wgpu.Device, + message: ?[*:0]const u8, + userdata: ?*anyopaque, + ) callconv(.C) void { + _ = message; + const response = @as(*Response, @ptrCast(@alignCast(userdata))); + response.status = status; + response.device = device; + } + }).callback; + + var toggles: [2][*:0]const u8 = undefined; + var num_toggles: usize = 0; + if (zgpu_options.dawn_skip_validation) { + toggles[num_toggles] = "skip_validation"; + num_toggles += 1; + } + if (zgpu_options.dawn_allow_unsafe_apis) { + toggles[num_toggles] = "allow_unsafe_apis"; + num_toggles += 1; + } + const dawn_toggles = wgpu.DawnTogglesDescriptor{ + .chain = .{ .next = null, .struct_type = .dawn_toggles_descriptor }, + .enabled_toggles_count = num_toggles, + .enabled_toggles = &toggles, + }; + + var response = Response{}; + adapter.requestDevice( + wgpu.DeviceDescriptor{ + .next_in_chain = @ptrCast(&dawn_toggles), + .required_features_count = options.required_features.len, + .required_features = options.required_features.ptr, + .required_limits = @ptrCast(options.required_limits), + }, + callback, + @ptrCast(&response), + ); + + if (emscripten) { + // wait for response. requires emscripten `-sASYNC` flag + // otherwise whole api would need to be changed in a way that allows whole program to return from main and wait to js to call back + std.log.debug("wait for adapter.requestDevice...", .{}); + while (response.status == .unknown) emscripten_sleep(5); + std.log.debug("{}", .{response.status}); + } + + if (response.status != .success) { + std.log.err("Failed to request GPU device (status: {s}).", .{@tagName(response.status)}); + return error.NoGraphicsDevice; + } + break :device response.device; + }; + errdefer device.release(); + + device.setUncapturedErrorCallback(logUnhandledError, null); + + const surface = createSurfaceForWindow(instance, window_provider); + errdefer surface.release(); + + const framebuffer_size = window_provider.getFramebufferSize(); + + const swapchain_descriptor = wgpu.SwapChainDescriptor{ + .label = "zig-gamedev-gctx-swapchain", + .usage = .{ .render_attachment = true }, + .format = swapchain_format, + .width = @intCast(framebuffer_size[0]), + .height = @intCast(framebuffer_size[1]), + .present_mode = options.present_mode, + }; + const swapchain = device.createSwapChain(surface, swapchain_descriptor); + errdefer swapchain.release(); + + const gctx = try allocator.create(GraphicsContext); + gctx.* = .{ + .window_provider = window_provider, + .native_instance = if (emscripten) null else native_instance, + .instance = instance, + .device = device, + .queue = device.getQueue(), + .surface = surface, + .swapchain = swapchain, + .swapchain_descriptor = swapchain_descriptor, + .buffer_pool = BufferPool.init(allocator, zgpu_options.buffer_pool_size), + .texture_pool = TexturePool.init(allocator, zgpu_options.texture_pool_size), + .texture_view_pool = TextureViewPool.init(allocator, zgpu_options.texture_view_pool_size), + .sampler_pool = SamplerPool.init(allocator, zgpu_options.sampler_pool_size), + .render_pipeline_pool = RenderPipelinePool.init(allocator, zgpu_options.render_pipeline_pool_size), + .compute_pipeline_pool = ComputePipelinePool.init(allocator, zgpu_options.compute_pipeline_pool_size), + .bind_group_pool = BindGroupPool.init(allocator, zgpu_options.bind_group_pool_size), + .bind_group_layout_pool = BindGroupLayoutPool.init(allocator, zgpu_options.bind_group_layout_pool_size), + .pipeline_layout_pool = PipelineLayoutPool.init(allocator, zgpu_options.pipeline_layout_pool_size), + .mipgens = std.AutoHashMap(wgpu.TextureFormat, MipgenResources).init(allocator), + }; + + uniformsInit(gctx); + return gctx; + } + + pub fn destroy(gctx: *GraphicsContext, allocator: std.mem.Allocator) void { + // Wait for the GPU to finish all encoded commands. + while (gctx.stats.cpu_frame_number != gctx.stats.gpu_frame_number) { + gctx.device.tick(); + } + + // Wait for all outstanding mapAsync() calls to complete. + wait_loop: while (true) { + gctx.device.tick(); + var i: u32 = 0; + while (i < gctx.uniforms.stage.num) : (i += 1) { + if (gctx.uniforms.stage.buffers[i].slice == null) { + continue :wait_loop; + } + } + break; + } + + gctx.mipgens.deinit(); + gctx.pipeline_layout_pool.deinit(allocator); + gctx.bind_group_pool.deinit(allocator); + gctx.bind_group_layout_pool.deinit(allocator); + gctx.buffer_pool.deinit(allocator); + gctx.texture_view_pool.deinit(allocator); + gctx.texture_pool.deinit(allocator); + gctx.sampler_pool.deinit(allocator); + gctx.render_pipeline_pool.deinit(allocator); + gctx.compute_pipeline_pool.deinit(allocator); + gctx.surface.release(); + gctx.swapchain.release(); + gctx.queue.release(); + gctx.device.release(); + if (!emscripten) dniDestroy(gctx.native_instance); + allocator.destroy(gctx); + } + + // + // Uniform buffer pool + // + pub fn uniformsAllocate( + gctx: *GraphicsContext, + comptime T: type, + num_elements: u32, + ) struct { slice: []T, offset: u32 } { + assert(num_elements > 0); + const size = num_elements * @sizeOf(T); + + const offset = gctx.uniforms.offset; + const aligned_size = (size + (uniforms_alloc_alignment - 1)) & ~(uniforms_alloc_alignment - 1); + if ((offset + aligned_size) >= uniforms_buffer_size) { + std.log.err("[zgpu] Uniforms buffer size is too small. " ++ + "Consider increasing 'zgpu.BuildOptions.uniforms_buffer_size' constant.", .{}); + return .{ .slice = @as([*]T, undefined)[0..0], .offset = 0 }; + } + + const current = gctx.uniforms.stage.current; + const slice = (gctx.uniforms.stage.buffers[current].slice.?.ptr + offset)[0..size]; + + gctx.uniforms.offset += aligned_size; + return .{ + .slice = std.mem.bytesAsSlice(T, @as([]align(@alignOf(T)) u8, @alignCast(slice))), + .offset = offset, + }; + } + + const UniformsStagingBuffer = struct { + slice: ?[]u8 = null, + buffer: wgpu.Buffer = undefined, + }; + const uniforms_buffer_size = zgpu_options.uniforms_buffer_size; + const uniforms_staging_pipeline_len = 8; + const uniforms_alloc_alignment: u32 = 256; + + fn uniformsInit(gctx: *GraphicsContext) void { + gctx.uniforms.buffer = gctx.createBuffer(.{ + .usage = .{ .copy_dst = true, .uniform = true }, + .size = uniforms_buffer_size, + }); + gctx.uniformsNextStagingBuffer(); + } + + fn uniformsMappedCallback(status: wgpu.BufferMapAsyncStatus, userdata: ?*anyopaque) callconv(.C) void { + const usb = @as(*UniformsStagingBuffer, @ptrCast(@alignCast(userdata))); + assert(usb.slice == null); + if (status == .success) { + usb.slice = usb.buffer.getMappedRange(u8, 0, uniforms_buffer_size).?; + } else { + std.log.err("[zgpu] Failed to map buffer (status: {s}).", .{@tagName(status)}); + } + } + + fn uniformsNextStagingBuffer(gctx: *GraphicsContext) void { + if (gctx.stats.cpu_frame_number > 0) { + // Map staging buffer which was used this frame. + const current = gctx.uniforms.stage.current; + assert(gctx.uniforms.stage.buffers[current].slice == null); + gctx.uniforms.stage.buffers[current].buffer.mapAsync( + .{ .write = true }, + 0, + uniforms_buffer_size, + uniformsMappedCallback, + @ptrCast(&gctx.uniforms.stage.buffers[current]), + ); + } + + gctx.uniforms.offset = 0; + + var i: u32 = 0; + while (i < gctx.uniforms.stage.num) : (i += 1) { + if (gctx.uniforms.stage.buffers[i].slice != null) { + gctx.uniforms.stage.current = i; + return; + } + } + + if (gctx.uniforms.stage.num >= uniforms_staging_pipeline_len) { + // Wait until one of the buffers is mapped and ready to use. + while (true) { + gctx.device.tick(); + + i = 0; + while (i < gctx.uniforms.stage.num) : (i += 1) { + if (gctx.uniforms.stage.buffers[i].slice != null) { + gctx.uniforms.stage.current = i; + return; + } + } + } + } + + assert(gctx.uniforms.stage.num < uniforms_staging_pipeline_len); + const current = gctx.uniforms.stage.num; + gctx.uniforms.stage.current = current; + gctx.uniforms.stage.num += 1; + + // Create new staging buffer. + const buffer_handle = gctx.createBuffer(.{ + .usage = .{ .copy_src = true, .map_write = true }, + .size = uniforms_buffer_size, + .mapped_at_creation = .true, + }); + + // Add new (mapped) staging buffer to the buffer list. + gctx.uniforms.stage.buffers[current] = .{ + .slice = gctx.lookupResource(buffer_handle).?.getMappedRange(u8, 0, uniforms_buffer_size).?, + .buffer = gctx.lookupResource(buffer_handle).?, + }; + } + + // + // Submit/Present + // + pub fn submit(gctx: *GraphicsContext, commands: []const wgpu.CommandBuffer) void { + const stage_commands = stage_commands: { + const stage_encoder = gctx.device.createCommandEncoder(null); + defer stage_encoder.release(); + + const current = gctx.uniforms.stage.current; + assert(gctx.uniforms.stage.buffers[current].slice != null); + + gctx.uniforms.stage.buffers[current].slice = null; + gctx.uniforms.stage.buffers[current].buffer.unmap(); + + if (gctx.uniforms.offset > 0) { + stage_encoder.copyBufferToBuffer( + gctx.uniforms.stage.buffers[current].buffer, + 0, + gctx.lookupResource(gctx.uniforms.buffer).?, + 0, + gctx.uniforms.offset, + ); + } + + break :stage_commands stage_encoder.finish(null); + }; + defer stage_commands.release(); + + // TODO: We support up to 32 command buffers for now. Make it more robust. + var command_buffers = std.BoundedArray(wgpu.CommandBuffer, 32).init(0) catch unreachable; + command_buffers.append(stage_commands) catch unreachable; + command_buffers.appendSlice(commands) catch unreachable; + + gctx.queue.onSubmittedWorkDone(0, gpuWorkDone, @ptrCast(&gctx.stats.gpu_frame_number)); + gctx.queue.submit(command_buffers.slice()); + + gctx.stats.tick(gctx.window_provider.getTime()); + + gctx.uniformsNextStagingBuffer(); + } + + fn gpuWorkDone(status: wgpu.QueueWorkDoneStatus, userdata: ?*anyopaque) callconv(.C) void { + const gpu_frame_number: *u64 = @ptrCast(@alignCast(userdata)); + gpu_frame_number.* += 1; + if (status != .success) { + std.log.err("[zgpu] Failed to complete GPU work (status: {s}).", .{@tagName(status)}); + } + } + + pub fn present(gctx: *GraphicsContext) enum { + normal_execution, + swap_chain_resized, + } { + if (!emscripten) gctx.swapchain.present(); + + const fb_size = gctx.window_provider.getFramebufferSize(); + if (gctx.swapchain_descriptor.width != fb_size[0] or + gctx.swapchain_descriptor.height != fb_size[1]) + { + if (fb_size[0] != 0 and fb_size[1] != 0) { + gctx.swapchain_descriptor.width = @intCast(fb_size[0]); + gctx.swapchain_descriptor.height = @intCast(fb_size[1]); + gctx.swapchain.release(); + + gctx.swapchain = gctx.device.createSwapChain(gctx.surface, gctx.swapchain_descriptor); + + std.log.info( + "[zgpu] Window has been resized to: {d}x{d}.", + .{ gctx.swapchain_descriptor.width, gctx.swapchain_descriptor.height }, + ); + return .swap_chain_resized; + } + } + + return .normal_execution; + } + + pub fn canRender(gctx: *GraphicsContext) bool { + if (emscripten) { + if (gctx.uniforms.stage.buffers[gctx.uniforms.stage.current].slice == null) { + var i: u32 = 0; + while (i < gctx.uniforms.stage.num) : (i += 1) { + if (gctx.uniforms.stage.buffers[i].slice != null) { + gctx.uniforms.stage.current = i; + return true; + } + } + return false; + } + } + return true; + } + + // + // Resources + // + pub fn createBuffer(gctx: *GraphicsContext, descriptor: wgpu.BufferDescriptor) BufferHandle { + return gctx.buffer_pool.addResource(gctx.*, .{ + .gpuobj = gctx.device.createBuffer(descriptor), + .size = descriptor.size, + .usage = descriptor.usage, + }); + } + + pub fn createTexture(gctx: *GraphicsContext, descriptor: wgpu.TextureDescriptor) TextureHandle { + return gctx.texture_pool.addResource(gctx.*, .{ + .gpuobj = gctx.device.createTexture(descriptor), + .usage = descriptor.usage, + .dimension = descriptor.dimension, + .size = descriptor.size, + .format = descriptor.format, + .mip_level_count = descriptor.mip_level_count, + .sample_count = descriptor.sample_count, + }); + } + + pub fn createTextureView( + gctx: *GraphicsContext, + texture_handle: TextureHandle, + descriptor: wgpu.TextureViewDescriptor, + ) TextureViewHandle { + const texture = gctx.lookupResource(texture_handle).?; + const info = gctx.lookupResourceInfo(texture_handle).?; + var dim = descriptor.dimension; + if (!emscripten and dim == .undef) { + dim = switch (info.dimension) { + .tdim_1d => .tvdim_1d, + .tdim_2d => .tvdim_2d, + .tdim_3d => .tvdim_3d, + }; + } + return gctx.texture_view_pool.addResource(gctx.*, .{ + .gpuobj = texture.createView(descriptor), + .format = if (descriptor.format == .undef) info.format else descriptor.format, + .dimension = dim, + .base_mip_level = descriptor.base_mip_level, + .mip_level_count = if (descriptor.mip_level_count == 0xffff_ffff) + info.mip_level_count + else + descriptor.mip_level_count, + .base_array_layer = descriptor.base_array_layer, + .array_layer_count = if (descriptor.array_layer_count == 0xffff_ffff) + info.size.depth_or_array_layers + else + descriptor.array_layer_count, + .aspect = descriptor.aspect, + .parent_texture_handle = texture_handle, + }); + } + + pub fn createSampler(gctx: *GraphicsContext, descriptor: wgpu.SamplerDescriptor) SamplerHandle { + return gctx.sampler_pool.addResource(gctx.*, .{ + .gpuobj = gctx.device.createSampler(descriptor), + .address_mode_u = descriptor.address_mode_u, + .address_mode_v = descriptor.address_mode_v, + .address_mode_w = descriptor.address_mode_w, + .mag_filter = descriptor.mag_filter, + .min_filter = descriptor.min_filter, + .mipmap_filter = descriptor.mipmap_filter, + .lod_min_clamp = descriptor.lod_min_clamp, + .lod_max_clamp = descriptor.lod_max_clamp, + .compare = descriptor.compare, + .max_anisotropy = descriptor.max_anisotropy, + }); + } + + pub fn createRenderPipeline( + gctx: *GraphicsContext, + pipeline_layout: PipelineLayoutHandle, + descriptor: wgpu.RenderPipelineDescriptor, + ) RenderPipelineHandle { + var desc = descriptor; + desc.layout = gctx.lookupResource(pipeline_layout) orelse null; + return gctx.render_pipeline_pool.addResource(gctx.*, .{ + .gpuobj = gctx.device.createRenderPipeline(desc), + .pipeline_layout_handle = pipeline_layout, + }); + } + + const AsyncCreateOpRender = struct { + gctx: *GraphicsContext, + result: *RenderPipelineHandle, + pipeline_layout: PipelineLayoutHandle, + allocator: std.mem.Allocator, + + fn create( + status: wgpu.CreatePipelineAsyncStatus, + pipeline: wgpu.RenderPipeline, + message: ?[*:0]const u8, + userdata: ?*anyopaque, + ) callconv(.C) void { + const op = @as(*AsyncCreateOpRender, @ptrCast(@alignCast(userdata))); + if (status == .success) { + op.result.* = op.gctx.render_pipeline_pool.addResource( + op.gctx.*, + .{ .gpuobj = pipeline, .pipeline_layout_handle = op.pipeline_layout }, + ); + } else { + std.log.err( + "[zgpu] Failed to async create render pipeline (status: {s}, message: {?s}).", + .{ @tagName(status), message }, + ); + } + op.allocator.destroy(op); + } + }; + + pub fn createRenderPipelineAsync( + gctx: *GraphicsContext, + allocator: std.mem.Allocator, + pipeline_layout: PipelineLayoutHandle, + descriptor: wgpu.RenderPipelineDescriptor, + result: *RenderPipelineHandle, + ) void { + var desc = descriptor; + desc.layout = gctx.lookupResource(pipeline_layout) orelse null; + + const op = allocator.create(AsyncCreateOpRender) catch unreachable; + op.* = .{ + .gctx = gctx, + .result = result, + .pipeline_layout = pipeline_layout, + .allocator = allocator, + }; + gctx.device.createRenderPipelineAsync(desc, AsyncCreateOpRender.create, @ptrCast(op)); + } + + pub fn createComputePipeline( + gctx: *GraphicsContext, + pipeline_layout: PipelineLayoutHandle, + descriptor: wgpu.ComputePipelineDescriptor, + ) ComputePipelineHandle { + var desc = descriptor; + desc.layout = gctx.lookupResource(pipeline_layout) orelse null; + return gctx.compute_pipeline_pool.addResource(gctx.*, .{ + .gpuobj = gctx.device.createComputePipeline(desc), + .pipeline_layout_handle = pipeline_layout, + }); + } + + const AsyncCreateOpCompute = struct { + gctx: *GraphicsContext, + result: *ComputePipelineHandle, + pipeline_layout: PipelineLayoutHandle, + allocator: std.mem.Allocator, + + fn create( + status: wgpu.CreatePipelineAsyncStatus, + pipeline: wgpu.ComputePipeline, + message: ?[*:0]const u8, + userdata: ?*anyopaque, + ) callconv(.C) void { + const op = @as(*AsyncCreateOpCompute, @ptrCast(@alignCast(userdata))); + if (status == .success) { + op.result.* = op.gctx.compute_pipeline_pool.addResource( + op.gctx.*, + .{ .gpuobj = pipeline, .pipeline_layout_handle = op.pipeline_layout }, + ); + } else { + std.log.err( + "[zgpu] Failed to async create compute pipeline (status: {s}, message: {?s}).", + .{ @tagName(status), message }, + ); + } + op.allocator.destroy(op); + } + }; + + pub fn createComputePipelineAsync( + gctx: *GraphicsContext, + allocator: std.mem.Allocator, + pipeline_layout: PipelineLayoutHandle, + descriptor: wgpu.ComputePipelineDescriptor, + result: *ComputePipelineHandle, + ) void { + var desc = descriptor; + desc.layout = gctx.lookupResource(pipeline_layout) orelse null; + + const op = allocator.create(AsyncCreateOpCompute) catch unreachable; + op.* = .{ + .gctx = gctx, + .result = result, + .pipeline_layout = pipeline_layout, + .allocator = allocator, + }; + gctx.device.createComputePipelineAsync(desc, AsyncCreateOpCompute.create, @ptrCast(op)); + } + + pub fn createBindGroup( + gctx: *GraphicsContext, + layout: BindGroupLayoutHandle, + entries: []const BindGroupEntryInfo, + ) BindGroupHandle { + assert(entries.len > 0 and entries.len <= max_num_bindings_per_group); + + var bind_group_info = BindGroupInfo{ .num_entries = @intCast(entries.len) }; + var gpu_bind_group_entries: [max_num_bindings_per_group]wgpu.BindGroupEntry = undefined; + + for (entries, 0..) |entry, i| { + bind_group_info.entries[i] = entry; + + if (entries[i].buffer_handle) |handle| { + gpu_bind_group_entries[i] = .{ + .binding = entries[i].binding, + .buffer = gctx.lookupResource(handle).?, + .offset = entries[i].offset, + .size = entries[i].size, + .sampler = null, + .texture_view = null, + }; + } else if (entries[i].sampler_handle) |handle| { + gpu_bind_group_entries[i] = .{ + .binding = entries[i].binding, + .buffer = null, + .offset = 0, + .size = 0, + .sampler = gctx.lookupResource(handle).?, + .texture_view = null, + }; + } else if (entries[i].texture_view_handle) |handle| { + gpu_bind_group_entries[i] = .{ + .binding = entries[i].binding, + .buffer = null, + .offset = 0, + .size = 0, + .sampler = null, + .texture_view = gctx.lookupResource(handle).?, + }; + } else unreachable; + } + bind_group_info.gpuobj = gctx.device.createBindGroup(.{ + .layout = gctx.lookupResource(layout).?, + .entry_count = @intCast(entries.len), + .entries = &gpu_bind_group_entries, + }); + return gctx.bind_group_pool.addResource(gctx.*, bind_group_info); + } + + pub fn createBindGroupLayout( + gctx: *GraphicsContext, + entries: []const wgpu.BindGroupLayoutEntry, + ) BindGroupLayoutHandle { + assert(entries.len > 0 and entries.len <= max_num_bindings_per_group); + + var bind_group_layout_info = BindGroupLayoutInfo{ + .gpuobj = gctx.device.createBindGroupLayout(.{ + .entry_count = @intCast(entries.len), + .entries = entries.ptr, + }), + .num_entries = @intCast(entries.len), + }; + for (entries, 0..) |entry, i| { + bind_group_layout_info.entries[i] = entry; + bind_group_layout_info.entries[i].next_in_chain = null; + bind_group_layout_info.entries[i].buffer.next_in_chain = null; + bind_group_layout_info.entries[i].sampler.next_in_chain = null; + bind_group_layout_info.entries[i].texture.next_in_chain = null; + bind_group_layout_info.entries[i].storage_texture.next_in_chain = null; + } + return gctx.bind_group_layout_pool.addResource(gctx.*, bind_group_layout_info); + } + + pub fn createBindGroupLayoutAuto( + gctx: *GraphicsContext, + pipeline: anytype, + group_index: u32, + ) BindGroupLayoutHandle { + const bgl = gctx.lookupResource(pipeline).?.getBindGroupLayout(group_index); + return gctx.bind_group_layout_pool.addResource(gctx.*, BindGroupLayoutInfo{ .gpuobj = bgl }); + } + + pub fn createPipelineLayout( + gctx: *GraphicsContext, + bind_group_layouts: []const BindGroupLayoutHandle, + ) PipelineLayoutHandle { + var info: PipelineLayoutInfo = .{ .num_bind_group_layouts = @as(u32, @intCast(bind_group_layouts.len)) }; + + var gpu_bind_group_layouts: [max_num_bind_groups_per_pipeline]wgpu.BindGroupLayout = undefined; + + for (bind_group_layouts, 0..) |bgl, i| { + info.bind_group_layouts[i] = bgl; + gpu_bind_group_layouts[i] = gctx.lookupResource(bgl).?; + } + + info.gpuobj = gctx.device.createPipelineLayout(.{ + .bind_group_layout_count = info.num_bind_group_layouts, + .bind_group_layouts = if (bind_group_layouts.len > 0) &gpu_bind_group_layouts else null, + }); + + return gctx.pipeline_layout_pool.addResource(gctx.*, info); + } + + pub fn lookupResource(gctx: GraphicsContext, handle: anytype) ?handleToGpuResourceType(@TypeOf(handle)) { + if (gctx.isResourceValid(handle)) { + const T = @TypeOf(handle); + return switch (T) { + BufferHandle => gctx.buffer_pool.getGpuObj(handle).?, + TextureHandle => gctx.texture_pool.getGpuObj(handle).?, + TextureViewHandle => gctx.texture_view_pool.getGpuObj(handle).?, + SamplerHandle => gctx.sampler_pool.getGpuObj(handle).?, + RenderPipelineHandle => gctx.render_pipeline_pool.getGpuObj(handle).?, + ComputePipelineHandle => gctx.compute_pipeline_pool.getGpuObj(handle).?, + BindGroupHandle => gctx.bind_group_pool.getGpuObj(handle).?, + BindGroupLayoutHandle => gctx.bind_group_layout_pool.getGpuObj(handle).?, + PipelineLayoutHandle => gctx.pipeline_layout_pool.getGpuObj(handle).?, + else => @compileError( + "[zgpu] GraphicsContext.lookupResource() not implemented for " ++ @typeName(T), + ), + }; + } + return null; + } + + pub fn lookupResourceInfo(gctx: GraphicsContext, handle: anytype) ?handleToResourceInfoType(@TypeOf(handle)) { + if (gctx.isResourceValid(handle)) { + const T = @TypeOf(handle); + return switch (T) { + BufferHandle => gctx.buffer_pool.getInfo(handle), + TextureHandle => gctx.texture_pool.getInfo(handle), + TextureViewHandle => gctx.texture_view_pool.getInfo(handle), + SamplerHandle => gctx.sampler_pool.getInfo(handle), + RenderPipelineHandle => gctx.render_pipeline_pool.getInfo(handle), + ComputePipelineHandle => gctx.compute_pipeline_pool.getInfo(handle), + BindGroupHandle => gctx.bind_group_pool.getInfo(handle), + BindGroupLayoutHandle => gctx.bind_group_layout_pool.getInfo(handle), + PipelineLayoutHandle => gctx.pipeline_layout_pool.getInfo(handle), + else => @compileError( + "[zgpu] GraphicsContext.lookupResourceInfo() not implemented for " ++ @typeName(T), + ), + }; + } + return null; + } + + pub fn releaseResource(gctx: *GraphicsContext, handle: anytype) void { + const T = @TypeOf(handle); + switch (T) { + BufferHandle => gctx.buffer_pool.destroyResource(handle, false), + TextureHandle => gctx.texture_pool.destroyResource(handle, false), + TextureViewHandle => gctx.texture_view_pool.destroyResource(handle, false), + SamplerHandle => gctx.sampler_pool.destroyResource(handle, false), + RenderPipelineHandle => gctx.render_pipeline_pool.destroyResource(handle, false), + ComputePipelineHandle => gctx.compute_pipeline_pool.destroyResource(handle, false), + BindGroupHandle => gctx.bind_group_pool.destroyResource(handle, false), + BindGroupLayoutHandle => gctx.bind_group_layout_pool.destroyResource(handle, false), + PipelineLayoutHandle => gctx.pipeline_layout_pool.destroyResource(handle, false), + else => @compileError("[zgpu] GraphicsContext.releaseResource() not implemented for " ++ @typeName(T)), + } + } + + pub fn destroyResource(gctx: *GraphicsContext, handle: anytype) void { + const T = @TypeOf(handle); + switch (T) { + BufferHandle => gctx.buffer_pool.destroyResource(handle, true), + TextureHandle => gctx.texture_pool.destroyResource(handle, true), + else => @compileError("[zgpu] GraphicsContext.destroyResource() not implemented for " ++ @typeName(T)), + } + } + + pub fn isResourceValid(gctx: GraphicsContext, handle: anytype) bool { + const T = @TypeOf(handle); + switch (T) { + BufferHandle => return gctx.buffer_pool.isHandleValid(handle), + TextureHandle => return gctx.texture_pool.isHandleValid(handle), + TextureViewHandle => { + if (gctx.texture_view_pool.isHandleValid(handle)) { + const texture = gctx.texture_view_pool.getInfoPtr(handle).parent_texture_handle; + return gctx.isResourceValid(texture); + } + return false; + }, + SamplerHandle => return gctx.sampler_pool.isHandleValid(handle), + RenderPipelineHandle => return gctx.render_pipeline_pool.isHandleValid(handle), + ComputePipelineHandle => return gctx.compute_pipeline_pool.isHandleValid(handle), + BindGroupHandle => { + if (gctx.bind_group_pool.isHandleValid(handle)) { + const num_entries = gctx.bind_group_pool.getInfoPtr(handle).num_entries; + const entries = &gctx.bind_group_pool.getInfoPtr(handle).entries; + var i: u32 = 0; + while (i < num_entries) : (i += 1) { + if (entries[i].buffer_handle) |buffer| { + if (!gctx.isResourceValid(buffer)) + return false; + } else if (entries[i].sampler_handle) |sampler| { + if (!gctx.isResourceValid(sampler)) + return false; + } else if (entries[i].texture_view_handle) |texture_view| { + if (!gctx.isResourceValid(texture_view)) + return false; + } else unreachable; + } + return true; + } + return false; + }, + BindGroupLayoutHandle => return gctx.bind_group_layout_pool.isHandleValid(handle), + PipelineLayoutHandle => return gctx.pipeline_layout_pool.isHandleValid(handle), + else => @compileError("[zgpu] GraphicsContext.isResourceValid() not implemented for " ++ @typeName(T)), + } + } + + // + // Mipmaps + // + const MipgenResources = struct { + pipeline: ComputePipelineHandle = .{}, + scratch_texture: TextureHandle = .{}, + scratch_texture_views: [max_levels_per_dispatch]TextureViewHandle = + [_]TextureViewHandle{.{}} ** max_levels_per_dispatch, + bind_group_layout: BindGroupLayoutHandle = .{}, + + const max_levels_per_dispatch = 4; + }; + + pub fn generateMipmaps( + gctx: *GraphicsContext, + arena: std.mem.Allocator, + encoder: wgpu.CommandEncoder, + texture: TextureHandle, + ) void { + const texture_info = gctx.lookupResourceInfo(texture) orelse return; + if (texture_info.mip_level_count == 1) return; + + const max_size = 2048; + + assert(texture_info.usage.copy_dst == true); + assert(texture_info.dimension == .tdim_2d); + assert(texture_info.size.width <= max_size and texture_info.size.height <= max_size); + assert(texture_info.size.width == texture_info.size.height); + assert(math.isPowerOfTwo(texture_info.size.width)); + + const format = texture_info.format; + const entry = gctx.mipgens.getOrPut(format) catch unreachable; + const mipgen = entry.value_ptr; + + if (!entry.found_existing) { + mipgen.bind_group_layout = gctx.createBindGroupLayout(&.{ + bufferEntry(0, .{ .compute = true }, .uniform, true, 0), + textureEntry(1, .{ .compute = true }, .unfilterable_float, .tvdim_2d, false), + storageTextureEntry(2, .{ .compute = true }, .write_only, format, .tvdim_2d), + storageTextureEntry(3, .{ .compute = true }, .write_only, format, .tvdim_2d), + storageTextureEntry(4, .{ .compute = true }, .write_only, format, .tvdim_2d), + storageTextureEntry(5, .{ .compute = true }, .write_only, format, .tvdim_2d), + }); + + const pipeline_layout = gctx.createPipelineLayout(&.{ + mipgen.bind_group_layout, + }); + defer gctx.releaseResource(pipeline_layout); + + const wgsl_src = wgsl.csGenerateMipmaps(arena, formatToShaderFormat(format)); + const cs_module = createWgslShaderModule(gctx.device, wgsl_src, "zgpu_cs_generate_mipmaps"); + defer { + arena.free(wgsl_src); + cs_module.release(); + } + + mipgen.pipeline = gctx.createComputePipeline(pipeline_layout, .{ + .compute = .{ + .module = cs_module, + .entry_point = "main", + }, + }); + + mipgen.scratch_texture = gctx.createTexture(.{ + .usage = .{ .copy_src = true, .storage_binding = true }, + .dimension = .tdim_2d, + .size = .{ .width = max_size / 2, .height = max_size / 2, .depth_or_array_layers = 1 }, + .format = format, + .mip_level_count = MipgenResources.max_levels_per_dispatch, + .sample_count = 1, + }); + + for (&mipgen.scratch_texture_views, 0..) |*view, i| { + view.* = gctx.createTextureView(mipgen.scratch_texture, .{ + .base_mip_level = @intCast(i), + .mip_level_count = 1, + .base_array_layer = 0, + .array_layer_count = 1, + }); + } + } + + var array_layer: u32 = 0; + while (array_layer < texture_info.size.depth_or_array_layers) : (array_layer += 1) { + const texture_view = gctx.createTextureView(texture, .{ + .dimension = .tvdim_2d, + .base_array_layer = array_layer, + .array_layer_count = 1, + }); + defer gctx.releaseResource(texture_view); + + const bind_group = gctx.createBindGroup(mipgen.bind_group_layout, &.{ + .{ .binding = 0, .buffer_handle = gctx.uniforms.buffer, .offset = 0, .size = 8 }, + .{ .binding = 1, .texture_view_handle = texture_view }, + .{ .binding = 2, .texture_view_handle = mipgen.scratch_texture_views[0] }, + .{ .binding = 3, .texture_view_handle = mipgen.scratch_texture_views[1] }, + .{ .binding = 4, .texture_view_handle = mipgen.scratch_texture_views[2] }, + .{ .binding = 5, .texture_view_handle = mipgen.scratch_texture_views[3] }, + }); + defer gctx.releaseResource(bind_group); + + const MipgenUniforms = extern struct { + src_mip_level: i32, + num_mip_levels: u32, + }; + + var total_num_mips: u32 = texture_info.mip_level_count - 1; + var current_src_mip_level: u32 = 0; + + while (true) { + const dispatch_num_mips = @min(MipgenResources.max_levels_per_dispatch, total_num_mips); + { + const pass = encoder.beginComputePass(null); + defer { + pass.end(); + pass.release(); + } + + pass.setPipeline(gctx.lookupResource(mipgen.pipeline).?); + + const mem = gctx.uniformsAllocate(MipgenUniforms, 1); + mem.slice[0] = .{ + .src_mip_level = @intCast(current_src_mip_level), + .num_mip_levels = dispatch_num_mips, + }; + pass.setBindGroup(0, gctx.lookupResource(bind_group).?, &.{mem.offset}); + + pass.dispatchWorkgroups( + @max(texture_info.size.width >> @intCast(3 + current_src_mip_level), 1), + @max(texture_info.size.height >> @intCast(3 + current_src_mip_level), 1), + 1, + ); + } + + var mip_index: u32 = 0; + while (mip_index < dispatch_num_mips) : (mip_index += 1) { + const src_origin = wgpu.Origin3D{ .x = 0, .y = 0, .z = 0 }; + const dst_origin = wgpu.Origin3D{ .x = 0, .y = 0, .z = array_layer }; + encoder.copyTextureToTexture( + .{ + .texture = gctx.lookupResource(mipgen.scratch_texture).?, + .mip_level = mip_index, + .origin = src_origin, + }, + .{ + .texture = gctx.lookupResource(texture).?, + .mip_level = mip_index + current_src_mip_level + 1, + .origin = dst_origin, + }, + .{ + .width = texture_info.size.width >> @intCast(mip_index + current_src_mip_level + 1), + .height = texture_info.size.height >> @intCast(mip_index + current_src_mip_level + 1), + }, + ); + } + + assert(total_num_mips >= dispatch_num_mips); + total_num_mips -= dispatch_num_mips; + if (total_num_mips == 0) { + break; + } + current_src_mip_level += dispatch_num_mips; + } + } + } +}; + +// Defined in dawn.cpp +const DawnNativeInstance = ?*opaque {}; +const DawnProcsTable = ?*opaque {}; +extern fn dniCreate() DawnNativeInstance; +extern fn dniDestroy(dni: DawnNativeInstance) void; +extern fn dniGetWgpuInstance(dni: DawnNativeInstance) ?wgpu.Instance; +extern fn dnGetProcs() DawnProcsTable; + +// Defined in Dawn codebase +extern fn dawnProcSetProcs(procs: DawnProcsTable) void; + +extern fn emscripten_sleep(ms: u32) void; + +/// Helper to create a buffer BindGroupLayoutEntry. +pub fn bufferEntry( + binding: u32, + visibility: wgpu.ShaderStage, + binding_type: wgpu.BufferBindingType, + has_dynamic_offset: bool, + min_binding_size: u64, +) wgpu.BindGroupLayoutEntry { + return .{ + .binding = binding, + .visibility = visibility, + .buffer = .{ + .binding_type = binding_type, + .has_dynamic_offset = switch (has_dynamic_offset) { + true => .true, + false => .false, + }, + .min_binding_size = min_binding_size, + }, + }; +} + +/// Helper to create a sampler BindGroupLayoutEntry. +pub fn samplerEntry( + binding: u32, + visibility: wgpu.ShaderStage, + binding_type: wgpu.SamplerBindingType, +) wgpu.BindGroupLayoutEntry { + return .{ + .binding = binding, + .visibility = visibility, + .sampler = .{ .binding_type = binding_type }, + }; +} + +/// Helper to create a texture BindGroupLayoutEntry. +pub fn textureEntry( + binding: u32, + visibility: wgpu.ShaderStage, + sample_type: wgpu.TextureSampleType, + view_dimension: wgpu.TextureViewDimension, + multisampled: bool, +) wgpu.BindGroupLayoutEntry { + return .{ + .binding = binding, + .visibility = visibility, + .texture = .{ + .sample_type = sample_type, + .view_dimension = view_dimension, + .multisampled = multisampled, + }, + }; +} + +/// Helper to create a storage texture BindGroupLayoutEntry. +pub fn storageTextureEntry( + binding: u32, + visibility: wgpu.ShaderStage, + access: wgpu.StorageTextureAccess, + format: wgpu.TextureFormat, + view_dimension: wgpu.TextureViewDimension, +) wgpu.BindGroupLayoutEntry { + return .{ + .binding = binding, + .visibility = visibility, + .storage_texture = .{ + .access = access, + .format = format, + .view_dimension = view_dimension, + }, + }; +} + +/// You may disable async shader compilation for debugging purposes. +const enable_async_shader_compilation = true; + +/// Helper function for creating render pipelines. +/// Supports: one vertex buffer, one non-blending render target, +/// one vertex shader module and one fragment shader module. +pub fn createRenderPipelineSimple( + allocator: std.mem.Allocator, + gctx: *GraphicsContext, + bgls: []const BindGroupLayoutHandle, + wgsl_vs: [:0]const u8, + wgsl_fs: [:0]const u8, + vertex_stride: ?u64, + vertex_attribs: ?[]const wgpu.VertexAttribute, + primitive_state: wgpu.PrimitiveState, + rt_format: wgpu.TextureFormat, + depth_state: ?wgpu.DepthStencilState, + out_pipe: *RenderPipelineHandle, +) void { + const pl = gctx.createPipelineLayout(bgls); + defer gctx.releaseResource(pl); + + const vs_mod = createWgslShaderModule(gctx.device, wgsl_vs, null); + defer vs_mod.release(); + + const fs_mod = createWgslShaderModule(gctx.device, wgsl_fs, null); + defer fs_mod.release(); + + const color_targets = [_]wgpu.ColorTargetState{.{ .format = rt_format }}; + + const vertex_buffers = if (vertex_stride) |vs| [_]wgpu.VertexBufferLayout{.{ + .array_stride = vs, + .attribute_count = @intCast(vertex_attribs.?.len), + .attributes = vertex_attribs.?.ptr, + }} else null; + + const pipe_desc = wgpu.RenderPipelineDescriptor{ + .vertex = wgpu.VertexState{ + .module = vs_mod, + .entry_point = "main", + .buffer_count = if (vertex_buffers) |vbs| vbs.len else 0, + .buffers = if (vertex_buffers) |vbs| &vbs else null, + }, + .fragment = &wgpu.FragmentState{ + .module = fs_mod, + .entry_point = "main", + .target_count = color_targets.len, + .targets = &color_targets, + }, + .depth_stencil = if (depth_state) |ds| &ds else null, + .primitive = primitive_state, + }; + + if (enable_async_shader_compilation) { + gctx.createRenderPipelineAsync(allocator, pl, pipe_desc, out_pipe); + } else { + out_pipe.* = gctx.createRenderPipeline(pl, pipe_desc); + } +} + +/// Helper function for creating render passes. +/// Supports: One color attachment and optional depth attachment. +pub fn beginRenderPassSimple( + encoder: wgpu.CommandEncoder, + load_op: wgpu.LoadOp, + color_texv: wgpu.TextureView, + clear_color: ?wgpu.Color, + depth_texv: ?wgpu.TextureView, + clear_depth: ?f32, +) wgpu.RenderPassEncoder { + if (depth_texv == null) { + assert(clear_depth == null); + } + const color_attachments = [_]wgpu.RenderPassColorAttachment{.{ + .view = color_texv, + .load_op = load_op, + .store_op = .store, + .clear_value = if (clear_color) |cc| cc else .{ .r = 0, .g = 0, .b = 0, .a = 0 }, + }}; + if (depth_texv) |dtexv| { + const depth_attachment = wgpu.RenderPassDepthStencilAttachment{ + .view = dtexv, + .depth_load_op = load_op, + .depth_store_op = .store, + .depth_clear_value = if (clear_depth) |cd| cd else 0.0, + }; + return encoder.beginRenderPass(.{ + .color_attachment_count = color_attachments.len, + .color_attachments = &color_attachments, + .depth_stencil_attachment = &depth_attachment, + }); + } + return encoder.beginRenderPass(.{ + .color_attachment_count = color_attachments.len, + .color_attachments = &color_attachments, + }); +} + +pub fn endReleasePass(pass: anytype) void { + pass.end(); + pass.release(); +} + +pub fn createWgslShaderModule( + device: wgpu.Device, + source: [*:0]const u8, + label: ?[*:0]const u8, +) wgpu.ShaderModule { + const wgsl_desc = wgpu.ShaderModuleWGSLDescriptor{ + .chain = .{ .next = null, .struct_type = .shader_module_wgsl_descriptor }, + .code = source, + }; + const desc = wgpu.ShaderModuleDescriptor{ + .next_in_chain = @ptrCast(&wgsl_desc), + .label = if (label) |l| l else null, + }; + return device.createShaderModule(desc); +} + +pub fn imageInfoToTextureFormat(num_components: u32, bytes_per_component: u32, is_hdr: bool) wgpu.TextureFormat { + assert(num_components == 1 or num_components == 2 or num_components == 4); + assert(bytes_per_component == 1 or bytes_per_component == 2); + assert(if (is_hdr and bytes_per_component != 2) false else true); + + if (is_hdr) { + if (num_components == 1) return .r16_float; + if (num_components == 2) return .rg16_float; + if (num_components == 4) return .rgba16_float; + } else { + if (bytes_per_component == 1) { + if (num_components == 1) return .r8_unorm; + if (num_components == 2) return .rg8_unorm; + if (num_components == 4) return .rgba8_unorm; + } else { + // TODO: Looks like wgpu does not support 16 bit unorm formats. + unreachable; + } + } + unreachable; +} + +pub const BufferInfo = struct { + gpuobj: ?wgpu.Buffer = null, + size: u64 = 0, + usage: wgpu.BufferUsage = .{}, +}; + +pub const TextureInfo = struct { + gpuobj: ?wgpu.Texture = null, + usage: wgpu.TextureUsage = .{}, + dimension: wgpu.TextureDimension = .tdim_1d, + size: wgpu.Extent3D = .{ .width = 0 }, + format: wgpu.TextureFormat = .undef, + mip_level_count: u32 = 0, + sample_count: u32 = 0, +}; + +pub const TextureViewInfo = struct { + gpuobj: ?wgpu.TextureView = null, + format: wgpu.TextureFormat = .undef, + dimension: wgpu.TextureViewDimension = .undef, + base_mip_level: u32 = 0, + mip_level_count: u32 = 0, + base_array_layer: u32 = 0, + array_layer_count: u32 = 0, + aspect: wgpu.TextureAspect = .all, + parent_texture_handle: TextureHandle = .{}, +}; + +pub const SamplerInfo = struct { + gpuobj: ?wgpu.Sampler = null, + address_mode_u: wgpu.AddressMode = .repeat, + address_mode_v: wgpu.AddressMode = .repeat, + address_mode_w: wgpu.AddressMode = .repeat, + mag_filter: wgpu.FilterMode = .nearest, + min_filter: wgpu.FilterMode = .nearest, + mipmap_filter: wgpu.MipmapFilterMode = .nearest, + lod_min_clamp: f32 = 0.0, + lod_max_clamp: f32 = 0.0, + compare: wgpu.CompareFunction = .undef, + max_anisotropy: u16 = 0, +}; + +pub const RenderPipelineInfo = struct { + gpuobj: ?wgpu.RenderPipeline = null, + pipeline_layout_handle: PipelineLayoutHandle = .{}, +}; + +pub const ComputePipelineInfo = struct { + gpuobj: ?wgpu.ComputePipeline = null, + pipeline_layout_handle: PipelineLayoutHandle = .{}, +}; + +pub const BindGroupEntryInfo = struct { + binding: u32 = 0, + buffer_handle: ?BufferHandle = null, + offset: u64 = 0, + size: u64 = 0, + sampler_handle: ?SamplerHandle = null, + texture_view_handle: ?TextureViewHandle = null, +}; + +const max_num_bindings_per_group = zgpu_options.max_num_bindings_per_group; + +pub const BindGroupInfo = struct { + gpuobj: ?wgpu.BindGroup = null, + num_entries: u32 = 0, + entries: [max_num_bindings_per_group]BindGroupEntryInfo = + [_]BindGroupEntryInfo{.{}} ** max_num_bindings_per_group, +}; + +pub const BindGroupLayoutInfo = struct { + gpuobj: ?wgpu.BindGroupLayout = null, + num_entries: u32 = 0, + entries: [max_num_bindings_per_group]wgpu.BindGroupLayoutEntry = + [_]wgpu.BindGroupLayoutEntry{.{ .binding = 0, .visibility = .{} }} ** max_num_bindings_per_group, +}; + +const max_num_bind_groups_per_pipeline = zgpu_options.max_num_bind_groups_per_pipeline; + +pub const PipelineLayoutInfo = struct { + gpuobj: ?wgpu.PipelineLayout = null, + num_bind_group_layouts: u32 = 0, + bind_group_layouts: [max_num_bind_groups_per_pipeline]BindGroupLayoutHandle = + [_]BindGroupLayoutHandle{.{}} ** max_num_bind_groups_per_pipeline, +}; + +pub const BufferHandle = BufferPool.Handle; +pub const TextureHandle = TexturePool.Handle; +pub const TextureViewHandle = TextureViewPool.Handle; +pub const SamplerHandle = SamplerPool.Handle; +pub const RenderPipelineHandle = RenderPipelinePool.Handle; +pub const ComputePipelineHandle = ComputePipelinePool.Handle; +pub const BindGroupHandle = BindGroupPool.Handle; +pub const BindGroupLayoutHandle = BindGroupLayoutPool.Handle; +pub const PipelineLayoutHandle = PipelineLayoutPool.Handle; + +const BufferPool = ResourcePool(BufferInfo, wgpu.Buffer); +const TexturePool = ResourcePool(TextureInfo, wgpu.Texture); +const TextureViewPool = ResourcePool(TextureViewInfo, wgpu.TextureView); +const SamplerPool = ResourcePool(SamplerInfo, wgpu.Sampler); +const RenderPipelinePool = ResourcePool(RenderPipelineInfo, wgpu.RenderPipeline); +const ComputePipelinePool = ResourcePool(ComputePipelineInfo, wgpu.ComputePipeline); +const BindGroupPool = ResourcePool(BindGroupInfo, wgpu.BindGroup); +const BindGroupLayoutPool = ResourcePool(BindGroupLayoutInfo, wgpu.BindGroupLayout); +const PipelineLayoutPool = ResourcePool(PipelineLayoutInfo, wgpu.PipelineLayout); + +fn ResourcePool(comptime Info: type, comptime Resource: type) type { + const zpool = @import("zpool"); + const Pool = zpool.Pool(16, 16, Resource, struct { info: Info }); + + return struct { + const Self = @This(); + + pub const Handle = Pool.Handle; + + pool: Pool, + + fn init(allocator: std.mem.Allocator, capacity: u32) Self { + const pool = Pool.initCapacity(allocator, capacity) catch unreachable; + return .{ .pool = pool }; + } + + fn deinit(self: *Self, allocator: std.mem.Allocator) void { + _ = allocator; + self.pool.deinit(); + } + + fn addResource(self: *Self, gctx: GraphicsContext, info: Info) Handle { + assert(info.gpuobj != null); + + if (self.pool.addIfNotFull(.{ .info = info })) |handle| { + return handle; + } + + // If pool is free, attempt to remove a resource that is now invalid + // because of dependent resources which have become invalid. + // For example, texture view becomes invalid when parent texture + // is destroyed. + // + // TODO: We could instead store a linked list in Info to track + // dependencies. The parent resource could "point" to the first + // dependent resource, and each dependent resource could "point" to + // the parent and the prev/next dependent resources of the same + // type (perhaps using handles instead of pointers). + // When a parent resource is destroyed, we could traverse that list + // to destroy dependent resources, and when a dependent resource + // is destroyed, we can remove it from the doubly-linked list. + // + // pub const TextureInfo = struct { + // ... + // // note generic name: + // first_dependent_handle: TextureViewHandle = .{} + // }; + // + // pub const TextureViewInfo = struct { + // ... + // // note generic names: + // parent_handle: TextureHandle = .{}, + // prev_dependent_handle: TextureViewHandle, + // next_dependent_handle: TextureViewHandle, + // }; + if (self.removeResourceIfInvalid(gctx)) { + if (self.pool.addIfNotFull(.{ .info = info })) |handle| { + return handle; + } + } + + // TODO: For now we just assert if pool is full - make it more roboust. + assert(false); + return Handle.nil; + } + + fn removeResourceIfInvalid(self: *Self, gctx: GraphicsContext) bool { + var live_handles = self.pool.liveHandles(); + while (live_handles.next()) |live_handle| { + if (!gctx.isResourceValid(live_handle)) { + self.destroyResource(live_handle, true); + return true; + } + } + return false; + } + + fn destroyResource(self: *Self, handle: Handle, comptime call_destroy: bool) void { + if (!self.isHandleValid(handle)) + return; + + const resource_info = self.pool.getColumnPtrAssumeLive(handle, .info); + const gpuobj = resource_info.gpuobj.?; + + if (call_destroy and (Handle == BufferHandle or Handle == TextureHandle)) { + gpuobj.destroy(); + } + gpuobj.release(); + resource_info.* = .{}; + + self.pool.removeAssumeLive(handle); + } + + fn isHandleValid(self: Self, handle: Handle) bool { + return self.pool.isLiveHandle(handle); + } + + fn getInfoPtr(self: Self, handle: Handle) *Info { + return self.pool.getColumnPtrAssumeLive(handle, .info); + } + + fn getInfo(self: Self, handle: Handle) Info { + return self.pool.getColumnAssumeLive(handle, .info); + } + + fn getGpuObj(self: Self, handle: Handle) ?Resource { + if (self.pool.getColumnPtrIfLive(handle, .info)) |info| { + return info.gpuobj; + } + return null; + } + }; +} + +const FrameStats = struct { + time: f64 = 0.0, + delta_time: f32 = 0.0, + fps_counter: u32 = 0, + fps: f64 = 0.0, + average_cpu_time: f64 = 0.0, + previous_time: f64 = 0.0, + fps_refresh_time: f64 = 0.0, + cpu_frame_number: u64 = 0, + gpu_frame_number: u64 = 0, + + fn tick(stats: *FrameStats, now_secs: f64) void { + stats.time = now_secs; + stats.delta_time = @floatCast(stats.time - stats.previous_time); + stats.previous_time = stats.time; + + if ((stats.time - stats.fps_refresh_time) >= 1.0) { + const t = stats.time - stats.fps_refresh_time; + const fps = @as(f64, @floatFromInt(stats.fps_counter)) / t; + const ms = (1.0 / fps) * 1000.0; + + stats.fps = fps; + stats.average_cpu_time = ms; + stats.fps_refresh_time = stats.time; + stats.fps_counter = 0; + } + stats.fps_counter += 1; + stats.cpu_frame_number += 1; + } +}; + +const SurfaceDescriptorTag = enum { + metal_layer, + windows_hwnd, + xlib, + wayland, + canvas_html, +}; + +const SurfaceDescriptor = union(SurfaceDescriptorTag) { + metal_layer: struct { + label: ?[*:0]const u8 = null, + layer: *anyopaque, + }, + windows_hwnd: struct { + label: ?[*:0]const u8 = null, + hinstance: *anyopaque, + hwnd: *anyopaque, + }, + xlib: struct { + label: ?[*:0]const u8 = null, + display: *anyopaque, + window: u32, + }, + wayland: struct { + label: ?[*:0]const u8 = null, + display: *anyopaque, + surface: *anyopaque, + }, + canvas_html: struct { + label: ?[*:0]const u8 = null, + selector: [*:0]const u8, + }, +}; + +fn isLinuxDesktopLike(tag: std.Target.Os.Tag) bool { + return switch (tag) { + .linux, + .freebsd, + .openbsd, + .dragonfly, + => true, + else => false, + }; +} + +fn createSurfaceForWindow(instance: wgpu.Instance, window_provider: WindowProvider) wgpu.Surface { + const os_tag = @import("builtin").target.os.tag; + + const descriptor = switch (os_tag) { + .windows => SurfaceDescriptor{ + .windows_hwnd = .{ + .label = "basic surface", + .hinstance = std.os.windows.kernel32.GetModuleHandleW(null).?, + .hwnd = window_provider.getWin32Window().?, + }, + }, + .macos => macos: { + const ns_window = window_provider.getCocoaWindow().?; + 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] + + break :macos SurfaceDescriptor{ + .metal_layer = .{ + .label = "basic surface", + .layer = layer.?, + }, + }; + }, + .emscripten => SurfaceDescriptor{ + .canvas_html = .{ + .label = "basic surface", + .selector = "#canvas", // TODO: can this be somehow exposed through api? + }, + }, + else => if (isLinuxDesktopLike(os_tag)) linux: { + if (window_provider.getWaylandDisplay()) |wl_display| { + break :linux SurfaceDescriptor{ + .wayland = .{ + .label = "basic surface", + .display = wl_display, + .surface = window_provider.getWaylandSurface().?, + }, + }; + } else { + break :linux SurfaceDescriptor{ + .xlib = .{ + .label = "basic surface", + .display = window_provider.getX11Display().?, + .window = window_provider.getX11Window(), + }, + }; + } + } else unreachable, + }; + + return switch (descriptor) { + .metal_layer => |src| blk: { + var desc: wgpu.SurfaceDescriptorFromMetalLayer = undefined; + desc.chain.next = null; + desc.chain.struct_type = .surface_descriptor_from_metal_layer; + desc.layer = src.layer; + break :blk instance.createSurface(.{ + .next_in_chain = @ptrCast(&desc), + .label = if (src.label) |l| l else null, + }); + }, + .windows_hwnd => |src| blk: { + var desc: wgpu.SurfaceDescriptorFromWindowsHWND = undefined; + desc.chain.next = null; + desc.chain.struct_type = .surface_descriptor_from_windows_hwnd; + desc.hinstance = src.hinstance; + desc.hwnd = src.hwnd; + break :blk instance.createSurface(.{ + .next_in_chain = @ptrCast(&desc), + .label = if (src.label) |l| l else null, + }); + }, + .xlib => |src| blk: { + var desc: wgpu.SurfaceDescriptorFromXlibWindow = undefined; + desc.chain.next = null; + desc.chain.struct_type = .surface_descriptor_from_xlib_window; + desc.display = src.display; + desc.window = src.window; + break :blk instance.createSurface(.{ + .next_in_chain = @ptrCast(&desc), + .label = if (src.label) |l| l else null, + }); + }, + .wayland => |src| blk: { + var desc: wgpu.SurfaceDescriptorFromWaylandSurface = undefined; + desc.chain.next = null; + desc.chain.struct_type = .surface_descriptor_from_wayland_surface; + desc.display = src.display; + desc.surface = src.surface; + break :blk instance.createSurface(.{ + .next_in_chain = @ptrCast(&desc), + .label = if (src.label) |l| l else null, + }); + }, + .canvas_html => |src| blk: { + var desc: wgpu.SurfaceDescriptorFromCanvasHTMLSelector = .{ + .chain = .{ .struct_type = .surface_descriptor_from_canvas_html_selector, .next = null }, + .selector = src.selector, + }; + break :blk instance.createSurface(.{ + .next_in_chain = @as(*const wgpu.ChainedStruct, @ptrCast(&desc)), + .label = if (src.label) |l| l else null, + }); + }, + }; +} + +const objc = struct { + const SEL = ?*opaque {}; + const Class = ?*opaque {}; + + extern fn sel_getUid(str: [*:0]const u8) SEL; + extern fn objc_getClass(name: [*:0]const u8) Class; + extern fn objc_msgSend() void; +}; + +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("[zgpu] Unsupported number of args"), + }; + + const func = @as(FnType, @ptrCast(&objc.objc_msgSend)); + const sel = objc.sel_getUid(sel_name.ptr); + + return @call(.never_inline, func, .{ obj, sel } ++ args); +} + +fn logUnhandledError( + err_type: wgpu.ErrorType, + message: ?[*:0]const u8, + userdata: ?*anyopaque, +) callconv(.C) void { + _ = userdata; + switch (err_type) { + .no_error => std.log.info("[zgpu] No error: {?s}", .{message}), + .validation => std.log.err("[zgpu] Validation: {?s}", .{message}), + .out_of_memory => std.log.err("[zgpu] Out of memory: {?s}", .{message}), + .device_lost => std.log.err("[zgpu] Device lost: {?s}", .{message}), + .internal => std.log.err("[zgpu] Internal error: {?s}", .{message}), + .unknown => std.log.err("[zgpu] Unknown error: {?s}", .{message}), + } + + // Exit the process for easier debugging. + if (@import("builtin").mode == .Debug) + std.process.exit(1); +} + +fn handleToGpuResourceType(comptime T: type) type { + return switch (T) { + BufferHandle => wgpu.Buffer, + TextureHandle => wgpu.Texture, + TextureViewHandle => wgpu.TextureView, + SamplerHandle => wgpu.Sampler, + RenderPipelineHandle => wgpu.RenderPipeline, + ComputePipelineHandle => wgpu.ComputePipeline, + BindGroupHandle => wgpu.BindGroup, + BindGroupLayoutHandle => wgpu.BindGroupLayout, + PipelineLayoutHandle => wgpu.PipelineLayout, + else => @compileError("[zgpu] handleToGpuResourceType() not implemented for " ++ @typeName(T)), + }; +} + +fn handleToResourceInfoType(comptime T: type) type { + return switch (T) { + BufferHandle => BufferInfo, + TextureHandle => TextureInfo, + TextureViewHandle => TextureViewInfo, + SamplerHandle => SamplerInfo, + RenderPipelineHandle => RenderPipelineInfo, + ComputePipelineHandle => ComputePipelineInfo, + BindGroupHandle => BindGroupInfo, + BindGroupLayoutHandle => BindGroupLayoutInfo, + PipelineLayoutHandle => PipelineLayoutInfo, + else => @compileError("[zgpu] handleToResourceInfoType() not implemented for " ++ @typeName(T)), + }; +} + +fn formatToShaderFormat(format: wgpu.TextureFormat) []const u8 { + // TODO: Add missing formats. + return switch (format) { + .rgba8_unorm => "rgba8unorm", + .rgba8_snorm => "rgba8snorm", + .rgba16_float => "rgba16float", + .rgba32_float => "rgba32float", + else => unreachable, + }; +} + +usingnamespace if (emscripten) struct { + // Missing symbols + var wgpuDeviceTickWarnPrinted: bool = false; + pub export fn wgpuDeviceTick() void { + if (!wgpuDeviceTickWarnPrinted) { + std.log.warn("wgpuDeviceTick(): this fn should be avoided! RequestAnimationFrame() is advised for smooth rendering in browser.", .{}); + wgpuDeviceTickWarnPrinted = true; + } + emscripten_sleep(1); + } +} else struct {}; diff --git a/vendor/zpool/LICENSE b/vendor/zpool/LICENSE new file mode 100644 index 0000000..38f2b34 --- /dev/null +++ b/vendor/zpool/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 zig-gamedev contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/zpool/README.md b/vendor/zpool/README.md new file mode 100644 index 0000000..c261dca --- /dev/null +++ b/vendor/zpool/README.md @@ -0,0 +1,96 @@ +# [zpool](https://github.com/zig-gamedev/zpool) + +Generic pool & handle implementation for Zig. Based on [Andre Weissflog's "Handles Are The Better Pointers"](https://floooh.github.io/2018/06/17/handles-vs-pointers.html). + +Exposing API resources using pools and handles is a common way to avoid exposing +implementation details to calling code and providing some insulation against +stale references in data structures maintained by the caller. + +When the caller is provided a handle instead of an opaque pointer, the API +implementation is free to move resources around, replace them, and even discard +them. + +```zig +Pool(index_bits: u8, cycle_bits: u8, TResource: type, TColumns: type) +Handle(index_bits: u8, cycle_bits: u8, TResource: type) +``` + +The generic `Pool` type has configurable bit distribution for the +`Handle`'s `index`/`cycle` fields, and supports multiple columns of data to +be indexed by a handle, using `std.MultiArrayList` to store all of the pool +data in a single memory allocation. The `TResource` parameter ensures the pool +and handle types can be distinct types even when other parameters are the same. + +## Getting started + +Example `build.zig`: + +```zig +pub fn build(b: *std.Build) void { + const exe = b.addExecutable(.{ ... }); + + const zpool = b.dependency("zpool", .{}); + exe.root_module.addImport("zpool", zpool.module("root")); +} +``` + +Now in your code you may import and use `zpool`: + +```zig +const Pool = @import("zpool").Pool; + +const ImagePtr = graphics.Image; +const ImageInfo = graphics.ImageInfo; + +pub const ImagePool = Pool(16, 16, ImagePtr, struct { + ptr: ImagePtr, + info: ImageInfo, +}); +pub const ImageHandle = ImagePool.Handle; +``` + +```zig +var imagePool = ImagePool.initMaxCapacity(allocator); +defer pool.deinit(); +``` + +```zig +pub fn acquireImage(info: ImageInfo) !ImageHandle { + const handle : ImageHandle = try imagePool.add(.{ + .ptr = graphics.createImage(info), + .info = info, + }); + return handle; +} + +pub fn drawImage(handle: ImageHandle) !void { + // get the stored ImagePtr + const ptr : ImagePtr = try imagePool.getColumn(handle, .ptr); + graphics.drawImage(ptr); +} + +pub fn resizeImage(handle: ImageHandle, width: u16, height: u16) !void { + // get a pointer to the stored ImageInfo + const info : *ImageInfo = try imagePool.getColumnPtr(handle, .info); + const old_width = info.width; + const old_height = info.height; + const old_pixels = // allocate memory to store old pixels + + // get the stored ImagePtr + const ptr = try imagePool.getColumn(handle, .ptr); + graphics.readPixels(ptr, old_pixels); + + const new_pixels = // allocate memory to store new pixels + + super_eagle.resizeImage( + old_width, old_height, old_pixels, + new_width, new_height, new_pixels); + + graphics.writePixels(ptr, new_width, new_height, new_pixels); + + // update the stored ImageInfo + info.width = new_width; + info.height = new_height; +} + +``` diff --git a/vendor/zpool/build.zig b/vendor/zpool/build.zig new file mode 100644 index 0000000..c5193be --- /dev/null +++ b/vendor/zpool/build.zig @@ -0,0 +1,22 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const optimize = b.standardOptimizeOption(.{}); + const target = b.standardTargetOptions(.{}); + + _ = b.addModule("root", .{ + .root_source_file = b.path("src/main.zig"), + }); + + const test_step = b.step("test", "Run zpool tests"); + + const tests = b.addTest(.{ + .name = "zpool-tests", + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + b.installArtifact(tests); + + test_step.dependOn(&b.addRunArtifact(tests).step); +} diff --git a/vendor/zpool/build.zig.zon b/vendor/zpool/build.zig.zon new file mode 100644 index 0000000..80d641e --- /dev/null +++ b/vendor/zpool/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = "zpool", + .version = "0.11.0-dev", + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + "README.md", + "LICENSE", + }, +} diff --git a/vendor/zpool/src/embedded_ring_queue.zig b/vendor/zpool/src/embedded_ring_queue.zig new file mode 100644 index 0000000..93bae47 --- /dev/null +++ b/vendor/zpool/src/embedded_ring_queue.zig @@ -0,0 +1,174 @@ +const std = @import("std"); + +pub fn EmbeddedRingQueue(comptime TElement: type) type { + const assert = std.debug.assert; + + return struct { + const Self = @This(); + + pub const Error = error{ + Empty, + Full, + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub const Element = TElement; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + head: usize = 0, + tail: usize = 0, + storage: []Element = &.{}, + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn init(buffer: []Element) Self { + return .{ .storage = buffer }; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn capacity(self: Self) usize { + return self.storage.len; + } + + pub fn len(self: Self) usize { + return self.tail -% self.head; + } + + pub fn empty(self: Self) bool { + return self.len() == 0; + } + + pub fn full(self: Self) bool { + return self.len() == self.capacity(); + } + + pub fn clear(self: *Self) void { + self.head = 0; + self.tail = 0; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn enqueue(self: *Self, value: Element) Error!void { + if (self.enqueueIfNotFull(value)) { + return; + } + return Error.Full; + } + + pub fn dequeue(self: *Self) Error!Element { + var value: Element = undefined; + if (self.dequeueIfNotEmpty(&value)) { + return value; + } + return Error.Empty; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn enqueueIfNotFull(self: *Self, value: Element) bool { + if (self.full()) { + return false; + } + self.enqueueUnchecked(value); + return true; + } + + pub fn dequeueIfNotEmpty(self: *Self, value: *Element) bool { + if (self.empty()) { + return false; + } + self.dequeueUnchecked(value); + return true; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn enqueueAssumeNotFull(self: *Self, value: Element) void { + assert(!self.full()); + self.enqueueUnchecked(value); + } + + pub fn dequeueAssumeNotEmpty(self: *Self) Element { + assert(!self.empty()); + var value: Element = undefined; + self.dequeueUnchecked(&value); + return value; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub fn enqueueUnchecked(self: *Self, value: Element) void { + const tail_index = self.tail % self.storage.len; + self.storage[tail_index] = value; + self.tail +%= 1; + } + + pub fn dequeueUnchecked(self: *Self, value: *Element) void { + const head_index = self.head % self.storage.len; + value.* = self.storage[head_index]; + self.head +%= 1; + } + }; +} + +//------------------------------------------------------------------------------ + +const expectEqual = std.testing.expectEqual; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "EmbeddedRingQueue basics" { + var buffer: [16]usize = undefined; + var queue = EmbeddedRingQueue(usize).init(buffer[0..]); + + try expectEqual(buffer.len, queue.capacity()); + try expectEqual(@as(usize, 0), queue.len()); + try expectEqual(true, queue.empty()); + try expectEqual(false, queue.full()); + + for (buffer, 0..) |_, i| { + try expectEqual(i, queue.len()); + try queue.enqueue(i); + try expectEqual(i, buffer[i]); + } + + try expectEqual(buffer.len, queue.capacity()); + try expectEqual(buffer.len, queue.len()); + try expectEqual(false, queue.empty()); + try expectEqual(true, queue.full()); + + for (buffer, 0..) |_, i| { + try expectEqual(buffer.len - i, queue.len()); + const j = try queue.dequeue(); + try expectEqual(i, j); + } + + try expectEqual(buffer.len, queue.capacity()); + try expectEqual(@as(usize, 0), queue.len()); + try expectEqual(true, queue.empty()); + try expectEqual(false, queue.full()); + + for (buffer, 0..) |_, i| { + try expectEqual(i, queue.len()); + try queue.enqueue(i); + try expectEqual(i, buffer[i]); + } + + try expectEqual(buffer.len, queue.capacity()); + try expectEqual(buffer.len, queue.len()); + try expectEqual(false, queue.empty()); + try expectEqual(true, queue.full()); + + queue.clear(); + + try expectEqual(buffer.len, queue.capacity()); + try expectEqual(@as(usize, 0), queue.len()); + try expectEqual(true, queue.empty()); + try expectEqual(false, queue.full()); +} + +//------------------------------------------------------------------------------ diff --git a/vendor/zpool/src/handle.zig b/vendor/zpool/src/handle.zig new file mode 100644 index 0000000..bb30b32 --- /dev/null +++ b/vendor/zpool/src/handle.zig @@ -0,0 +1,278 @@ +const std = @import("std"); + +/// Returns a struct consisting of an array `index` and a semi-unique `cycle`, +/// which exists to distinguish handles with the same array `index`. +/// +/// The `cycle` value is only unique within the incremental period of an +/// unsigned integer with `cycle_bits`, so a larger number of `cycle_bits` +/// provides a larger scope of identifiable conflicts between handles for the +/// same `index`. +/// +/// `Handle` is generic because while the `{ index, cycle }` pattern is widely +/// applicable, a good distribution of bits between `index` and `cycle` and the +/// overall size of a handle are highly dependent on the lifecycle of the +/// resource being identified by a handle and the systems consuming handles. +/// +/// Reasonable values for `index_bits` depend on the maximum number of +/// uniquely identifiable resources your API will to identify with handles. +/// Generally this is directly tied to the length of the array(s) in which +/// you will store data to be referenced by a handle's `index`. +/// +/// Reasonable values for `cycle_bits` depend on the frequency with which your +/// API expects to be issuing handles, and how many cycles of your application +/// are likely to elapse before an expired handle will likely no longer be +/// retained by the API caller's data structures. +/// +/// For example, a `Handle(16, 16)` may be sufficient for a GPU resource like +/// a texture or buffer, where 64k instances of that resource is a reasonable +/// upper bound. +/// +/// A `Handle(22, 10)` may be more appropriate to identify an entity in a +/// system where we can safely assume that 4 million entities, is a lot, and +/// that API callers can discover and discard expired entity handles within +/// 1024 frames of an entity being destroyed and its handle's `index` being +/// reissued for use by a distinct entity. +/// +/// `TResource` identifies type of resource referenced by a handle, and +/// provides a type-safe distinction between two otherwise equivalently +/// configured `Handle` types, such as: +/// * `const BufferHandle = Handle(16, 16, Buffer);` +/// * `const TextureHandle = Handle(16, 16, Texture);` +/// +/// The total size of a handle will always be the size of an addressable +/// unsigned integer of type `u8`, `u16`, `u32`, `u64`, `u128`, or `u256`. +pub fn Handle( + comptime index_bits: u8, + comptime cycle_bits: u8, + comptime TResource: type, +) type { + if (index_bits == 0) @compileError("index_bits must be greater than 0"); + if (cycle_bits == 0) @compileError("cycle_bits must be greater than 0"); + + const id_bits: u16 = @as(u16, index_bits) + @as(u16, cycle_bits); + const Id = switch (id_bits) { + 8 => u8, + 16 => u16, + 32 => u32, + 64 => u64, + 128 => u128, + 256 => u256, + else => @compileError("index_bits + cycle_bits must sum to exactly " ++ + "8, 16, 32, 64, 128, or 256 bits"), + }; + + const field_bits = @max(index_bits, cycle_bits); + + const utils = @import("utils.zig"); + const UInt = utils.UInt; + const AddressableUInt = utils.AddressableUInt; + + return extern struct { + const Self = @This(); + + const HandleType = Self; + const IndexType = UInt(index_bits); + const CycleType = UInt(cycle_bits); + const HandleUnion = extern union { + id: Id, + bits: packed struct { + cycle: CycleType, // least significant bits + index: IndexType, // most significant bits + }, + }; + + pub const Resource = TResource; + + pub const AddressableCycle = AddressableUInt(field_bits); + pub const AddressableIndex = AddressableUInt(field_bits); + + pub const max_cycle = ~@as(CycleType, 0); + pub const max_index = ~@as(IndexType, 0); + pub const max_count = @as(Id, max_index - 1) + 2; + + id: Id = 0, + + pub const nil = Self{ .id = 0 }; + + pub fn init(i: IndexType, c: CycleType) Self { + const u = HandleUnion{ .bits = .{ + .cycle = c, + .index = i, + } }; + return .{ .id = u.id }; + } + + pub fn cycle(self: Self) CycleType { + const u = HandleUnion{ .id = self.id }; + return u.bits.cycle; + } + + pub fn index(self: Self) IndexType { + const u = HandleUnion{ .id = self.id }; + return u.bits.index; + } + + /// Unpacks the `index` and `cycle` bit fields that comprise + /// `Handle.id` into an `AddressableHandle`, which stores + /// the `index` and `cycle` values in pointer-addressable fields. + pub fn addressable(self: Self) AddressableHandle { + const u = HandleUnion{ .id = self.id }; + return .{ + .cycle = u.bits.cycle, + .index = u.bits.index, + }; + } + + /// When you want to directly access the `index` and `cycle` of a + /// handle, first convert it to an `AddressableHandle` by calling + /// `Handle.addressable()`. + /// An `AddressableHandle` can be converted back into a "compact" + /// `Handle` by calling `AddressableHandle.compact()`. + pub const AddressableHandle = struct { + cycle: AddressableCycle = 0, + index: AddressableIndex = 0, + + /// Returns the corresponding `Handle` + pub fn handle(self: AddressableHandle) HandleType { + const u = HandleUnion{ .bits = .{ + .cycle = @as(CycleType, @intCast(self.cycle)), + .index = @as(IndexType, @intCast(self.index)), + } }; + return .{ .id = u.id }; + } + }; + + pub fn format( + self: Self, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + const n = @typeName(Resource); + const a = self.addressable(); + return writer.print("{s}[{}#{}]", .{ n, a.index, a.cycle }); + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + +test "Handle sizes and alignments" { + const expectEqual = std.testing.expectEqual; + + { + const H = Handle(4, 4, void); + try expectEqual(@sizeOf(u8), @sizeOf(H)); + try expectEqual(@alignOf(u8), @alignOf(H)); + try expectEqual(4, @bitSizeOf(H.IndexType)); + try expectEqual(4, @bitSizeOf(H.CycleType)); + try expectEqual(8, @bitSizeOf(H.AddressableIndex)); + try expectEqual(8, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u16), @sizeOf(A)); + try expectEqual(@alignOf(u8), @alignOf(A)); + } + + { + const H = Handle(6, 2, void); + try expectEqual(@sizeOf(u8), @sizeOf(H)); + try expectEqual(@alignOf(u8), @alignOf(H)); + try expectEqual(6, @bitSizeOf(H.IndexType)); + try expectEqual(2, @bitSizeOf(H.CycleType)); + try expectEqual(8, @bitSizeOf(H.AddressableIndex)); + try expectEqual(8, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u16), @sizeOf(A)); + try expectEqual(@alignOf(u8), @alignOf(A)); + } + + { + const H = Handle(8, 8, void); + try expectEqual(@sizeOf(u16), @sizeOf(H)); + try expectEqual(@alignOf(u16), @alignOf(H)); + try expectEqual(8, @bitSizeOf(H.IndexType)); + try expectEqual(8, @bitSizeOf(H.CycleType)); + try expectEqual(8, @bitSizeOf(H.AddressableIndex)); + try expectEqual(8, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u16), @sizeOf(A)); + try expectEqual(@alignOf(u8), @alignOf(A)); + } + + { + const H = Handle(12, 4, void); + try expectEqual(@sizeOf(u16), @sizeOf(H)); + try expectEqual(@alignOf(u16), @alignOf(H)); + try expectEqual(12, @bitSizeOf(H.IndexType)); + try expectEqual(4, @bitSizeOf(H.CycleType)); + try expectEqual(16, @bitSizeOf(H.AddressableIndex)); + try expectEqual(16, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u32), @sizeOf(A)); + try expectEqual(@alignOf(u16), @alignOf(A)); + } + + { + const H = Handle(16, 16, void); + try expectEqual(@sizeOf(u32), @sizeOf(H)); + try expectEqual(@alignOf(u32), @alignOf(H)); + try expectEqual(16, @bitSizeOf(H.IndexType)); + try expectEqual(16, @bitSizeOf(H.CycleType)); + try expectEqual(16, @bitSizeOf(H.AddressableIndex)); + try expectEqual(16, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u32), @sizeOf(A)); + try expectEqual(@alignOf(u16), @alignOf(A)); + } + + { + const H = Handle(22, 10, void); + try expectEqual(@sizeOf(u32), @sizeOf(H)); + try expectEqual(@alignOf(u32), @alignOf(H)); + try expectEqual(22, @bitSizeOf(H.IndexType)); + try expectEqual(10, @bitSizeOf(H.CycleType)); + try expectEqual(32, @bitSizeOf(H.AddressableIndex)); + try expectEqual(32, @bitSizeOf(H.AddressableCycle)); + + const A = H.AddressableHandle; + try expectEqual(@sizeOf(u64), @sizeOf(A)); + try expectEqual(@alignOf(u32), @alignOf(A)); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +test "Handle sort order" { + const expect = std.testing.expect; + + const handle = Handle(4, 4, void).init; + const a = handle(0, 3); + const b = handle(1, 1); + + // id order is consistent with index order, even when cycle order is not + try expect(a.id < b.id); + try expect(a.index() < b.index()); + try expect(a.cycle() > b.cycle()); +} + +//////////////////////////////////////////////////////////////////////////////// + +test "Handle.format()" { + const bufPrint = std.fmt.bufPrint; + const expectEqualStrings = std.testing.expectEqualStrings; + + const Foo = struct {}; + const H = Handle(12, 4, Foo); + const h = H.init(0, 1); + + var buffer = [_]u8{0} ** 128; + const s = try bufPrint(buffer[0..], "{}", .{h}); + try expectEqualStrings("handle.test.Handle.format().Foo[0#1]", s); +} diff --git a/vendor/zpool/src/main.zig b/vendor/zpool/src/main.zig new file mode 100644 index 0000000..9e45aa4 --- /dev/null +++ b/vendor/zpool/src/main.zig @@ -0,0 +1,8 @@ +pub const Handle = @import("handle.zig").Handle; +pub const Pool = @import("pool.zig").Pool; + +// ensure transitive closure of test coverage +comptime { + _ = Handle; + _ = Pool; +} diff --git a/vendor/zpool/src/pool.zig b/vendor/zpool/src/pool.zig new file mode 100644 index 0000000..40849af --- /dev/null +++ b/vendor/zpool/src/pool.zig @@ -0,0 +1,1430 @@ +const std = @import("std"); + +pub const PoolError = error{PoolIsFull} || HandleError; + +pub const HandleError = error{ + HandleIsUnacquired, + HandleIsOutOfBounds, + HandleIsReleased, +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/// Returns a struct that maintains a pool of data. Handles returned by +/// `Pool.add()` can be used to get/set the data in zero or more columns. +/// +/// See `handles.zig` for more information on `index_bits` and `cycle_bits`, +/// and handles in general. +/// +/// `TResource` identifies type of resource referenced by a handle, and +/// provides a type-safe distinction between two otherwise equivalently +/// configured `Handle` types, such as: +/// * `const BufferHandle = Handle(16, 16, Buffer);` +/// * `const TextureHandle = Handle(16, 16, Texture);` +/// +/// `TColumns` is a struct that defines the column names, and the element types +/// of the column arrays. +/// +/// ```zig +/// const Texture = gpu.Texture; +/// +/// const TexturePool = Pool(16, 16, Texture, struct { obj:Texture, desc:Texture.Descriptor }); +/// const TextureHandle = TexturePool.Handle; +/// +/// const GPA = std.heap.GeneralPurposeAllocator; +/// var gpa = GPA(.{}){}; +/// var pool = try TexturePool.initMaxCapacity(gpa.allocator()); +/// defer pool.deinit(); +/// +/// // creating a texture and adding it to the pool returns a handle +/// const desc : Texture.Descriptor = .{ ... }; +/// const obj = device.createTexture(desc); +/// const handle : TextureHandle = pool.add(.{ .obj = obj, .desc = desc }); +/// +/// // elsewhere, use the handle to get `obj` or `desc` as needed +/// const obj = pool.getColumn(handle, .obj); +/// const desc = pool.getColumn(handle, .desc); +/// +/// // ... +/// +/// // once the texture is no longer needed, release it. +/// _ = pool.removeIfLive(handle); +/// ``` +pub fn Pool( + comptime index_bits: u8, + comptime cycle_bits: u8, + comptime TResource: type, + comptime TColumns: type, +) type { + // Handle performs compile time checks on index_bits & cycle_bits + const ring_queue = @import("embedded_ring_queue.zig"); + const handles = @import("handle.zig"); + const utils = @import("utils.zig"); + + if (!utils.isStruct(TColumns)) @compileError("TColumns must be a struct"); + + const assert = std.debug.assert; + const meta = std.meta; + const Allocator = std.mem.Allocator; + const MultiArrayList = std.MultiArrayList; + const StructOfSlices = utils.StructOfSlices; + const RingQueue = ring_queue.EmbeddedRingQueue; + + return struct { + const Self = @This(); + + pub const Error = PoolError; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub const Resource = TResource; + pub const Handle = handles.Handle(index_bits, cycle_bits, TResource); + + pub const AddressableHandle = Handle.AddressableHandle; + pub const AddressableIndex = Handle.AddressableIndex; + pub const AddressableCycle = Handle.AddressableCycle; + + pub const max_index: usize = Handle.max_index; + pub const max_cycle: usize = Handle.max_cycle; + pub const max_capacity: usize = Handle.max_count; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + pub const Columns = TColumns; + pub const ColumnSlices = StructOfSlices(Columns); + pub const Column = meta.FieldEnum(Columns); + + pub const column_fields = meta.fields(Columns); + pub const column_count = column_fields.len; + + pub fn ColumnType(comptime column: Column) type { + return meta.fieldInfo(Columns, column).type; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + const private_fields = meta.fields(struct { + @"Pool._free_queue": AddressableIndex, + @"Pool._curr_cycle": AddressableCycle, + }); + + const Storage = MultiArrayList(@Type(.{ .@"struct" = .{ + .layout = .auto, + .fields = private_fields ++ column_fields, + .decls = &.{}, + .is_tuple = false, + } })); + + const FreeQueue = RingQueue(AddressableIndex); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + _allocator: Allocator = undefined, + _storage: Storage = .{}, + _free_queue: FreeQueue = .{}, + _curr_cycle: []AddressableCycle = &.{}, + columns: ColumnSlices = undefined, + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns an initialized `Pool` that will use `allocator` for all + /// allocations. The `Pool` stores all handles and columns in a single + /// memory allocation backed by `std.MultiArrayList`. + pub fn init(allocator: Allocator) Self { + var self = Self{ ._allocator = allocator }; + updateSlices(&self); + return self; + } + + /// Returns an initialized `Pool` that will use `allocator` for all + /// allocations, with at least `min_capacity` preallocated. + pub fn initCapacity(allocator: Allocator, min_capacity: usize) !Self { + var self = Self{ ._allocator = allocator }; + try self.reserve(min_capacity); + return self; + } + + /// Returns an initialized `Pool` that will use `allocator` for all + /// allocations, with the `Pool.max_capacity` preallocated. + pub fn initMaxCapacity(allocator: Allocator) !Self { + return initCapacity(allocator, max_capacity); + } + + /// Releases all resources assocated with an initialized pool. + pub fn deinit(self: *Self) void { + self.clear(); + self._storage.deinit(self._allocator); + self.* = .{}; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the capacity of the pool, i.e. the maximum number of handles + /// it can contain without allocating additional memory. + pub fn capacity(self: Self) usize { + return self._storage.capacity; + } + + /// Requests the capacity of the pool be at least `min_capacity`. + /// If the pool `capacity()` is already equal to or greater than + /// `min_capacity`, `reserve()` has no effect. + pub fn reserve(self: *Self, min_capacity: usize) !void { + const old_capacity = self._storage.capacity; + if (min_capacity <= old_capacity) + return; + + if (min_capacity > max_capacity) + return Error.PoolIsFull; + + try self._storage.setCapacity(self._allocator, min_capacity); + updateSlices(self); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns the number of live handles. + pub fn liveHandleCount(self: Self) usize { + return self._storage.len - self._free_queue.len(); + } + + /// Returns `true` if `handle` is live, otherwise `false`. + pub fn isLiveHandle(self: Self, handle: Handle) bool { + return self.isLiveAddressableHandle(handle.addressable()); + } + + /// Checks whether `handle` is live. + /// Unlike `std.debug.assert()`, this check is evaluated in all builds. + pub fn requireLiveHandle(self: Self, handle: Handle) HandleError!void { + try self.requireLiveAddressableHandle(handle.addressable()); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns an iterator that can enumerate each live index. + /// The iterator is invalidated by calls to `add()`. + pub fn liveIndices(self: Self) LiveIndexIterator { + return .{ .curr_cycle = self._curr_cycle }; + } + + pub const LiveIndexIterator = struct { + curr_cycle: []const AddressableCycle = &.{}, + next_index: AddressableIndex = 0, + ended: bool = false, + + pub fn next(self: *LiveIndexIterator) ?AddressableIndex { + while (!self.ended and self.next_index < self.curr_cycle.len) { + const curr_index = self.next_index; + if (curr_index < max_index) { + self.next_index += 1; + } else { + self.ended = true; + } + if (isLiveCycle(self.curr_cycle[curr_index])) + return curr_index; + } + return null; + } + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Returns an iterator that can enumerate each live handle. + /// The iterator is invalidated by calls to `add()`. + pub fn liveHandles(self: Self) LiveHandleIterator { + return .{ .live_indices = liveIndices(self) }; + } + + pub const LiveHandleIterator = struct { + live_indices: LiveIndexIterator = .{}, + + pub fn next(self: *LiveHandleIterator) ?Handle { + if (self.live_indices.next()) |index| { + const ahandle = AddressableHandle{ + .index = index, + .cycle = self.live_indices.curr_cycle[index], + }; + return ahandle.handle(); + } + return null; + } + }; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Releases all live `Handles` and calls `deinit()` on columns if + /// defined. + pub fn clear(self: *Self) void { + var ahandle = AddressableHandle{ .index = 0 }; + for (self._curr_cycle, 0..) |cycle, i| { + if (isLiveCycle(cycle)) { + ahandle.index = @as(AddressableIndex, @intCast(i)); + ahandle.cycle = cycle; + self.releaseAddressableHandleUnchecked(ahandle); + } + } + } + + /// Adds `values` and returns a live `Handle` if possible, otherwise + /// returns one of: + /// * `Error.PoolIsFull` + /// * `Allocator.Error.OutOfMemory` + pub fn add(self: *Self, values: Columns) !Handle { + const ahandle = try self.acquireAddressableHandle(); + self.initColumnsAt(ahandle.index, values); + return ahandle.handle(); + } + + /// Adds `values` and returns a live `Handle` if possible, otherwise + /// returns null. + pub fn addIfNotFull(self: *Self, values: Columns) ?Handle { + const ahandle = self.acquireAddressableHandle() catch { + return null; + }; + self.initColumnsAt(ahandle.index, values); + return ahandle.handle(); + } + + /// Adds `values` and returns a live `Handle` if possible, otherwise + /// calls `std.debug.assert(false)` and returns `Handle.nil`. + pub fn addAssumeNotFull(self: *Self, values: Columns) Handle { + const ahandle = self.acquireAddressableHandle() catch { + assert(false); + return Handle.nil; + }; + self.initColumnsAt(ahandle.index, values); + return ahandle.handle(); + } + + /// Removes (and invalidates) `handle` if live. + pub fn remove(self: *Self, handle: Handle) HandleError!void { + try self.releaseAddressableHandle(handle.addressable()); + } + + /// Removes (and invalidates) `handle` if live. + /// Returns `true` if removed, otherwise `false`. + pub fn removeIfLive(self: *Self, handle: Handle) bool { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + self.releaseAddressableHandleUnchecked(ahandle); + return true; + } + return false; + } + + /// Attempts to remove (and invalidates) `handle` assuming it is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn removeAssumeLive(self: *Self, handle: Handle) void { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + self.releaseAddressableHandleUnchecked(ahandle); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Gets a column pointer if `handle` is live. + pub fn getColumnPtr(self: Self, handle: Handle, comptime column: Column) HandleError!*ColumnType(column) { + const ahandle = handle.addressable(); + try self.requireLiveAddressableHandle(ahandle); + return self.getColumnPtrUnchecked(ahandle, column); + } + + /// Gets a column value if `handle` is live. + pub fn getColumn(self: Self, handle: Handle, comptime column: Column) HandleError!ColumnType(column) { + const ahandle = handle.addressable(); + try self.requireLiveAddressableHandle(ahandle); + return self.getColumnUnchecked(ahandle, column); + } + + /// Gets column values if `handle` is live. + pub fn getColumns(self: Self, handle: Handle) HandleError!Columns { + const ahandle = handle.addressable(); + try self.requireLiveAddressableHandle(ahandle); + return self.getColumnsUnchecked(ahandle); + } + + /// Sets a column value if `handle` is live. + pub fn setColumn(self: Self, handle: Handle, comptime column: Column, value: ColumnType(column)) HandleError!void { + const ahandle = handle.addressable(); + try self.requireLiveAddressableHandle(ahandle); + self.setColumnUnchecked(ahandle, column, value); + } + + /// Sets column values if `handle` is live. + pub fn setColumns(self: Self, handle: Handle, values: Columns) HandleError!void { + const ahandle = handle.addressable(); + try self.requireLiveAddressableHandle(ahandle); + self.setColumnsUnchecked(ahandle, values); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Gets a column pointer if `handle` is live, otherwise `null`. + pub fn getColumnPtrIfLive(self: Self, handle: Handle, comptime column: Column) ?*ColumnType(column) { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + return self.getColumnPtrUnchecked(ahandle, column); + } + return null; + } + + /// Gets a column value if `handle` is live, otherwise `null`. + pub fn getColumnIfLive(self: Self, handle: Handle, comptime column: Column) ?ColumnType(column) { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + return self.getColumnUnchecked(ahandle, column); + } + return null; + } + + /// Gets column values if `handle` is live, otherwise `null`. + pub fn getColumnsIfLive(self: Self, handle: Handle) ?Columns { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + return self.getColumnsUnchecked(ahandle); + } + return null; + } + + /// Sets a column value if `handle` is live. + /// Returns `true` if the column value was set, otherwise `false`. + pub fn setColumnIfLive(self: Self, handle: Handle, comptime column: Column, value: ColumnType(column)) bool { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + self.setColumnUnchecked(ahandle, column, value); + return true; + } + return false; + } + + /// Sets column values if `handle` is live. + /// Returns `true` if the column value was set, otherwise `false`. + pub fn setColumnsIfLive(self: Self, handle: Handle, values: Columns) bool { + const ahandle = handle.addressable(); + if (self.isLiveAddressableHandle(ahandle)) { + self.setColumnsUnchecked(ahandle, values); + return true; + } + return false; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Attempts to get a column pointer assuming `handle` is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn getColumnPtrAssumeLive(self: Self, handle: Handle, comptime column: Column) *ColumnType(column) { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + return self.getColumnPtrUnchecked(ahandle, column); + } + + /// Attempts to get a column value assuming `handle` is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn getColumnAssumeLive(self: Self, handle: Handle, comptime column: Column) ColumnType(column) { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + return self.getColumnUnchecked(ahandle, column); + } + + /// Attempts to get column values assuming `handle` is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn getColumnsAssumeLive(self: Self, handle: Handle) Columns { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + return self.getColumnsUnchecked(ahandle); + } + + /// Attempts to set a column value assuming `handle` is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn setColumnAssumeLive(self: Self, handle: Handle, comptime column: Column, value: ColumnType(column)) void { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + self.setColumnUnchecked(ahandle, column, value); + } + + /// Attempts to set column values assuming `handle` is live. + /// Liveness of `handle` is checked by `std.debug.assert()`. + pub fn setColumnsAssumeLive(self: Self, handle: Handle, values: Columns) void { + const ahandle = handle.addressable(); + assert(self.isLiveAddressableHandle(ahandle)); + self.setColumnsUnchecked(ahandle, values); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Gets a column pointer. In most cases, `getColumnPtrAssumeLive` should be used instead. + pub fn getColumnPtrUnchecked(self: Self, handle: AddressableHandle, comptime column: Column) *ColumnType(column) { + const column_field = meta.fieldInfo(Columns, column); + return &@field(self.columns, column_field.name)[handle.index]; + } + + /// Gets a column value. In most cases, `getColumnAssumeLive` should be used instead. + pub fn getColumnUnchecked(self: Self, handle: AddressableHandle, comptime column: Column) ColumnType(column) { + return self.getColumnPtrUnchecked(handle, column).*; + } + + /// Gets column values. In most cases, `getColumnsAssumeLive` should be used instead. + pub fn getColumnsUnchecked(self: Self, handle: AddressableHandle) Columns { + var values: Columns = undefined; + inline for (column_fields) |column_field| { + @field(values, column_field.name) = + @field(self.columns, column_field.name)[handle.index]; + } + return values; + } + + /// Sets a column value. In most cases, `setColumnAssumeLive` should be used instead. + pub fn setColumnUnchecked(self: Self, handle: AddressableHandle, comptime column: Column, value: ColumnType(column)) void { + const column_field = meta.fieldInfo(Columns, column); + self.deinitColumnAt(handle.index, column_field); + @field(self.columns, column_field.name)[handle.index] = value; + } + + /// Sets column values. In most cases, `setColumnsAssumeLive` should be used instead. + pub fn setColumnsUnchecked(self: Self, handle: AddressableHandle, values: Columns) void { + self.deinitColumnsAt(handle.index); + self.initColumnsAt(handle.index, values); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + const StructField = std.builtin.Type.StructField; + + fn initColumnsAt(self: Self, index: AddressableIndex, values: Columns) void { + inline for (column_fields) |column_field| { + @field(self.columns, column_field.name)[index] = + @field(values, column_field.name); + } + } + + /// Call `value.deinit()` if defined. + fn deinitColumnAt(self: Self, index: AddressableIndex, comptime column_field: StructField) void { + switch (@typeInfo(column_field.type)) { + .@"struct", .@"enum", .@"union", .@"opaque" => { + if (@hasDecl(column_field.type, "deinit")) { + @field(self.columns, column_field.name)[index].deinit(); + } + }, + else => {}, + } + } + + /// Call `values.deinit()` if defined. + fn deinitColumnsAt(self: Self, index: AddressableIndex) void { + if (@hasDecl(Columns, "deinit")) { + var values: Columns = undefined; + inline for (column_fields) |column_field| { + @field(values, column_field.name) = + @field(self.columns, column_field.name)[index]; + } + values.deinit(); + inline for (column_fields) |column_field| { + @field(self.columns, column_field.name)[index] = + @field(values, column_field.name); + } + } else { + inline for (column_fields) |column_field| { + self.deinitColumnAt(index, column_field); + } + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + fn updateSlices(self: *Self) void { + var slice = self._storage.slice(); + self._free_queue.storage = slice.items(.@"Pool._free_queue"); + self._curr_cycle = slice.items(.@"Pool._curr_cycle"); + inline for (column_fields, 0..) |column_field, i| { + const F = column_field.type; + const p = slice.ptrs[private_fields.len + i]; + const f = @as([*]F, @ptrCast(@alignCast(p))); + @field(self.columns, column_field.name) = f[0..slice.len]; + } + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + fn isLiveAddressableHandle( + self: Self, + handle: AddressableHandle, + ) bool { + if (isFreeCycle(handle.cycle)) + return false; + if (handle.index >= self._curr_cycle.len) + return false; + if (handle.cycle != self._curr_cycle[handle.index]) + return false; + return true; + } + + fn requireLiveAddressableHandle( + self: Self, + handle: AddressableHandle, + ) HandleError!void { + if (isFreeCycle(handle.cycle)) + return Error.HandleIsUnacquired; + if (handle.index >= self._curr_cycle.len) + return Error.HandleIsOutOfBounds; + if (handle.cycle != self._curr_cycle[handle.index]) + return Error.HandleIsReleased; + } + + fn acquireAddressableHandle(self: *Self) !AddressableHandle { + if (self._storage.len == max_capacity) { + return Error.PoolIsFull; + } + + var handle = AddressableHandle{}; + if (self.didGetNewHandleNoResize(&handle)) { + assert(self.isLiveAddressableHandle(handle)); + return handle; + } + + if (self.didDequeueFreeIndex(&handle.index)) { + handle.cycle = self.incrementAndReturnCycle(handle.index); + assert(self.isLiveAddressableHandle(handle)); + return handle; + } + + try self.getNewHandleAfterResize(&handle); + assert(self.isLiveAddressableHandle(handle)); + return handle; + } + + fn releaseAddressableHandle( + self: *Self, + handle: AddressableHandle, + ) !void { + try self.requireLiveAddressableHandle(handle); + self.releaseAddressableHandleUnchecked(handle); + } + + fn releaseAddressableHandleUnchecked( + self: *Self, + handle: AddressableHandle, + ) void { + self.deinitColumnsAt(handle.index); + self.incrementCycle(handle.index); + self.enqueueFreeIndex(handle.index); + } + + fn tryReleaseAddressableHandle( + self: *Self, + handle: AddressableHandle, + ) bool { + if (self.isLiveAddressableHandle(handle)) { + self.releaseAddressableHandleUnchecked(handle); + return true; + } + return false; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + /// Even cycles (least significant bit is `0`) are "free". + fn isFreeCycle(cycle: AddressableCycle) bool { + return (cycle & @as(AddressableCycle, 1)) == @as(AddressableCycle, 0); + } + + /// Odd cycles (least significant bit is `1`) are "live". + fn isLiveCycle(cycle: AddressableCycle) bool { + return (cycle & @as(AddressableCycle, 1)) == @as(AddressableCycle, 1); + } + + fn incrementCycle(self: *Self, index: AddressableIndex) void { + const new_cycle = self._curr_cycle[index] +% 1; + self._curr_cycle[index] = new_cycle; + } + + fn incrementAndReturnCycle( + self: *Self, + index: AddressableIndex, + ) AddressableCycle { + const new_cycle = self._curr_cycle[index] +% 1; + self._curr_cycle[index] = new_cycle; + return new_cycle; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + fn enqueueFreeIndex(self: *Self, index: AddressableIndex) void { + self._free_queue.enqueueAssumeNotFull(index); + } + + fn didDequeueFreeIndex(self: *Self, index: *AddressableIndex) bool { + return self._free_queue.dequeueIfNotEmpty(index); + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + fn didGetNewHandleNoResize(self: *Self, handle: *AddressableHandle) bool { + if (self._storage.len < max_capacity and + self._storage.len < self._storage.capacity) + { + const new_index = self._storage.addOneAssumeCapacity(); + updateSlices(self); + self._curr_cycle[new_index] = 1; + handle.index = @as(AddressableIndex, @intCast(new_index)); + handle.cycle = 1; + return true; + } + return false; + } + + fn getNewHandleAfterResize(self: *Self, handle: *AddressableHandle) !void { + const new_index = try self._storage.addOne(self._allocator); + updateSlices(self); + self._curr_cycle[new_index] = 1; + handle.index = @as(AddressableIndex, @intCast(new_index)); + handle.cycle = 1; + } + }; +} + +//------------------------------------------------------------------------------ + +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; +const expectError = std.testing.expectError; + +const DeinitCounter = struct { + const Self = @This(); + + counter: *u32, + + fn init(_counter: *u32) Self { + return Self{ .counter = _counter }; + } + + fn deinit(self: *Self) void { + self.counter.* += 1; + } +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.init()" { + const TestPool = Pool(8, 8, void, struct {}); + var pool = TestPool.init(std.testing.allocator); + defer pool.deinit(); +} + +test "Pool with no columns" { + const TestPool = Pool(8, 8, void, struct {}); + try expectEqual(@as(usize, 0), TestPool.column_count); + try expectEqual(@as(usize, 0), @sizeOf(TestPool.ColumnSlices)); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + const handle = try pool.add(.{}); + defer _ = pool.removeIfLive(handle); + + try pool.requireLiveHandle(handle); + try expect(pool.isLiveHandle(handle)); + try expectEqual(@as(u8, 0), handle.addressable().index); + try expectEqual(@as(u8, 1), handle.addressable().cycle); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); +} + +test "Pool with one column" { + const TestPool = Pool(8, 8, void, struct { a: u32 }); + try expectEqual(@as(usize, 1), TestPool.column_count); + try expectEqual(@sizeOf([]u32), @sizeOf(TestPool.ColumnSlices)); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + const handle = try pool.add(.{ .a = 123 }); + defer _ = pool.removeIfLive(handle); + + try pool.requireLiveHandle(handle); + try expect(pool.isLiveHandle(handle)); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); + try expectEqual(@as(u8, 0), handle.addressable().index); + try expectEqual(@as(u8, 1), handle.addressable().cycle); + + try expectEqual(@as(u32, 123), try pool.getColumn(handle, .a)); + try pool.setColumn(handle, .a, 456); + try expectEqual(@as(u32, 456), try pool.getColumn(handle, .a)); +} + +test "Pool with two columns" { + const TestPool = Pool(8, 8, void, struct { a: u32, b: u64 }); + try expectEqual(@as(usize, 2), TestPool.column_count); + try expectEqual(@sizeOf([]u32) * 2, @sizeOf(TestPool.ColumnSlices)); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + const handle = try pool.add(.{ .a = 123, .b = 456 }); + defer _ = pool.removeIfLive(handle); + + try pool.requireLiveHandle(handle); + try expect(pool.isLiveHandle(handle)); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); + try expectEqual(@as(u8, 0), handle.addressable().index); + try expectEqual(@as(u8, 1), handle.addressable().cycle); + + try expectEqual(@as(u32, 123), try pool.getColumn(handle, .a)); + try pool.setColumn(handle, .a, 456); + try expectEqual(@as(u32, 456), try pool.getColumn(handle, .a)); + + try expectEqual(@as(u64, 456), try pool.getColumn(handle, .b)); + try pool.setColumn(handle, .b, 123); + try expectEqual(@as(u64, 123), try pool.getColumn(handle, .b)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.liveHandleCount()" { + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); + + const handle1 = try pool.add(.{}); + try expectEqual(@as(usize, 2), pool.liveHandleCount()); + + try pool.remove(handle0); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); + + try pool.remove(handle1); + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle2 = try pool.add(.{}); + try expectEqual(@as(usize, 1), pool.liveHandleCount()); + + try pool.remove(handle2); + try expectEqual(@as(usize, 0), pool.liveHandleCount()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.isLiveHandle()" { + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const unacquiredHandle = TestPool.Handle.init(0, 0); + try expect(!pool.isLiveHandle(unacquiredHandle)); + + const outOfBoundsHandle = TestPool.Handle.init(1, 1); + try expect(!pool.isLiveHandle(outOfBoundsHandle)); + + const handle = try pool.add(.{}); + try expect(pool.isLiveHandle(handle)); + + try pool.remove(handle); + try expect(!pool.isLiveHandle(handle)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.requireLiveHandle()" { + const TestPool = Pool(8, 8, void, struct {}); + try expectEqual(@as(usize, 0), TestPool.column_count); + try expectEqual(@as(usize, 0), @sizeOf(TestPool.ColumnSlices)); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const unacquiredHandle = TestPool.Handle.init(0, 0); + try expectError(TestPool.Error.HandleIsUnacquired, pool.requireLiveHandle(unacquiredHandle)); + + const outOfBoundsHandle = TestPool.Handle.init(1, 1); + try expectError(TestPool.Error.HandleIsOutOfBounds, pool.requireLiveHandle(outOfBoundsHandle)); + + const handle = try pool.add(.{}); + try pool.requireLiveHandle(handle); + + try pool.remove(handle); + try expectError(TestPool.Error.HandleIsReleased, pool.requireLiveHandle(handle)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.liveIndices()" { + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + try expectEqual(@as(usize, 3), pool.liveHandleCount()); + + var live_indices = pool.liveIndices(); + try expectEqual(handle0.addressable().index, live_indices.next().?); + try expectEqual(handle1.addressable().index, live_indices.next().?); + try expectEqual(handle2.addressable().index, live_indices.next().?); + try expect(null == live_indices.next()); +} + +test "Pool.liveIndices() when full" { + // Test that iterator's internal index doesn't overflow when pool is full. + // (8,8 is the smallest size we can easily test because AddressableIndex is + // at least a u8) + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + var i: usize = 0; + while (i < 256) { + _ = try pool.add(.{}); + i += 1; + } + try expectEqual(@as(usize, 256), pool.liveHandleCount()); + + // Make sure it does correctly iterate all the way. + var j: usize = 0; + var live_indices = pool.liveIndices(); + while (live_indices.next()) |_| { + j += 1; + } + try expectEqual(@as(usize, 256), j); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.liveHandles()" { + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + try expectEqual(@as(usize, 3), pool.liveHandleCount()); + + var live_handles = pool.liveHandles(); + try expectEqual(handle0.id, live_handles.next().?.id); + try expectEqual(handle1.id, live_handles.next().?.id); + try expectEqual(handle2.id, live_handles.next().?.id); + try expect(null == live_handles.next()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.clear()" { + const TestPool = Pool(8, 8, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + try expectEqual(@as(usize, 3), pool.liveHandleCount()); + try expect(pool.isLiveHandle(handle0)); + try expect(pool.isLiveHandle(handle1)); + try expect(pool.isLiveHandle(handle2)); + + pool.clear(); + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + try expect(!pool.isLiveHandle(handle0)); + try expect(!pool.isLiveHandle(handle1)); + try expect(!pool.isLiveHandle(handle2)); +} + +test "Pool.clear() calls Columns.deinit()" { + const TestPool = Pool(2, 6, void, DeinitCounter); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + _ = try pool.add(DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 0), deinit_count); + pool.clear(); + try expectEqual(@as(u32, 1), deinit_count); +} + +test "Pool.clear() calls ColumnType.deinit()" { + const TestPool = Pool(2, 6, void, struct { a: DeinitCounter, b: DeinitCounter }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + _ = try pool.add(.{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 0), deinit_count); + pool.clear(); + try expectEqual(@as(u32, 2), deinit_count); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.add()" { + const TestPool = Pool(2, 6, void, struct {}); + try expectEqual(@sizeOf(u8), @sizeOf(TestPool.Handle)); + try expectEqual(@as(usize, 4), TestPool.max_capacity); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + const handle3 = try pool.add(.{}); + try expectEqual(@as(usize, 4), pool.liveHandleCount()); + try expect(pool.isLiveHandle(handle0)); + try expect(pool.isLiveHandle(handle1)); + try expect(pool.isLiveHandle(handle2)); + try expect(pool.isLiveHandle(handle3)); + try expectError(TestPool.Error.PoolIsFull, pool.add(.{})); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.remove()" { + const TestPool = Pool(2, 6, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + const handle3 = try pool.add(.{}); + try pool.remove(handle0); + try pool.remove(handle1); + try pool.remove(handle2); + try pool.remove(handle3); + try expectError(TestPool.Error.HandleIsReleased, pool.remove(handle0)); + try expectError(TestPool.Error.HandleIsReleased, pool.remove(handle1)); + try expectError(TestPool.Error.HandleIsReleased, pool.remove(handle2)); + try expectError(TestPool.Error.HandleIsReleased, pool.remove(handle3)); +} + +test "Pool.remove() calls Columns.deinit()" { + const TestPool = Pool(2, 6, void, DeinitCounter); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 0), deinit_count); + try pool.remove(handle); + try expectEqual(@as(u32, 1), deinit_count); +} + +test "Pool.remove() calls ColumnType.deinit()" { + const TestPool = Pool(2, 6, void, struct { a: DeinitCounter, b: DeinitCounter }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(.{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 0), deinit_count); + try pool.remove(handle); + try expectEqual(@as(u32, 2), deinit_count); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.removeIfLive()" { + const TestPool = Pool(2, 6, void, struct {}); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{}); + const handle1 = try pool.add(.{}); + const handle2 = try pool.add(.{}); + const handle3 = try pool.add(.{}); + try expect(pool.isLiveHandle(handle0)); + try expect(pool.isLiveHandle(handle1)); + try expect(pool.isLiveHandle(handle2)); + try expect(pool.isLiveHandle(handle3)); + + try expect(pool.removeIfLive(handle0)); + try expect(pool.removeIfLive(handle1)); + try expect(pool.removeIfLive(handle2)); + try expect(pool.removeIfLive(handle3)); + + try expect(!pool.isLiveHandle(handle0)); + try expect(!pool.isLiveHandle(handle1)); + try expect(!pool.isLiveHandle(handle2)); + try expect(!pool.isLiveHandle(handle3)); + + try expect(!pool.removeIfLive(handle0)); + try expect(!pool.removeIfLive(handle1)); + try expect(!pool.removeIfLive(handle2)); + try expect(!pool.removeIfLive(handle3)); +} + +test "Pool.removeIfLive() calls Columns.deinit()" { + const TestPool = Pool(2, 6, void, DeinitCounter); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 0), deinit_count); + try expect(pool.removeIfLive(handle)); + try expectEqual(@as(u32, 1), deinit_count); +} + +test "Pool.removeIfLive() calls ColumnType.deinit()" { + const TestPool = Pool(2, 6, void, struct { a: DeinitCounter, b: DeinitCounter }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(.{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 0), deinit_count); + try expect(pool.removeIfLive(handle)); + try expectEqual(@as(u32, 2), deinit_count); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.getColumnPtr*()" { + const TestPool = Pool(2, 6, void, struct { a: u32 }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{ .a = 0 }); + const handle1 = try pool.add(.{ .a = 1 }); + const handle2 = try pool.add(.{ .a = 2 }); + const handle3 = try pool.add(.{ .a = 3 }); + + const a0ptr: *u32 = try pool.getColumnPtr(handle0, .a); + const a1ptr: *u32 = try pool.getColumnPtr(handle1, .a); + const a2ptr: *u32 = try pool.getColumnPtr(handle2, .a); + const a3ptr: *u32 = try pool.getColumnPtr(handle3, .a); + try expectEqual(@as(u32, 0), a0ptr.*); + try expectEqual(@as(u32, 1), a1ptr.*); + try expectEqual(@as(u32, 2), a2ptr.*); + try expectEqual(@as(u32, 3), a3ptr.*); + try expectEqual(a0ptr, pool.getColumnPtrIfLive(handle0, .a).?); + try expectEqual(a1ptr, pool.getColumnPtrIfLive(handle1, .a).?); + try expectEqual(a2ptr, pool.getColumnPtrIfLive(handle2, .a).?); + try expectEqual(a3ptr, pool.getColumnPtrIfLive(handle3, .a).?); + try expectEqual(a0ptr, pool.getColumnPtrAssumeLive(handle0, .a)); + try expectEqual(a1ptr, pool.getColumnPtrAssumeLive(handle1, .a)); + try expectEqual(a2ptr, pool.getColumnPtrAssumeLive(handle2, .a)); + try expectEqual(a3ptr, pool.getColumnPtrAssumeLive(handle3, .a)); + + try pool.remove(handle0); + try pool.remove(handle1); + try pool.remove(handle2); + try pool.remove(handle3); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumnPtr(handle0, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumnPtr(handle1, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumnPtr(handle2, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumnPtr(handle3, .a)); + try expect(null == pool.getColumnPtrIfLive(handle0, .a)); + try expect(null == pool.getColumnPtrIfLive(handle1, .a)); + try expect(null == pool.getColumnPtrIfLive(handle2, .a)); + try expect(null == pool.getColumnPtrIfLive(handle3, .a)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.getColumn*()" { + const TestPool = Pool(2, 6, void, struct { a: u32 }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{ .a = 0 }); + const handle1 = try pool.add(.{ .a = 1 }); + const handle2 = try pool.add(.{ .a = 2 }); + const handle3 = try pool.add(.{ .a = 3 }); + + try expectEqual(@as(u32, 0), try pool.getColumn(handle0, .a)); + try expectEqual(@as(u32, 1), try pool.getColumn(handle1, .a)); + try expectEqual(@as(u32, 2), try pool.getColumn(handle2, .a)); + try expectEqual(@as(u32, 3), try pool.getColumn(handle3, .a)); + try expectEqual(@as(u32, 0), pool.getColumnIfLive(handle0, .a).?); + try expectEqual(@as(u32, 1), pool.getColumnIfLive(handle1, .a).?); + try expectEqual(@as(u32, 2), pool.getColumnIfLive(handle2, .a).?); + try expectEqual(@as(u32, 3), pool.getColumnIfLive(handle3, .a).?); + try expectEqual(@as(u32, 0), pool.getColumnAssumeLive(handle0, .a)); + try expectEqual(@as(u32, 1), pool.getColumnAssumeLive(handle1, .a)); + try expectEqual(@as(u32, 2), pool.getColumnAssumeLive(handle2, .a)); + try expectEqual(@as(u32, 3), pool.getColumnAssumeLive(handle3, .a)); + + try pool.remove(handle0); + try pool.remove(handle1); + try pool.remove(handle2); + try pool.remove(handle3); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumn(handle0, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumn(handle1, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumn(handle2, .a)); + try expectError(TestPool.Error.HandleIsReleased, pool.getColumn(handle3, .a)); + try expect(null == pool.getColumnIfLive(handle0, .a)); + try expect(null == pool.getColumnIfLive(handle1, .a)); + try expect(null == pool.getColumnIfLive(handle2, .a)); + try expect(null == pool.getColumnIfLive(handle3, .a)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.setColumn*()" { + const TestPool = Pool(2, 6, void, struct { a: u32 }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{ .a = 0 }); + const handle1 = try pool.add(.{ .a = 1 }); + const handle2 = try pool.add(.{ .a = 2 }); + const handle3 = try pool.add(.{ .a = 3 }); + + try expectEqual(@as(u32, 0), try pool.getColumn(handle0, .a)); + try expectEqual(@as(u32, 1), try pool.getColumn(handle1, .a)); + try expectEqual(@as(u32, 2), try pool.getColumn(handle2, .a)); + try expectEqual(@as(u32, 3), try pool.getColumn(handle3, .a)); + try expectEqual(@as(u32, 0), pool.getColumnIfLive(handle0, .a).?); + try expectEqual(@as(u32, 1), pool.getColumnIfLive(handle1, .a).?); + try expectEqual(@as(u32, 2), pool.getColumnIfLive(handle2, .a).?); + try expectEqual(@as(u32, 3), pool.getColumnIfLive(handle3, .a).?); + try expectEqual(@as(u32, 0), pool.getColumnAssumeLive(handle0, .a)); + try expectEqual(@as(u32, 1), pool.getColumnAssumeLive(handle1, .a)); + try expectEqual(@as(u32, 2), pool.getColumnAssumeLive(handle2, .a)); + try expectEqual(@as(u32, 3), pool.getColumnAssumeLive(handle3, .a)); + + try pool.setColumn(handle0, .a, 10); + try pool.setColumn(handle1, .a, 11); + try pool.setColumn(handle2, .a, 12); + try pool.setColumn(handle3, .a, 13); + try expect(pool.setColumnIfLive(handle0, .a, 20)); + try expect(pool.setColumnIfLive(handle1, .a, 21)); + try expect(pool.setColumnIfLive(handle2, .a, 22)); + try expect(pool.setColumnIfLive(handle3, .a, 23)); + pool.setColumnAssumeLive(handle0, .a, 30); + pool.setColumnAssumeLive(handle1, .a, 31); + pool.setColumnAssumeLive(handle2, .a, 32); + pool.setColumnAssumeLive(handle3, .a, 33); + + try expectEqual(@as(u32, 30), try pool.getColumn(handle0, .a)); + try expectEqual(@as(u32, 31), try pool.getColumn(handle1, .a)); + try expectEqual(@as(u32, 32), try pool.getColumn(handle2, .a)); + try expectEqual(@as(u32, 33), try pool.getColumn(handle3, .a)); + try expectEqual(@as(u32, 30), pool.getColumnIfLive(handle0, .a).?); + try expectEqual(@as(u32, 31), pool.getColumnIfLive(handle1, .a).?); + try expectEqual(@as(u32, 32), pool.getColumnIfLive(handle2, .a).?); + try expectEqual(@as(u32, 33), pool.getColumnIfLive(handle3, .a).?); + try expectEqual(@as(u32, 30), pool.getColumnAssumeLive(handle0, .a)); + try expectEqual(@as(u32, 31), pool.getColumnAssumeLive(handle1, .a)); + try expectEqual(@as(u32, 32), pool.getColumnAssumeLive(handle2, .a)); + try expectEqual(@as(u32, 33), pool.getColumnAssumeLive(handle3, .a)); + + try pool.remove(handle0); + try pool.remove(handle1); + try pool.remove(handle2); + try pool.remove(handle3); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumn(handle0, .a, 40)); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumn(handle1, .a, 41)); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumn(handle2, .a, 42)); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumn(handle3, .a, 43)); + try expect(!pool.setColumnIfLive(handle0, .a, 50)); + try expect(!pool.setColumnIfLive(handle1, .a, 51)); + try expect(!pool.setColumnIfLive(handle2, .a, 52)); + try expect(!pool.setColumnIfLive(handle3, .a, 53)); + + // setColumnAssumeLive() would fail an assert() +} + +test "Pool.setColumn*() calls ColumnType.deinit()" { + const TestPool = Pool(2, 6, void, struct { a: DeinitCounter, b: DeinitCounter }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(.{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 0), deinit_count); + + try pool.setColumn(handle, .a, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 1), deinit_count); + try pool.setColumn(handle, .b, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 2), deinit_count); + + try expect(pool.setColumnIfLive(handle, .a, DeinitCounter.init(&deinit_count))); + try expectEqual(@as(u32, 3), deinit_count); + try expect(pool.setColumnIfLive(handle, .b, DeinitCounter.init(&deinit_count))); + try expectEqual(@as(u32, 4), deinit_count); + + pool.setColumnAssumeLive(handle, .a, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 5), deinit_count); + pool.setColumnAssumeLive(handle, .b, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 6), deinit_count); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +test "Pool.setColumns*()" { + const TestPool = Pool(2, 6, void, struct { a: u32 }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + try expectEqual(@as(usize, 0), pool.liveHandleCount()); + + const handle0 = try pool.add(.{ .a = 0 }); + const handle1 = try pool.add(.{ .a = 1 }); + const handle2 = try pool.add(.{ .a = 2 }); + const handle3 = try pool.add(.{ .a = 3 }); + + try expectEqual(@as(u32, 0), try pool.getColumn(handle0, .a)); + try expectEqual(@as(u32, 1), try pool.getColumn(handle1, .a)); + try expectEqual(@as(u32, 2), try pool.getColumn(handle2, .a)); + try expectEqual(@as(u32, 3), try pool.getColumn(handle3, .a)); + try expectEqual(@as(u32, 0), pool.getColumnIfLive(handle0, .a).?); + try expectEqual(@as(u32, 1), pool.getColumnIfLive(handle1, .a).?); + try expectEqual(@as(u32, 2), pool.getColumnIfLive(handle2, .a).?); + try expectEqual(@as(u32, 3), pool.getColumnIfLive(handle3, .a).?); + try expectEqual(@as(u32, 0), pool.getColumnAssumeLive(handle0, .a)); + try expectEqual(@as(u32, 1), pool.getColumnAssumeLive(handle1, .a)); + try expectEqual(@as(u32, 2), pool.getColumnAssumeLive(handle2, .a)); + try expectEqual(@as(u32, 3), pool.getColumnAssumeLive(handle3, .a)); + + try pool.setColumns(handle0, .{ .a = 10 }); + try pool.setColumns(handle1, .{ .a = 11 }); + try pool.setColumns(handle2, .{ .a = 12 }); + try pool.setColumns(handle3, .{ .a = 13 }); + try expect(pool.setColumnsIfLive(handle0, .{ .a = 20 })); + try expect(pool.setColumnsIfLive(handle1, .{ .a = 21 })); + try expect(pool.setColumnsIfLive(handle2, .{ .a = 22 })); + try expect(pool.setColumnsIfLive(handle3, .{ .a = 23 })); + pool.setColumnsAssumeLive(handle0, .{ .a = 30 }); + pool.setColumnsAssumeLive(handle1, .{ .a = 31 }); + pool.setColumnsAssumeLive(handle2, .{ .a = 32 }); + pool.setColumnsAssumeLive(handle3, .{ .a = 33 }); + + try expectEqual(@as(u32, 30), try pool.getColumn(handle0, .a)); + try expectEqual(@as(u32, 31), try pool.getColumn(handle1, .a)); + try expectEqual(@as(u32, 32), try pool.getColumn(handle2, .a)); + try expectEqual(@as(u32, 33), try pool.getColumn(handle3, .a)); + try expectEqual(@as(u32, 30), pool.getColumnIfLive(handle0, .a).?); + try expectEqual(@as(u32, 31), pool.getColumnIfLive(handle1, .a).?); + try expectEqual(@as(u32, 32), pool.getColumnIfLive(handle2, .a).?); + try expectEqual(@as(u32, 33), pool.getColumnIfLive(handle3, .a).?); + try expectEqual(@as(u32, 30), pool.getColumnAssumeLive(handle0, .a)); + try expectEqual(@as(u32, 31), pool.getColumnAssumeLive(handle1, .a)); + try expectEqual(@as(u32, 32), pool.getColumnAssumeLive(handle2, .a)); + try expectEqual(@as(u32, 33), pool.getColumnAssumeLive(handle3, .a)); + + try pool.remove(handle0); + try pool.remove(handle1); + try pool.remove(handle2); + try pool.remove(handle3); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumns(handle0, .{ .a = 40 })); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumns(handle1, .{ .a = 41 })); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumns(handle2, .{ .a = 42 })); + try expectError(TestPool.Error.HandleIsReleased, pool.setColumns(handle3, .{ .a = 43 })); + try expect(!pool.setColumnsIfLive(handle0, .{ .a = 50 })); + try expect(!pool.setColumnsIfLive(handle1, .{ .a = 51 })); + try expect(!pool.setColumnsIfLive(handle2, .{ .a = 52 })); + try expect(!pool.setColumnsIfLive(handle3, .{ .a = 53 })); + + // setColumnsAssumeLive() would fail an assert() +} + +test "Pool.setColumns() calls Columns.deinit()" { + const TestPool = Pool(2, 6, void, DeinitCounter); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 0), deinit_count); + + try pool.setColumns(handle, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 1), deinit_count); + + try expect(pool.setColumnsIfLive(handle, DeinitCounter.init(&deinit_count))); + try expectEqual(@as(u32, 2), deinit_count); + + pool.setColumnsAssumeLive(handle, DeinitCounter.init(&deinit_count)); + try expectEqual(@as(u32, 3), deinit_count); +} + +test "Pool.setColumns() calls ColumnType.deinit()" { + const TestPool = Pool(2, 6, void, struct { a: DeinitCounter, b: DeinitCounter }); + + var pool = try TestPool.initMaxCapacity(std.testing.allocator); + defer pool.deinit(); + + var deinit_count: u32 = 0; + const handle = try pool.add(.{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 0), deinit_count); + + try pool.setColumns(handle, .{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 2), deinit_count); + + try expect(pool.setColumnsIfLive(handle, .{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + })); + try expectEqual(@as(u32, 4), deinit_count); + + pool.setColumnsAssumeLive(handle, .{ + .a = DeinitCounter.init(&deinit_count), + .b = DeinitCounter.init(&deinit_count), + }); + try expectEqual(@as(u32, 6), deinit_count); +} + +//------------------------------------------------------------------------------ diff --git a/vendor/zpool/src/utils.zig b/vendor/zpool/src/utils.zig new file mode 100644 index 0000000..a1708e9 --- /dev/null +++ b/vendor/zpool/src/utils.zig @@ -0,0 +1,106 @@ +const std = @import("std"); + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +pub fn asTypeId(comptime typeInfo: std.builtin.Type) std.builtin.TypeId { + return @as(std.builtin.TypeId, typeInfo); +} + +pub fn typeIdOf(comptime T: type) std.builtin.TypeId { + return asTypeId(@typeInfo(T)); +} + +pub fn isStruct(comptime T: type) bool { + return typeIdOf(T) == std.builtin.TypeId.@"struct"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/// UInt(bits) returns an unsigned integer type of the requested bit width. +pub fn UInt(comptime bits: u8) type { + const unsigned = std.builtin.Signedness.unsigned; + return @Type(.{ .int = .{ .signedness = unsigned, .bits = bits } }); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/// Returns an unsigned integer type with ***at least*** `min_bits`, +/// that is also large enough to be addressable by a normal pointer. +/// The returned type will always be one of the following: +/// * `u8` +/// * `u16` +/// * `u32` +/// * `u64` +/// * `u128` +/// * `u256` +pub fn AddressableUInt(comptime min_bits: u8) type { + return switch (min_bits) { + 0...8 => u8, + 9...16 => u16, + 17...32 => u32, + 33...64 => u64, + 65...128 => u128, + 129...255 => u256, + }; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/// Given: `Struct = struct { foo: u32, bar: u64 }` +/// Returns: `StructOfSlices = struct { foo: []u32, bar: []u64 }` +pub fn StructOfSlices(comptime Struct: type) type { + const StructField = std.builtin.Type.StructField; + + // same number of fields in the new struct + const struct_fields = @typeInfo(Struct).@"struct".fields; + + comptime var struct_of_slices_fields: []const StructField = &.{}; + inline for (struct_fields) |struct_field| { + // u32 -> []u32 + const element_type = struct_field.type; + + const slice_type_info = std.builtin.Type{ + .pointer = .{ + .child = element_type, + .alignment = @alignOf(element_type), + .size = .slice, + .is_const = false, + .is_volatile = false, + .address_space = .generic, + .is_allowzero = false, + .sentinel_ptr = null, + }, + }; + + const FieldType = @Type(slice_type_info); + + // Struct.foo: u32 -> StructOfSlices.foo : []u32 + const slice_field = std.builtin.Type.StructField{ + .name = struct_field.name, + .type = FieldType, + .default_value_ptr = null, + .is_comptime = false, + .alignment = @alignOf(FieldType), + }; + + // Struct.foo: u32 -> StructOfSlices.foo : []u32 + struct_of_slices_fields = struct_of_slices_fields ++ [1]StructField{slice_field}; + } + + return @Type(.{ .@"struct" = .{ + .layout = .auto, + .fields = struct_of_slices_fields, + .decls = &.{}, + .is_tuple = false, + } }); +} + +test "StructOfSlices" { + const expectEqual = std.testing.expectEqual; + + const Struct = struct { a: u16, b: u16, c: u16 }; + try expectEqual(@sizeOf(u16) * 3, @sizeOf(Struct)); + + const SOS = StructOfSlices(Struct); + try expectEqual(@sizeOf([]u16) * 3, @sizeOf(SOS)); +}