forked from mirror/vulkan-zig
Compare commits
18 Commits
fix-window
...
instructiv
| Author | SHA1 | Date | |
|---|---|---|---|
| c93e5a0fe2 | |||
| d1902bddd6 | |||
|
|
8961518db2 | ||
|
|
7acf3a1163 | ||
|
|
4b7b9a8b94 | ||
|
|
4066c2c526 | ||
|
|
c9c4dae703 | ||
|
|
ecf97034c4 | ||
|
|
3c7d4021e9 | ||
|
|
f879074293 | ||
|
|
571c59180d | ||
|
|
8322c9593f | ||
|
|
33407b8e4e | ||
|
|
93bc6f1ac3 | ||
|
|
bed9e2d224 | ||
|
|
ed429842b8 | ||
|
|
cb618dea81 | ||
|
|
e492b17810 |
@@ -2,7 +2,7 @@
|
|||||||
.name = .vulkan,
|
.name = .vulkan,
|
||||||
.fingerprint = 0xbe155a03c72db6af,
|
.fingerprint = 0xbe155a03c72db6af,
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.minimum_zig_version = "0.14.0-dev.1359+e9a00ba7f",
|
.minimum_zig_version = "0.15.1",
|
||||||
.paths = .{
|
.paths = .{
|
||||||
"build.zig",
|
"build.zig",
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ pub const GraphicsContext = struct {
|
|||||||
vkb: BaseWrapper,
|
vkb: BaseWrapper,
|
||||||
|
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
|
debug_messenger: vk.DebugUtilsMessengerEXT,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
props: vk.PhysicalDeviceProperties,
|
props: vk.PhysicalDeviceProperties,
|
||||||
@@ -49,16 +50,17 @@ pub const GraphicsContext = struct {
|
|||||||
self.allocator = allocator;
|
self.allocator = allocator;
|
||||||
self.vkb = BaseWrapper.load(c.glfwGetInstanceProcAddress);
|
self.vkb = BaseWrapper.load(c.glfwGetInstanceProcAddress);
|
||||||
|
|
||||||
var extension_names = std.ArrayList([*:0]const u8).init(allocator);
|
var extension_names: std.ArrayList([*:0]const u8) = .empty;
|
||||||
defer extension_names.deinit();
|
defer extension_names.deinit(allocator);
|
||||||
// these extensions are to support vulkan in mac os
|
try extension_names.append(allocator, vk.extensions.ext_debug_utils.name);
|
||||||
|
// the following extensions are to support vulkan in mac os
|
||||||
// see https://github.com/glfw/glfw/issues/2335
|
// see https://github.com/glfw/glfw/issues/2335
|
||||||
try extension_names.append("VK_KHR_portability_enumeration");
|
try extension_names.append(allocator, vk.extensions.khr_portability_enumeration.name);
|
||||||
try extension_names.append("VK_KHR_get_physical_device_properties2");
|
try extension_names.append(allocator, vk.extensions.khr_get_physical_device_properties_2.name);
|
||||||
|
|
||||||
var glfw_exts_count: u32 = 0;
|
var glfw_exts_count: u32 = 0;
|
||||||
const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count);
|
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(&.{
|
const instance = try self.vkb.createInstance(&.{
|
||||||
.p_application_info = &.{
|
.p_application_info = &.{
|
||||||
@@ -81,6 +83,22 @@ pub const GraphicsContext = struct {
|
|||||||
self.instance = Instance.init(instance, vki);
|
self.instance = Instance.init(instance, vki);
|
||||||
errdefer self.instance.destroyInstance(null);
|
errdefer self.instance.destroyInstance(null);
|
||||||
|
|
||||||
|
self.debug_messenger = try self.instance.createDebugUtilsMessengerEXT(&.{
|
||||||
|
.message_severity = .{
|
||||||
|
//.verbose_bit_ext = true,
|
||||||
|
//.info_bit_ext = true,
|
||||||
|
.warning_bit_ext = true,
|
||||||
|
.error_bit_ext = true,
|
||||||
|
},
|
||||||
|
.message_type = .{
|
||||||
|
.general_bit_ext = true,
|
||||||
|
.validation_bit_ext = true,
|
||||||
|
.performance_bit_ext = true,
|
||||||
|
},
|
||||||
|
.pfn_user_callback = &debugUtilsMessengerCallback,
|
||||||
|
.p_user_data = null,
|
||||||
|
}, null);
|
||||||
|
|
||||||
self.surface = try createSurface(self.instance, window);
|
self.surface = try createSurface(self.instance, window);
|
||||||
errdefer self.instance.destroySurfaceKHR(self.surface, null);
|
errdefer self.instance.destroySurfaceKHR(self.surface, null);
|
||||||
|
|
||||||
@@ -107,6 +125,7 @@ pub const GraphicsContext = struct {
|
|||||||
pub fn deinit(self: GraphicsContext) void {
|
pub fn deinit(self: GraphicsContext) void {
|
||||||
self.dev.destroyDevice(null);
|
self.dev.destroyDevice(null);
|
||||||
self.instance.destroySurfaceKHR(self.surface, null);
|
self.instance.destroySurfaceKHR(self.surface, null);
|
||||||
|
self.instance.destroyDebugUtilsMessengerEXT(self.debug_messenger, null);
|
||||||
self.instance.destroyInstance(null);
|
self.instance.destroyInstance(null);
|
||||||
|
|
||||||
// Don't forget to free the tables to prevent a memory leak.
|
// Don't forget to free the tables to prevent a memory leak.
|
||||||
@@ -196,6 +215,17 @@ const QueueAllocation = struct {
|
|||||||
present_family: u32,
|
present_family: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn debugUtilsMessengerCallback(severity: vk.DebugUtilsMessageSeverityFlagsEXT, msg_type: vk.DebugUtilsMessageTypeFlagsEXT, callback_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT, _: ?*anyopaque) callconv(.c) vk.Bool32 {
|
||||||
|
const severity_str = if (severity.verbose_bit_ext) "verbose" else if (severity.info_bit_ext) "info" else if (severity.warning_bit_ext) "warning" else if (severity.error_bit_ext) "error" else "unknown";
|
||||||
|
|
||||||
|
const type_str = if (msg_type.general_bit_ext) "general" else if (msg_type.validation_bit_ext) "validation" else if (msg_type.performance_bit_ext) "performance" else if (msg_type.device_address_binding_bit_ext) "device addr" else "unknown";
|
||||||
|
|
||||||
|
const message: [*c]const u8 = if (callback_data) |cb_data| cb_data.p_message else "NO MESSAGE!";
|
||||||
|
std.debug.print("[{s}][{s}]. Message:\n {s}\n", .{ severity_str, type_str, message });
|
||||||
|
|
||||||
|
return .false;
|
||||||
|
}
|
||||||
|
|
||||||
fn pickPhysicalDevice(
|
fn pickPhysicalDevice(
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
@@ -253,7 +283,7 @@ fn allocateQueues(instance: Instance, pdev: vk.PhysicalDevice, allocator: Alloca
|
|||||||
graphics_family = family;
|
graphics_family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present_family == null and (try instance.getPhysicalDeviceSurfaceSupportKHR(pdev, family, surface)) == vk.TRUE) {
|
if (present_family == null and (try instance.getPhysicalDeviceSurfaceSupportKHR(pdev, family, surface)) == .true) {
|
||||||
present_family = family;
|
present_family = family;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ pub const Swapchain = struct {
|
|||||||
.pre_transform = caps.current_transform,
|
.pre_transform = caps.current_transform,
|
||||||
.composite_alpha = .{ .opaque_bit_khr = true },
|
.composite_alpha = .{ .opaque_bit_khr = true },
|
||||||
.present_mode = present_mode,
|
.present_mode = present_mode,
|
||||||
.clipped = vk.TRUE,
|
.clipped = .true,
|
||||||
.old_swapchain = old_handle,
|
.old_swapchain = old_handle,
|
||||||
}, null) catch {
|
}, null) catch {
|
||||||
return error.SwapchainCreationFailed;
|
return error.SwapchainCreationFailed;
|
||||||
@@ -261,7 +261,7 @@ const SwapImage = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn waitForFence(self: SwapImage, gc: *const GraphicsContext) !void {
|
fn waitForFence(self: SwapImage, gc: *const GraphicsContext) !void {
|
||||||
_ = try gc.dev.waitForFences(1, @ptrCast(&self.frame_fence), vk.TRUE, std.math.maxInt(u64));
|
_ = try gc.dev.waitForFences(1, @ptrCast(&self.frame_fence), .true, std.math.maxInt(u64));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ fn createPipeline(
|
|||||||
|
|
||||||
const piasci = vk.PipelineInputAssemblyStateCreateInfo{
|
const piasci = vk.PipelineInputAssemblyStateCreateInfo{
|
||||||
.topology = .triangle_list,
|
.topology = .triangle_list,
|
||||||
.primitive_restart_enable = vk.FALSE,
|
.primitive_restart_enable = .false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const pvsci = vk.PipelineViewportStateCreateInfo{
|
const pvsci = vk.PipelineViewportStateCreateInfo{
|
||||||
@@ -425,12 +425,12 @@ fn createPipeline(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const prsci = vk.PipelineRasterizationStateCreateInfo{
|
const prsci = vk.PipelineRasterizationStateCreateInfo{
|
||||||
.depth_clamp_enable = vk.FALSE,
|
.depth_clamp_enable = .false,
|
||||||
.rasterizer_discard_enable = vk.FALSE,
|
.rasterizer_discard_enable = .false,
|
||||||
.polygon_mode = .fill,
|
.polygon_mode = .fill,
|
||||||
.cull_mode = .{ .back_bit = true },
|
.cull_mode = .{ .back_bit = true },
|
||||||
.front_face = .clockwise,
|
.front_face = .clockwise,
|
||||||
.depth_bias_enable = vk.FALSE,
|
.depth_bias_enable = .false,
|
||||||
.depth_bias_constant_factor = 0,
|
.depth_bias_constant_factor = 0,
|
||||||
.depth_bias_clamp = 0,
|
.depth_bias_clamp = 0,
|
||||||
.depth_bias_slope_factor = 0,
|
.depth_bias_slope_factor = 0,
|
||||||
@@ -439,14 +439,14 @@ fn createPipeline(
|
|||||||
|
|
||||||
const pmsci = vk.PipelineMultisampleStateCreateInfo{
|
const pmsci = vk.PipelineMultisampleStateCreateInfo{
|
||||||
.rasterization_samples = .{ .@"1_bit" = true },
|
.rasterization_samples = .{ .@"1_bit" = true },
|
||||||
.sample_shading_enable = vk.FALSE,
|
.sample_shading_enable = .false,
|
||||||
.min_sample_shading = 1,
|
.min_sample_shading = 1,
|
||||||
.alpha_to_coverage_enable = vk.FALSE,
|
.alpha_to_coverage_enable = .false,
|
||||||
.alpha_to_one_enable = vk.FALSE,
|
.alpha_to_one_enable = .false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const pcbas = vk.PipelineColorBlendAttachmentState{
|
const pcbas = vk.PipelineColorBlendAttachmentState{
|
||||||
.blend_enable = vk.FALSE,
|
.blend_enable = .false,
|
||||||
.src_color_blend_factor = .one,
|
.src_color_blend_factor = .one,
|
||||||
.dst_color_blend_factor = .zero,
|
.dst_color_blend_factor = .zero,
|
||||||
.color_blend_op = .add,
|
.color_blend_op = .add,
|
||||||
@@ -457,7 +457,7 @@ fn createPipeline(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const pcbsci = vk.PipelineColorBlendStateCreateInfo{
|
const pcbsci = vk.PipelineColorBlendStateCreateInfo{
|
||||||
.logic_op_enable = vk.FALSE,
|
.logic_op_enable = .false,
|
||||||
.logic_op = .copy,
|
.logic_op = .copy,
|
||||||
.attachment_count = 1,
|
.attachment_count = 1,
|
||||||
.p_attachments = @ptrCast(&pcbas),
|
.p_attachments = @ptrCast(&pcbas),
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pub fn isZigPrimitiveType(name: []const u8) bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn writeIdentifier(w: *std.io.Writer, id: []const u8) !void {
|
pub fn writeIdentifier(w: *std.Io.Writer, id: []const u8) !void {
|
||||||
try w.print("{f}", .{std.zig.fmtId(id)});
|
try w.print("{f}", .{std.zig.fmtId(id)});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,12 +121,12 @@ pub const SegmentIterator = struct {
|
|||||||
|
|
||||||
pub const IdRenderer = struct {
|
pub const IdRenderer = struct {
|
||||||
tags: []const []const u8,
|
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 {
|
pub fn init(allocator: Allocator, tags: []const []const u8) IdRenderer {
|
||||||
return .{
|
return .{
|
||||||
.tags = tags,
|
.tags = tags,
|
||||||
.text_cache = std.ArrayList(u8).init(allocator),
|
.text_cache = .init(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,19 +142,19 @@ pub const IdRenderer = struct {
|
|||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
try self.text_cache.append('_');
|
try self.text_cache.writer.writeByte('_');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (segment) |c| {
|
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| {
|
if (tag) |name| {
|
||||||
try self.text_cache.append('_');
|
try self.text_cache.writer.writeByte('_');
|
||||||
|
|
||||||
for (name) |c| {
|
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| {
|
while (it.next()) |segment| {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < segment.len and std.ascii.isDigit(segment[i])) {
|
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;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,26 +175,26 @@ pub const IdRenderer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i == 0 and lower_first) {
|
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 {
|
} 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;
|
lower_first = false;
|
||||||
|
|
||||||
for (segment[i + 1 ..]) |c| {
|
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| {
|
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 {
|
pub fn renderFmt(self: *IdRenderer, out: *std.Io.Writer, comptime fmt: []const u8, args: anytype) !void {
|
||||||
self.text_cache.items.len = 0;
|
_ = self.text_cache.writer.consumeAll();
|
||||||
try std.fmt.format(self.text_cache.writer(), fmt, args);
|
try self.text_cache.writer.print(fmt, args);
|
||||||
try writeIdentifier(out, self.text_cache.items);
|
try writeIdentifier(out, self.text_cache.writer.buffered());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn renderWithCase(self: *IdRenderer, out: *std.Io.Writer, case_style: CaseStyle, id: []const u8) !void {
|
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.
|
// 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;
|
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) {
|
switch (case_style) {
|
||||||
.snake => try self.renderSnake(false, adjusted_id, tag),
|
.snake => try self.renderSnake(false, adjusted_id, tag),
|
||||||
@@ -211,7 +211,7 @@ pub const IdRenderer = struct {
|
|||||||
.camel => try self.renderCamel(false, adjusted_id, tag),
|
.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 {
|
pub fn getAuthorTag(self: IdRenderer, id: []const u8) ?[]const u8 {
|
||||||
|
|||||||
31
src/main.zig
31
src/main.zig
@@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const generator = @import("vulkan/generator.zig");
|
const generator = @import("vulkan/generator.zig");
|
||||||
|
|
||||||
fn invalidUsage(prog_name: []const u8, comptime fmt: []const u8, args: anytype) noreturn {
|
fn invalidUsage(prog_name: []const u8, comptime fmt: []const u8, args: anytype) noreturn {
|
||||||
@@ -21,6 +22,11 @@ fn reportParseErrors(tree: std.zig.Ast) !void {
|
|||||||
}
|
}
|
||||||
try w.writeAll("^\n");
|
try w.writeAll("^\n");
|
||||||
}
|
}
|
||||||
|
try w.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn oomPanic() noreturn {
|
||||||
|
@panic("Out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
@@ -29,7 +35,7 @@ pub fn main() !void {
|
|||||||
const allocator = arena.allocator();
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
var args = std.process.argsWithAllocator(allocator) catch |err| switch (err) {
|
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";
|
const prog_name = args.next() orelse "vulkan-zig-generator";
|
||||||
|
|
||||||
@@ -65,6 +71,9 @@ pub fn main() !void {
|
|||||||
) catch |err| {
|
) catch |err| {
|
||||||
std.process.fatal("failed to write to stdout: {s}", .{@errorName(err)});
|
std.process.fatal("failed to write to stdout: {s}", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
|
w.interface.flush() catch |err| {
|
||||||
|
std.process.fatal("failed to flush stdout: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
return;
|
return;
|
||||||
} else if (std.mem.eql(u8, arg, "-a") or std.mem.eql(u8, arg, "--api")) {
|
} else if (std.mem.eql(u8, arg, "-a") or std.mem.eql(u8, arg, "--api")) {
|
||||||
const api_str = args.next() orelse {
|
const api_str = args.next() orelse {
|
||||||
@@ -97,20 +106,19 @@ pub fn main() !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const cwd = std.fs.cwd();
|
const cwd = std.fs.cwd();
|
||||||
const xml_src = cwd.readFileAlloc(allocator, xml_path, std.math.maxInt(usize)) catch |err| {
|
const xml_src = cwd.readFileAlloc(xml_path, allocator, .unlimited) catch |err| {
|
||||||
std.process.fatal("failed to open input file '{s}' ({s})", .{ xml_path, @errorName(err) });
|
std.process.fatal("failed to open input file '{s}' ({s})", .{ xml_path, @errorName(err) });
|
||||||
};
|
};
|
||||||
|
|
||||||
const maybe_video_xml_src = if (maybe_video_xml_path) |video_xml_path|
|
const maybe_video_xml_src = if (maybe_video_xml_path) |video_xml_path|
|
||||||
cwd.readFileAlloc(allocator, video_xml_path, std.math.maxInt(usize)) catch |err| {
|
cwd.readFileAlloc(video_xml_path, allocator, .unlimited) catch |err| {
|
||||||
std.process.fatal("failed to open input file '{s}' ({s})", .{ video_xml_path, @errorName(err) });
|
std.process.fatal("failed to open input file '{s}' ({s})", .{ video_xml_path, @errorName(err) });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
|
|
||||||
var out_buffer = std.ArrayList(u8).init(allocator);
|
var aw: std.Io.Writer.Allocating = .init(allocator);
|
||||||
var w = out_buffer.writer().adaptToNewApi();
|
generator.generate(allocator, api, xml_src, maybe_video_xml_src, &aw.writer) catch |err| {
|
||||||
generator.generate(allocator, api, xml_src, maybe_video_xml_src, &w.new_interface) catch |err| {
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -132,15 +140,16 @@ pub fn main() !void {
|
|||||||
std.log.err("please make a bug report at https://github.com/Snektron/vulkan-zig/issues/", .{});
|
std.log.err("please make a bug report at https://github.com/Snektron/vulkan-zig/issues/", .{});
|
||||||
std.process.exit(1);
|
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) {
|
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: {
|
const formatted = if (tree.errors.len > 0) blk: {
|
||||||
@@ -158,7 +167,7 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
} else tree.renderAlloc(allocator) catch |err| switch (err) {
|
} else tree.renderAlloc(allocator) catch |err| switch (err) {
|
||||||
error.OutOfMemory => @panic("oom"),
|
error.OutOfMemory => oomPanic(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (std.fs.path.dirname(out_path)) |dir| {
|
if (std.fs.path.dirname(out_path)) |dir| {
|
||||||
|
|||||||
@@ -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.
|
// 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,
|
// 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.
|
// so an ArrayList backed by an arena allocator is good enough.
|
||||||
var params = std.ArrayList(registry.Command.Param).init(allocator);
|
var params: std.ArrayList(registry.Command.Param) = .empty;
|
||||||
try params.append(.{
|
try params.append(allocator, .{
|
||||||
.name = first_param.name.?,
|
.name = first_param.name.?,
|
||||||
.param_type = first_param.decl_type,
|
.param_type = first_param.decl_type,
|
||||||
.is_buffer_len = false,
|
.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);
|
const decl = try parseDeclaration(allocator, xctok, ptrs_optional);
|
||||||
try params.append(.{
|
try params.append(allocator, .{
|
||||||
.name = decl.name orelse return error.MissingTypeIdentifier,
|
.name = decl.name orelse return error.MissingTypeIdentifier,
|
||||||
.param_type = decl.decl_type,
|
.param_type = decl.decl_type,
|
||||||
.is_buffer_len = false,
|
.is_buffer_len = false,
|
||||||
@@ -482,7 +482,7 @@ fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: Ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ = try xctok.nextNoEof();
|
_ = 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;
|
return command_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const EnumFieldMerger = struct {
|
|||||||
fn putEnumExtension(self: *EnumFieldMerger, enum_name: []const u8, field: reg.Enum.Field) !void {
|
fn putEnumExtension(self: *EnumFieldMerger, enum_name: []const u8, field: reg.Enum.Field) !void {
|
||||||
const res = try self.enum_extensions.getOrPut(self.arena, enum_name);
|
const res = try self.enum_extensions.getOrPut(self.arena, enum_name);
|
||||||
if (!res.found_existing) {
|
if (!res.found_existing) {
|
||||||
res.value_ptr.* = std.ArrayListUnmanaged(reg.Enum.Field){};
|
res.value_ptr.* = .empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
try res.value_ptr.append(self.arena, field);
|
try res.value_ptr.append(self.arena, field);
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ pub fn parseXml(
|
|||||||
|
|
||||||
const allocator = arena.allocator();
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
var decls: std.ArrayListUnmanaged(registry.Declaration) = .{};
|
var decls: std.ArrayList(registry.Declaration) = .empty;
|
||||||
var api_constants: std.ArrayListUnmanaged(registry.ApiConstant) = .{};
|
var api_constants: std.ArrayList(registry.ApiConstant) = .empty;
|
||||||
var tags: std.ArrayListUnmanaged(registry.Tag) = .{};
|
var tags: std.ArrayList(registry.Tag) = .empty;
|
||||||
var features: std.ArrayListUnmanaged(registry.Feature) = .{};
|
var features: std.ArrayList(registry.Feature) = .empty;
|
||||||
var extensions: std.ArrayListUnmanaged(registry.Extension) = .{};
|
var extensions: std.ArrayList(registry.Extension) = .empty;
|
||||||
|
|
||||||
try parseDeclarations(allocator, root, api, &decls);
|
try parseDeclarations(allocator, root, api, &decls);
|
||||||
try parseApiConstants(allocator, root, api, &api_constants);
|
try parseApiConstants(allocator, root, api, &api_constants);
|
||||||
@@ -66,7 +66,7 @@ fn parseDeclarations(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
root: *xml.Element,
|
root: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
decls: *std.ArrayListUnmanaged(registry.Declaration),
|
decls: *std.ArrayList(registry.Declaration),
|
||||||
) !void {
|
) !void {
|
||||||
const types_elem = root.findChildByTag("types") orelse return error.InvalidRegistry;
|
const types_elem = root.findChildByTag("types") orelse return error.InvalidRegistry;
|
||||||
try decls.ensureUnusedCapacity(allocator, types_elem.children.len);
|
try decls.ensureUnusedCapacity(allocator, types_elem.children.len);
|
||||||
@@ -84,7 +84,7 @@ fn parseTypes(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
types_elem: *xml.Element,
|
types_elem: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
decls: *std.ArrayListUnmanaged(registry.Declaration),
|
decls: *std.ArrayList(registry.Declaration),
|
||||||
) !void {
|
) !void {
|
||||||
var it = types_elem.findChildrenByTag("type");
|
var it = types_elem.findChildrenByTag("type");
|
||||||
while (it.next()) |ty| {
|
while (it.next()) |ty| {
|
||||||
@@ -429,7 +429,7 @@ fn parseEnums(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
root: *xml.Element,
|
root: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
decls: *std.ArrayListUnmanaged(registry.Declaration),
|
decls: *std.ArrayList(registry.Declaration),
|
||||||
) !void {
|
) !void {
|
||||||
var it = root.findChildrenByTag("enums");
|
var it = root.findChildrenByTag("enums");
|
||||||
while (it.next()) |enums| {
|
while (it.next()) |enums| {
|
||||||
@@ -519,7 +519,7 @@ fn parseCommands(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
commands_elem: *xml.Element,
|
commands_elem: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
decls: *std.ArrayListUnmanaged(registry.Declaration),
|
decls: *std.ArrayList(registry.Declaration),
|
||||||
) !void {
|
) !void {
|
||||||
var it = commands_elem.findChildrenByTag("command");
|
var it = commands_elem.findChildrenByTag("command");
|
||||||
while (it.next()) |elem| {
|
while (it.next()) |elem| {
|
||||||
@@ -630,7 +630,7 @@ fn parseApiConstants(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
root: *xml.Element,
|
root: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
api_constants: *std.ArrayListUnmanaged(registry.ApiConstant),
|
api_constants: *std.ArrayList(registry.ApiConstant),
|
||||||
) !void {
|
) !void {
|
||||||
const maybe_enums = blk: {
|
const maybe_enums = blk: {
|
||||||
var it = root.findChildrenByTag("enums");
|
var it = root.findChildrenByTag("enums");
|
||||||
@@ -672,7 +672,7 @@ fn parseDefines(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
types: *xml.Element,
|
types: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
api_constants: *std.ArrayListUnmanaged(registry.ApiConstant),
|
api_constants: *std.ArrayList(registry.ApiConstant),
|
||||||
) !void {
|
) !void {
|
||||||
var it = types.findChildrenByTag("type");
|
var it = types.findChildrenByTag("type");
|
||||||
while (it.next()) |ty| {
|
while (it.next()) |ty| {
|
||||||
@@ -703,7 +703,7 @@ fn parseDefines(
|
|||||||
fn parseTags(
|
fn parseTags(
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
root: *xml.Element,
|
root: *xml.Element,
|
||||||
tags: *std.ArrayListUnmanaged(registry.Tag),
|
tags: *std.ArrayList(registry.Tag),
|
||||||
) !void {
|
) !void {
|
||||||
var tags_elem = root.findChildByTag("tags") orelse return;
|
var tags_elem = root.findChildByTag("tags") orelse return;
|
||||||
try tags.ensureUnusedCapacity(allocator, tags_elem.children.len);
|
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");
|
var it = root.findChildrenByTag("feature");
|
||||||
while (it.next()) |feature| {
|
while (it.next()) |feature| {
|
||||||
if (!requiredByApi(feature, api))
|
if (!requiredByApi(feature, api))
|
||||||
@@ -881,7 +881,7 @@ fn parseExtensions(
|
|||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
root: *xml.Element,
|
root: *xml.Element,
|
||||||
api: registry.Api,
|
api: registry.Api,
|
||||||
extensions: *std.ArrayListUnmanaged(registry.Extension),
|
extensions: *std.ArrayList(registry.Extension),
|
||||||
) !void {
|
) !void {
|
||||||
const extensions_elem = root.findChildByTag("extensions") orelse return error.InvalidRegistry;
|
const extensions_elem = root.findChildByTag("extensions") orelse return error.InvalidRegistry;
|
||||||
try extensions.ensureUnusedCapacity(allocator, extensions_elem.children.len);
|
try extensions.ensureUnusedCapacity(allocator, extensions_elem.children.len);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
const std = @import("std");
|
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 mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
|
const id_render = @import("../id_render.zig");
|
||||||
const CaseStyle = id_render.CaseStyle;
|
const CaseStyle = id_render.CaseStyle;
|
||||||
const IdRenderer = id_render.IdRenderer;
|
const IdRenderer = id_render.IdRenderer;
|
||||||
|
const cparse = @import("c_parse.zig");
|
||||||
|
const reg = @import("registry.zig");
|
||||||
|
|
||||||
const preamble =
|
const preamble =
|
||||||
\\// This file is generated from the Khronos Vulkan XML API registry by vulkan-zig.
|
\\// This file is generated from the Khronos Vulkan XML API registry by vulkan-zig.
|
||||||
@@ -18,7 +19,7 @@ const preamble =
|
|||||||
\\
|
\\
|
||||||
\\pub const vulkan_call_conv: std.builtin.CallingConvention = if (builtin.os.tag == .windows and builtin.cpu.arch == .x86)
|
\\pub const vulkan_call_conv: std.builtin.CallingConvention = if (builtin.os.tag == .windows and builtin.cpu.arch == .x86)
|
||||||
\\ .winapi
|
\\ .winapi
|
||||||
\\ else if (builtin.abi == .android and (builtin.cpu.arch.isARM() or builtin.cpu.arch.isThumb()) and std.Target.arm.featureSetHas(builtin.cpu.features, .has_v7) and builtin.cpu.arch.ptrBitWidth() == 32)
|
\\ else if (builtin.abi == .android and (builtin.cpu.arch.isArm() or builtin.cpu.arch.isThumb()) and std.Target.arm.featureSetHas(builtin.cpu.features, .has_v7) and builtin.cpu.arch.ptrBitWidth() == 32)
|
||||||
\\ // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
\\ // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||||
\\ // calling convention, i.e. float parameters are passed in registers. This
|
\\ // calling convention, i.e. float parameters are passed in registers. This
|
||||||
\\ // is true even if the rest of the application passes floats on the stack,
|
\\ // is true even if the rest of the application passes floats on the stack,
|
||||||
@@ -58,8 +59,6 @@ const preamble =
|
|||||||
\\ return struct {
|
\\ return struct {
|
||||||
\\ pub fn format(
|
\\ pub fn format(
|
||||||
\\ self: FlagsType,
|
\\ self: FlagsType,
|
||||||
\\ comptime _: []const u8,
|
|
||||||
\\ _: std.fmt.FormatOptions,
|
|
||||||
\\ writer: anytype,
|
\\ writer: anytype,
|
||||||
\\ ) !void {
|
\\ ) !void {
|
||||||
\\ try writer.writeAll(@typeName(FlagsType) ++ "{");
|
\\ try writer.writeAll(@typeName(FlagsType) ++ "{");
|
||||||
@@ -336,6 +335,194 @@ pub fn trimVkNamespace(id: []const u8) []const u8 {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Renderer2 = struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
writer: *std.Io.Writer,
|
||||||
|
allocator: Allocator,
|
||||||
|
registry: *const reg.Registry,
|
||||||
|
id_renderer: *IdRenderer,
|
||||||
|
// decls_by_name: std.StringArrayHashMap(reg.DeclarationType),
|
||||||
|
// structure_types: std.StringHashMap(void),
|
||||||
|
have_video: bool,
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
writer: *std.Io.Writer,
|
||||||
|
allocator: Allocator,
|
||||||
|
registry: *const reg.Registry,
|
||||||
|
id_renderer: *IdRenderer,
|
||||||
|
have_video: bool,
|
||||||
|
) !Self {
|
||||||
|
return Self{
|
||||||
|
.writer = writer,
|
||||||
|
.allocator = allocator,
|
||||||
|
.registry = registry,
|
||||||
|
.id_renderer = id_renderer,
|
||||||
|
// .decls_by_name = decls_by_name,
|
||||||
|
// .structure_types = structure_types,
|
||||||
|
.have_video = have_video,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *Self) void {
|
||||||
|
_ = self; // autofix
|
||||||
|
// self.decls_by_name.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Error = error{
|
||||||
|
UnhandledBitfieldStruct,
|
||||||
|
InvalidApiConstant,
|
||||||
|
InvalidConstantExpr,
|
||||||
|
InvalidRegistry,
|
||||||
|
UnexpectedCharacter,
|
||||||
|
InvalidCharacter,
|
||||||
|
Overflow,
|
||||||
|
OutOfMemory,
|
||||||
|
WriteFailed,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn render(self: *Self) Error!void {
|
||||||
|
try self.renderDecls();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text(self: *Self, str: []const u8) Error!void {
|
||||||
|
try self.writer.writeAll(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(self: *Self, comptime fmt: []const u8, args: anytype) Error!void {
|
||||||
|
try self.writer.print(fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn idWithCase(self: *Self, case: CaseStyle, id: []const u8) Error!void {
|
||||||
|
try self.id_renderer.renderWithCase(self.writer, case, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _reserved_names = std.StaticStringMap([]const u8).initComptime(.{
|
||||||
|
.{ "void", "void" },
|
||||||
|
.{ "char", "u8" },
|
||||||
|
.{ "float", "f32" },
|
||||||
|
.{ "double", "f64" },
|
||||||
|
.{ "uint8_t", "u8" },
|
||||||
|
.{ "int8_t", "i8" },
|
||||||
|
.{ "int16_t", "i16" },
|
||||||
|
.{ "uint16_t", "u16" },
|
||||||
|
.{ "uint32_t", "u32" },
|
||||||
|
.{ "uint64_t", "u64" },
|
||||||
|
.{ "int32_t", "i32" },
|
||||||
|
.{ "int64_t", "i64" },
|
||||||
|
.{ "size_t", "usize" },
|
||||||
|
.{ "int", "c_int" },
|
||||||
|
});
|
||||||
|
|
||||||
|
fn renderDecls(self: *Self) Error!void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
for (self.registry.decls) |decl| {
|
||||||
|
defer _ = arena.reset(.retain_capacity);
|
||||||
|
|
||||||
|
switch (decl.decl_type) {
|
||||||
|
.alias => |alias| {
|
||||||
|
switch (alias.target) {
|
||||||
|
.other_command => try self.print("pub const Pfn{s} = Pfn{s};\n", .{
|
||||||
|
trimVkNamespace(decl.name),
|
||||||
|
trimVkNamespace(alias.name),
|
||||||
|
}),
|
||||||
|
.other_type => try self.print("pub const {s} = {s};\n", .{
|
||||||
|
trimVkNamespace(decl.name),
|
||||||
|
trimVkNamespace(alias.name),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.handle => |handle| {
|
||||||
|
const backing_int = if (handle.is_dispatchable) "usize" else "u32";
|
||||||
|
try self.print("pub const {s} = enum({s}) {{ null_handle = 0, _ }}; // parent {?s}\n", .{
|
||||||
|
trimVkNamespace(decl.name),
|
||||||
|
backing_int,
|
||||||
|
handle.parent,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
.typedef => |typ| {
|
||||||
|
try self.text("pub const ");
|
||||||
|
if (typ == .command_ptr) {
|
||||||
|
try self.text("Pfn");
|
||||||
|
}
|
||||||
|
try self.text(trimVkNamespace(decl.name));
|
||||||
|
try self.text(" = ");
|
||||||
|
try self.typeInfo(typ);
|
||||||
|
try self.text(";\n");
|
||||||
|
},
|
||||||
|
.foreign => |frn| {
|
||||||
|
if (_reserved_names.has(decl.name)) continue;
|
||||||
|
try self.print("pub const {s} = opaque {{}};", .{trimVkNamespace(decl.name)});
|
||||||
|
if (frn.depends.len > 0) {
|
||||||
|
try self.print(" // requires \"{s}\"", .{frn.depends});
|
||||||
|
}
|
||||||
|
try self.text("\n");
|
||||||
|
},
|
||||||
|
.command => |cmd| {
|
||||||
|
try self.text("pub const Pfn");
|
||||||
|
try self.idWithCase(.title, trimVkNamespace(decl.name));
|
||||||
|
try self.text(" = *const ");
|
||||||
|
try self.commandType(cmd);
|
||||||
|
try self.text(";\n");
|
||||||
|
},
|
||||||
|
else => try self.print("pub const {s} = undefined; // {s};\n", .{
|
||||||
|
trimVkNamespace(decl.name),
|
||||||
|
@tagName(decl.decl_type),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commandType(self: *Self, cmd: reg.Command) Error!void {
|
||||||
|
try self.text("fn(");
|
||||||
|
for (cmd.params, 0..) |param, idx| {
|
||||||
|
if (idx > 0) try self.text(", ");
|
||||||
|
try self.idWithCase(.snake, param.name);
|
||||||
|
try self.text(": ");
|
||||||
|
try self.typeInfo(param.param_type);
|
||||||
|
}
|
||||||
|
try self.text(") void");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn typeInfo(self: *Self, typ: reg.TypeInfo) Error!void {
|
||||||
|
switch (typ) {
|
||||||
|
.name => |name| {
|
||||||
|
if (_reserved_names.get(name)) |real| {
|
||||||
|
try self.text(real);
|
||||||
|
} else {
|
||||||
|
try self.text(trimVkNamespace(name));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.command_ptr => |cmd| {
|
||||||
|
try self.text("?*const ");
|
||||||
|
try self.commandType(cmd);
|
||||||
|
},
|
||||||
|
.pointer => |ptr| {
|
||||||
|
if (ptr.is_optional) try self.text("?");
|
||||||
|
switch (ptr.size) {
|
||||||
|
.one => try self.text("*"),
|
||||||
|
.many, .other_field => try self.text("[*]"),
|
||||||
|
.zero_terminated => try self.text("[*:0]"),
|
||||||
|
}
|
||||||
|
if (ptr.is_const) try self.text("const ");
|
||||||
|
try self.typeInfo(ptr.child.*);
|
||||||
|
},
|
||||||
|
.array => |arr| {
|
||||||
|
if (arr.is_optional) try self.text("?");
|
||||||
|
try self.text("[");
|
||||||
|
switch (arr.size) {
|
||||||
|
.int => |size| try self.print("{}", .{size}),
|
||||||
|
.alias => |_| @panic("Not implemented."),
|
||||||
|
}
|
||||||
|
try self.text("]");
|
||||||
|
try self.typeInfo(arr.child.*);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const Renderer = struct {
|
const Renderer = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
const RenderTypeInfoError = std.Io.Writer.Error || std.fmt.ParseIntError || error{ OutOfMemory, InvalidRegistry };
|
const RenderTypeInfoError = std.Io.Writer.Error || std.fmt.ParseIntError || error{ OutOfMemory, InvalidRegistry };
|
||||||
@@ -849,6 +1036,10 @@ const Renderer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn renderDecl(self: *Self, decl: reg.Declaration) !void {
|
fn renderDecl(self: *Self, decl: reg.Declaration) !void {
|
||||||
|
if (try self.renderSpecial(decl.name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (decl.decl_type) {
|
switch (decl.decl_type) {
|
||||||
.container => |container| try self.renderContainer(decl.name, container),
|
.container => |container| try self.renderContainer(decl.name, container),
|
||||||
.enumeration => |enumeration| try self.renderEnumeration(decl.name, enumeration),
|
.enumeration => |enumeration| try self.renderEnumeration(decl.name, enumeration),
|
||||||
@@ -862,10 +1053,27 @@ const Renderer = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderSpecialContainer(self: *Self, name: []const u8) !bool {
|
fn renderAssign(self: *Self, name: []const u8) !void {
|
||||||
|
try self.writer.writeAll("pub const ");
|
||||||
|
try self.renderName(name);
|
||||||
|
try self.writer.writeAll(" = ");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn renderSpecial(self: *Self, name: []const u8) !bool {
|
||||||
const maybe_author = self.id_renderer.getAuthorTag(name);
|
const maybe_author = self.id_renderer.getAuthorTag(name);
|
||||||
const basename = self.id_renderer.stripAuthorTag(name);
|
const basename = self.id_renderer.stripAuthorTag(name);
|
||||||
if (std.mem.eql(u8, basename, "VkAccelerationStructureInstance")) {
|
if (std.mem.eql(u8, basename, "VkBool32")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
|
try self.writer.writeAll(
|
||||||
|
\\enum(i32) {
|
||||||
|
\\ false,
|
||||||
|
\\ true,
|
||||||
|
\\ _,
|
||||||
|
\\};
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
} else if (std.mem.eql(u8, basename, "VkAccelerationStructureInstance")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ transform: TransformMatrix{s},
|
\\ transform: TransformMatrix{s},
|
||||||
@@ -883,8 +1091,8 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
} else if (std.mem.eql(u8, basename, "VkAccelerationStructureSRTMotionInstance")) {
|
} else if (std.mem.eql(u8, basename, "VkAccelerationStructureSRTMotionInstance")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ transform_t0: SRTData{0s},
|
\\ transform_t0: SRTData{0s},
|
||||||
@@ -903,8 +1111,8 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
} else if (std.mem.eql(u8, basename, "VkAccelerationStructureMatrixMotionInstance")) {
|
} else if (std.mem.eql(u8, basename, "VkAccelerationStructureMatrixMotionInstance")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ transform_t0: TransformMatrix{0s},
|
\\ transform_t0: TransformMatrix{0s},
|
||||||
@@ -923,8 +1131,8 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureBuildTriangleClusterInfo")) {
|
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureBuildTriangleClusterInfo")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ cluster_id: u32,
|
\\ cluster_id: u32,
|
||||||
@@ -950,8 +1158,8 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureBuildTriangleClusterTemplateInfo")) {
|
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureBuildTriangleClusterTemplateInfo")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ cluster_id: u32,
|
\\ cluster_id: u32,
|
||||||
@@ -978,8 +1186,8 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
|
||||||
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureInstantiateClusterInfo")) {
|
} else if (std.mem.eql(u8, basename, "VkClusterAccelerationStructureInstantiateClusterInfo")) {
|
||||||
|
try self.renderAssign(name);
|
||||||
try self.writer.print(
|
try self.writer.print(
|
||||||
\\extern struct {{
|
\\extern struct {{
|
||||||
\\ cluster_id_offset: u32,
|
\\ cluster_id_offset: u32,
|
||||||
@@ -993,10 +1201,11 @@ const Renderer = struct {
|
|||||||
,
|
,
|
||||||
.{maybe_author orelse ""},
|
.{maybe_author orelse ""},
|
||||||
);
|
);
|
||||||
return true;
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderSimpleBitContainer(self: *Self, container: reg.Container) !bool {
|
fn renderSimpleBitContainer(self: *Self, container: reg.Container) !bool {
|
||||||
@@ -1052,10 +1261,6 @@ const Renderer = struct {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (try self.renderSpecialContainer(name)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (container.fields) |field| {
|
for (container.fields) |field| {
|
||||||
if (field.bits != null) {
|
if (field.bits != null) {
|
||||||
return error.UnhandledBitfieldStruct;
|
return error.UnhandledBitfieldStruct;
|
||||||
@@ -1110,7 +1315,7 @@ const Renderer = struct {
|
|||||||
try self.writer.writeAll(" = .");
|
try self.writer.writeAll(" = .");
|
||||||
try self.writeIdentifierWithCase(.snake, stype["VK_STRUCTURE_TYPE_".len..]);
|
try self.writeIdentifierWithCase(.snake, stype["VK_STRUCTURE_TYPE_".len..]);
|
||||||
} else if (field.field_type == .name and mem.eql(u8, "VkBool32", field.field_type.name) and isFeatureStruct(name, container.extends)) {
|
} else if (field.field_type == .name and mem.eql(u8, "VkBool32", field.field_type.name) and isFeatureStruct(name, container.extends)) {
|
||||||
try self.writer.writeAll(" = FALSE");
|
try self.writer.writeAll(" = .false");
|
||||||
} else if (field.is_optional) {
|
} else if (field.is_optional) {
|
||||||
if (field.field_type == .name) {
|
if (field.field_type == .name) {
|
||||||
const field_type_name = field.field_type.name;
|
const field_type_name = field.field_type.name;
|
||||||
@@ -1121,6 +1326,8 @@ const Renderer = struct {
|
|||||||
try self.writer.writeAll(" = .{}");
|
try self.writer.writeAll(" = .{}");
|
||||||
} else if (decl_type == .typedef and decl_type.typedef == .command_ptr) {
|
} else if (decl_type == .typedef and decl_type.typedef == .command_ptr) {
|
||||||
try self.writer.writeAll(" = null");
|
try self.writer.writeAll(" = null");
|
||||||
|
} else if (mem.eql(u8, "VkBool32", field.field_type.name)) {
|
||||||
|
try self.writer.writeAll(" = .false");
|
||||||
} else if ((decl_type == .typedef and builtin_types.has(decl_type.typedef.name)) or
|
} else if ((decl_type == .typedef and builtin_types.has(decl_type.typedef.name)) or
|
||||||
(decl_type == .foreign and builtin_types.has(field_type_name)))
|
(decl_type == .foreign and builtin_types.has(field_type_name)))
|
||||||
{
|
{
|
||||||
@@ -1810,12 +2017,13 @@ const Renderer = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extractReturns(self: *Self, command: reg.Command) ![]const ReturnValue {
|
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) {
|
if (command.return_type.* == .name) {
|
||||||
const return_name = 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")) {
|
if (!mem.eql(u8, return_name, "void") and !mem.eql(u8, return_name, "VkResult")) {
|
||||||
try returns.append(.{
|
try returns.append(allocator, .{
|
||||||
.name = "return_value",
|
.name = "return_value",
|
||||||
.return_value_type = command.return_type.*,
|
.return_value_type = command.return_type.*,
|
||||||
.origin = .inner_return_value,
|
.origin = .inner_return_value,
|
||||||
@@ -1828,7 +2036,7 @@ const Renderer = struct {
|
|||||||
return error.InvalidRegistry;
|
return error.InvalidRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
try returns.append(.{
|
try returns.append(allocator, .{
|
||||||
.name = "result",
|
.name = "result",
|
||||||
.return_value_type = command.return_type.*,
|
.return_value_type = command.return_type.*,
|
||||||
.origin = .inner_return_value,
|
.origin = .inner_return_value,
|
||||||
@@ -1839,7 +2047,7 @@ const Renderer = struct {
|
|||||||
|
|
||||||
for (command.params) |param| {
|
for (command.params) |param| {
|
||||||
if ((try self.classifyParam(param)) == .out_pointer) {
|
if ((try self.classifyParam(param)) == .out_pointer) {
|
||||||
try returns.append(.{
|
try returns.append(allocator, .{
|
||||||
.name = derefName(param.name),
|
.name = derefName(param.name),
|
||||||
.return_value_type = param.param_type.pointer.child.*,
|
.return_value_type = param.param_type.pointer.child.*,
|
||||||
.origin = .parameter,
|
.origin = .parameter,
|
||||||
@@ -1847,7 +2055,7 @@ const Renderer = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return try returns.toOwnedSlice();
|
return try returns.toOwnedSlice(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderReturnStructName(self: *Self, command_name: []const u8) !void {
|
fn renderReturnStructName(self: *Self, command_name: []const u8) !void {
|
||||||
@@ -2121,7 +2329,9 @@ pub fn render(
|
|||||||
id_renderer: *IdRenderer,
|
id_renderer: *IdRenderer,
|
||||||
have_video: bool,
|
have_video: bool,
|
||||||
) !void {
|
) !void {
|
||||||
var renderer = try Renderer.init(writer, allocator, registry, id_renderer, have_video);
|
// var renderer = try Renderer.init(writer, allocator, registry, id_renderer, have_video);
|
||||||
|
var renderer = try Renderer2.init(writer, allocator, registry, id_renderer, have_video);
|
||||||
defer renderer.deinit();
|
defer renderer.deinit();
|
||||||
try renderer.render();
|
try renderer.render();
|
||||||
|
try writer.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/xml.zig
16
src/xml.zig
@@ -439,15 +439,15 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var attributes = std.ArrayList(Attribute).init(alloc);
|
var attributes: std.ArrayList(Attribute) = .empty;
|
||||||
defer attributes.deinit();
|
defer attributes.deinit(alloc);
|
||||||
|
|
||||||
var children = std.ArrayList(Content).init(alloc);
|
var children: std.ArrayList(Content) = .empty;
|
||||||
defer children.deinit();
|
defer children.deinit(alloc);
|
||||||
|
|
||||||
while (parser.eatWs()) {
|
while (parser.eatWs()) {
|
||||||
const attr = (try parseAttr(parser, alloc)) orelse break;
|
const attr = (try parseAttr(parser, alloc)) orelse break;
|
||||||
try attributes.append(attr);
|
try attributes.append(alloc, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
@@ -464,7 +464,7 @@ fn parseElement(parser: *Parser, alloc: Allocator, comptime kind: ElementKind) !
|
|||||||
}
|
}
|
||||||
|
|
||||||
const content = try parseContent(parser, alloc);
|
const content = try parseContent(parser, alloc);
|
||||||
try children.append(content);
|
try children.append(alloc, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
const closing_tag = try parseNameNoDupe(parser);
|
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);
|
const element = try alloc.create(Element);
|
||||||
element.* = .{
|
element.* = .{
|
||||||
.tag = try alloc.dupe(u8, tag),
|
.tag = try alloc.dupe(u8, tag),
|
||||||
.attributes = try attributes.toOwnedSlice(),
|
.attributes = try attributes.toOwnedSlice(alloc),
|
||||||
.children = try children.toOwnedSlice(),
|
.children = try children.toOwnedSlice(alloc),
|
||||||
};
|
};
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user