Skip to content

Commit

Permalink
Implement shaderc in runtime via static lib + litle hack
Browse files Browse the repository at this point in the history
  • Loading branch information
OndraVoves committed Apr 13, 2024
1 parent a5671db commit 1b8d2ba
Show file tree
Hide file tree
Showing 19 changed files with 1,006 additions and 117 deletions.
67 changes: 54 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@

When [zig](https://github.com/ziglang/zig) meets [bgfx](https://github.com/bkaradzic/bgfx).

REMEMBER: This is only zig binding for BGFX. For BGFX stuff goto [bgfx](https://github.com/bkaradzic/bgfx).
REMEMBER: This is only zig binding. For BGFX stuff goto [bgfx](https://github.com/bkaradzic/bgfx).

## Features

- [x] Zig api.
- [x] Compile as standard zig library.
- [x] `imgui` render backend. Use build option `imgui_include` to enable. ex. for zgui: `.imgui_include = zgui.path("libs").getPath(b),`
- [x] `imgui` render backend. Use build option `imgui_include` to enable. ex. for
zgui: `.imgui_include = zgui.path("libs").getPath(b),`
- [x] `shaderc` as build artifact.
- [x] Shader compile in `build.zig` to `*.bin.h`.
- [x] Shader compile in `build.zig` and embed as zig module. (this is zig equivalent of `*.bin.h`)
- [ ] WIP: Shader compile from code (in memory solution, no tmp files).
- [x] Shader compile from code (in memory solution, no tmp files).
- [ ] WIP: [DebugDraw API](https://github.com/bkaradzic/bgfx/tree/master/examples/common/debugdraw)

## Warnings

- Shader compile api for building shaders in `build.zig` is first draft and need cleanup.
- Shader compile/shaderc api is first draft and need cleanup.

## Know problems

Expand All @@ -46,20 +47,29 @@ Then in your `build.zig` add:
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{ ... });
const zbgfx = b.dependency("zbgfx", .{});
exe.root_module.addImport("zbgfx", zbgfx.module("zbgfx"));
exe.linkLibrary(zbgfx.artifact("bgfx"));
const zbgfx = b.dependency("zbgfx", .{});
exe.root_module.addImport("zbgfx", zbgfx.module("zbgfx"));
exe.linkLibrary(zbgfx.artifact("bgfx"));
// This install shaderc to install dir
// For shader build in build =D check examples
// b.installArtifact(zbgfx.artifact("shaderc"));
// This install shaderc to install dir
// For shader build in build =D check examples
// b.installArtifact(zbgfx.artifact("shaderc"));
}
```

## Usage

See examples for binding usage and [bgfx](https://github.com/bkaradzic/bgfx) for bgfx stuff.

## Build options

| Build option | Default | Description |
|-----------------------|---------|------------------------------------------------------|
| `imgui_include` | `null` | Path to ImGui includes (need for imgui bgfx backend) |
| `multithread` | `true` | Compile with BGFX_CONFIG_MULTITHREAD |
| `with_shaderc` | `true` | Compile with shaderc executable |
| `with_static_shaderc` | `true` | Compile with shaderc as static lib |

## Examples

Examples use [zig-gamedev](https://github.com/zig-gamedev/zig-gamedev) as submodule.
Expand All @@ -71,16 +81,47 @@ git submodule update --init --depth=1

### [00-Minimal](examples/00-minimal/)

Minimal setup with GLFW for window and input.

```sh
cd examples/00-minimal
zig build
zig-out/bin/minimal
```

### [01-Minimal-ZGui](examples/01-minimal-zgui/)
| Key | Description |
|-----|--------------|
| `v` | Vsync on/off |
| `d` | Debug on/off |

### [01-ZGui](examples/01-zgui/)

Minimal setup for zgui/ImGui.

```sh
cd examples/01-minimal-zgui
cd examples/01-zgui
zig build
zig-out/bin/minimal-zgui
zig-out/bin/zgui
```

| Key | Description |
|-----|--------------|
| `v` | Vsync on/off |
| `d` | Debug on/off |

### [02-Runtime shaderc](examples/02-runtime-shaderc/)

Basic usage of shader compile in runtime.
Try edit shaders in `zig-out/bin/shaders` and hit `r` to recompile.

```sh
cd examples/02-runtime-shaderc
zig build
zig-out/bin/runtime-shaderc
```

| Key | Description |
|-----|-----------------------------|
| `v` | Vsync on/off |
| `d` | Debug on/off |
| `r` | Recompile shaders form file |
180 changes: 103 additions & 77 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub fn build(b: *std.Build) !void {
const options = .{
.imgui_include = b.option([]const u8, "imgui_include", "Path to imgui (need for imgui bgfx backend)"),
.multithread = b.option(bool, "multithread", "Compile with BGFX_CONFIG_MULTITHREAD") orelse true,
.with_shaderc = b.option(bool, "with_shaderc", "Compile with shaderc") orelse true,
.with_shaderc = b.option(bool, "with_shaderc", "Compile with shaderc executable") orelse true,
.with_static_shaderc = b.option(bool, "with_static_shaderc", "Compile with shaderc as static lib") orelse true,
};

const options_step = b.addOptions();
Expand Down Expand Up @@ -110,6 +111,7 @@ pub fn build(b: *std.Build) !void {
//
// Bgfx
//
const bgfx_path = "libs/bgfx/";
const bgfx = b.addStaticLibrary(.{
.name = "bgfx",
.target = target,
Expand Down Expand Up @@ -169,7 +171,6 @@ pub fn build(b: *std.Build) !void {
//
if (options.imgui_include) |include| {
bgfx.addIncludePath(.{ .path = include });

bgfx.addCSourceFiles(.{
.flags = &cxx_options,
.files = &[_][]const u8{
Expand All @@ -187,14 +188,36 @@ pub fn build(b: *std.Build) !void {
// Shaderc
// Base steal from https://github.com/Interrupt/zig-bgfx-example/blob/main/build_shader_compiler.zig
//
var shaderc_variant = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
defer shaderc_variant.deinit();

if (options.with_shaderc) {
const bgfx_path = "libs/bgfx/";
const shaderc = b.addExecutable(.{
.name = "shaderc",
.target = target,
.optimize = optimize,
});
try shaderc_variant.append(shaderc);
}

if (options.with_static_shaderc) {
const shaderc = b.addStaticLibrary(.{
.name = "shaderc-static",
.target = target,
.optimize = optimize,
});
shaderc.defineCMacro("ZBGFX_EMBED_SHADERC", null);
shaderc.defineCMacro("bgfx", "bgfx_shader"); // Tricky&Dirty (without this is problem with duplicate symbols).
b.installArtifact(shaderc);

try shaderc_variant.append(shaderc);
}

for (shaderc_variant.items) |shaderc| {
if (shaderc.kind == .exe) {
b.installArtifact(shaderc);
}

bxInclude(shaderc, target, optimize);

shaderc.addIncludePath(.{ .path = "libs/bimg/include" });
Expand All @@ -211,77 +234,6 @@ pub fn build(b: *std.Build) !void {
shaderc.addIncludePath(.{ .path = bgfx_path ++ "3rdparty/spirv-tools/include" });
shaderc.addIncludePath(.{ .path = bgfx_path ++ "3rdparty/webgpu/include" });

const shader_includes = .{ .path = "libs/bgfx/src/" };

const fs_imgui_image_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.typee = .fragment,
.input = .{ .path = "src/imgui_impl_bgfx/fs_imgui_image.sc" },
},
.{
.bin2c = "fs_imgui_image",
.output = "src/imgui_impl_bgfx/fs_imgui_image.bin.h",
.includes = &.{shader_includes},
},
);

//
const fs_ocornut_imgui_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.typee = .fragment,
.input = .{ .path = "src/imgui_impl_bgfx/fs_ocornut_imgui.sc" },
},
.{
.bin2c = "fs_ocornut_imgui",
.output = "src/imgui_impl_bgfx/fs_ocornut_imgui.bin.h",
.includes = &.{shader_includes},
},
);

const vs_imgui_image_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.typee = .vertex,
.input = .{ .path = "src/imgui_impl_bgfx/vs_imgui_image.sc" },
},
.{
.bin2c = "vs_imgui_image",
.output = "src/imgui_impl_bgfx/vs_imgui_image.bin.h",
.includes = &.{shader_includes},
},
);

const vs_ocornut_imgui_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.typee = .vertex,
.input = .{ .path = "src/imgui_impl_bgfx/vs_ocornut_imgui.sc" },
},
.{
.bin2c = "vs_ocornut_imgui",
.output = "src/imgui_impl_bgfx/vs_ocornut_imgui.bin.h",
.includes = &.{shader_includes},
},
);
compile_imgui_shaders.dependOn(fs_imgui_image_bin_h);
compile_imgui_shaders.dependOn(fs_ocornut_imgui_bin_h);
compile_imgui_shaders.dependOn(vs_imgui_image_bin_h);
compile_imgui_shaders.dependOn(vs_ocornut_imgui_bin_h);

shaderc.addCSourceFiles(.{
.files = &.{
bgfx_path ++ "src/shader.cpp",
Expand All @@ -302,10 +254,84 @@ pub fn build(b: *std.Build) !void {
shaderc.linkFramework("CoreFoundation");
shaderc.linkFramework("Foundation");
}
shaderc.linkLibrary(bx);

shaderc.linkLibC();
shaderc.linkLibCpp();
if (shaderc.kind == .exe) {
shaderc.linkLibrary(bx);
shaderc.linkLibC();
shaderc.linkLibCpp();
}

if (shaderc.kind == .exe) {
const shader_includes = .{ .path = "shaders" };
const fs_imgui_image_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.shaderType = .fragment,
.input = .{ .path = "src/imgui_impl_bgfx/fs_imgui_image.sc" },
},
.{
.bin2c = "fs_imgui_image",
.output = "src/imgui_impl_bgfx/fs_imgui_image.bin.h",
.includes = &.{shader_includes},
},
);

//
const fs_ocornut_imgui_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.shaderType = .fragment,
.input = .{ .path = "src/imgui_impl_bgfx/fs_ocornut_imgui.sc" },
},
.{
.bin2c = "fs_ocornut_imgui",
.output = "src/imgui_impl_bgfx/fs_ocornut_imgui.bin.h",
.includes = &.{shader_includes},
},
);

const vs_imgui_image_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.shaderType = .vertex,
.input = .{ .path = "src/imgui_impl_bgfx/vs_imgui_image.sc" },
},
.{
.bin2c = "vs_imgui_image",
.output = "src/imgui_impl_bgfx/vs_imgui_image.bin.h",
.includes = &.{shader_includes},
},
);

const vs_ocornut_imgui_bin_h = try zbgfx.build.compileBasicBinH(
b,
target,
shaderc,
combine_bin_h,
.{
.shaderType = .vertex,
.input = .{ .path = "src/imgui_impl_bgfx/vs_ocornut_imgui.sc" },
},
.{
.bin2c = "vs_ocornut_imgui",
.output = "src/imgui_impl_bgfx/vs_ocornut_imgui.bin.h",
.includes = &.{shader_includes},
},
);
compile_imgui_shaders.dependOn(fs_imgui_image_bin_h);
compile_imgui_shaders.dependOn(fs_ocornut_imgui_bin_h);
compile_imgui_shaders.dependOn(vs_imgui_image_bin_h);
compile_imgui_shaders.dependOn(vs_ocornut_imgui_bin_h);
}

//
// fcpp
Expand Down
4 changes: 2 additions & 2 deletions examples/00-minimal/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn build(b: *std.Build) !void {
combine_bin_zig,
"fs_cubes.zig",
.{
.typee = .fragment,
.shaderType = .fragment,
.input = .{ .path = "src/fs_cubes.sc" },
},
.{
Expand All @@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {
combine_bin_zig,
"vs_cubes.zig",
.{
.typee = .vertex,
.shaderType = .vertex,
.input = .{ .path = "src/vs_cubes.sc" },
},
.{
Expand Down
2 changes: 1 addition & 1 deletion examples/00-minimal/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub fn main() anyerror!u8 {
bgfx.initCtor(&bgfx_init);

// This force renderer type.
// bgfx_init.type == .Vulkan
// bgfx_init.type = .Vulkan

bgfx_init.resolution.width = WIDTH;
bgfx_init.resolution.height = HEIGHT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn build(b: *std.Build) !void {
);

const exe = b.addExecutable(.{
.name = "minimal-zgui",
.name = "zgui",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
});
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn main() anyerror!u8 {
bgfx.initCtor(&bgfx_init);

// This force renderer type.
// bgfx_init.type == .Vulkan
// bgfx_init.type = .Vulkan

bgfx_init.resolution.width = WIDTH;
bgfx_init.resolution.height = HEIGHT;
Expand Down
Loading

0 comments on commit 1b8d2ba

Please sign in to comment.