proxy wrappers: strip queue and cmd from QueueProxy and CommandBufferProxy functions

This commit is contained in:
Robin Voetter
2024-04-29 20:26:45 +02:00
parent 1260c86f60
commit 8694a69697

View File

@@ -173,9 +173,22 @@ const dispatchable_handles = std.StaticStringMap(CommandDispatchType).initCompti
.{ "VkInstance", .instance }, .{ "VkInstance", .instance },
}); });
const additional_namespaces = std.StaticStringMap([]const u8).initComptime(.{
// vkCmdBegin...
.{ "VkCommandBuffer", "Cmd" },
// vkQueueSubmit...
.{ "VkQueue", "Queue" },
});
const dispatch_override_functions = std.StaticStringMap(CommandDispatchType).initComptime(.{ const dispatch_override_functions = std.StaticStringMap(CommandDispatchType).initComptime(.{
// See https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#initialization-functionpointers
.{ "vkGetInstanceProcAddr", .base }, .{ "vkGetInstanceProcAddr", .base },
.{ "vkGetDeviceProcAddr", .instance }, .{ "vkGetDeviceProcAddr", .instance },
.{ "vkEnumerateInstanceVersion", .base },
.{ "vkEnumerateInstanceExtensionProperties", .base },
.{ "vkEnumerateInstanceLayerProperties", .base },
.{ "vkCreateInstance", .base },
}); });
fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool { fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool {
@@ -478,7 +491,7 @@ fn Renderer(comptime WriterType: type) type {
else => {}, else => {},
} }
return .base; return .instance;
} }
fn render(self: *Self) !void { fn render(self: *Self) !void {
@@ -1440,17 +1453,17 @@ fn Renderer(comptime WriterType: type) type {
} }
fn renderProxies(self: *Self) !void { fn renderProxies(self: *Self) !void {
try self.renderProxy(.instance, "VkInstance", null); try self.renderProxy(.instance, "VkInstance", true);
try self.renderProxy(.device, "VkDevice", null); try self.renderProxy(.device, "VkDevice", true);
try self.renderProxy(.device, "VkCommandBuffer", "VkDevice"); try self.renderProxy(.device, "VkCommandBuffer", false);
try self.renderProxy(.device, "VkQueue", "VkDevice"); try self.renderProxy(.device, "VkQueue", false);
} }
fn renderProxy( fn renderProxy(
self: *Self, self: *Self,
dispatch_type: CommandDispatchType, dispatch_type: CommandDispatchType,
dispatch_handle: []const u8, dispatch_handle: []const u8,
maybe_parent_dispatch_handle: ?[]const u8, also_add_other_commands: bool,
) !void { ) !void {
const loader_name = dispatch_type.name(); const loader_name = dispatch_type.name();
@@ -1463,7 +1476,7 @@ fn Renderer(comptime WriterType: type) type {
\\ handle: {0s}, \\ handle: {0s},
\\ wrapper: *const Wrapper, \\ wrapper: *const Wrapper,
\\ \\
\\ pub fn init(handle: {0s}, wrapper: *const Wrapper) error{{CommandLoadFailure}}!Self {{ \\ pub fn init(handle: {0s}, wrapper: *const Wrapper) Self {{
\\ return .{{ \\ return .{{
\\ .handle = handle, \\ .handle = handle,
\\ .wrapper = wrapper, \\ .wrapper = wrapper,
@@ -1484,21 +1497,20 @@ fn Renderer(comptime WriterType: type) type {
switch (command.params[0].param_type) { switch (command.params[0].param_type) {
.name => |name| { .name => |name| {
if (!mem.eql(u8, name, dispatch_handle)) { const skip = blk: {
// Also render queue/cmdBuf functions in the proxy of the device, for conveniece if (mem.eql(u8, name, dispatch_handle)) {
if (maybe_parent_dispatch_handle) |parent_dispatch_handle| { break :blk false;
if (!mem.eql(u8, name, parent_dispatch_handle)) {
continue;
}
} else {
continue;
} }
}
break :blk !also_add_other_commands;
};
if (skip) continue;
}, },
else => continue, // Not a dispatchable handle else => continue, // Not a dispatchable handle
} }
try self.renderProxyCommand(decl.name, command); try self.renderProxyCommand(decl.name, command, dispatch_handle);
} }
try self.writer.writeAll( try self.writer.writeAll(
@@ -1507,7 +1519,7 @@ fn Renderer(comptime WriterType: type) type {
); );
} }
fn renderProxyCommand(self: *Self, name: []const u8, command: reg.Command) !void { fn renderProxyCommand(self: *Self, name: []const u8, command: reg.Command, dispatch_handle: []const u8) !void {
const returns_vk_result = command.return_type.* == .name and mem.eql(u8, command.return_type.name, "VkResult"); const returns_vk_result = command.return_type.* == .name and mem.eql(u8, command.return_type.name, "VkResult");
const returns = try self.extractReturns(command); const returns = try self.extractReturns(command);
@@ -1527,7 +1539,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(";\n"); try self.writer.writeAll(";\n");
} }
try self.renderWrapperPrototype(name, command, returns, .proxy); try self.renderWrapperPrototype(name, command, returns, dispatch_handle, .proxy);
try self.writer.writeAll( try self.writer.writeAll(
\\{ \\{
@@ -1540,7 +1552,11 @@ fn Renderer(comptime WriterType: type) type {
switch (try self.classifyParam(param)) { switch (try self.classifyParam(param)) {
.out_pointer => continue, .out_pointer => continue,
.dispatch_handle => { .dispatch_handle => {
try self.writer.writeAll("self.handle"); if (mem.eql(u8, param.param_type.name, dispatch_handle)) {
try self.writer.writeAll("self.handle");
} else {
try self.writeIdentifierWithCase(.snake, param.name);
}
}, },
else => { else => {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
@@ -1574,16 +1590,31 @@ fn Renderer(comptime WriterType: type) type {
name: []const u8, name: []const u8,
command: reg.Command, command: reg.Command,
returns: []const ReturnValue, returns: []const ReturnValue,
dispatch_handle: []const u8,
kind: WrapperKind, kind: WrapperKind,
) !void { ) !void {
try self.writer.writeAll("pub fn "); try self.writer.writeAll("pub fn ");
try self.writeIdentifierWithCase(.camel, trimVkNamespace(name)); const trimmed_name = switch (kind) {
.wrapper => trimVkNamespace(name),
.proxy => blk: {
// Strip additional namespaces: queue for VkQueue and cmd for VkCommandBuffer
const no_vk = trimVkNamespace(name);
const additional_namespace = additional_namespaces.get(dispatch_handle) orelse break :blk no_vk;
if (std.mem.startsWith(u8, no_vk, additional_namespace)) {
break :blk no_vk[additional_namespace.len..];
}
break :blk no_vk;
},
};
try self.writeIdentifierWithCase(.camel, trimmed_name);
try self.writer.writeAll("(self: Self, "); try self.writer.writeAll("(self: Self, ");
for (command.params) |param| { for (command.params) |param| {
const class = try self.classifyParam(param); const class = try self.classifyParam(param);
// Skip the dispatch type for proxying wrappers // Skip the dispatch type for proxying wrappers
if (kind == .proxy and class == .dispatch_handle) { if (kind == .proxy and class == .dispatch_handle and mem.eql(u8, param.param_type.name, dispatch_handle)) {
continue; continue;
} }
@@ -1727,7 +1758,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(";\n"); try self.writer.writeAll(";\n");
} }
try self.renderWrapperPrototype(name, command, returns, .wrapper); try self.renderWrapperPrototype(name, command, returns, "", .wrapper);
if (returns.len == 1 and returns[0].origin == .inner_return_value) { if (returns.len == 1 and returns[0].origin == .inner_return_value) {
try self.writer.writeAll("{\n\n"); try self.writer.writeAll("{\n\n");