11 Commits

Author SHA1 Message Date
Robin Voetter
2ccb04a619 Merge pull request #57 from ashpil/zig-stage1-compat
Update stage1 branch
2022-10-06 20:25:24 +02:00
Robin Voetter
c42f540ce3 fix alignment for shader binary 2022-10-05 18:58:29 -04:00
Robin Voetter
33a137a0dd CI: Bump Vulkan SDK version 2022-10-05 18:58:23 -04:00
Robin Voetter
889d84a5db remove unused unused variables 2022-10-05 18:58:01 -04:00
Robin Voetter
84def477bf Merge pull request #53 from Avokadoen/zig-stage1-compat
fix compile errors on stage1
2022-09-01 22:13:45 +02:00
avokadoen
8e45eff185 fix compile errors on stage1 2022-09-01 14:01:34 +02:00
Robin Voetter
445f3e6b7a update generator out path in readme 2022-08-20 12:32:11 +02:00
Robin Voetter
2d76a88a46 clean up ShaderCompileStep.make 2022-08-20 12:32:11 +02:00
Robin Voetter
efa1a714a8 Merge pull request #50 from viviicat/multi-entrypoints
Add support for multiple entrypoints, specifying stage, and a custom output file for shader compilation
2022-08-20 12:32:11 +02:00
Robin Voetter
fe786c1be7 ci: test stage 1 builds 2022-08-20 12:32:10 +02:00
Robin Voetter
ea6cfb9073 elaborate on stage 1 compatibility 2022-08-20 11:39:09 +02:00
10 changed files with 67 additions and 40 deletions

View File

@@ -2,9 +2,9 @@ name: Build
on:
push:
branches: [ master ]
branches: [ zig-stage1-compat ]
pull_request:
branches: [ master ]
branches: [ zig-stage1-compat ]
schedule:
- cron: '0 6 * * *'
@@ -22,12 +22,12 @@ jobs:
- name: Test
run: |
zig build test
zig build -fstage1 test
- name: Fetch Vulkan SDK
run: |
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.3.216-focal.list https://packages.lunarg.com/vulkan/1.3.216/lunarg-vulkan-1.3.216-focal.list
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.3.224-focal.list https://packages.lunarg.com/vulkan/1.3.224/lunarg-vulkan-1.3.224-focal.list
sudo apt update
sudo apt install shaderc libglfw3 libglfw3-dev
@@ -37,7 +37,7 @@ jobs:
- name: Build with latest zig & vk.xml
run: |
zig build -Dvulkan-registry=./vk.xml
zig build -fstage1 -Dvulkan-registry=./vk.xml
- name: Archive vk.xml
uses: actions/upload-artifact@v2

View File

@@ -14,11 +14,13 @@ vulkan-zig is automatically tested daily against the latest vk.xml and zig, and
vulkan-zig aims to be always compatible with the ever-changing Zig master branch (however, development may lag a few days behind). Sometimes, the Zig master branch breaks a bunch of functionality however, which may make the latest version vulkan-zig incompatible with older releases of Zig. This repository aims to have a version compatible for both the latest Zig master, and the latest Zig release. The `master` branch is compatible with the `master` branch of Zig, and versions for older versions of Zig are maintained in the `zig-<version>-compat` branch.
This branch (zig-stage1-compat) is compatible with the Zig stage 1 compiler.
## Features
### CLI-interface
A CLI-interface is provided to generate vk.zig from the [Vulkan XML registry](https://github.com/KhronosGroup/Vulkan-Docs/blob/main/xml), which is built by default when invoking `zig build` in the project root. To generate vk.zig, simply invoke the program as follows:
```
$ zig-cache/bin/vulkan-zig-generator path/to/vk.xml output/path/to/vk.zig
$ zig-out/bin/vulkan-zig-generator path/to/vk.xml output/path/to/vk.zig
```
This reads the xml file, parses its contents, renders the Vulkan bindings, and formats file, before writing the result to the output path. While the intended usage of vulkan-zig is through direct generation from build.zig (see below), the CLI-interface can be used for one-off generation and vendoring the result.

View File

@@ -56,12 +56,12 @@ pub const ResourceGenStep = struct {
}
pub fn addShader(self: *ResourceGenStep, name: []const u8, source: []const u8) void {
const shader_out_path = self.shader_step.add(source);
const shader_out_path = self.shader_step.add(source, .{});
var writer = self.resources.writer();
writer.print("pub const {s} = @embedFile(\"", .{name}) catch unreachable;
writer.print("pub const {s} align(@alignOf(u32)) = @embedFile(\"", .{name}) catch unreachable;
renderPath(shader_out_path, writer);
writer.writeAll("\");\n") catch unreachable;
writer.writeAll("\").*;\n") catch unreachable;
}
fn make(step: *Step) !void {

View File

@@ -236,13 +236,6 @@ fn createCommandBuffers(
const cmdbufs = try allocator.alloc(vk.CommandBuffer, framebuffers.len);
errdefer allocator.free(cmdbufs);
_ = pipeline;
_ = render_pass;
_ = extent;
_ = buffer;
_ = pool;
_ = gc;
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
.command_pool = pool,
.level = .primary,
@@ -269,7 +262,6 @@ fn createCommandBuffers(
};
for (cmdbufs) |cmdbuf, i| {
_ = i;
try gc.vkd.beginCommandBuffer(cmdbuf, &.{
.flags = .{},
.p_inheritance_info = null,
@@ -387,14 +379,14 @@ fn createPipeline(
const vert = try gc.vkd.createShaderModule(gc.dev, &.{
.flags = .{},
.code_size = resources.triangle_vert.len,
.p_code = @ptrCast([*]const u32, resources.triangle_vert),
.p_code = @ptrCast([*]const u32, &resources.triangle_vert),
}, null);
defer gc.vkd.destroyShaderModule(gc.dev, vert, null);
const frag = try gc.vkd.createShaderModule(gc.dev, &.{
.flags = .{},
.code_size = resources.triangle_frag.len,
.p_code = @ptrCast([*]const u32, resources.triangle_frag),
.p_code = @ptrCast([*]const u32, &resources.triangle_frag),
}, null);
defer gc.vkd.destroyShaderModule(gc.dev, frag, null);

View File

@@ -3,10 +3,27 @@ const path = std.fs.path;
const Builder = std.build.Builder;
const Step = std.build.Step;
/// Stage the shader should be built for. This is passed to the -fshader-stage
/// argument when invoking glslc.
pub const ShaderStage = enum {
vertex,
fragment,
tesscontrol,
tesseval,
geometry,
compute,
};
/// Utility functionality to help with compiling shaders from build.zig.
/// Invokes glslc (or another shader compiler passed to `init`) for each shader
/// added via `addShader`.
pub const ShaderCompileStep = struct {
const AddFileParams = struct {
entry_point: ?[]const u8 = null,
stage: ?ShaderStage = null,
output_filename: ?[]const u8 = null,
};
/// Structure representing a shader to be compiled.
const Shader = struct {
/// The path to the shader, relative to the current build root.
@@ -14,6 +31,13 @@ pub const ShaderCompileStep = struct {
/// The full output path where the compiled shader binary is placed.
full_out_path: []const u8,
/// The entry point to use when compiling the shader.
entry_point: ?[]const u8,
/// The stage to use when building. If not null, this is passed to
/// the -fshader-stage argument.
stage: ?ShaderStage,
};
step: Step,
@@ -45,16 +69,15 @@ pub const ShaderCompileStep = struct {
/// Add a shader to be compiled. `src` is shader source path, relative to the project root.
/// Returns the full path where the compiled binary will be stored upon successful compilation.
/// This path can then be used to include the binary into an executable, for example by passing it
/// to @embedFile via an additional generated file.
pub fn add(self: *ShaderCompileStep, src: []const u8) []const u8 {
const output_filename = std.fmt.allocPrint(self.builder.allocator, "{s}.spv", .{ src }) catch unreachable;
/// to @embedFile via an additional generated file. `entry_point` is the entry point to pass to the compiler.
/// `stage` is an optional shader stage to pass to the compiler with the flag `-fshader-stage` when building the shader.
pub fn add(self: *ShaderCompileStep, src: []const u8, params: AddFileParams) []const u8 {
const full_out_path = path.join(self.builder.allocator, &[_][]const u8{
self.builder.build_root,
self.builder.cache_root,
self.output_dir,
output_filename,
if (params.output_filename) |out| out else std.fmt.allocPrint(self.builder.allocator, "{s}.spv", .{src}) catch unreachable,
}) catch unreachable;
self.shaders.append(.{ .source_path = src, .full_out_path = full_out_path }) catch unreachable;
self.shaders.append(.{ .source_path = src, .full_out_path = full_out_path, .entry_point = params.entry_point, .stage = params.stage }) catch unreachable;
return full_out_path;
}
@@ -63,18 +86,26 @@ pub const ShaderCompileStep = struct {
const self = @fieldParentPtr(ShaderCompileStep, "step", step);
const cwd = std.fs.cwd();
const cmd = try self.builder.allocator.alloc([]const u8, self.glslc_cmd.len + 3);
for (self.glslc_cmd) |part, i| {
cmd[i] = part;
}
cmd[cmd.len - 2] = "-o";
var cmd = std.ArrayList([]const u8).init(self.builder.allocator);
try cmd.appendSlice(self.glslc_cmd);
const base_cmd_len = cmd.items.len;
for (self.shaders.items) |shader| {
cmd.items.len = base_cmd_len;
if (shader.entry_point) |entry_point| {
try cmd.append(try std.fmt.allocPrint(self.builder.allocator, "-fentry-point={s}", .{entry_point}));
}
if (shader.stage) |stage| {
try cmd.append(try std.fmt.allocPrint(self.builder.allocator, "-fshader-stage={s}", .{@tagName(stage)}));
}
const dir = path.dirname(shader.full_out_path).?;
try cwd.makePath(dir);
cmd[cmd.len - 3] = shader.source_path;
cmd[cmd.len - 1] = shader.full_out_path;
try self.builder.spawnChild(cmd);
try cmd.appendSlice(&.{shader.source_path, "-o", shader.full_out_path});
try self.builder.spawnChild(cmd.items);
}
}
};

View File

@@ -139,7 +139,7 @@ pub const IdRenderer = struct {
self.text_cache.deinit();
}
fn renderSnake(self: *IdRenderer, screaming: bool, id: []const u8, tag: ?[]const u8) !void {
fn renderSnake(self: *IdRenderer, comptime screaming: bool, id: []const u8, tag: ?[]const u8) !void {
var it = SegmentIterator.init(id);
var first = true;
const transform = if (screaming) std.ascii.toUpper else std.ascii.toLower;

View File

@@ -1,5 +1,6 @@
pub const generateVk = @import("vulkan/generator.zig").generate;
pub const VkGenerateStep = @import("vulkan/build_integration.zig").GenerateStep;
pub const ShaderStage = @import("build_integration.zig").ShaderStage;
pub const ShaderCompileStep = @import("build_integration.zig").ShaderCompileStep;
test "main" {

View File

@@ -468,12 +468,12 @@ fn parseCommand(allocator: Allocator, elem: *xml.Element) !registry.Declaration
const return_type = try allocator.create(registry.TypeInfo);
return_type.* = command_decl.decl_type.typedef;
const success_codes = if (elem.getAttribute("successcodes")) |codes|
const success_codes: [][]const u8 = if (elem.getAttribute("successcodes")) |codes|
try splitCommaAlloc(allocator, codes)
else
&[_][]const u8{};
const error_codes = if (elem.getAttribute("errorcodes")) |codes|
const error_codes: [][]const u8 = if (elem.getAttribute("errorcodes")) |codes|
try splitCommaAlloc(allocator, codes)
else
&[_][]const u8{};

View File

@@ -1081,7 +1081,7 @@ fn Renderer(comptime WriterType: type) type {
\\ .Struct = .{{
\\ .layout = .Auto,
\\ .fields = &fields,
\\ .decls = &[_]std.builtin.TypeInfo.Declaration{{}},
\\ .decls = &[_]std.builtin.Type.Declaration{{}},
\\ .is_tuple = false,
\\ }},
\\ }});

View File

@@ -56,7 +56,8 @@ pub const Element = struct {
}
pub fn findChildByTag(self: Element, tag: []const u8) ?*Element {
return self.findChildrenByTag(tag).next();
var children = self.findChildrenByTag(tag);
return children.next();
}
pub fn findChildrenByTag(self: Element, tag: []const u8) FindChildrenByTagIterator {
@@ -435,7 +436,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
return null;
};
break :blk tag;
}
},
};
var attributes = std.ArrayList(Attribute).init(alloc);
@@ -474,7 +475,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
_ = parser.eatWs();
try parser.expect('>');
}
}
},
}
const element = try alloc.create(Element);