Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 116 additions & 32 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,87 @@ const std = @import("std");
// spirv-cross --reflect <input file>.spv --output <input file>.json
//
// 3. compile the reflect program, and invoke it on the json file.
// spirv-reflect-zig <input file>.json
//
// <input file>.zig

pub const SpirvGenerator2 = struct {
b: *std.Build,
spirv_build: *std.Build,
glslTypes: *std.Build.Module,
reflect: *std.Build.Step.Compile,

const BuildOptions = struct {
importName: []const u8 = "SpirvReflect",
optimize: std.builtin.OptimizeMode = .Debug,
};

fn initFromBuilder(b: *std.Build, spirv_build: *std.Build, opts: BuildOptions) SpirvGenerator2 {
const reflect = spirv_build.addExecutable(.{
.name = "spirv-reflect-zig",
.root_source_file = .{ .path = "src/main.zig" },
.target = spirv_build.host,
.optimize = opts.optimize,
});

return .{
.b = b,
.spirv_build = spirv_build,
.reflect = reflect,
.glslTypes = spirv_build.createModule(.{
.root_source_file = .{ .path = "src/glslTypes.zig" },
}),
};
}

pub fn init(b: *std.Build, opts: BuildOptions) SpirvGenerator2 {
const dep = b.dependency(opts.importName, .{});
return initFromBuilder(b, dep.builder, opts);
}

pub fn createShader(self: SpirvGenerator2, shaderPath: std.Build.LazyPath, shaderName: []const u8) *std.Build.Module {
const finalSpv = self.b.fmt("shaders/{s}.spv", .{shaderName});
const finalJson = self.b.fmt("shaders/{s}.spv", .{shaderName});

const shaderCompile = self.b.addSystemCommand(&[_][]const u8{"glslc"});
shaderCompile.addArg("--target-env=vulkan1.2");
shaderCompile.addFileArg(shaderPath);
shaderCompile.addArg("-o");
const spvOutputFile = shaderCompile.addOutputFileArg(finalSpv);

const jsonReflectStep = self.spirv_build.addSystemCommand(&[_][]const u8{"spirv-cross"});
jsonReflectStep.addFileArg(spvOutputFile);
jsonReflectStep.addArg("--reflect");
jsonReflectStep.addArg("--output");
const outputJson = jsonReflectStep.addOutputFileArg(finalJson);

const outputFile = self.b.fmt("reflectedTypes/{s}.zig", .{shaderName});

const run_cmd = self.b.addRunArtifact(self.reflect);

run_cmd.addFileArg(outputJson);
run_cmd.addArg("-o");
const outputZigFile = run_cmd.addOutputFileArg(outputFile);

const module = self.spirv_build.createModule(.{
.root_source_file = outputZigFile,
});

module.addImport("glslTypes", self.glslTypes);

return module;
}

// creates a shader and immediately adds it to the executable
pub fn addShader(
self: SpirvGenerator2,
module: *std.Build.Module,
shaderPath: []const u8,
shaderName: []const u8,
) void {
module.addImport(shaderName, self.createShader(.{ .path = shaderPath }, shaderName));
}
};

pub const SpirvGenerator = struct {
steps: std.ArrayList(*std.Build.Step),
Expand Down Expand Up @@ -92,7 +173,8 @@ pub const SpirvGenerator = struct {
const outputJson = jsonReflectStep.addOutputFileArg(finalJson);

var reflect = b.allocator.create(std.Build.Step) catch unreachable;
reflect.* = std.Build.Step.init(.{ .id = .custom, .name = options.output_name, .owner = b, .makeFn = make });

// reflect.* = std.Build.Step.init(.{ .id = .custom, .name = options.output_name, .owner = b, .makeFn = make });
// reflect.dependOn(&b.addInstallFile(spvOutputFile, finalSpv).step);
// reflect.dependOn(&b.addInstallFile(outputJson, finalJson).step);

Expand All @@ -114,10 +196,6 @@ pub const SpirvGenerator = struct {
};
}

fn make(_: *std.Build.Step, _: *std.Progress.Node) !void {
// just a no-op, not entirely sure how to make a custom step without
}

pub fn addShader(
self: *@This(),
options: struct {
Expand Down Expand Up @@ -207,32 +285,38 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

_ = target;
_ = optimize;

const spirvGen = SpirvGenerator2.initFromBuilder(b, b, .{});
b.installArtifact(spirvGen.reflect);

// ==== create the spirv compiler and generate both .spv files and .zig files ====
var spirvCompile = SpirvGenerator.init(b, .{
.target = target,
.optimize = optimize,
.repoPath = "src",
});

// This returns a module which contains the reflected.zig file which correct
// data layout
const test_vk = spirvCompile.shader("shaders/test_vk.vert", "test_vk", .{ .embedFile = true });
// ===============================================================================

// Create your executables as you normally would
const exe = b.addExecutable(.{
.name = "example",
.root_source_file = .{ .path = "example.zig" },
.target = target,
.optimize = optimize,
});

exe.addModule("test_vk", test_vk);
b.installArtifact(exe);

var run_step = b.step("run", "runs my program");
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());

run_step.dependOn(&run_cmd.step);
// var spirvCompile = SpirvGenerator.init(b, .{
// .target = target,
// .optimize = optimize,
// .repoPath = "src",
// });

// // This returns a module which contains the reflected.zig file which correct
// // data layout
// const test_vk = spirvCompile.shader("shaders/test_vk.vert", "test_vk", .{ .embedFile = true });
// // ===============================================================================

// // Create your executables as you normally would
// const exe = b.addExecutable(.{
// .name = "example",
// .root_source_file = .{ .path = "example.zig" },
// .target = target,
// .optimize = optimize,
// });

// exe.addModule("test_vk", test_vk);
// b.installArtifact(exe);

// var run_step = b.step("run", "runs my program");
// const run_cmd = b.addRunArtifact(exe);
// run_cmd.step.dependOn(b.getInstallStep());
// run_step.dependOn(&run_cmd.step);

}
25 changes: 25 additions & 0 deletions build_test/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const std = @import("std");

const SpirvReflect = @import("SpirvReflect");

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const spirvGen = SpirvReflect.SpirvGenerator2.init(b, .{});
b.installArtifact(spirvGen.reflect);

const test_vk = spirvGen.createShader(.{ .path = "../shaders/test_vk.vert" }, "test_vk");

const exe = b.addExecutable(.{
.name = "example",
.root_source_file = .{ .path = "main.zig" },
.target = target,
.optimize = optimize,
});

exe.root_module.addImport("test_vk", test_vk);
spirvGen.addShader(&exe.root_module, "../shaders/test_vk.vert", "test_vk2");

b.installArtifact(exe);
}
12 changes: 12 additions & 0 deletions build_test/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.{
.name = "testing",
.version = "0.0.0",

.dependencies = .{
.SpirvReflect = .{ .path = "../" },
},

.paths = .{
"",
},
}
9 changes: 9 additions & 0 deletions build_test/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const std = @import("std");
const test_vk = @import("test_vk");
const test_vk2 = @import("test_vk2");

pub fn main() !void {
std.debug.print("hello world {d}\n", .{@sizeOf(test_vk.ImageRenderData)});
std.debug.print("hello world {d}\n", .{@sizeOf(test_vk2.ImageRenderData)});
return;
}