{"id":18893214,"url":"https://github.com/zig-gamedev/zgpu","last_synced_at":"2025-06-30T09:37:35.722Z","repository":{"id":261577584,"uuid":"882838605","full_name":"zig-gamedev/zgpu","owner":"zig-gamedev","description":"Cross-platform graphics lib for Zig built on top of Dawn native WebGPU implementation.","archived":false,"fork":false,"pushed_at":"2025-05-04T18:07:51.000Z","size":97,"stargazers_count":19,"open_issues_count":6,"forks_count":14,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-04T19:20:22.004Z","etag":null,"topics":["cross-platform","dawn","gamedev","graphics","native","webgpu","zig"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zig-gamedev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-03T22:07:58.000Z","updated_at":"2025-05-04T18:07:54.000Z","dependencies_parsed_at":"2024-11-07T10:23:29.582Z","dependency_job_id":"3ad6b0bc-bb42-4e9e-a167-ef1a0ad66ca0","html_url":"https://github.com/zig-gamedev/zgpu","commit_stats":null,"previous_names":["zig-gamedev/zgpu"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zig-gamedev/zgpu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zig-gamedev%2Fzgpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zig-gamedev%2Fzgpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zig-gamedev%2Fzgpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zig-gamedev%2Fzgpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zig-gamedev","download_url":"https://codeload.github.com/zig-gamedev/zgpu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zig-gamedev%2Fzgpu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262748867,"owners_count":23358288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cross-platform","dawn","gamedev","graphics","native","webgpu","zig"],"created_at":"2024-11-08T08:12:29.634Z","updated_at":"2025-06-30T09:37:35.667Z","avatar_url":"https://github.com/zig-gamedev.png","language":"C++","funding_links":[],"categories":["Game Development \u0026 Graphics"],"sub_categories":[],"readme":"# [zgpu](https://github.com/zig-gamedev/zgpu)\n\nCross-platform graphics lib for Zig built on top of [Dawn](https://github.com/zig-gamedev/dawn) native WebGPU implementation.\n\nSupports Windows 10+ (DirectX 12), macOS 12+ (Metal) and Linux (Vulkan).\n\n## Features\n\n- Zero-overhead wgpu API bindings ([source code](https://github.com/zig-gamedev/zgpu/blob/main/src/wgpu.zig))\n- Uniform buffer pool for fast CPU-\u003eGPU transfers\n- Resource pools and handle-based GPU resources\n- Async shader compilation\n- GPU mipmap generator\n\n## Getting started\n\nExample `build.zig`:\n\n```zig\npub fn build(b: *std.Build) void {\n    const exe = b.addExecutable(.{ ... });\n\n    @import(\"zgpu\").addLibraryPathsTo(exe);\n\n    const zgpu = b.dependency(\"zgpu\", .{});\n    exe.root_module.addImport(\"zgpu\", zgpu.module(\"root\"));\n\n    if (target.result.os.tag != .emscripten) {\n      exe.linkLibrary(zgpu.artifact(\"zdawn\"));\n    }\n}\n```\n\n## Sample applications\n\n- [gui test (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/gui_test_wgpu)\n- [physically based rendering (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/physically_based_rendering_wgpu)\n- [bullet physics test (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/bullet_physics_test_wgpu)\n- [procedural mesh (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/procedural_mesh_wgpu)\n- [textured quad (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/textured_quad_wgpu)\n- [triangle (wgpu)](https://github.com/zig-gamedev/zig-gamedev/tree/main/samples/triangle_wgpu)\n\n## Library overview\n\nBelow you can find an overview of main `zgpu` features.\n\n### Compile-time options\n\nYou can override default options in your `build.zig`:\n\n```zig\npub fn build(b: *std.Build) void {\n    ...\n\n    const zgpu = @import(\"zgpu\").package(b, target, optimize, .{\n        .options = .{\n            .uniforms_buffer_size = 4 * 1024 * 1024,\n            .dawn_skip_validation = false,\n            .buffer_pool_size = 256,\n            .texture_pool_size = 256,\n            .texture_view_pool_size = 256,\n            .sampler_pool_size = 16,\n            .render_pipeline_pool_size = 128,\n            .compute_pipeline_pool_size = 128,\n            .bind_group_pool_size = 32,\n            .bind_group_layout_pool_size = 32,\n            .pipeline_layout_pool_size = 32,\n        },\n    });\n\n    zgpu.link(exe);\n\n    ...\n}\n```\n\n### Graphics Context\n\nCreate a `GraphicsContext` using a `WindowProvider`. For example, using [zglfw](https://github.com/zig-gamedev/zglfw):\n\n```zig\nconst gctx = try zgpu.GraphicsContext.create(\n    allocator,\n    .{\n        .window = window,\n        .fn_getTime = @ptrCast(\u0026zglfw.getTime),\n        .fn_getFramebufferSize = @ptrCast(\u0026zglfw.Window.getFramebufferSize),\n\n        // optional fields\n        .fn_getWin32Window = @ptrCast(\u0026zglfw.getWin32Window),\n        .fn_getX11Display = @ptrCast(\u0026zglfw.getX11Display),\n        .fn_getX11Window = @ptrCast(\u0026zglfw.getX11Window),\n        .fn_getWaylandDisplay = @ptrCast(\u0026zglfw.getWaylandDisplay),\n        .fn_getWaylandSurface = @ptrCast(\u0026zglfw.getWaylandWindow),\n        .fn_getCocoaWindow = @ptrCast(\u0026zglfw.getCocoaWindow),\n    },\n    .{}, // default context creation options\n);\n```\n\n### Uniforms\n\n- Implemented as a uniform buffer pool\n- Easy to use\n- Efficient - only one copy operation per frame\n\n```zig\nstruct DrawUniforms = extern struct {\n    object_to_world: zm.Mat,\n};\nconst mem = gctx.uniformsAllocate(DrawUniforms, 1);\nmem.slice[0] = .{ .object_to_world = zm.transpose(zm.translation(...)) };\n\npass.setBindGroup(0, bind_group, \u0026.{mem.offset});\npass.drawIndexed(...);\n\n// When you are done encoding all commands for a frame:\ngctx.submit(...); // Injects *one* copy operation to transfer *all* allocated uniforms\n```\n\n### Resource pools\n\n- Every GPU resource is identified by 32-bit integer handle\n- All resources are stored in one system\n- We keep basic info about each resource (size of the buffer, format of the texture, etc.)\n- You can always check if resource is valid (very useful for async operations)\n- System keeps basic info about resource dependencies, for example, `TextureViewHandle` knows about its\n  parent texture and becomes invalid when parent texture becomes invalid; `BindGroupHandle` knows\n  about all resources it binds so it becomes invalid if any of those resources become invalid\n\n```zig\nconst buffer_handle = gctx.createBuffer(...);\n\nif (gctx.isResourceValid(buffer_handle)) {\n    const buffer = gctx.lookupResource(buffer_handle).?;  // Returns `wgpu.Buffer`\n\n    const buffer_info = gctx.lookupResourceInfo(buffer_handle).?; // Returns `zgpu.BufferInfo`\n    std.debug.print(\"Buffer size is: {d}\", .{buffer_info.size});\n}\n\n// If you want to destroy a resource before shutting down graphics context:\ngctx.destroyResource(buffer_handle);\n\n```\n\n### Async shader compilation\n\n- Thanks to resource pools and resources identified by handles we can easily async compile all our shaders\n\n```zig\nconst DemoState = struct {\n    pipeline_handle: zgpu.PipelineLayoutHandle = .{},\n    ...\n};\nconst demo = try allocator.create(DemoState);\n\n// Below call schedules pipeline compilation and returns immediately. When compilation is complete\n// valid pipeline handle will be stored in `demo.pipeline_handle`.\ngctx.createRenderPipelineAsync(allocator, pipeline_layout, pipeline_descriptor, \u0026demo.pipeline_handle);\n\n// Pass using our pipeline will be skipped until compilation is ready\npass: {\n    const pipeline = gctx.lookupResource(demo.pipeline_handle) orelse break :pass;\n    ...\n\n    pass.setPipeline(pipeline);\n    pass.drawIndexed(...);\n}\n```\n\n### Mipmap generation on the GPU\n\n- wgpu API does not provide mipmap generator\n- zgpu provides decent mipmap generator implemented in a compute shader\n- It supports 2D textures, array textures and cubemap textures of any format\n  (`rgba8_unorm`, `rg16_float`, `rgba32_float`, etc.)\n- Currently it requires that: `texture_width == texture_height and isPowerOfTwo(texture_width)`\n- It takes ~260 microsec to generate all mips for 1024x1024 `rgba8_unorm` texture on GTX 1660\n\n```zig\n// Usage:\ngctx.generateMipmaps(arena, command_encoder, texture_handle);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzig-gamedev%2Fzgpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzig-gamedev%2Fzgpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzig-gamedev%2Fzgpu/lists"}