Replace command enums with command flag structs

This commit is contained in:
InKryption
2022-06-03 03:39:32 +02:00
parent 8bf440cdf0
commit 05deff877b

View File

@@ -13,6 +13,7 @@ const preamble =
\\const std = @import("std"); \\const std = @import("std");
\\const builtin = @import("builtin"); \\const builtin = @import("builtin");
\\const root = @import("root"); \\const root = @import("root");
\\const vk = @This();
\\ \\
\\pub const vulkan_call_conv: std.builtin.CallingConvention = if (builtin.os.tag == .windows and builtin.cpu.arch == .i386) \\pub const vulkan_call_conv: std.builtin.CallingConvention = if (builtin.os.tag == .windows and builtin.cpu.arch == .i386)
\\ .Stdcall \\ .Stdcall
@@ -407,7 +408,6 @@ fn Renderer(comptime WriterType: type) type {
fn render(self: *Self) !void { fn render(self: *Self) !void {
try self.writer.writeAll(preamble); try self.writer.writeAll(preamble);
try self.renderCommandEnums();
for (self.registry.api_constants) |api_constant| { for (self.registry.api_constants) |api_constant| {
try self.renderApiConstant(api_constant); try self.renderApiConstant(api_constant);
@@ -422,90 +422,6 @@ fn Renderer(comptime WriterType: type) type {
try self.renderWrappers(); try self.renderWrappers();
} }
fn renderCommandEnums(self: *Self) !void {
try self.renderCommandEnumOfDispatchType(.base);
try self.renderCommandEnumOfDispatchType(.instance);
try self.renderCommandEnumOfDispatchType(.device);
try self.writer.writeAll("\n");
}
fn renderCommandEnumOfDispatchType(self: *Self, dispatch_type: CommandDispatchType) !void {
const dispatch_type_name = switch (dispatch_type) {
.base => "Base",
.instance => "Instance",
.device => "Device",
};
try self.writer.print("pub const {s}Command = enum {{\n", .{dispatch_type_name});
for (self.registry.decls) |decl| {
const command = switch (decl.decl_type) {
.command => |cmd| cmd,
else => continue,
};
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
try self.writer.writeAll(",\n");
}
}
{
try self.writer.print(
\\
\\pub fn symbol(self: {s}Command) [:0]const u8 {{
\\ return switch (self) {{
\\
,
.{dispatch_type_name},
);
for (self.registry.decls) |decl| {
const command = switch (decl.decl_type) {
.command => |cmd| cmd,
else => continue,
};
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
try self.writer.writeAll(".");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
try self.writer.print(" => \"{s}\",\n", .{decl.name});
}
}
try self.writer.writeAll("};\n}\n");
}
{
try self.writer.print(
\\
\\pub fn PfnType(comptime self: {s}Command) type {{
\\ return switch (self) {{
\\
,
.{dispatch_type_name},
);
for (self.registry.decls) |decl| {
const command = switch (decl.decl_type) {
.command => |cmd| cmd,
else => continue,
};
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
try self.writer.writeAll(".");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
try self.writer.writeAll(" => ");
try self.renderCommandPtrName(decl.name);
try self.writer.writeAll(",\n");
}
}
try self.writer.writeAll("};\n}\n");
}
try self.writer.writeAll("};\n");
}
fn renderApiConstant(self: *Self, api_constant: reg.ApiConstant) !void { fn renderApiConstant(self: *Self, api_constant: reg.ApiConstant) !void {
try self.writer.writeAll("pub const "); try self.writer.writeAll("pub const ");
try self.renderName(api_constant.name); try self.renderName(api_constant.name);
@@ -1020,7 +936,25 @@ fn Renderer(comptime WriterType: type) type {
}; };
try self.writer.print( try self.writer.print(
\\pub const {0s}CommandFlags = std.enums.EnumFieldStruct({0s}Command, bool, false); \\pub const {0s}CommandFlags = packed struct {{
\\
, .{name});
for (self.registry.decls) |decl| {
const command = switch (decl.decl_type) {
.command => |cmd| cmd,
else => continue,
};
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
try self.writer.writeAll(" ");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
try self.writer.writeAll(": bool = false,\n");
}
}
// TODO: Add methods for merging/intersecting/etc the flag struct here
try self.writer.writeAll("};\n");
try self.writer.print(
\\pub fn {0s}Wrapper(comptime cmds: {0s}CommandFlags) type {{ \\pub fn {0s}Wrapper(comptime cmds: {0s}CommandFlags) type {{
\\ return struct {{ \\ return struct {{
\\ dispatch: Dispatch, \\ dispatch: Dispatch,
@@ -1029,21 +963,22 @@ fn Renderer(comptime WriterType: type) type {
\\ pub const commands = cmds; \\ pub const commands = cmds;
\\ pub const Dispatch = blk: {{ \\ pub const Dispatch = blk: {{
\\ @setEvalBranchQuota(10_000); \\ @setEvalBranchQuota(10_000);
\\ const TypeInfo = std.builtin.TypeInfo; \\ const Type = std.builtin.Type;
\\ const fields_len = fields_len: {{ \\ const fields_len = fields_len: {{
\\ var fields_len = 0; \\ var fields_len = 0;
\\ for (std.meta.fieldNames({0s}Command)) |field_name| {{ \\ for (@typeInfo({0s}CommandFlags).Struct.fields) |field| {{
\\ fields_len += @boolToInt(@field(cmds, field_name)); \\ fields_len += @boolToInt(@field(cmds, field.name));
\\ }} \\ }}
\\ break :fields_len fields_len; \\ break :fields_len fields_len;
\\ }}; \\ }};
\\ var fields: [fields_len]TypeInfo.StructField = undefined; \\ var fields: [fields_len]Type.StructField = undefined;
\\ var i: usize = 0; \\ var i: usize = 0;
\\ for (std.enums.values({0s}Command)) |cmd_tag| {{ \\ for (@typeInfo({0s}CommandFlags).Struct.fields) |field| {{
\\ if (@field(cmds, @tagName(cmd_tag))) {{ \\ if (@field(cmds, field.name)) {{
\\ const PfnType = cmd_tag.PfnType(); \\ const title_case_name = [_]u8{{std.ascii.toUpper(field.name[0])}} ++ field.name[1..];
\\ const PfnType = @field(vk, "Pfn" ++ title_case_name);
\\ fields[i] = .{{ \\ fields[i] = .{{
\\ .name = cmd_tag.symbol(), \\ .name = "vk" ++ title_case_name,
\\ .field_type = PfnType, \\ .field_type = PfnType,
\\ .default_value = null, \\ .default_value = null,
\\ .is_comptime = false, \\ .is_comptime = false,
@@ -1062,7 +997,7 @@ fn Renderer(comptime WriterType: type) type {
\\ }}); \\ }});
\\ }}; \\ }};
\\ \\
, .{ name }); , .{name});
try self.renderWrapperLoader(dispatch_type); try self.renderWrapperLoader(dispatch_type);