Add extension function metadata for #112

This commit is contained in:
bluesillybeard
2024-04-10 17:06:43 -06:00
parent e60869528c
commit 9c45afca2e

View File

@@ -1035,13 +1035,80 @@ fn Renderer(comptime WriterType: type) type {
\\ const Info = struct { \\ const Info = struct {
\\ name: [:0]const u8, \\ name: [:0]const u8,
\\ version: u32, \\ version: u32,
\\ instance_functions: InstanceCommandFlags,
\\ device_functions: DeviceCommandFlags,
\\ }; \\ };
); );
// The commands in an extension are not pre-sorted based on if they are instance or device functions.
var instance_commands = std.ArrayList([]const u8).init(self.allocator);
defer instance_commands.deinit();
var device_commands = std.ArrayList([]const u8).init(self.allocator);
defer device_commands.deinit();
for (self.registry.extensions) |ext| { for (self.registry.extensions) |ext| {
try self.writer.writeAll("pub const "); try self.writer.writeAll("pub const ");
try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name)); try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name));
try self.writer.writeAll("= Info {\n"); try self.writer.writeAll("= Info {\n");
try self.writer.print(".name = \"{s}\", .version = {},", .{ ext.name, ext.version }); try self.writer.print(".name = \"{s}\", .version = {},", .{ ext.name, ext.version });
// collect extension functions
for(ext.requires) |require| {
for(require.commands) |command_name| {
const decl = self.resolveDeclaration(command_name) orelse continue;
// If the target type does not exist, it was likely an empty enum -
// assume spec is correct and that this was not a function alias.
const decl_type = self.resolveAlias(decl) catch continue;
const command = switch (decl_type) {
.command => |cmd| cmd,
else => continue,
};
const class = classifyCommandDispatch(command_name, command);
switch (class) {
// Vulkan extensions cannot add base functions.
.base => continue,
// TODO: some extensions have multiple separate requirements.
// For example, "VK_KHR_push_descriptor" depends on either "VK_VERSION_1_1" or "VK_KHR_descriptor_update_template",
// which causes the same function to be mentioned twice; once for each requirement.
// For now, duplicate functions are just removed,
// However in the future it might be worth exposing these separate requirements somehow.
.instance => {
var duplicate = false;
for(instance_commands.items) |cmd| {
if(std.mem.eql(u8, cmd, command_name)) {
duplicate = true;
}
}
if(!duplicate) try instance_commands.append(command_name);
},
.device => {
var duplicate = false;
for(device_commands.items) |cmd| {
if(std.mem.eql(u8, cmd, command_name)) {
duplicate = true;
}
}
if(!duplicate) try device_commands.append(command_name);
},
}
}
}
// and write them out
try self.writer.writeAll(".instance_functions = .{\n");
for(instance_commands.items) |command_name| {
try self.writer.writeAll(".");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name));
try self.writer.writeAll(" = true, \n");
}
try self.writer.writeAll("},\n");
instance_commands.clearRetainingCapacity();
try self.writer.writeAll(".device_functions = .{\n");
for(device_commands.items) |command_name| {
try self.writer.writeAll(".");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name));
try self.writer.writeAll(" = true, \n");
}
try self.writer.writeAll("},\n");
device_commands.clearRetainingCapacity();
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");
} }
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");