Add special cases for bit packed structs

This commit adds special cases for AccelerationStructureInstanceKHR and
VkAccelerationStructureSRTMotionInstanceNV. These types use bit-packed
fields which are not representable in the current version of the zig
stage 2 compiler. This might change when
https://github.com/ziglang/zig/issues/13009 is resolved.

Fixes #56
This commit is contained in:
Robin Voetter
2022-10-07 00:15:04 +02:00
parent 80a201f89a
commit 09d2de4fb6
5 changed files with 133 additions and 9 deletions

View File

@@ -75,7 +75,25 @@ pub const GenerateStep = struct {
const spec = try 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));
var out_buffer = std.ArrayList(u8).init(self.builder.allocator); 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); try out_buffer.append(0);
const src = out_buffer.items[0 .. out_buffer.items.len - 1 :0]; const src = out_buffer.items[0 .. out_buffer.items.len - 1 :0];

View File

@@ -175,13 +175,49 @@ pub const Generator = struct {
/// internal datastructures - mostly via an ArenaAllocator, but sometimes a hashmap uses this allocator /// internal datastructures - mostly via an ArenaAllocator, but sometimes a hashmap uses this allocator
/// directly. /// directly.
pub fn generate(allocator: Allocator, spec_xml: []const u8, writer: anytype) !void { 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(); 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(); defer gen.deinit();
try gen.mergeEnumFields(); try gen.mergeEnumFields();
try gen.fixupBitFlags(); 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,
};
} }

View File

@@ -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 { fn renderContainer(self: *Self, name: []const u8, container: reg.Container) !void {
try self.writer.writeAll("pub const "); try self.writer.writeAll("pub const ");
try self.renderName(name); try self.renderName(name);
try self.writer.writeAll(" = "); try self.writer.writeAll(" = ");
if (try self.renderSpecialContainer(name)) {
return;
}
for (container.fields) |field| { for (container.fields) |field| {
if (field.bits != null) { if (field.bits != null) {
try self.writer.writeAll("packed "); return error.UnhandledBitfieldStruct;
break;
} }
} else { } else {
try self.writer.writeAll("extern "); try self.writer.writeAll("extern ");

View File

@@ -436,7 +436,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
return null; return null;
}; };
break :blk tag; break :blk tag;
} },
}; };
var attributes = std.ArrayList(Attribute).init(alloc); var attributes = std.ArrayList(Attribute).init(alloc);
@@ -475,7 +475,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
_ = parser.eatWs(); _ = parser.eatWs();
try parser.expect('>'); try parser.expect('>');
} }
} },
} }
const element = try alloc.create(Element); const element = try alloc.create(Element);