From 72917ccdb357ff1fa08bca2075b3692734d7f76e Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 4 Jul 2020 04:18:56 +0200 Subject: [PATCH] Shader compilation utility --- examples/shaders/test.frag | 7 ++++ generator/build-integration.zig | 54 ++++++++++++++++++++++++++ generator/vulkan/build-integration.zig | 14 +++---- 3 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 examples/shaders/test.frag create mode 100644 generator/build-integration.zig diff --git a/examples/shaders/test.frag b/examples/shaders/test.frag new file mode 100644 index 0000000..40e75e9 --- /dev/null +++ b/examples/shaders/test.frag @@ -0,0 +1,7 @@ +#version 450 + +layout(location = 0) out vec4 f_color; + +void main() { + f_color = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/generator/build-integration.zig b/generator/build-integration.zig new file mode 100644 index 0000000..d0c1a55 --- /dev/null +++ b/generator/build-integration.zig @@ -0,0 +1,54 @@ +const std = @import("std"); +const path = std.fs.path; +const Builder = std.build.Builder; +const Step = std.build.Step; + +pub const ShaderCompileStep = struct { + const Shader = struct { + source_path: []const u8, + full_out_path: []const u8, + }; + + step: Step, + builder: *Builder, + glslc_path: []const u8, + shaders: std.ArrayList(Shader), + + pub fn init(builder: *Builder, glslc_path: []const u8) *ShaderCompileStep { + const self = builder.allocator.create(ShaderCompileStep) catch unreachable; + self.* = .{ + .step = Step.init(.Custom, "shader-compile", builder.allocator, make), + .builder = builder, + .glslc_path = glslc_path, + .shaders = std.ArrayList(Shader).init(builder.allocator), + }; + return self; + } + + pub fn add(self: *ShaderCompileStep, src: []const u8) []const u8 { + const full_out_path = path.join(self.builder.allocator, &[_][]const u8{ + self.builder.build_root, + self.builder.cache_root, + "shaders", + src, + }) catch unreachable; + self.shaders.append(.{.source_path = src, .full_out_path = full_out_path}) catch unreachable; + return full_out_path; + } + + fn make(step: *Step) !void { + const self = @fieldParentPtr(ShaderCompileStep, "step", step); + const cwd = std.fs.cwd(); + + for (self.shaders.items) |shader| { + const dir = path.dirname(shader.full_out_path).?; + try cwd.makePath(dir); + try self.builder.spawnChild(&[_][]const u8{ + self.glslc_path, + shader.source_path, + "-o", + shader.full_out_path, + }); + } + } +}; diff --git a/generator/vulkan/build-integration.zig b/generator/vulkan/build-integration.zig index ce3c36a..e5408fc 100644 --- a/generator/vulkan/build-integration.zig +++ b/generator/vulkan/build-integration.zig @@ -10,16 +10,17 @@ pub const GenerateStep = struct { spec_path: []const u8, full_out_path: []const u8, - // relative_out_path is relative to builder.cache_root - pub fn init(builder: *Builder, spec_path: []const u8, relative_out_path: []const u8) *GenerateStep { + // out_path is relative to builder.cache_root + pub fn init(builder: *Builder, spec_path: []const u8, out_path: []const u8) *GenerateStep { const self = builder.allocator.create(GenerateStep) catch unreachable; self.* = .{ .step = Step.init(.Custom, "vulkan-generate", builder.allocator, make), .builder = builder, .spec_path = spec_path, .full_out_path = path.join(builder.allocator, &[_][]const u8{ + self.builder.build_root, builder.cache_root, - relative_out_path, + out_path, }) catch unreachable, }; return self; @@ -28,16 +29,15 @@ pub const GenerateStep = struct { fn make(step: *Step) !void { const self = @fieldParentPtr(GenerateStep, "step", step); const cwd = std.fs.cwd(); - var out_buffer = std.ArrayList(u8).init(self.builder.allocator); - const spec = try std.fs.cwd().readFileAlloc(self.builder.allocator, self.spec_path, std.math.maxInt(usize)); + const spec = try cwd.readFileAlloc(self.builder.allocator, self.spec_path, std.math.maxInt(usize)); try generate(self.builder.allocator, spec, out_buffer.writer()); const tree = try std.zig.parse(self.builder.allocator, out_buffer.items); const dir = path.dirname(self.full_out_path).?; - try std.fs.cwd().makePath(dir); - const output_file = std.fs.cwd().createFile(self.full_out_path, .{}) catch unreachable; + try cwd.makePath(dir); + const output_file = cwd.createFile(self.full_out_path, .{}) catch unreachable; _ = try std.zig.render(self.builder.allocator, output_file.outStream(), tree); } };