diff --git a/generator/build_integration.zig b/generator/build_integration.zig index 9b81b70..04874ad 100644 --- a/generator/build_integration.zig +++ b/generator/build_integration.zig @@ -104,7 +104,7 @@ pub const ShaderCompileStep = struct { const dir = path.dirname(shader.full_out_path).?; try cwd.makePath(dir); - try cmd.appendSlice(&.{shader.source_path, "-o", shader.full_out_path}); + try cmd.appendSlice(&.{ shader.source_path, "-o", shader.full_out_path }); try self.builder.spawnChild(cmd.items); } } diff --git a/generator/vulkan/build_integration.zig b/generator/vulkan/build_integration.zig index e0274fc..f9a2a1d 100644 --- a/generator/vulkan/build_integration.zig +++ b/generator/vulkan/build_integration.zig @@ -75,7 +75,25 @@ pub const GenerateStep = struct { const spec = try cwd.readFileAlloc(self.builder.allocator, self.spec_path, std.math.maxInt(usize)); var out_buffer = std.ArrayList(u8).init(self.builder.allocator); - try generate(self.builder.allocator, spec, out_buffer.writer()); + generate(self.builder.allocator, spec, out_buffer.writer()) catch |err| switch (err) { + error.InvalidXml => { + std.log.err("invalid vulkan registry - invalid xml", .{}); + std.log.err("please check that the correct vk.xml file is passed", .{}); + return err; + }, + error.InvalidRegistry => { + std.log.err("invalid vulkan registry - registry is valid xml but contents are invalid", .{}); + std.log.err("please check that the correct vk.xml file is passed", .{}); + return err; + }, + error.UnhandledBitfieldStruct => { + std.log.err("unhandled struct with bit fields detected in vk.xml", .{}); + std.log.err("this is a bug in vulkan-zig", .{}); + std.log.err("please make a bug report at https://github.com/Snektron/vulkan-zig/issues/", .{}); + return err; + }, + error.OutOfMemory => return error.OutOfMemory, + }; try out_buffer.append(0); const src = out_buffer.items[0 .. out_buffer.items.len - 1 :0]; diff --git a/generator/vulkan/generator.zig b/generator/vulkan/generator.zig index 39620db..b29053b 100644 --- a/generator/vulkan/generator.zig +++ b/generator/vulkan/generator.zig @@ -175,13 +175,49 @@ pub const Generator = struct { /// internal datastructures - mostly via an ArenaAllocator, but sometimes a hashmap uses this allocator /// directly. pub fn generate(allocator: Allocator, spec_xml: []const u8, writer: anytype) !void { - const spec = try xml.parse(allocator, spec_xml); + const spec = xml.parse(allocator, spec_xml) catch |err| switch (err) { + error.InvalidDocument, + error.UnexpectedEof, + error.UnexpectedCharacter, + error.IllegalCharacter, + error.InvalidEntity, + error.InvalidName, + error.InvalidStandaloneValue, + error.NonMatchingClosingTag, + error.UnclosedComment, + error.UnclosedValue, + => return error.InvalidXml, + error.OutOfMemory => return error.OutOfMemory, + }; defer spec.deinit(); - var gen = try Generator.init(allocator, spec.root); + var gen = Generator.init(allocator, spec.root) catch |err| switch (err) { + error.InvalidXml, + error.InvalidCharacter, + error.Overflow, + error.InvalidFeatureLevel, + error.InvalidSyntax, + error.InvalidTag, + error.MissingTypeIdentifier, + error.UnexpectedCharacter, + error.UnexpectedEof, + error.UnexpectedToken, + error.InvalidRegistry, + => return error.InvalidRegistry, + error.OutOfMemory => return error.OutOfMemory, + }; defer gen.deinit(); try gen.mergeEnumFields(); try gen.fixupBitFlags(); - try gen.render(writer); + gen.render(writer) catch |err| switch (err) { + error.InvalidApiConstant, + error.InvalidConstantExpr, + error.InvalidRegistry, + error.UnexpectedCharacter, + error.InvalidCharacter, + error.Overflow, + => return error.InvalidRegistry, + else => |others| return others, + }; } diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index d5b9d28..da9bb99 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -625,15 +625,85 @@ fn Renderer(comptime WriterType: type) type { } } + fn renderSpecialContainer(self: *Self, name: []const u8) !bool { + const maybe_author = self.id_renderer.getAuthorTag(name); + const basename = self.id_renderer.stripAuthorTag(name); + if (std.mem.eql(u8, basename, "VkAccelerationStructureInstance")) { + try self.writer.print( + \\extern struct {{ + \\ transform: TransformMatrix{s}, + \\ instance_custom_index_and_mask: packed struct(u32) {{ + \\ instance_custom_index: u24, + \\ mask: u8, + \\ }}, + \\ instance_shader_binding_table_record_offset_and_flags: packed struct(u32) {{ + \\ instance_shader_binding_table_record_offset: u24, + \\ flags: u8, // GeometryInstanceFlagsKHR + \\ }}, + \\ acceleration_structure_reference: u64, + \\}}; + \\ + , + .{maybe_author orelse ""}, + ); + return true; + } else if (std.mem.eql(u8, basename, "VkAccelerationStructureSRTMotionInstance")) { + try self.writer.print( + \\extern struct {{ + \\ transform_t0: SRTData{0s}, + \\ transform_t1: SRTData{0s}, + \\ instance_custom_index_and_mask: packed struct(u32) {{ + \\ instance_custom_index: u24, + \\ mask: u8, + \\ }}, + \\ instance_shader_binding_table_record_offset_and_flags: packed struct(u32) {{ + \\ instance_shader_binding_table_record_offset: u24, + \\ flags: u8, // GeometryInstanceFlagsKHR + \\ }}, + \\ acceleration_structure_reference: u64, + \\}}; + \\ + , + .{maybe_author orelse ""}, + ); + return true; + } else if (std.mem.eql(u8, basename, "VkAccelerationStructureMatrixMotionInstance")) { + try self.writer.print( + \\extern struct {{ + \\ transform_t0: TransformMatrix{0s}, + \\ transform_t1: TransformMatrix{0s}, + \\ instance_custom_index_and_mask: packed struct(u32) {{ + \\ instance_custom_index: u24, + \\ mask: u8, + \\ }}, + \\ instance_shader_binding_table_record_offset_and_flags: packed struct(u32) {{ + \\ instance_shader_binding_table_record_offset: u24, + \\ flags: u8, // GeometryInstanceFlagsKHR + \\ }}, + \\ acceleration_structure_reference: u64, + \\}}; + \\ + , + .{maybe_author orelse ""}, + ); + return true; + } + + return false; + } + fn renderContainer(self: *Self, name: []const u8, container: reg.Container) !void { try self.writer.writeAll("pub const "); try self.renderName(name); try self.writer.writeAll(" = "); + if (try self.renderSpecialContainer(name)) { + return; + } + for (container.fields) |field| { if (field.bits != null) { - try self.writer.writeAll("packed "); - break; + return error.UnhandledBitfieldStruct; } } else { try self.writer.writeAll("extern "); diff --git a/generator/xml.zig b/generator/xml.zig index a925a8f..412401c 100644 --- a/generator/xml.zig +++ b/generator/xml.zig @@ -436,7 +436,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) ! return null; }; break :blk tag; - } + }, }; var attributes = std.ArrayList(Attribute).init(alloc); @@ -475,7 +475,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) ! _ = parser.eatWs(); try parser.expect('>'); } - } + }, } const element = try alloc.create(Element);