From bed9e2d2241ade679b78892c829f41cecc2ef5ef Mon Sep 17 00:00:00 2001 From: flut2 <150191812+flut2@users.noreply.github.com> Date: Fri, 15 Aug 2025 06:48:14 +0100 Subject: [PATCH] update to 0.15.0-dev.1518+749f10af4 --- build.zig.zon | 2 +- examples/graphics_context.zig | 10 +++++----- src/id_render.zig | 32 ++++++++++++++++---------------- src/main.zig | 23 ++++++++++++++--------- src/vulkan/c_parse.zig | 8 ++++---- src/vulkan/generator.zig | 2 +- src/vulkan/parse.zig | 28 ++++++++++++++-------------- src/vulkan/render.zig | 18 ++++++++++-------- src/xml.zig | 16 ++++++++-------- 9 files changed, 73 insertions(+), 66 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 1ffcf1b..2af5b45 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .vulkan, .fingerprint = 0xbe155a03c72db6af, .version = "0.0.0", - .minimum_zig_version = "0.14.0-dev.1359+e9a00ba7f", + .minimum_zig_version = "0.15.0-dev.1518+749f10af4", .paths = .{ "build.zig", "LICENSE", diff --git a/examples/graphics_context.zig b/examples/graphics_context.zig index aaa4e7c..a31aaa3 100644 --- a/examples/graphics_context.zig +++ b/examples/graphics_context.zig @@ -49,16 +49,16 @@ pub const GraphicsContext = struct { self.allocator = allocator; self.vkb = BaseWrapper.load(c.glfwGetInstanceProcAddress); - var extension_names = std.ArrayList([*:0]const u8).init(allocator); - defer extension_names.deinit(); + var extension_names: std.ArrayList([*:0]const u8) = .empty; + defer extension_names.deinit(allocator); // these extensions are to support vulkan in mac os // see https://github.com/glfw/glfw/issues/2335 - try extension_names.append("VK_KHR_portability_enumeration"); - try extension_names.append("VK_KHR_get_physical_device_properties2"); + try extension_names.append(allocator, "VK_KHR_portability_enumeration"); + try extension_names.append(allocator, "VK_KHR_get_physical_device_properties2"); var glfw_exts_count: u32 = 0; const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count); - try extension_names.appendSlice(@ptrCast(glfw_exts[0..glfw_exts_count])); + try extension_names.appendSlice(allocator, @ptrCast(glfw_exts[0..glfw_exts_count])); const instance = try self.vkb.createInstance(&.{ .p_application_info = &.{ diff --git a/src/id_render.zig b/src/id_render.zig index 26c0161..60c6f7c 100644 --- a/src/id_render.zig +++ b/src/id_render.zig @@ -121,12 +121,12 @@ pub const SegmentIterator = struct { pub const IdRenderer = struct { tags: []const []const u8, - text_cache: std.ArrayList(u8), + text_cache: std.io.Writer.Allocating, pub fn init(allocator: Allocator, tags: []const []const u8) IdRenderer { return .{ .tags = tags, - .text_cache = std.ArrayList(u8).init(allocator), + .text_cache = .init(allocator), }; } @@ -142,19 +142,19 @@ pub const IdRenderer = struct { if (first) { first = false; } else { - try self.text_cache.append('_'); + try self.text_cache.writer.writeByte('_'); } for (segment) |c| { - try self.text_cache.append(if (screaming) std.ascii.toUpper(c) else std.ascii.toLower(c)); + try self.text_cache.writer.writeByte(if (screaming) std.ascii.toUpper(c) else std.ascii.toLower(c)); } } if (tag) |name| { - try self.text_cache.append('_'); + try self.text_cache.writer.writeByte('_'); for (name) |c| { - try self.text_cache.append(if (screaming) std.ascii.toUpper(c) else std.ascii.toLower(c)); + try self.text_cache.writer.writeByte(if (screaming) std.ascii.toUpper(c) else std.ascii.toLower(c)); } } } @@ -166,7 +166,7 @@ pub const IdRenderer = struct { while (it.next()) |segment| { var i: usize = 0; while (i < segment.len and std.ascii.isDigit(segment[i])) { - try self.text_cache.append(segment[i]); + try self.text_cache.writer.writeByte(segment[i]); i += 1; } @@ -175,26 +175,26 @@ pub const IdRenderer = struct { } if (i == 0 and lower_first) { - try self.text_cache.append(std.ascii.toLower(segment[i])); + try self.text_cache.writer.writeByte(std.ascii.toLower(segment[i])); } else { - try self.text_cache.append(std.ascii.toUpper(segment[i])); + try self.text_cache.writer.writeByte(std.ascii.toUpper(segment[i])); } lower_first = false; for (segment[i + 1 ..]) |c| { - try self.text_cache.append(std.ascii.toLower(c)); + try self.text_cache.writer.writeByte(std.ascii.toLower(c)); } } if (tag) |name| { - try self.text_cache.appendSlice(name); + try self.text_cache.writer.writeAll(name); } } pub fn renderFmt(self: *IdRenderer, out: *std.Io.Writer, comptime fmt: []const u8, args: anytype) !void { - self.text_cache.items.len = 0; - try std.fmt.format(self.text_cache.writer(), fmt, args); - try writeIdentifier(out, self.text_cache.items); + _ = self.text_cache.writer.consumeAll(); + try self.text_cache.writer.print(fmt, args); + try writeIdentifier(out, self.text_cache.writer.buffered()); } pub fn renderWithCase(self: *IdRenderer, out: *std.Io.Writer, case_style: CaseStyle, id: []const u8) !void { @@ -202,7 +202,7 @@ pub const IdRenderer = struct { // The trailing underscore doesn't need to be removed here as its removed by the SegmentIterator. const adjusted_id = if (tag) |name| id[0 .. id.len - name.len] else id; - self.text_cache.items.len = 0; + _ = self.text_cache.writer.consumeAll(); switch (case_style) { .snake => try self.renderSnake(false, adjusted_id, tag), @@ -211,7 +211,7 @@ pub const IdRenderer = struct { .camel => try self.renderCamel(false, adjusted_id, tag), } - try writeIdentifier(out, self.text_cache.items); + try writeIdentifier(out, self.text_cache.writer.buffered()); } pub fn getAuthorTag(self: IdRenderer, id: []const u8) ?[]const u8 { diff --git a/src/main.zig b/src/main.zig index f2ee7bd..14bd975 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,4 +1,5 @@ const std = @import("std"); + const generator = @import("vulkan/generator.zig"); fn invalidUsage(prog_name: []const u8, comptime fmt: []const u8, args: anytype) noreturn { @@ -23,13 +24,17 @@ fn reportParseErrors(tree: std.zig.Ast) !void { } } +fn oomPanic() noreturn { + @panic("Out of memory"); +} + pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); var args = std.process.argsWithAllocator(allocator) catch |err| switch (err) { - error.OutOfMemory => @panic("OOM"), + error.OutOfMemory => oomPanic(), }; const prog_name = args.next() orelse "vulkan-zig-generator"; @@ -108,9 +113,8 @@ pub fn main() !void { else null; - var out_buffer = std.ArrayList(u8).init(allocator); - var w = out_buffer.writer().adaptToNewApi(); - generator.generate(allocator, api, xml_src, maybe_video_xml_src, &w.new_interface) catch |err| { + var aw: std.io.Writer.Allocating = .init(allocator); + generator.generate(allocator, api, xml_src, maybe_video_xml_src, &aw.writer) catch |err| { if (debug) { return err; } @@ -132,15 +136,16 @@ pub fn main() !void { std.log.err("please make a bug report at https://github.com/Snektron/vulkan-zig/issues/", .{}); std.process.exit(1); }, - error.OutOfMemory, error.WriteFailed => @panic("oom"), + error.OutOfMemory, error.WriteFailed => oomPanic(), } }; - out_buffer.append(0) catch @panic("oom"); + aw.writer.writeByte(0) catch oomPanic(); - const src = out_buffer.items[0 .. out_buffer.items.len - 1 :0]; + const buffered = aw.writer.buffered(); + const src = buffered[0 .. buffered.len - 1 :0]; const tree = std.zig.Ast.parse(allocator, src, .zig) catch |err| switch (err) { - error.OutOfMemory => @panic("oom"), + error.OutOfMemory => oomPanic(), }; const formatted = if (tree.errors.len > 0) blk: { @@ -158,7 +163,7 @@ pub fn main() !void { } std.process.exit(1); } else tree.renderAlloc(allocator) catch |err| switch (err) { - error.OutOfMemory => @panic("oom"), + error.OutOfMemory => oomPanic(), }; if (std.fs.path.dirname(out_path)) |dir| { diff --git a/src/vulkan/c_parse.zig b/src/vulkan/c_parse.zig index 3dcb8a4..d621fd8 100644 --- a/src/vulkan/c_parse.zig +++ b/src/vulkan/c_parse.zig @@ -457,8 +457,8 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty // There is no good way to estimate the number of parameters beforehand. // Fortunately, there are usually a relatively low number of parameters to a function pointer, // so an ArrayList backed by an arena allocator is good enough. - var params = std.ArrayList(registry.Command.Param).init(allocator); - try params.append(.{ + var params: std.ArrayList(registry.Command.Param) = .empty; + try params.append(allocator, .{ .name = first_param.name.?, .param_type = first_param.decl_type, .is_buffer_len = false, @@ -473,7 +473,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty } const decl = try parseDeclaration(allocator, xctok, ptrs_optional); - try params.append(.{ + try params.append(allocator, .{ .name = decl.name orelse return error.MissingTypeIdentifier, .param_type = decl.decl_type, .is_buffer_len = false, @@ -482,7 +482,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty } _ = try xctok.nextNoEof(); - command_ptr.decl_type.command_ptr.params = try params.toOwnedSlice(); + command_ptr.decl_type.command_ptr.params = try params.toOwnedSlice(allocator); return command_ptr; } diff --git a/src/vulkan/generator.zig b/src/vulkan/generator.zig index e5f5be2..b833ab5 100644 --- a/src/vulkan/generator.zig +++ b/src/vulkan/generator.zig @@ -32,7 +32,7 @@ const EnumFieldMerger = struct { fn putEnumExtension(self: *EnumFieldMerger, enum_name: []const u8, field: reg.Enum.Field) !void { const res = try self.enum_extensions.getOrPut(self.arena, enum_name); if (!res.found_existing) { - res.value_ptr.* = std.ArrayListUnmanaged(reg.Enum.Field){}; + res.value_ptr.* = .empty; } try res.value_ptr.append(self.arena, field); diff --git a/src/vulkan/parse.zig b/src/vulkan/parse.zig index 7cd72c1..e4f355a 100644 --- a/src/vulkan/parse.zig +++ b/src/vulkan/parse.zig @@ -28,11 +28,11 @@ pub fn parseXml( const allocator = arena.allocator(); - var decls: std.ArrayListUnmanaged(registry.Declaration) = .{}; - var api_constants: std.ArrayListUnmanaged(registry.ApiConstant) = .{}; - var tags: std.ArrayListUnmanaged(registry.Tag) = .{}; - var features: std.ArrayListUnmanaged(registry.Feature) = .{}; - var extensions: std.ArrayListUnmanaged(registry.Extension) = .{}; + var decls: std.ArrayList(registry.Declaration) = .empty; + var api_constants: std.ArrayList(registry.ApiConstant) = .empty; + var tags: std.ArrayList(registry.Tag) = .empty; + var features: std.ArrayList(registry.Feature) = .empty; + var extensions: std.ArrayList(registry.Extension) = .empty; try parseDeclarations(allocator, root, api, &decls); try parseApiConstants(allocator, root, api, &api_constants); @@ -66,7 +66,7 @@ fn parseDeclarations( allocator: Allocator, root: *xml.Element, api: registry.Api, - decls: *std.ArrayListUnmanaged(registry.Declaration), + decls: *std.ArrayList(registry.Declaration), ) !void { const types_elem = root.findChildByTag("types") orelse return error.InvalidRegistry; try decls.ensureUnusedCapacity(allocator, types_elem.children.len); @@ -84,7 +84,7 @@ fn parseTypes( allocator: Allocator, types_elem: *xml.Element, api: registry.Api, - decls: *std.ArrayListUnmanaged(registry.Declaration), + decls: *std.ArrayList(registry.Declaration), ) !void { var it = types_elem.findChildrenByTag("type"); while (it.next()) |ty| { @@ -429,7 +429,7 @@ fn parseEnums( allocator: Allocator, root: *xml.Element, api: registry.Api, - decls: *std.ArrayListUnmanaged(registry.Declaration), + decls: *std.ArrayList(registry.Declaration), ) !void { var it = root.findChildrenByTag("enums"); while (it.next()) |enums| { @@ -519,7 +519,7 @@ fn parseCommands( allocator: Allocator, commands_elem: *xml.Element, api: registry.Api, - decls: *std.ArrayListUnmanaged(registry.Declaration), + decls: *std.ArrayList(registry.Declaration), ) !void { var it = commands_elem.findChildrenByTag("command"); while (it.next()) |elem| { @@ -630,7 +630,7 @@ fn parseApiConstants( allocator: Allocator, root: *xml.Element, api: registry.Api, - api_constants: *std.ArrayListUnmanaged(registry.ApiConstant), + api_constants: *std.ArrayList(registry.ApiConstant), ) !void { const maybe_enums = blk: { var it = root.findChildrenByTag("enums"); @@ -672,7 +672,7 @@ fn parseDefines( allocator: Allocator, types: *xml.Element, api: registry.Api, - api_constants: *std.ArrayListUnmanaged(registry.ApiConstant), + api_constants: *std.ArrayList(registry.ApiConstant), ) !void { var it = types.findChildrenByTag("type"); while (it.next()) |ty| { @@ -703,7 +703,7 @@ fn parseDefines( fn parseTags( allocator: Allocator, root: *xml.Element, - tags: *std.ArrayListUnmanaged(registry.Tag), + tags: *std.ArrayList(registry.Tag), ) !void { var tags_elem = root.findChildByTag("tags") orelse return; try tags.ensureUnusedCapacity(allocator, tags_elem.children.len); @@ -717,7 +717,7 @@ fn parseTags( } } -fn parseFeatures(allocator: Allocator, root: *xml.Element, api: registry.Api, features: *std.ArrayListUnmanaged(registry.Feature)) !void { +fn parseFeatures(allocator: Allocator, root: *xml.Element, api: registry.Api, features: *std.ArrayList(registry.Feature)) !void { var it = root.findChildrenByTag("feature"); while (it.next()) |feature| { if (!requiredByApi(feature, api)) @@ -881,7 +881,7 @@ fn parseExtensions( allocator: Allocator, root: *xml.Element, api: registry.Api, - extensions: *std.ArrayListUnmanaged(registry.Extension), + extensions: *std.ArrayList(registry.Extension), ) !void { const extensions_elem = root.findChildByTag("extensions") orelse return error.InvalidRegistry; try extensions.ensureUnusedCapacity(allocator, extensions_elem.children.len); diff --git a/src/vulkan/render.zig b/src/vulkan/render.zig index 058e4ab..58520ba 100644 --- a/src/vulkan/render.zig +++ b/src/vulkan/render.zig @@ -1,11 +1,12 @@ const std = @import("std"); -const reg = @import("registry.zig"); -const id_render = @import("../id_render.zig"); -const cparse = @import("c_parse.zig"); const mem = std.mem; const Allocator = mem.Allocator; + +const id_render = @import("../id_render.zig"); const CaseStyle = id_render.CaseStyle; const IdRenderer = id_render.IdRenderer; +const cparse = @import("c_parse.zig"); +const reg = @import("registry.zig"); const preamble = \\// This file is generated from the Khronos Vulkan XML API registry by vulkan-zig. @@ -1810,12 +1811,13 @@ const Renderer = struct { } fn extractReturns(self: *Self, command: reg.Command) ![]const ReturnValue { - var returns = std.ArrayList(ReturnValue).init(self.allocator); + const allocator = self.allocator; + var returns: std.ArrayList(ReturnValue) = .empty; if (command.return_type.* == .name) { const return_name = command.return_type.name; if (!mem.eql(u8, return_name, "void") and !mem.eql(u8, return_name, "VkResult")) { - try returns.append(.{ + try returns.append(allocator, .{ .name = "return_value", .return_value_type = command.return_type.*, .origin = .inner_return_value, @@ -1828,7 +1830,7 @@ const Renderer = struct { return error.InvalidRegistry; } - try returns.append(.{ + try returns.append(allocator, .{ .name = "result", .return_value_type = command.return_type.*, .origin = .inner_return_value, @@ -1839,7 +1841,7 @@ const Renderer = struct { for (command.params) |param| { if ((try self.classifyParam(param)) == .out_pointer) { - try returns.append(.{ + try returns.append(allocator, .{ .name = derefName(param.name), .return_value_type = param.param_type.pointer.child.*, .origin = .parameter, @@ -1847,7 +1849,7 @@ const Renderer = struct { } } - return try returns.toOwnedSlice(); + return try returns.toOwnedSlice(allocator); } fn renderReturnStructName(self: *Self, command_name: []const u8) !void { diff --git a/src/xml.zig b/src/xml.zig index 814663f..ee3b79f 100644 --- a/src/xml.zig +++ b/src/xml.zig @@ -439,15 +439,15 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) ! }, }; - var attributes = std.ArrayList(Attribute).init(alloc); - defer attributes.deinit(); + var attributes: std.ArrayList(Attribute) = .empty; + defer attributes.deinit(alloc); - var children = std.ArrayList(Content).init(alloc); - defer children.deinit(); + var children: std.ArrayList(Content) = .empty; + defer children.deinit(alloc); while (parser.eatWs()) { const attr = (try parseAttr(parser, alloc)) orelse break; - try attributes.append(attr); + try attributes.append(alloc, attr); } switch (kind) { @@ -464,7 +464,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) ! } const content = try parseContent(parser, alloc); - try children.append(content); + try children.append(alloc, content); } const closing_tag = try parseNameNoDupe(parser); @@ -481,8 +481,8 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) ! const element = try alloc.create(Element); element.* = .{ .tag = try alloc.dupe(u8, tag), - .attributes = try attributes.toOwnedSlice(), - .children = try children.toOwnedSlice(), + .attributes = try attributes.toOwnedSlice(alloc), + .children = try children.toOwnedSlice(alloc), }; return element; }