From 9c45afca2ed3b9bc743fdcdab8c0b25aebf7c6bf Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Wed, 10 Apr 2024 17:06:43 -0600 Subject: [PATCH 1/8] Add extension function metadata for #112 --- generator/vulkan/render.zig | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index d730758..a8841c1 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -1035,13 +1035,80 @@ fn Renderer(comptime WriterType: type) type { \\ const Info = struct { \\ name: [:0]const u8, \\ 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| { try self.writer.writeAll("pub const "); try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name)); try self.writer.writeAll("= Info {\n"); 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"); From 571cecdda64d548e2df59226ab72112ac0fcdec4 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 13 Apr 2024 23:18:44 +0200 Subject: [PATCH 2/8] actually run the tests --- build.zig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index c7673f3..6a1c7c6 100644 --- a/build.zig +++ b/build.zig @@ -68,12 +68,14 @@ pub fn build(b: *std.Build) void { const triangle_run_step = b.step("run-triangle", "Run the triangle example"); triangle_run_step.dependOn(&triangle_run_cmd.step); - var test_target = b.addTest(.{ + const test_target = b.addTest(.{ .root_source_file = .{ .path = "generator/index.zig" }, }); - var test_step = b.step("test", "Run all the tests"); - test_step.dependOn(&test_target.step); + const run_test = b.addRunArtifact(test_target); + + const test_step = b.step("test", "Run all the tests"); + test_step.dependOn(&run_test.step); // This test needs to be an object so that vulkan-zig can import types from the root. // It does not need to run anyway. From 500d7cc3e8cd3606cd4574ef8f0ff5c17f9b4c2a Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Apr 2024 11:10:42 +0800 Subject: [PATCH 3/8] fix: change ComptimeStringMap to StaticStringMap reflect changes made in https://github.com/ziglang/zig/commit/8af59d1f98266bd70b3afb44d196bbd151cedf22 --- generator/vulkan/render.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index a8841c1..3b9115a 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -96,7 +96,7 @@ const preamble = \\ ; -const builtin_types = std.ComptimeStringMap([]const u8, .{ +const builtin_types = std.StaticStringMap([]const u8).initComptime(.{ .{ "void", @typeName(void) }, .{ "char", @typeName(u8) }, .{ "float", @typeName(f32) }, @@ -113,7 +113,7 @@ const builtin_types = std.ComptimeStringMap([]const u8, .{ .{ "int", @typeName(c_int) }, }); -const foreign_types = std.ComptimeStringMap([]const u8, .{ +const foreign_types = std.StaticStringMap([]const u8).initComptime(.{ .{ "Display", "opaque {}" }, .{ "VisualID", @typeName(c_uint) }, .{ "Window", @typeName(c_ulong) }, @@ -425,13 +425,13 @@ fn Renderer(comptime WriterType: type) type { } fn classifyCommandDispatch(name: []const u8, command: reg.Command) CommandDispatchType { - const device_handles = std.ComptimeStringMap(void, .{ + const device_handles = std.StaticStringMap(void).initComptime(.{ .{ "VkDevice", {} }, .{ "VkCommandBuffer", {} }, .{ "VkQueue", {} }, }); - const override_functions = std.ComptimeStringMap(CommandDispatchType, .{ + const override_functions = std.StaticStringMap(CommandDispatchType).initComptime(.{ .{ "vkGetInstanceProcAddr", .base }, .{ "vkCreateInstance", .base }, .{ "vkEnumerateInstanceLayerProperties", .base }, From d4a04e0bea045f273c21a997583181e02b854a7f Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Fri, 26 Apr 2024 20:42:44 -0600 Subject: [PATCH 4/8] Implement initial suggestions on PR --- generator/vulkan/render.zig | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index 3b9115a..18720d0 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -1050,8 +1050,8 @@ fn Renderer(comptime WriterType: type) type { try self.writer.writeAll("= Info {\n"); try self.writer.print(".name = \"{s}\", .version = {},", .{ ext.name, ext.version }); // collect extension functions - for(ext.requires) |require| { - for(require.commands) |command_name| { + 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. @@ -1063,36 +1063,19 @@ fn Renderer(comptime WriterType: type) type { 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. + .base => return error.InvalidRegistry, .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); + 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); + try device_commands.append(command_name); }, } } } // and write them out try self.writer.writeAll(".instance_functions = .{\n"); - for(instance_commands.items) |command_name| { + for (instance_commands.items) |command_name| { try self.writer.writeAll("."); try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name)); try self.writer.writeAll(" = true, \n"); @@ -1101,7 +1084,7 @@ fn Renderer(comptime WriterType: type) type { instance_commands.clearRetainingCapacity(); try self.writer.writeAll(".device_functions = .{\n"); - for(device_commands.items) |command_name| { + for (device_commands.items) |command_name| { try self.writer.writeAll("."); try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name)); try self.writer.writeAll(" = true, \n"); From 9479fe480ab7fe348e7b0701629db3ebdbd8dabc Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Fri, 26 Apr 2024 21:56:38 -0600 Subject: [PATCH 5/8] Add feature info --- generator/vulkan/render.zig | 107 +++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 20 deletions(-) diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index 18720d0..54e3f51 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -469,6 +469,7 @@ fn Renderer(comptime WriterType: type) type { try self.renderCommandPtrs(); try self.renderExtensionInfo(); + try self.renderFeatureInfo(); try self.renderWrappers(); } @@ -1040,9 +1041,9 @@ fn Renderer(comptime WriterType: type) type { \\ }; ); // 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); + var instance_commands = std.BufSet.init(self.allocator); defer instance_commands.deinit(); - var device_commands = std.ArrayList([]const u8).init(self.allocator); + var device_commands = std.BufSet.init(self.allocator); defer device_commands.deinit(); for (self.registry.extensions) |ext| { try self.writer.writeAll("pub const "); @@ -1065,38 +1066,104 @@ fn Renderer(comptime WriterType: type) type { // Vulkan extensions cannot add base functions. .base => return error.InvalidRegistry, .instance => { - try instance_commands.append(command_name); + try instance_commands.insert(command_name); }, .device => { - try device_commands.append(command_name); + try device_commands.insert(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(".instance_functions = "); + try self.renderCommandFlags(&instance_commands); + instance_commands.hash_map.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(".device_functions = "); + try self.renderCommandFlags(&device_commands); + device_commands.hash_map.clearRetainingCapacity(); try self.writer.writeAll("};\n"); } try self.writer.writeAll("};\n"); } + fn renderFeatureInfo(self: *Self) !void { + try self.writer.writeAll( + \\pub const feature_info = struct { + \\ const Info = struct { + \\ base_functions: BaseCommandFlags, + \\ instance_functions: InstanceCommandFlags, + \\ device_functions: DeviceCommandFlags, + \\ }; + ); + // The commands in a feature level are not pre-sorted based on if they are instance or device functions. + var base_commands = std.BufSet.init(self.allocator); + defer base_commands.deinit(); + var instance_commands = std.BufSet.init(self.allocator); + defer instance_commands.deinit(); + var device_commands = std.BufSet.init(self.allocator); + defer device_commands.deinit(); + for (self.registry.features) |feature| { + try self.writer.writeAll("pub const "); + try self.writeIdentifierWithCase(.snake, trimVkNamespace(feature.name)); + try self.writer.writeAll("= Info {\n"); + // collect feature information + for (feature.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) { + .base => { + try base_commands.insert(command_name); + }, + .instance => { + try instance_commands.insert(command_name); + }, + .device => { + try device_commands.insert(command_name); + }, + } + } + } + // and write them out + // clear command lists for next iteration + try self.writer.writeAll(".base_functions = "); + try self.renderCommandFlags(&base_commands); + base_commands.hash_map.clearRetainingCapacity(); + + try self.writer.writeAll(".instance_functions = "); + try self.renderCommandFlags(&instance_commands); + instance_commands.hash_map.clearRetainingCapacity(); + + try self.writer.writeAll(".device_functions = "); + try self.renderCommandFlags(&device_commands); + device_commands.hash_map.clearRetainingCapacity(); + + try self.writer.writeAll("};\n"); + } + + try self.writer.writeAll("};\n"); + } + + fn renderCommandFlags(self: *Self, commands: *const std.BufSet) !void { + try self.writer.writeAll(".{\n"); + var iterator = commands.iterator(); + while (iterator.next()) |command_name| { + try self.writer.writeAll("."); + try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name.*)); + try self.writer.writeAll(" = true, \n"); + } + try self.writer.writeAll("},\n"); + } + fn renderWrappers(self: *Self) !void { try self.writer.writeAll( \\pub fn CommandFlagsMixin(comptime CommandFlags: type) type { From e4d6c50b55cb68ed792d6ef4f1199cd17aa36aea Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Fri, 26 Apr 2024 22:14:26 -0600 Subject: [PATCH 6/8] Increase branch quota for command flags --- generator/vulkan/render.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index 54e3f51..7989d28 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -62,6 +62,7 @@ const preamble = \\ ) !void { \\ try writer.writeAll(@typeName(FlagsType) ++ "{"); \\ var first = true; + \\ @setEvalBranchQuota(10_000); \\ inline for (comptime std.meta.fieldNames(FlagsType)) |name| { \\ if (name[0] == '_') continue; \\ if (@field(self, name)) { @@ -1170,6 +1171,7 @@ fn Renderer(comptime WriterType: type) type { \\ return struct { \\ pub fn merge(lhs: CommandFlags, rhs: CommandFlags) CommandFlags { \\ var result: CommandFlags = .{}; + \\ @setEvalBranchQuota(10_000); \\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| { \\ @field(result, field.name) = @field(lhs, field.name) or @field(rhs, field.name); \\ } @@ -1177,6 +1179,7 @@ fn Renderer(comptime WriterType: type) type { \\ } \\ pub fn intersect(lhs: CommandFlags, rhs: CommandFlags) CommandFlags { \\ var result: CommandFlags = .{}; + \\ @setEvalBranchQuota(10_000); \\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| { \\ @field(result, field.name) = @field(lhs, field.name) and @field(rhs, field.name); \\ } @@ -1184,6 +1187,7 @@ fn Renderer(comptime WriterType: type) type { \\ } \\ pub fn complement(self: CommandFlags) CommandFlags { \\ var result: CommandFlags = .{}; + \\ @setEvalBranchQuota(10_000); \\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| { \\ @field(result, field.name) = !@field(self, field.name); \\ } @@ -1191,12 +1195,14 @@ fn Renderer(comptime WriterType: type) type { \\ } \\ pub fn subtract(lhs: CommandFlags, rhs: CommandFlags) CommandFlags { \\ var result: CommandFlags = .{}; + \\ @setEvalBranchQuota(10_000); \\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| { \\ @field(result, field.name) = @field(lhs, field.name) and !@field(rhs, field.name); \\ } \\ return result; \\ } \\ pub fn contains(lhs: CommandFlags, rhs: CommandFlags) bool { + \\ @setEvalBranchQuota(10_000); \\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| { \\ if (!@field(lhs, field.name) and @field(rhs, field.name)) { \\ return false; From 110d836854e372c42bad239e85fa4cf2f8f0a6fc Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Fri, 26 Apr 2024 22:15:08 -0600 Subject: [PATCH 7/8] Refactor example to use extension info and feature info for functions --- examples/graphics_context.zig | 99 ++++++++++------------------------- 1 file changed, 28 insertions(+), 71 deletions(-) diff --git a/examples/graphics_context.zig b/examples/graphics_context.zig index fdfae55..0b9c406 100644 --- a/examples/graphics_context.zig +++ b/examples/graphics_context.zig @@ -5,79 +5,36 @@ const Allocator = std.mem.Allocator; const required_device_extensions = [_][*:0]const u8{vk.extension_info.khr_swapchain.name}; -const BaseDispatch = vk.BaseWrapper(.{ - .createInstance = true, - .getInstanceProcAddr = true, -}); +const BaseDispatch = vk.BaseWrapper( + blk: { + var commands = vk.feature_info.version_1_0.base_functions; + commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_1.base_functions); + commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_2.base_functions); + break :blk commands; + } +); -const InstanceDispatch = vk.InstanceWrapper(.{ - .destroyInstance = true, - .createDevice = true, - .destroySurfaceKHR = true, - .enumeratePhysicalDevices = true, - .getPhysicalDeviceProperties = true, - .enumerateDeviceExtensionProperties = true, - .getPhysicalDeviceSurfaceFormatsKHR = true, - .getPhysicalDeviceSurfacePresentModesKHR = true, - .getPhysicalDeviceSurfaceCapabilitiesKHR = true, - .getPhysicalDeviceQueueFamilyProperties = true, - .getPhysicalDeviceSurfaceSupportKHR = true, - .getPhysicalDeviceMemoryProperties = true, - .getDeviceProcAddr = true, -}); +const InstanceDispatch = vk.InstanceWrapper( + blk: { + var commands = vk.feature_info.version_1_0.instance_functions; + commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_1.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_2.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_surface.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.instance_functions); + break :blk commands; + } +); -const DeviceDispatch = vk.DeviceWrapper(.{ - .destroyDevice = true, - .getDeviceQueue = true, - .createSemaphore = true, - .createFence = true, - .createImageView = true, - .destroyImageView = true, - .destroySemaphore = true, - .destroyFence = true, - .getSwapchainImagesKHR = true, - .createSwapchainKHR = true, - .destroySwapchainKHR = true, - .acquireNextImageKHR = true, - .deviceWaitIdle = true, - .waitForFences = true, - .resetFences = true, - .queueSubmit = true, - .queuePresentKHR = true, - .createCommandPool = true, - .destroyCommandPool = true, - .allocateCommandBuffers = true, - .freeCommandBuffers = true, - .queueWaitIdle = true, - .createShaderModule = true, - .destroyShaderModule = true, - .createPipelineLayout = true, - .destroyPipelineLayout = true, - .createRenderPass = true, - .destroyRenderPass = true, - .createGraphicsPipelines = true, - .destroyPipeline = true, - .createFramebuffer = true, - .destroyFramebuffer = true, - .beginCommandBuffer = true, - .endCommandBuffer = true, - .allocateMemory = true, - .freeMemory = true, - .createBuffer = true, - .destroyBuffer = true, - .getBufferMemoryRequirements = true, - .mapMemory = true, - .unmapMemory = true, - .bindBufferMemory = true, - .cmdBeginRenderPass = true, - .cmdEndRenderPass = true, - .cmdBindPipeline = true, - .cmdDraw = true, - .cmdSetViewport = true, - .cmdSetScissor = true, - .cmdBindVertexBuffers = true, - .cmdCopyBuffer = true, -}); +const DeviceDispatch = vk.DeviceWrapper( + blk: { + var commands = vk.feature_info.version_1_0.device_functions; + commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_1.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_2.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_surface.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.device_functions); + break :blk commands; + } +); pub const GraphicsContext = struct { vkb: BaseDispatch, From d19313ba759cd257c32de44068dca6ac2b5f800b Mon Sep 17 00:00:00 2001 From: bluesillybeard Date: Sat, 27 Apr 2024 21:27:43 -0600 Subject: [PATCH 8/8] Run zig fmt --- examples/graphics_context.zig | 50 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/examples/graphics_context.zig b/examples/graphics_context.zig index 0b9c406..faf9baf 100644 --- a/examples/graphics_context.zig +++ b/examples/graphics_context.zig @@ -5,36 +5,30 @@ const Allocator = std.mem.Allocator; const required_device_extensions = [_][*:0]const u8{vk.extension_info.khr_swapchain.name}; -const BaseDispatch = vk.BaseWrapper( - blk: { - var commands = vk.feature_info.version_1_0.base_functions; - commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_1.base_functions); - commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_2.base_functions); - break :blk commands; - } -); +const BaseDispatch = vk.BaseWrapper(blk: { + var commands = vk.feature_info.version_1_0.base_functions; + commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_1.base_functions); + commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_2.base_functions); + break :blk commands; +}); -const InstanceDispatch = vk.InstanceWrapper( - blk: { - var commands = vk.feature_info.version_1_0.instance_functions; - commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_1.instance_functions); - commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_2.instance_functions); - commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_surface.instance_functions); - commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.instance_functions); - break :blk commands; - } -); +const InstanceDispatch = vk.InstanceWrapper(blk: { + var commands = vk.feature_info.version_1_0.instance_functions; + commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_1.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_2.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_surface.instance_functions); + commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.instance_functions); + break :blk commands; +}); -const DeviceDispatch = vk.DeviceWrapper( - blk: { - var commands = vk.feature_info.version_1_0.device_functions; - commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_1.device_functions); - commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_2.device_functions); - commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_surface.device_functions); - commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.device_functions); - break :blk commands; - } -); +const DeviceDispatch = vk.DeviceWrapper(blk: { + var commands = vk.feature_info.version_1_0.device_functions; + commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_1.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_2.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_surface.device_functions); + commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.device_functions); + break :blk commands; +}); pub const GraphicsContext = struct { vkb: BaseDispatch,