zig fmt **.zig

This commit is contained in:
Robin Voetter
2021-06-13 15:15:42 +02:00
parent 4b4ef38c93
commit 419e541a16
12 changed files with 313 additions and 342 deletions

View File

@@ -3,9 +3,7 @@ const vk = @import("vulkan");
const c = @import("c.zig"); const c = @import("c.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const required_device_extensions = [_][]const u8{ const required_device_extensions = [_][]const u8{vk.extension_info.khr_swapchain.name};
vk.extension_info.khr_swapchain.name
};
const BaseDispatch = struct { const BaseDispatch = struct {
vkCreateInstance: vk.PfnCreateInstance, vkCreateInstance: vk.PfnCreateInstance,
@@ -151,11 +149,11 @@ pub const GraphicsContext = struct {
pub fn deviceName(self: GraphicsContext) []const u8 { pub fn deviceName(self: GraphicsContext) []const u8 {
const len = std.mem.indexOfScalar(u8, &self.props.device_name, 0).?; const len = std.mem.indexOfScalar(u8, &self.props.device_name, 0).?;
return self.props.device_name[0 .. len]; return self.props.device_name[0..len];
} }
pub fn findMemoryTypeIndex(self: GraphicsContext, memory_type_bits: u32, flags: vk.MemoryPropertyFlags) !u32 { pub fn findMemoryTypeIndex(self: GraphicsContext, memory_type_bits: u32, flags: vk.MemoryPropertyFlags) !u32 {
for (self.mem_props.memory_types[0 .. self.mem_props.memory_type_count]) |mem_type, i| { for (self.mem_props.memory_types[0..self.mem_props.memory_type_count]) |mem_type, i| {
if (memory_type_bits & (@as(u32, 1) << @truncate(u5, i)) != 0 and mem_type.property_flags.contains(flags)) { if (memory_type_bits & (@as(u32, 1) << @truncate(u5, i)) != 0 and mem_type.property_flags.contains(flags)) {
return @truncate(u32, i); return @truncate(u32, i);
} }
@@ -207,13 +205,13 @@ fn initializeCandidate(vki: InstanceDispatch, candidate: DeviceCandidate) !vk.De
.queue_family_index = candidate.queues.present_family, .queue_family_index = candidate.queues.present_family,
.queue_count = 1, .queue_count = 1,
.p_queue_priorities = &priority, .p_queue_priorities = &priority,
} },
}; };
const queue_count: u32 = if (candidate.queues.graphics_family == candidate.queues.present_family) const queue_count: u32 = if (candidate.queues.graphics_family == candidate.queues.present_family)
1 1
else else
2; 2;
return try vki.createDevice(candidate.pdev, .{ return try vki.createDevice(candidate.pdev, .{
.flags = .{}, .flags = .{},
@@ -281,19 +279,14 @@ fn checkSuitable(
return DeviceCandidate{ return DeviceCandidate{
.pdev = pdev, .pdev = pdev,
.props = props, .props = props,
.queues = allocation .queues = allocation,
}; };
} }
return null; return null;
} }
fn allocateQueues( fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: *Allocator, surface: vk.SurfaceKHR) !?QueueAllocation {
vki: InstanceDispatch,
pdev: vk.PhysicalDevice,
allocator: *Allocator,
surface: vk.SurfaceKHR
) !?QueueAllocation {
var family_count: u32 = undefined; var family_count: u32 = undefined;
vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null); vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
@@ -307,7 +300,7 @@ fn allocateQueues(
for (families) |properties, i| { for (families) |properties, i| {
const family = @intCast(u32, i); const family = @intCast(u32, i);
if (graphics_family == null and properties.queue_flags.contains(.{.graphics_bit = true})) { if (graphics_family == null and properties.queue_flags.graphics_bit) {
graphics_family = family; graphics_family = family;
} }
@@ -319,7 +312,7 @@ fn allocateQueues(
if (graphics_family != null and present_family != null) { if (graphics_family != null and present_family != null) {
return QueueAllocation{ return QueueAllocation{
.graphics_family = graphics_family.?, .graphics_family = graphics_family.?,
.present_family = present_family.? .present_family = present_family.?,
}; };
} }
@@ -352,7 +345,7 @@ fn checkExtensionSupport(
for (required_device_extensions) |ext| { for (required_device_extensions) |ext| {
for (propsv) |props| { for (propsv) |props| {
const len = std.mem.indexOfScalar(u8, &props.extension_name, 0).?; const len = std.mem.indexOfScalar(u8, &props.extension_name, 0).?;
const prop_ext_name = props.extension_name[0 .. len]; const prop_ext_name = props.extension_name[0..len];
if (std.mem.eql(u8, ext, prop_ext_name)) { if (std.mem.eql(u8, ext, prop_ext_name)) {
break; break;
} }

View File

@@ -41,7 +41,7 @@ pub const Swapchain = struct {
} }
const concurrent = gc.graphics_queue.family != gc.present_queue.family; const concurrent = gc.graphics_queue.family != gc.present_queue.family;
const qfi = [_]u32{gc.graphics_queue.family, gc.present_queue.family}; const qfi = [_]u32{ gc.graphics_queue.family, gc.present_queue.family };
const handle = try gc.vkd.createSwapchainKHR(gc.dev, .{ const handle = try gc.vkd.createSwapchainKHR(gc.dev, .{
.flags = .{}, .flags = .{},
@@ -51,12 +51,12 @@ pub const Swapchain = struct {
.image_color_space = surface_format.color_space, .image_color_space = surface_format.color_space,
.image_extent = actual_extent, .image_extent = actual_extent,
.image_array_layers = 1, .image_array_layers = 1,
.image_usage = .{.color_attachment_bit = true, .transfer_dst_bit = true}, .image_usage = .{ .color_attachment_bit = true, .transfer_dst_bit = true },
.image_sharing_mode = if (concurrent) .concurrent else .exclusive, .image_sharing_mode = if (concurrent) .concurrent else .exclusive,
.queue_family_index_count = qfi.len, .queue_family_index_count = qfi.len,
.p_queue_family_indices = &qfi, .p_queue_family_indices = &qfi,
.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 = vk.TRUE,
.old_swapchain = old_handle, .old_swapchain = old_handle,
@@ -71,7 +71,7 @@ pub const Swapchain = struct {
const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator); const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator);
errdefer for (swap_images) |si| si.deinit(gc); errdefer for (swap_images) |si| si.deinit(gc);
var next_image_acquired = try gc.vkd.createSemaphore(gc.dev, .{.flags = .{}}, null); var next_image_acquired = try gc.vkd.createSemaphore(gc.dev, .{ .flags = .{} }, null);
errdefer gc.vkd.destroySemaphore(gc.dev, next_image_acquired, null); errdefer gc.vkd.destroySemaphore(gc.dev, next_image_acquired, null);
const result = try gc.vkd.acquireNextImageKHR(gc.dev, handle, std.math.maxInt(u64), next_image_acquired, .null_handle); const result = try gc.vkd.acquireNextImageKHR(gc.dev, handle, std.math.maxInt(u64), next_image_acquired, .null_handle);
@@ -147,7 +147,7 @@ pub const Swapchain = struct {
try self.gc.vkd.resetFences(self.gc.dev, 1, @ptrCast([*]const vk.Fence, &current.frame_fence)); try self.gc.vkd.resetFences(self.gc.dev, 1, @ptrCast([*]const vk.Fence, &current.frame_fence));
// Step 2: Submit the command buffer // Step 2: Submit the command buffer
const wait_stage = [_]vk.PipelineStageFlags{.{.top_of_pipe_bit = true}}; const wait_stage = [_]vk.PipelineStageFlags{.{ .top_of_pipe_bit = true }};
try self.gc.vkd.queueSubmit(self.gc.graphics_queue.handle, 1, &[_]vk.SubmitInfo{.{ try self.gc.vkd.queueSubmit(self.gc.graphics_queue.handle, 1, &[_]vk.SubmitInfo{.{
.wait_semaphore_count = 1, .wait_semaphore_count = 1,
.p_wait_semaphores = @ptrCast([*]const vk.Semaphore, &current.image_acquired), .p_wait_semaphores = @ptrCast([*]const vk.Semaphore, &current.image_acquired),
@@ -201,9 +201,9 @@ const SwapImage = struct {
.image = image, .image = image,
.view_type = .@"2d", .view_type = .@"2d",
.format = format, .format = format,
.components = .{.r = .identity, .g = .identity, .b = .identity, .a = .identity}, .components = .{ .r = .identity, .g = .identity, .b = .identity, .a = .identity },
.subresource_range = .{ .subresource_range = .{
.aspect_mask = .{.color_bit = true}, .aspect_mask = .{ .color_bit = true },
.base_mip_level = 0, .base_mip_level = 0,
.level_count = 1, .level_count = 1,
.base_array_layer = 0, .base_array_layer = 0,
@@ -212,13 +212,13 @@ const SwapImage = struct {
}, null); }, null);
errdefer gc.vkd.destroyImageView(gc.dev, view, null); errdefer gc.vkd.destroyImageView(gc.dev, view, null);
const image_acquired = try gc.vkd.createSemaphore(gc.dev, .{.flags = .{}}, null); const image_acquired = try gc.vkd.createSemaphore(gc.dev, .{ .flags = .{} }, null);
errdefer gc.vkd.destroySemaphore(gc.dev, image_acquired, null); errdefer gc.vkd.destroySemaphore(gc.dev, image_acquired, null);
const render_finished = try gc.vkd.createSemaphore(gc.dev, .{.flags = .{}}, null); const render_finished = try gc.vkd.createSemaphore(gc.dev, .{ .flags = .{} }, null);
errdefer gc.vkd.destroySemaphore(gc.dev, image_acquired, null); errdefer gc.vkd.destroySemaphore(gc.dev, image_acquired, null);
const frame_fence = try gc.vkd.createFence(gc.dev, .{.flags = .{.signaled_bit = true}}, null); const frame_fence = try gc.vkd.createFence(gc.dev, .{ .flags = .{ .signaled_bit = true } }, null);
errdefer gc.vkd.destroyFence(gc.dev, frame_fence, null); errdefer gc.vkd.destroyFence(gc.dev, frame_fence, null);
return SwapImage{ return SwapImage{
@@ -254,7 +254,7 @@ fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, f
errdefer allocator.free(images); errdefer allocator.free(images);
var i: usize = 0; var i: usize = 0;
errdefer for (swap_images[0 .. i]) |si| si.deinit(gc); errdefer for (swap_images[0..i]) |si| si.deinit(gc);
for (images) |image| { for (images) |image| {
swap_images[i] = try SwapImage.init(gc, image, format); swap_images[i] = try SwapImage.init(gc, image, format);

View File

@@ -35,16 +35,16 @@ const Vertex = struct {
}; };
const vertices = [_]Vertex{ const vertices = [_]Vertex{
.{.pos = .{0, -0.5}, .color = .{1, 0, 0}}, .{ .pos = .{ 0, -0.5 }, .color = .{ 1, 0, 0 } },
.{.pos = .{0.5, 0.5}, .color = .{0, 1, 0}}, .{ .pos = .{ 0.5, 0.5 }, .color = .{ 0, 1, 0 } },
.{.pos = .{-0.5, 0.5}, .color = .{0, 0, 1}}, .{ .pos = .{ -0.5, 0.5 }, .color = .{ 0, 0, 1 } },
}; };
pub fn main() !void { pub fn main() !void {
if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed; if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed;
defer c.glfwTerminate(); defer c.glfwTerminate();
var extent = vk.Extent2D{.width = 800, .height = 600}; var extent = vk.Extent2D{ .width = 800, .height = 600 };
c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API); c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API);
const window = c.glfwCreateWindow( const window = c.glfwCreateWindow(
@@ -52,7 +52,7 @@ pub fn main() !void {
@intCast(c_int, extent.height), @intCast(c_int, extent.height),
app_name, app_name,
null, null,
null null,
) orelse return error.WindowInitFailed; ) orelse return error.WindowInitFailed;
defer c.glfwDestroyWindow(window); defer c.glfwDestroyWindow(window);
@@ -61,7 +61,7 @@ pub fn main() !void {
const gc = try GraphicsContext.init(allocator, app_name, window); const gc = try GraphicsContext.init(allocator, app_name, window);
defer gc.deinit(); defer gc.deinit();
std.debug.print("Using device: {s}\n", .{ gc.deviceName() }); std.debug.print("Using device: {s}\n", .{gc.deviceName()});
var swapchain = try Swapchain.init(&gc, allocator, extent); var swapchain = try Swapchain.init(&gc, allocator, extent);
defer swapchain.deinit(); defer swapchain.deinit();
@@ -93,14 +93,14 @@ pub fn main() !void {
const buffer = try gc.vkd.createBuffer(gc.dev, .{ const buffer = try gc.vkd.createBuffer(gc.dev, .{
.flags = .{}, .flags = .{},
.size = @sizeOf(@TypeOf(vertices)), .size = @sizeOf(@TypeOf(vertices)),
.usage = .{.transfer_dst_bit = true, .vertex_buffer_bit = true}, .usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true },
.sharing_mode = .exclusive, .sharing_mode = .exclusive,
.queue_family_index_count = 0, .queue_family_index_count = 0,
.p_queue_family_indices = undefined, .p_queue_family_indices = undefined,
}, null); }, null);
defer gc.vkd.destroyBuffer(gc.dev, buffer, null); defer gc.vkd.destroyBuffer(gc.dev, buffer, null);
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer); const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer);
const memory = try gc.allocate(mem_reqs, .{.device_local_bit = true}); const memory = try gc.allocate(mem_reqs, .{ .device_local_bit = true });
defer gc.vkd.freeMemory(gc.dev, memory, null); defer gc.vkd.freeMemory(gc.dev, memory, null);
try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0); try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0);
@@ -114,7 +114,7 @@ pub fn main() !void {
swapchain.extent, swapchain.extent,
render_pass, render_pass,
pipeline, pipeline,
framebuffers framebuffers,
); );
defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs); defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
@@ -146,13 +146,12 @@ pub fn main() !void {
swapchain.extent, swapchain.extent,
render_pass, render_pass,
pipeline, pipeline,
framebuffers framebuffers,
); );
} }
c.glfwSwapBuffers(window); c.glfwSwapBuffers(window);
c.glfwPollEvents(); c.glfwPollEvents();
} }
try swapchain.waitForAllFences(); try swapchain.waitForAllFences();
@@ -162,14 +161,14 @@ fn uploadVertices(gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.B
const staging_buffer = try gc.vkd.createBuffer(gc.dev, .{ const staging_buffer = try gc.vkd.createBuffer(gc.dev, .{
.flags = .{}, .flags = .{},
.size = @sizeOf(@TypeOf(vertices)), .size = @sizeOf(@TypeOf(vertices)),
.usage = .{.transfer_src_bit = true}, .usage = .{ .transfer_src_bit = true },
.sharing_mode = .exclusive, .sharing_mode = .exclusive,
.queue_family_index_count = 0, .queue_family_index_count = 0,
.p_queue_family_indices = undefined, .p_queue_family_indices = undefined,
}, null); }, null);
defer gc.vkd.destroyBuffer(gc.dev, staging_buffer, null); defer gc.vkd.destroyBuffer(gc.dev, staging_buffer, null);
const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, staging_buffer); const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, staging_buffer);
const staging_memory = try gc.allocate(mem_reqs, .{.host_visible_bit = true, .host_coherent_bit = true}); const staging_memory = try gc.allocate(mem_reqs, .{ .host_visible_bit = true, .host_coherent_bit = true });
defer gc.vkd.freeMemory(gc.dev, staging_memory, null); defer gc.vkd.freeMemory(gc.dev, staging_memory, null);
try gc.vkd.bindBufferMemory(gc.dev, staging_buffer, staging_memory, 0); try gc.vkd.bindBufferMemory(gc.dev, staging_buffer, staging_memory, 0);
@@ -196,7 +195,7 @@ fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer,
defer gc.vkd.freeCommandBuffers(gc.dev, pool, 1, @ptrCast([*]const vk.CommandBuffer, &cmdbuf)); defer gc.vkd.freeCommandBuffers(gc.dev, pool, 1, @ptrCast([*]const vk.CommandBuffer, &cmdbuf));
try gc.vkd.beginCommandBuffer(cmdbuf, .{ try gc.vkd.beginCommandBuffer(cmdbuf, .{
.flags = .{.one_time_submit_bit = true}, .flags = .{ .one_time_submit_bit = true },
.p_inheritance_info = null, .p_inheritance_info = null,
}); });
@@ -243,7 +242,7 @@ fn createCommandBuffers(
errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr); errdefer gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr);
const clear = vk.ClearValue{ const clear = vk.ClearValue{
.color = .{.float_32 = .{0, 0, 0, 1}}, .color = .{ .float_32 = .{ 0, 0, 0, 1 } },
}; };
const viewport = vk.Viewport{ const viewport = vk.Viewport{
@@ -256,7 +255,7 @@ fn createCommandBuffers(
}; };
const scissor = vk.Rect2D{ const scissor = vk.Rect2D{
.offset = .{.x = 0, .y = 0}, .offset = .{ .x = 0, .y = 0 },
.extent = extent, .extent = extent,
}; };
@@ -273,7 +272,7 @@ fn createCommandBuffers(
.render_pass = render_pass, .render_pass = render_pass,
.framebuffer = framebuffers[i], .framebuffer = framebuffers[i],
.render_area = .{ .render_area = .{
.offset = .{.x = 0, .y = 0}, .offset = .{ .x = 0, .y = 0 },
.extent = extent, .extent = extent,
}, },
.clear_value_count = 1, .clear_value_count = 1,
@@ -297,17 +296,12 @@ fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, alloc
allocator.free(cmdbufs); allocator.free(cmdbufs);
} }
fn createFramebuffers( fn createFramebuffers(gc: *const GraphicsContext, allocator: *Allocator, render_pass: vk.RenderPass, swapchain: Swapchain) ![]vk.Framebuffer {
gc: *const GraphicsContext,
allocator: *Allocator,
render_pass: vk.RenderPass,
swapchain: Swapchain
) ![]vk.Framebuffer {
const framebuffers = try allocator.alloc(vk.Framebuffer, swapchain.swap_images.len); const framebuffers = try allocator.alloc(vk.Framebuffer, swapchain.swap_images.len);
errdefer allocator.free(framebuffers); errdefer allocator.free(framebuffers);
var i: usize = 0; var i: usize = 0;
errdefer for (framebuffers[0 .. i]) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null); errdefer for (framebuffers[0..i]) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
for (framebuffers) |*fb| { for (framebuffers) |*fb| {
fb.* = try gc.vkd.createFramebuffer(gc.dev, .{ fb.* = try gc.vkd.createFramebuffer(gc.dev, .{
@@ -334,7 +328,7 @@ fn createRenderPass(gc: *const GraphicsContext, swapchain: Swapchain) !vk.Render
const color_attachment = vk.AttachmentDescription{ const color_attachment = vk.AttachmentDescription{
.flags = .{}, .flags = .{},
.format = swapchain.surface_format.format, .format = swapchain.surface_format.format,
.samples = .{.@"1_bit" = true}, .samples = .{ .@"1_bit" = true },
.load_op = .clear, .load_op = .clear,
.store_op = .store, .store_op = .store,
.stencil_load_op = .dont_care, .stencil_load_op = .dont_care,
@@ -395,14 +389,14 @@ fn createPipeline(
const pssci = [_]vk.PipelineShaderStageCreateInfo{ const pssci = [_]vk.PipelineShaderStageCreateInfo{
.{ .{
.flags = .{}, .flags = .{},
.stage = .{.vertex_bit = true}, .stage = .{ .vertex_bit = true },
.module = vert, .module = vert,
.p_name = "main", .p_name = "main",
.p_specialization_info = null, .p_specialization_info = null,
}, },
.{ .{
.flags = .{}, .flags = .{},
.stage = .{.fragment_bit = true}, .stage = .{ .fragment_bit = true },
.module = frag, .module = frag,
.p_name = "main", .p_name = "main",
.p_specialization_info = null, .p_specialization_info = null,
@@ -436,7 +430,7 @@ fn createPipeline(
.depth_clamp_enable = vk.FALSE, .depth_clamp_enable = vk.FALSE,
.rasterizer_discard_enable = vk.FALSE, .rasterizer_discard_enable = vk.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 = vk.FALSE,
.depth_bias_constant_factor = 0, .depth_bias_constant_factor = 0,
@@ -447,7 +441,7 @@ fn createPipeline(
const pmsci = vk.PipelineMultisampleStateCreateInfo{ const pmsci = vk.PipelineMultisampleStateCreateInfo{
.flags = .{}, .flags = .{},
.rasterization_samples = .{.@"1_bit" = true}, .rasterization_samples = .{ .@"1_bit" = true },
.sample_shading_enable = vk.FALSE, .sample_shading_enable = vk.FALSE,
.min_sample_shading = 1, .min_sample_shading = 1,
.p_sample_mask = null, .p_sample_mask = null,
@@ -463,7 +457,7 @@ fn createPipeline(
.src_alpha_blend_factor = .one, .src_alpha_blend_factor = .one,
.dst_alpha_blend_factor = .zero, .dst_alpha_blend_factor = .zero,
.alpha_blend_op = .add, .alpha_blend_op = .add,
.color_write_mask = .{.r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true}, .color_write_mask = .{ .r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true },
}; };
const pcbsci = vk.PipelineColorBlendStateCreateInfo{ const pcbsci = vk.PipelineColorBlendStateCreateInfo{
@@ -472,10 +466,10 @@ fn createPipeline(
.logic_op = .copy, .logic_op = .copy,
.attachment_count = 1, .attachment_count = 1,
.p_attachments = @ptrCast([*]const vk.PipelineColorBlendAttachmentState, &pcbas), .p_attachments = @ptrCast([*]const vk.PipelineColorBlendAttachmentState, &pcbas),
.blend_constants = [_]f32{0, 0, 0, 0}, .blend_constants = [_]f32{ 0, 0, 0, 0 },
}; };
const dynstate = [_]vk.DynamicState{.viewport, .scissor}; const dynstate = [_]vk.DynamicState{ .viewport, .scissor };
const pdsci = vk.PipelineDynamicStateCreateInfo{ const pdsci = vk.PipelineDynamicStateCreateInfo{
.flags = .{}, .flags = .{},
.dynamic_state_count = dynstate.len, .dynamic_state_count = dynstate.len,
@@ -506,7 +500,8 @@ fn createPipeline(
_ = try gc.vkd.createGraphicsPipelines( _ = try gc.vkd.createGraphicsPipelines(
gc.dev, gc.dev,
.null_handle, .null_handle,
1, @ptrCast([*]const vk.GraphicsPipelineCreateInfo, &gpci), 1,
@ptrCast([*]const vk.GraphicsPipelineCreateInfo, &gpci),
null, null,
@ptrCast([*]vk.Pipeline, &pipeline), @ptrCast([*]vk.Pipeline, &pipeline),
); );

View File

@@ -49,7 +49,7 @@ pub const ShaderCompileStep = struct {
"shaders", "shaders",
src, src,
}) catch unreachable; }) catch unreachable;
self.shaders.append(.{.source_path = src, .full_out_path = full_out_path}) catch unreachable; self.shaders.append(.{ .source_path = src, .full_out_path = full_out_path }) catch unreachable;
return full_out_path; return full_out_path;
} }

View File

@@ -51,7 +51,7 @@ pub const SegmentIterator = struct {
} }
const end = self.nextBoundary(); const end = self.nextBoundary();
const word = self.text[self.offset .. end]; const word = self.text[self.offset..end];
self.offset = end; self.offset = end;
return word; return word;
} }
@@ -128,7 +128,7 @@ pub const IdRenderer = struct {
} }
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.append(std.ascii.toLower(c));
} }
} }
@@ -139,13 +139,13 @@ pub const IdRenderer = struct {
} }
pub fn render(self: IdRenderer, out: anytype, id: []const u8) !void { pub fn render(self: IdRenderer, out: anytype, id: []const u8) !void {
try out.print("{}", .{ std.zig.fmtId(id) }); try out.print("{}", .{std.zig.fmtId(id)});
} }
pub fn renderFmt(self: *IdRenderer, out: anytype, comptime fmt: []const u8, args: anytype) !void { pub fn renderFmt(self: *IdRenderer, out: anytype, comptime fmt: []const u8, args: anytype) !void {
self.text_cache.items.len = 0; self.text_cache.items.len = 0;
try std.fmt.format(self.text_cache.writer(), fmt, args); try std.fmt.format(self.text_cache.writer(), fmt, args);
try out.print("{}", .{ std.zig.fmtId(self.text_cache.items) }); try out.print("{}", .{std.zig.fmtId(self.text_cache.items)});
} }
pub fn renderWithCase(self: *IdRenderer, out: anytype, case_style: CaseStyle, id: []const u8) !void { pub fn renderWithCase(self: *IdRenderer, out: anytype, case_style: CaseStyle, id: []const u8) !void {
@@ -162,7 +162,7 @@ pub const IdRenderer = struct {
.camel => try self.renderCamel(false, adjusted_id, tag), .camel => try self.renderCamel(false, adjusted_id, tag),
} }
try out.print("{}", .{ std.zig.fmtId(self.text_cache.items) }); try out.print("{}", .{std.zig.fmtId(self.text_cache.items)});
} }
pub fn getAuthorTag(self: IdRenderer, id: []const u8) ?[]const u8 { pub fn getAuthorTag(self: IdRenderer, id: []const u8) ?[]const u8 {

View File

@@ -32,7 +32,7 @@ pub fn main() !void {
\\ \\
\\ \\
++ usage, ++ usage,
.{ prog_name }, .{prog_name},
); );
return; return;
} else if (maybe_xml_path == null) { } else if (maybe_xml_path == null) {
@@ -40,17 +40,17 @@ pub fn main() !void {
} else if (maybe_out_path == null) { } else if (maybe_out_path == null) {
maybe_out_path = arg; maybe_out_path = arg;
} else { } else {
try stderr.writer().print("Error: Superficial argument '{s}'\n", .{ arg }); try stderr.writer().print("Error: Superficial argument '{s}'\n", .{arg});
} }
} }
const xml_path = maybe_xml_path orelse { const xml_path = maybe_xml_path orelse {
try stderr.writer().print("Error: Missing required argument <spec xml path>\n" ++ usage, .{ prog_name }); try stderr.writer().print("Error: Missing required argument <spec xml path>\n" ++ usage, .{prog_name});
return; return;
}; };
const out_path = maybe_out_path orelse { const out_path = maybe_out_path orelse {
try stderr.writer().print("Error: Missing required argument <output zig source>\n" ++ usage, .{ prog_name }); try stderr.writer().print("Error: Missing required argument <output zig source>\n" ++ usage, .{prog_name});
return; return;
}; };

View File

@@ -52,7 +52,7 @@ pub const GenerateStep = struct {
pub fn initFromSdk(builder: *Builder, sdk_path: []const u8, out_path: []const u8) *GenerateStep { pub fn initFromSdk(builder: *Builder, sdk_path: []const u8, out_path: []const u8) *GenerateStep {
const spec_path = std.fs.path.join( const spec_path = std.fs.path.join(
builder.allocator, builder.allocator,
&[_][]const u8{sdk_path, "share/vulkan/registry/vk.xml"}, &[_][]const u8{ sdk_path, "share/vulkan/registry/vk.xml" },
) catch unreachable; ) catch unreachable;
return init(builder, spec_path, out_path); return init(builder, spec_path, out_path);

View File

@@ -53,9 +53,9 @@ pub const CTokenizer = struct {
fn consume(self: *CTokenizer) !u8 { fn consume(self: *CTokenizer) !u8 {
return if (self.offset < self.source.len) return if (self.offset < self.source.len)
return self.consumeNoEof() return self.consumeNoEof()
else else
return null; return null;
} }
fn keyword(self: *CTokenizer) Token { fn keyword(self: *CTokenizer) Token {
@@ -70,20 +70,20 @@ pub const CTokenizer = struct {
} }
} }
const token_text = self.source[start .. self.offset]; const token_text = self.source[start..self.offset];
const kind = if (mem.eql(u8, token_text, "typedef")) const kind = if (mem.eql(u8, token_text, "typedef"))
Token.Kind.kw_typedef Token.Kind.kw_typedef
else if (mem.eql(u8, token_text, "const")) else if (mem.eql(u8, token_text, "const"))
Token.Kind.kw_const Token.Kind.kw_const
else if (mem.eql(u8, token_text, "VKAPI_PTR")) else if (mem.eql(u8, token_text, "VKAPI_PTR"))
Token.Kind.kw_vkapi_ptr Token.Kind.kw_vkapi_ptr
else if (mem.eql(u8, token_text, "struct")) else if (mem.eql(u8, token_text, "struct"))
Token.Kind.kw_struct Token.Kind.kw_struct
else else
Token.Kind.id; Token.Kind.id;
return .{.kind = kind, .text = token_text}; return .{ .kind = kind, .text = token_text };
} }
fn int(self: *CTokenizer) Token { fn int(self: *CTokenizer) Token {
@@ -100,7 +100,7 @@ pub const CTokenizer = struct {
return .{ return .{
.kind = .int, .kind = .int,
.text = self.source[start .. self.offset], .text = self.source[start..self.offset],
}; };
} }
@@ -115,7 +115,7 @@ pub const CTokenizer = struct {
pub fn next(self: *CTokenizer) !?Token { pub fn next(self: *CTokenizer) !?Token {
self.skipws(); self.skipws();
if (mem.startsWith(u8, self.source[self.offset ..], "//") or self.in_comment) { if (mem.startsWith(u8, self.source[self.offset..], "//") or self.in_comment) {
const end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse { const end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse {
self.offset = self.source.len; self.offset = self.source.len;
self.in_comment = true; self.in_comment = true;
@@ -143,15 +143,12 @@ pub const CTokenizer = struct {
']' => kind = .rbracket, ']' => kind = .rbracket,
'(' => kind = .lparen, '(' => kind = .lparen,
')' => kind = .rparen, ')' => kind = .rparen,
else => return error.UnexpectedCharacter else => return error.UnexpectedCharacter,
} }
const start = self.offset; const start = self.offset;
_ = self.consumeNoEof(); _ = self.consumeNoEof();
return Token{ return Token{ .kind = kind, .text = self.source[start..self.offset] };
.kind = kind,
.text = self.source[start .. self.offset]
};
} }
}; };
@@ -173,11 +170,11 @@ pub const XmlCTokenizer = struct {
const text = elem.children.items[0].CharData; const text = elem.children.items[0].CharData;
if (mem.eql(u8, elem.tag, "type")) { if (mem.eql(u8, elem.tag, "type")) {
return Token{.kind = .type_name, .text = text}; return Token{ .kind = .type_name, .text = text };
} else if (mem.eql(u8, elem.tag, "enum")) { } else if (mem.eql(u8, elem.tag, "enum")) {
return Token{.kind = .enum_name, .text = text}; return Token{ .kind = .enum_name, .text = text };
} else if (mem.eql(u8, elem.tag, "name")) { } else if (mem.eql(u8, elem.tag, "name")) {
return Token{.kind = .name, .text = text}; return Token{ .kind = .name, .text = text };
} else if (mem.eql(u8, elem.tag, "comment")) { } else if (mem.eql(u8, elem.tag, "comment")) {
return null; return null;
} else { } else {
@@ -206,7 +203,7 @@ pub const XmlCTokenizer = struct {
if (self.it.next()) |child| { if (self.it.next()) |child| {
switch (child.*) { switch (child.*) {
.CharData => |cdata| self.ctok = CTokenizer{.source = cdata, .in_comment = in_comment}, .CharData => |cdata| self.ctok = CTokenizer{ .source = cdata, .in_comment = in_comment },
.Comment => {}, // xml comment .Comment => {}, // xml comment
.Element => |elem| if (!in_comment) if (try elemToToken(elem)) |tok| return tok, .Element => |elem| if (!in_comment) if (try elemToToken(elem)) |tok| return tok,
} }
@@ -254,14 +251,14 @@ pub fn parseTypedef(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Decl
return registry.Declaration{ return registry.Declaration{
.name = decl.name orelse return error.MissingTypeIdentifier, .name = decl.name orelse return error.MissingTypeIdentifier,
.decl_type = .{.typedef = decl.decl_type}, .decl_type = .{ .typedef = decl.decl_type },
}; };
} }
// MEMBER = DECLARATION (':' int)? // MEMBER = DECLARATION (':' int)?
pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Container.Field { pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Container.Field {
const decl = try parseDeclaration(allocator, xctok); const decl = try parseDeclaration(allocator, xctok);
var field = registry.Container.Field { var field = registry.Container.Field{
.name = decl.name orelse return error.MissingTypeIdentifier, .name = decl.name orelse return error.MissingTypeIdentifier,
.field_type = decl.decl_type, .field_type = decl.decl_type,
.bits = null, .bits = null,
@@ -294,7 +291,7 @@ pub fn parseParamOrProto(allocator: *Allocator, xctok: *XmlCTokenizer) !registry
} }
return registry.Declaration{ return registry.Declaration{
.name = decl.name orelse return error.MissingTypeIdentifier, .name = decl.name orelse return error.MissingTypeIdentifier,
.decl_type = .{.typedef = decl.decl_type}, .decl_type = .{ .typedef = decl.decl_type },
}; };
} }
@@ -333,7 +330,7 @@ fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) ParseError!Dec
if (tok.kind != .type_name and tok.kind != .id) return error.InvalidSyntax; if (tok.kind != .type_name and tok.kind != .id) return error.InvalidSyntax;
const type_name = tok.text; const type_name = tok.text;
var type_info = TypeInfo{.name = type_name}; var type_info = TypeInfo{ .name = type_name };
// Parse pointers // Parse pointers
type_info = try parsePointers(allocator, xctok, inner_is_const, type_info); type_info = try parsePointers(allocator, xctok, inner_is_const, type_info);
@@ -365,7 +362,7 @@ fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) ParseError!Dec
.array = .{ .array = .{
.size = array_size, .size = array_size,
.child = child, .child = child,
} },
}; };
// update the inner_type pointer so it points to the proper // update the inner_type pointer so it points to the proper
@@ -403,8 +400,8 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T
.return_type = return_type_heap, .return_type = return_type_heap,
.success_codes = &[_][]const u8{}, .success_codes = &[_][]const u8{},
.error_codes = &[_][]const u8{}, .error_codes = &[_][]const u8{},
} },
} },
}; };
const first_param = try parseDeclaration(allocator, xctok); const first_param = try parseDeclaration(allocator, xctok);
@@ -500,10 +497,10 @@ fn parseArrayDeclarator(xctok: *XmlCTokenizer) !?ArraySize {
.int = std.fmt.parseInt(usize, size_tok.text, 10) catch |err| switch (err) { .int = std.fmt.parseInt(usize, size_tok.text, 10) catch |err| switch (err) {
error.Overflow => return error.Overflow, error.Overflow => return error.Overflow,
error.InvalidCharacter => unreachable, error.InvalidCharacter => unreachable,
} },
}, },
.enum_name => .{.alias = size_tok.text}, .enum_name => .{ .alias = size_tok.text },
else => return error.InvalidSyntax else => return error.InvalidSyntax,
}; };
_ = try xctok.expect(.rbracket); _ = try xctok.expect(.rbracket);
@@ -551,33 +548,27 @@ fn testTokenizer(tokenizer: anytype, expected_tokens: []const Token) !void {
} }
test "CTokenizer" { test "CTokenizer" {
var ctok = CTokenizer { var ctok = CTokenizer{ .source = "typedef ([const)]** VKAPI_PTR 123,;aaaa" };
.source = \\typedef ([const)]** VKAPI_PTR 123,;aaaa
};
try testTokenizer( try testTokenizer(&ctok, &[_]Token{
&ctok, .{ .kind = .kw_typedef, .text = "typedef" },
&[_]Token{ .{ .kind = .lparen, .text = "(" },
.{.kind = .kw_typedef, .text = "typedef"}, .{ .kind = .lbracket, .text = "[" },
.{.kind = .lparen, .text = "("}, .{ .kind = .kw_const, .text = "const" },
.{.kind = .lbracket, .text = "["}, .{ .kind = .rparen, .text = ")" },
.{.kind = .kw_const, .text = "const"}, .{ .kind = .rbracket, .text = "]" },
.{.kind = .rparen, .text = ")"}, .{ .kind = .star, .text = "*" },
.{.kind = .rbracket, .text = "]"}, .{ .kind = .star, .text = "*" },
.{.kind = .star, .text = "*"}, .{ .kind = .kw_vkapi_ptr, .text = "VKAPI_PTR" },
.{.kind = .star, .text = "*"}, .{ .kind = .int, .text = "123" },
.{.kind = .kw_vkapi_ptr, .text = "VKAPI_PTR"}, .{ .kind = .comma, .text = "," },
.{.kind = .int, .text = "123"}, .{ .kind = .semicolon, .text = ";" },
.{.kind = .comma, .text = ","}, .{ .kind = .id, .text = "aaaa" },
.{.kind = .semicolon, .text = ";"}, });
.{.kind = .id, .text = "aaaa"},
}
);
} }
test "XmlCTokenizer" { test "XmlCTokenizer" {
const document = try xml.parse( const document = try xml.parse(testing.allocator,
testing.allocator,
\\<root>// comment <name>commented name</name> <type>commented type</type> trailing \\<root>// comment <name>commented name</name> <type>commented type</type> trailing
\\ typedef void (VKAPI_PTR *<name>PFN_vkVoidFunction</name>)(void); \\ typedef void (VKAPI_PTR *<name>PFN_vkVoidFunction</name>)(void);
\\</root> \\</root>
@@ -586,27 +577,23 @@ test "XmlCTokenizer" {
var xctok = XmlCTokenizer.init(document.root); var xctok = XmlCTokenizer.init(document.root);
try testTokenizer( try testTokenizer(&xctok, &[_]Token{
&xctok, .{ .kind = .kw_typedef, .text = "typedef" },
&[_]Token{ .{ .kind = .id, .text = "void" },
.{.kind = .kw_typedef, .text = "typedef"}, .{ .kind = .lparen, .text = "(" },
.{.kind = .id, .text = "void"}, .{ .kind = .kw_vkapi_ptr, .text = "VKAPI_PTR" },
.{.kind = .lparen, .text = "("}, .{ .kind = .star, .text = "*" },
.{.kind = .kw_vkapi_ptr, .text = "VKAPI_PTR"}, .{ .kind = .name, .text = "PFN_vkVoidFunction" },
.{.kind = .star, .text = "*"}, .{ .kind = .rparen, .text = ")" },
.{.kind = .name, .text = "PFN_vkVoidFunction"}, .{ .kind = .lparen, .text = "(" },
.{.kind = .rparen, .text = ")"}, .{ .kind = .id, .text = "void" },
.{.kind = .lparen, .text = "("}, .{ .kind = .rparen, .text = ")" },
.{.kind = .id, .text = "void"}, .{ .kind = .semicolon, .text = ";" },
.{.kind = .rparen, .text = ")"}, });
.{.kind = .semicolon, .text = ";"},
}
);
} }
test "parseTypedef" { test "parseTypedef" {
const document = try xml.parse( const document = try xml.parse(testing.allocator,
testing.allocator,
\\<root> // comment <name>commented name</name> trailing \\<root> // comment <name>commented name</name> trailing
\\ typedef const struct <type>Python</type>* pythons[4]; \\ typedef const struct <type>Python</type>* pythons[4];
\\ // more comments \\ // more comments
@@ -623,7 +610,7 @@ test "parseTypedef" {
try testing.expectEqualSlices(u8, "pythons", decl.name); try testing.expectEqualSlices(u8, "pythons", decl.name);
const array = decl.decl_type.typedef.array; const array = decl.decl_type.typedef.array;
try testing.expectEqual(ArraySize{.int = 4}, array.size); try testing.expectEqual(ArraySize{ .int = 4 }, array.size);
const ptr = array.child.pointer; const ptr = array.child.pointer;
try testing.expectEqual(true, ptr.is_const); try testing.expectEqual(true, ptr.is_const);
try testing.expectEqualSlices(u8, "Python", ptr.child.name); try testing.expectEqualSlices(u8, "Python", ptr.child.name);

View File

@@ -89,13 +89,13 @@ fn parseTypes(allocator: *Allocator, out: []registry.Declaration, types_elem: *x
fn parseForeigntype(ty: *xml.Element) !registry.Declaration { fn parseForeigntype(ty: *xml.Element) !registry.Declaration {
const name = ty.getAttribute("name") orelse return error.InvalidRegistry; const name = ty.getAttribute("name") orelse return error.InvalidRegistry;
const depends = ty.getAttribute("requires") orelse if (mem.eql(u8, name, "int")) const depends = ty.getAttribute("requires") orelse if (mem.eql(u8, name, "int"))
"vk_platform" // for some reason, int doesn't depend on vk_platform (but the other c types do) "vk_platform" // for some reason, int doesn't depend on vk_platform (but the other c types do)
else else
return error.InvalidRegistry; return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.foreign = .{.depends = depends}}, .decl_type = .{ .foreign = .{ .depends = depends } },
}; };
} }
@@ -104,24 +104,27 @@ fn parseBitmaskType(ty: *xml.Element) !registry.Declaration {
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry; const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.alias = .{.name = alias, .target = .other_type}}, .decl_type = .{ .alias = .{ .name = alias, .target = .other_type } },
}; };
} else { } else {
const flags_type = ty.getCharData("type") orelse return error.InvalidRegistry; const flags_type = ty.getCharData("type") orelse return error.InvalidRegistry;
const bitwidth: u8 = if (mem.eql(u8, flags_type, "VkFlags")) const bitwidth: u8 = if (mem.eql(u8, flags_type, "VkFlags"))
32 32
else if (mem.eql(u8, flags_type, "VkFlags64")) else if (mem.eql(u8, flags_type, "VkFlags64"))
64 64
else else
return error.InvalidRegistry; return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = ty.getCharData("name") orelse return error.InvalidRegistry, .name = ty.getCharData("name") orelse return error.InvalidRegistry,
.decl_type = .{.bitmask = .{ .decl_type = .{
.bits_enum = ty.getAttribute("requires") orelse ty.getAttribute("bitvalues"), // Who knows why these are different fields .bitmask = .{
.bitwidth = bitwidth, // Who knows why these are different fields
}}, .bits_enum = ty.getAttribute("requires") orelse ty.getAttribute("bitvalues"),
.bitwidth = bitwidth,
},
},
}; };
} }
} }
@@ -132,7 +135,9 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration {
const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry; const alias = ty.getAttribute("alias") orelse return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.alias = .{.name = alias, .target = .other_type}}, .decl_type = .{
.alias = .{ .name = alias, .target = .other_type },
},
}; };
} else { } else {
const name = ty.getCharData("name") orelse return error.InvalidRegistry; const name = ty.getCharData("name") orelse return error.InvalidRegistry;
@@ -148,7 +153,7 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration {
.handle = .{ .handle = .{
.parent = ty.getAttribute("parent"), .parent = ty.getAttribute("parent"),
.is_dispatchable = dispatchable, .is_dispatchable = dispatchable,
} },
}, },
}; };
} }
@@ -164,7 +169,7 @@ fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration
// macros, which is why this part is not built into the xml/c parser. // macros, which is why this part is not built into the xml/c parser.
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.external = {}}, .decl_type = .{ .external = {} },
}; };
} }
} }
@@ -175,7 +180,9 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
if (ty.getAttribute("alias")) |alias| { if (ty.getAttribute("alias")) |alias| {
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.alias = .{.name = alias, .target = .other_type}}, .decl_type = .{
.alias = .{ .name = alias, .target = .other_type },
},
}; };
} }
@@ -201,18 +208,18 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
it = ty.findChildrenByTag("member"); it = ty.findChildrenByTag("member");
for (members) |*member| { for (members) |*member| {
const member_elem = it.next().?; const member_elem = it.next().?;
try parsePointerMeta(.{.container = members}, &member.field_type, member_elem); try parsePointerMeta(.{ .container = members }, &member.field_type, member_elem);
} }
return registry.Declaration { return registry.Declaration{
.name = name, .name = name,
.decl_type = .{ .decl_type = .{
.container = .{ .container = .{
.stype = maybe_stype, .stype = maybe_stype,
.fields = members, .fields = members,
.is_union = is_union, .is_union = is_union,
} },
} },
}; };
} }
@@ -235,7 +242,7 @@ fn lenToPointerSize(fields: Fields, len: []const u8) registry.Pointer.PointerSiz
for (params) |*param| { for (params) |*param| {
if (mem.eql(u8, param.name, len)) { if (mem.eql(u8, param.name, len)) {
param.is_buffer_len = true; param.is_buffer_len = true;
return .{.other_field = param.name}; return .{ .other_field = param.name };
} }
} }
}, },
@@ -243,7 +250,7 @@ fn lenToPointerSize(fields: Fields, len: []const u8) registry.Pointer.PointerSiz
for (members) |*member| { for (members) |*member| {
if (mem.eql(u8, member.name, len)) { if (mem.eql(u8, member.name, len)) {
member.is_buffer_len = true; member.is_buffer_len = true;
return .{.other_field = member.name}; return .{ .other_field = member.name };
} }
} }
}, },
@@ -295,7 +302,9 @@ fn parseEnumAlias(allocator: *Allocator, elem: *xml.Element) !?registry.Declarat
const name = elem.getAttribute("name") orelse return error.InvalidRegistry; const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.alias = .{.name = alias, .target = .other_type}}, .decl_type = .{
.alias = .{ .name = alias, .target = .other_type },
},
}; };
} }
@@ -313,7 +322,7 @@ fn parseEnums(allocator: *Allocator, out: []registry.Declaration, root: *xml.Ele
out[i] = .{ out[i] = .{
.name = name, .name = name,
.decl_type = .{.enumeration = try parseEnumFields(allocator, enums)}, .decl_type = .{ .enumeration = try parseEnumFields(allocator, enums) },
}; };
i += 1; i += 1;
} }
@@ -330,9 +339,9 @@ fn parseEnumFields(allocator: *Allocator, elem: *xml.Element) !registry.Enum {
} }
const bitwidth = if (elem.getAttribute("bitwidth")) |bitwidth| const bitwidth = if (elem.getAttribute("bitwidth")) |bitwidth|
try std.fmt.parseInt(u8, bitwidth, 10) try std.fmt.parseInt(u8, bitwidth, 10)
else else
32; 32;
const fields = try allocator.alloc(registry.Enum.Field, elem.children.items.len); const fields = try allocator.alloc(registry.Enum.Field, elem.children.items.len);
@@ -369,14 +378,14 @@ fn parseEnumField(field: *xml.Element) !registry.Enum.Field {
// tag. In the latter case its passed via the `ext_nr` parameter. // tag. In the latter case its passed via the `ext_nr` parameter.
if (field.getAttribute("value")) |value| { if (field.getAttribute("value")) |value| {
if (mem.startsWith(u8, value, "0x")) { if (mem.startsWith(u8, value, "0x")) {
break :blk .{.bit_vector = try std.fmt.parseInt(i32, value[2..], 16)}; break :blk .{ .bit_vector = try std.fmt.parseInt(i32, value[2..], 16) };
} else { } else {
break :blk .{.int = try std.fmt.parseInt(i32, value, 10)}; break :blk .{ .int = try std.fmt.parseInt(i32, value, 10) };
} }
} else if (field.getAttribute("bitpos")) |bitpos| { } else if (field.getAttribute("bitpos")) |bitpos| {
break :blk .{.bitpos = try std.fmt.parseInt(u6, bitpos, 10)}; break :blk .{ .bitpos = try std.fmt.parseInt(u6, bitpos, 10) };
} else if (field.getAttribute("alias")) |alias| { } else if (field.getAttribute("alias")) |alias| {
break :blk .{.alias = .{.name = alias, .is_compat_alias = is_compat_alias}}; break :blk .{ .alias = .{ .name = alias, .is_compat_alias = is_compat_alias } };
} else { } else {
return error.InvalidRegistry; return error.InvalidRegistry;
} }
@@ -419,7 +428,9 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
const name = elem.getAttribute("name") orelse return error.InvalidRegistry; const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
return registry.Declaration{ return registry.Declaration{
.name = name, .name = name,
.decl_type = .{.alias = .{.name = alias, .target = .other_command}} .decl_type = .{
.alias = .{ .name = alias, .target = .other_command },
},
}; };
} }
@@ -446,24 +457,24 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
return_type.* = command_decl.decl_type.typedef; return_type.* = command_decl.decl_type.typedef;
const success_codes = if (elem.getAttribute("successcodes")) |codes| const success_codes = if (elem.getAttribute("successcodes")) |codes|
try splitCommaAlloc(allocator, codes) try splitCommaAlloc(allocator, codes)
else else
&[_][]const u8{}; &[_][]const u8{};
const error_codes = if (elem.getAttribute("errorcodes")) |codes| const error_codes = if (elem.getAttribute("errorcodes")) |codes|
try splitCommaAlloc(allocator, codes) try splitCommaAlloc(allocator, codes)
else else
&[_][]const u8{}; &[_][]const u8{};
params = allocator.shrink(params, i); params = allocator.shrink(params, i);
it = elem.findChildrenByTag("param"); it = elem.findChildrenByTag("param");
for (params) |*param| { for (params) |*param| {
const param_elem = it.next().?; const param_elem = it.next().?;
try parsePointerMeta(.{.command = params}, &param.param_type, param_elem); try parsePointerMeta(.{ .command = params }, &param.param_type, param_elem);
} }
return registry.Declaration { return registry.Declaration{
.name = command_decl.name, .name = command_decl.name,
.decl_type = .{ .decl_type = .{
.command = .{ .command = .{
@@ -471,8 +482,8 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
.return_type = return_type, .return_type = return_type,
.success_codes = success_codes, .success_codes = success_codes,
.error_codes = error_codes, .error_codes = error_codes,
} },
} },
}; };
} }
@@ -509,15 +520,15 @@ fn parseApiConstants(allocator: *Allocator, root: *xml.Element) ![]registry.ApiC
var it = enums.findChildrenByTag("enum"); var it = enums.findChildrenByTag("enum");
while (it.next()) |constant| { while (it.next()) |constant| {
const expr = if (constant.getAttribute("value")) |expr| const expr = if (constant.getAttribute("value")) |expr|
expr expr
else if (constant.getAttribute("alias")) |alias| else if (constant.getAttribute("alias")) |alias|
alias alias
else else
return error.InvalidRegistry; return error.InvalidRegistry;
constants[i] = .{ constants[i] = .{
.name = constant.getAttribute("name") orelse return error.InvalidRegistry, .name = constant.getAttribute("name") orelse return error.InvalidRegistry,
.value = .{.expr = expr}, .value = .{ .expr = expr },
}; };
i += 1; i += 1;
@@ -540,15 +551,13 @@ fn parseDefines(types: *xml.Element, out: []registry.ApiConstant) !usize {
if (mem.eql(u8, name, "VK_HEADER_VERSION")) { if (mem.eql(u8, name, "VK_HEADER_VERSION")) {
out[i] = .{ out[i] = .{
.name = name, .name = name,
.value = .{.expr = mem.trim(u8, ty.children.items[2].CharData, " ")}, .value = .{ .expr = mem.trim(u8, ty.children.items[2].CharData, " ") },
}; };
} else { } else {
var xctok = cparse.XmlCTokenizer.init(ty); var xctok = cparse.XmlCTokenizer.init(ty);
out[i] = .{ out[i] = .{
.name = name, .name = name,
.value = .{ .value = .{ .version = cparse.parseVersion(&xctok) catch continue },
.version = cparse.parseVersion(&xctok) catch continue
},
}; };
} }
i += 1; i += 1;
@@ -609,7 +618,7 @@ fn parseFeature(allocator: *Allocator, feature: *xml.Element) !registry.Feature
return registry.Feature{ return registry.Feature{
.name = name, .name = name,
.level = feature_level, .level = feature_level,
.requires = allocator.shrink(requires, i) .requires = allocator.shrink(requires, i),
}; };
} }
@@ -642,7 +651,10 @@ fn parseEnumExtension(elem: *xml.Element, parent_extnumber: ?u31) !?registry.Req
return registry.Require.EnumExtension{ return registry.Require.EnumExtension{
.extends = extends, .extends = extends,
.extnumber = actual_extnumber, .extnumber = actual_extnumber,
.field = .{.name = name, .value = .{.int = value}}, .field = .{
.name = name,
.value = .{ .int = value },
},
}; };
} }
@@ -705,7 +717,7 @@ fn parseRequire(allocator: *Allocator, require: *xml.Element, extnumber: ?u31) !
return error.InvalidRegistry; return error.InvalidRegistry;
} }
break :blk try splitFeatureLevel(feature_level["VK_VERSION_".len ..], "_"); break :blk try splitFeatureLevel(feature_level["VK_VERSION_".len..], "_");
}; };
return registry.Require{ return registry.Require{
@@ -763,19 +775,18 @@ fn parseExtension(allocator: *Allocator, extension: *xml.Element) !registry.Exte
// feature level: both seperately in each <require> tag, or using // feature level: both seperately in each <require> tag, or using
// the requiresCore attribute. // the requiresCore attribute.
const requires_core = if (extension.getAttribute("requiresCore")) |feature_level| const requires_core = if (extension.getAttribute("requiresCore")) |feature_level|
try splitFeatureLevel(feature_level, ".") try splitFeatureLevel(feature_level, ".")
else else
null; null;
const promoted_to: registry.Extension.Promotion = blk: { const promoted_to: registry.Extension.Promotion = blk: {
const promotedto = extension.getAttribute("promotedto") orelse break :blk .none; const promotedto = extension.getAttribute("promotedto") orelse break :blk .none;
if (mem.startsWith(u8, promotedto, "VK_VERSION_")) { if (mem.startsWith(u8, promotedto, "VK_VERSION_")) {
const feature_level = try splitFeatureLevel(promotedto["VK_VERSION_".len ..], "_"); const feature_level = try splitFeatureLevel(promotedto["VK_VERSION_".len..], "_");
break :blk .{ .feature = feature_level };
break :blk .{.feature = feature_level};
} }
break :blk .{.extension = promotedto}; break :blk .{ .extension = promotedto };
}; };
const number = blk: { const number = blk: {
@@ -816,7 +827,7 @@ fn parseExtension(allocator: *Allocator, extension: *xml.Element) !registry.Exte
.promoted_to = promoted_to, .promoted_to = promoted_to,
.platform = platform, .platform = platform,
.required_feature_level = requires_core, .required_feature_level = requires_core,
.requires = allocator.shrink(requires, i) .requires = allocator.shrink(requires, i),
}; };
} }

View File

@@ -70,15 +70,12 @@ pub const Container = struct {
}; };
pub const Enum = struct { pub const Enum = struct {
pub const Value = union(enum) { pub const Value = union(enum) { bitpos: u6, // 1 << bitpos
bitpos: u6, // 1 << bitpos bit_vector: i32, // Combined flags & some vendor IDs
bit_vector: i32, // Combined flags & some vendor IDs int: i32, alias: struct {
int: i32, name: []const u8,
alias: struct { is_compat_alias: bool,
name: []const u8, } };
is_compat_alias: bool,
}
};
pub const Field = struct { pub const Field = struct {
name: []const u8, name: []const u8,
@@ -118,7 +115,7 @@ pub const Pointer = struct {
one, one,
many, // The length is given by some complex expression, possibly involving another field many, // The length is given by some complex expression, possibly involving another field
other_field: []const u8, // The length is given by some other field or parameter other_field: []const u8, // The length is given by some other field or parameter
zero_terminated zero_terminated,
}; };
is_const: bool, is_const: bool,

View File

@@ -66,45 +66,45 @@ const preamble =
\\ return @truncate(u12, version); \\ return @truncate(u12, version);
\\} \\}
\\ \\
; ;
const builtin_types = std.ComptimeStringMap([]const u8, .{ const builtin_types = std.ComptimeStringMap([]const u8, .{
.{"void", @typeName(void)}, .{ "void", @typeName(void) },
.{"char", @typeName(u8)}, .{ "char", @typeName(u8) },
.{"float", @typeName(f32)}, .{ "float", @typeName(f32) },
.{"double", @typeName(f64)}, .{ "double", @typeName(f64) },
.{"uint8_t", @typeName(u8)}, .{ "uint8_t", @typeName(u8) },
.{"uint16_t", @typeName(u16)}, .{ "uint16_t", @typeName(u16) },
.{"uint32_t", @typeName(u32)}, .{ "uint32_t", @typeName(u32) },
.{"uint64_t", @typeName(u64)}, .{ "uint64_t", @typeName(u64) },
.{"int8_t", @typeName(i8)}, .{ "int8_t", @typeName(i8) },
.{"int16_t", @typeName(i16)}, .{ "int16_t", @typeName(i16) },
.{"int32_t", @typeName(i32)}, .{ "int32_t", @typeName(i32) },
.{"int64_t", @typeName(i64)}, .{ "int64_t", @typeName(i64) },
.{"size_t", @typeName(usize)}, .{ "size_t", @typeName(usize) },
.{"int", @typeName(c_int)}, .{ "int", @typeName(c_int) },
}); });
const foreign_types = std.ComptimeStringMap([]const u8, .{ const foreign_types = std.ComptimeStringMap([]const u8, .{
.{"Display", "opaque {}"}, .{ "Display", "opaque {}" },
.{"VisualID", @typeName(c_uint)}, .{ "VisualID", @typeName(c_uint) },
.{"Window", @typeName(c_ulong)}, .{ "Window", @typeName(c_ulong) },
.{"RROutput", @typeName(c_ulong)}, .{ "RROutput", @typeName(c_ulong) },
.{"wl_display", "opaque {}"}, .{ "wl_display", "opaque {}" },
.{"wl_surface", "opaque {}"}, .{ "wl_surface", "opaque {}" },
.{"HINSTANCE", "std.os.HINSTANCE"}, .{ "HINSTANCE", "std.os.HINSTANCE" },
.{"HWND", "*opaque {}"}, .{ "HWND", "*opaque {}" },
.{"HMONITOR", "*opaque {}"}, .{ "HMONITOR", "*opaque {}" },
.{"HANDLE", "std.os.HANDLE"}, .{ "HANDLE", "std.os.HANDLE" },
.{"SECURITY_ATTRIBUTES", "std.os.SECURITY_ATTRIBUTES"}, .{ "SECURITY_ATTRIBUTES", "std.os.SECURITY_ATTRIBUTES" },
.{"DWORD", "std.os.DWORD"}, .{ "DWORD", "std.os.DWORD" },
.{"LPCWSTR", "std.os.LPCWSTR"}, .{ "LPCWSTR", "std.os.LPCWSTR" },
.{"xcb_connection_t", "opaque {}"}, .{ "xcb_connection_t", "opaque {}" },
.{"xcb_visualid_t", @typeName(u32)}, .{ "xcb_visualid_t", @typeName(u32) },
.{"xcb_window_t", @typeName(u32)}, .{ "xcb_window_t", @typeName(u32) },
.{"zx_handle_t", @typeName(u32)}, .{ "zx_handle_t", @typeName(u32) },
.{"_screen_context", "opaque {}"}, .{ "_screen_context", "opaque {}" },
.{"_screen_window", "opaque {}"}, .{ "_screen_window", "opaque {}" },
}); });
fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool { fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool {
@@ -122,7 +122,7 @@ fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool {
} }
pub fn trimVkNamespace(id: []const u8) []const u8 { pub fn trimVkNamespace(id: []const u8) []const u8 {
const prefixes = [_][]const u8{"VK_", "vk", "Vk", "PFN_vk"}; const prefixes = [_][]const u8{ "VK_", "vk", "Vk", "PFN_vk" };
for (prefixes) |prefix| { for (prefixes) |prefix| {
if (mem.startsWith(u8, id, prefix)) { if (mem.startsWith(u8, id, prefix)) {
return id[prefix.len..]; return id[prefix.len..];
@@ -136,7 +136,7 @@ fn Renderer(comptime WriterType: type) type {
return struct { return struct {
const Self = @This(); const Self = @This();
const WriteError = WriterType.Error; const WriteError = WriterType.Error;
const RenderTypeInfoError = WriteError || std.fmt.ParseIntError || error { OutOfMemory, InvalidRegistry }; const RenderTypeInfoError = WriteError || std.fmt.ParseIntError || error{ OutOfMemory, InvalidRegistry };
const BitflagName = struct { const BitflagName = struct {
/// Name without FlagBits, so VkSurfaceTransformFlagBitsKHR /// Name without FlagBits, so VkSurfaceTransformFlagBitsKHR
@@ -389,18 +389,18 @@ fn Renderer(comptime WriterType: type) type {
fn classifyCommandDispatch(self: Self, name: []const u8, command: reg.Command) CommandDispatchType { fn classifyCommandDispatch(self: Self, name: []const u8, command: reg.Command) CommandDispatchType {
const device_handles = std.ComptimeStringMap(void, .{ const device_handles = std.ComptimeStringMap(void, .{
.{"VkDevice", {}}, .{ "VkDevice", {} },
.{"VkCommandBuffer", {}}, .{ "VkCommandBuffer", {} },
.{"VkQueue", {}}, .{ "VkQueue", {} },
}); });
const override_functions = std.ComptimeStringMap(CommandDispatchType, .{ const override_functions = std.ComptimeStringMap(CommandDispatchType, .{
.{"vkGetInstanceProcAddr", .base}, .{ "vkGetInstanceProcAddr", .base },
.{"vkCreateInstance", .base}, .{ "vkCreateInstance", .base },
.{"vkEnumerateInstanceLayerProperties", .base}, .{ "vkEnumerateInstanceLayerProperties", .base },
.{"vkEnumerateInstanceExtensionProperties", .base}, .{ "vkEnumerateInstanceExtensionProperties", .base },
.{"vkEnumerateInstanceVersion", .base}, .{ "vkEnumerateInstanceVersion", .base },
.{"vkGetDeviceProcAddr", .instance}, .{ "vkGetDeviceProcAddr", .instance },
}); });
if (override_functions.get(name)) |dispatch_type| { if (override_functions.get(name)) |dispatch_type| {
@@ -428,7 +428,7 @@ fn Renderer(comptime WriterType: type) type {
} }
for (self.registry.decls) |decl| { for (self.registry.decls) |decl| {
try self.renderDecl(decl); try self.renderDecl(decl);
} }
try self.renderCommandPtrs(); try self.renderCommandPtrs();
@@ -467,11 +467,11 @@ fn Renderer(comptime WriterType: type) type {
fn renderApiConstantExpr(self: *Self, expr: []const u8) !void { fn renderApiConstantExpr(self: *Self, expr: []const u8) !void {
const adjusted_expr = if (expr.len > 2 and expr[0] == '(' and expr[expr.len - 1] == ')') const adjusted_expr = if (expr.len > 2 and expr[0] == '(' and expr[expr.len - 1] == ')')
expr[1 .. expr.len - 1] expr[1 .. expr.len - 1]
else else
expr; expr;
var tokenizer = cparse.CTokenizer{.source = adjusted_expr}; var tokenizer = cparse.CTokenizer{ .source = adjusted_expr };
var peeked: ?cparse.Token = null; var peeked: ?cparse.Token = null;
while (true) { while (true) {
const tok = peeked orelse (try tokenizer.next()) orelse break; const tok = peeked orelse (try tokenizer.next()) orelse break;
@@ -507,7 +507,7 @@ fn Renderer(comptime WriterType: type) type {
}, },
.dot => { .dot => {
const decimal = (try tokenizer.next()) orelse return error.InvalidConstantExpr; const decimal = (try tokenizer.next()) orelse return error.InvalidConstantExpr;
try self.writer.print("@as(f32, {s}.{s})", .{tok.text, decimal.text}); try self.writer.print("@as(f32, {s}.{s})", .{ tok.text, decimal.text });
const f = (try tokenizer.next()) orelse return error.InvalidConstantExpr; const f = (try tokenizer.next()) orelse return error.InvalidConstantExpr;
if (f.kind != .id or f.text.len != 1 or (f.text[0] != 'f' and f.text[0] != 'F')) { if (f.kind != .id or f.text.len != 1 or (f.text[0] != 'f' and f.text[0] != 'F')) {
@@ -536,10 +536,10 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(zig_name); try self.writer.writeAll(zig_name);
return; return;
} else if (try self.extractBitflagName(name)) |bitflag_name| { } else if (try self.extractBitflagName(name)) |bitflag_name| {
try self.writeIdentifierFmt("{s}Flags{s}{s}", .{ try self.writeIdentifierFmt("{s}Flags{s}{s}", .{
trimVkNamespace(bitflag_name.base_name), trimVkNamespace(bitflag_name.base_name),
@as([]const u8, if (bitflag_name.revision) |revision| revision else ""), @as([]const u8, if (bitflag_name.revision) |revision| revision else ""),
@as([]const u8, if (bitflag_name.tag) |tag| tag else "") @as([]const u8, if (bitflag_name.tag) |tag| tag else ""),
}); });
return; return;
} else if (mem.startsWith(u8, name, "vk")) { } else if (mem.startsWith(u8, name, "vk")) {
@@ -579,7 +579,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writeIdentifierFmt("{s}Flags{s}{s}", .{ try self.writeIdentifierFmt("{s}Flags{s}{s}", .{
trimVkNamespace(bitflag_name.base_name), trimVkNamespace(bitflag_name.base_name),
@as([]const u8, if (bitflag_name.revision) |revision| revision else ""), @as([]const u8, if (bitflag_name.revision) |revision| revision else ""),
@as([]const u8, if (bitflag_name.tag) |tag| tag else "") @as([]const u8, if (bitflag_name.tag) |tag| tag else ""),
}); });
try self.writer.writeAll(".IntType"); try self.writer.writeAll(".IntType");
break :blk; break :blk;
@@ -702,7 +702,7 @@ fn Renderer(comptime WriterType: type) type {
} }
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..]);
} }
} }
@@ -774,7 +774,7 @@ fn Renderer(comptime WriterType: type) type {
const flags_type = try bitmaskFlagsType(bitwidth); const flags_type = try bitmaskFlagsType(bitwidth);
try self.writer.writeAll("pub usingnamespace FlagsMixin("); try self.writer.writeAll("pub usingnamespace FlagsMixin(");
try self.renderName(name); try self.renderName(name);
try self.writer.print(", {s});\n", .{ flags_type }); try self.writer.print(", {s});\n", .{flags_type});
} }
fn renderBitmaskBits(self: *Self, name: []const u8, bits: reg.Enum) !void { fn renderBitmaskBits(self: *Self, name: []const u8, bits: reg.Enum) !void {
@@ -786,7 +786,7 @@ fn Renderer(comptime WriterType: type) type {
const flags_type = try bitmaskFlagsType(bits.bitwidth); const flags_type = try bitmaskFlagsType(bits.bitwidth);
if (bits.fields.len == 0) { if (bits.fields.len == 0) {
try self.writer.print("_reserved_bits: {s} = 0,", .{ flags_type }); try self.writer.print("_reserved_bits: {s} = 0,", .{flags_type});
} else { } else {
var flags_by_bitpos = [_]?[]const u8{null} ** 64; var flags_by_bitpos = [_]?[]const u8{null} ** 64;
for (bits.fields) |field| { for (bits.fields) |field| {
@@ -795,7 +795,7 @@ fn Renderer(comptime WriterType: type) type {
} }
} }
for (flags_by_bitpos[0.. bits.bitwidth]) |maybe_flag_name, bitpos| { for (flags_by_bitpos[0..bits.bitwidth]) |maybe_flag_name, bitpos| {
if (maybe_flag_name) |flag_name| { if (maybe_flag_name) |flag_name| {
const field_name = try self.extractBitflagFieldName(bitflag_name, flag_name); const field_name = try self.extractBitflagFieldName(bitflag_name, flag_name);
try self.writeIdentifierWithCase(.snake, field_name); try self.writeIdentifierWithCase(.snake, field_name);
@@ -805,14 +805,14 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(": bool "); try self.writer.writeAll(": bool ");
if (bitpos == 0) { // Force alignment to integer boundaries if (bitpos == 0) { // Force alignment to integer boundaries
try self.writer.print("align(@alignOf({s})) ", .{ flags_type }); try self.writer.print("align(@alignOf({s})) ", .{flags_type});
} }
try self.writer.writeAll("= false, "); try self.writer.writeAll("= false, ");
} }
} }
try self.writer.writeAll("pub usingnamespace FlagsMixin("); try self.writer.writeAll("pub usingnamespace FlagsMixin(");
try self.renderName(name); try self.renderName(name);
try self.writer.print(", {s});\n}};\n", .{ flags_type }); try self.writer.print(", {s});\n}};\n", .{flags_type});
} }
fn renderBitmask(self: *Self, name: []const u8, bitmask: reg.Bitmask) !void { fn renderBitmask(self: *Self, name: []const u8, bitmask: reg.Bitmask) !void {
@@ -828,15 +828,13 @@ fn Renderer(comptime WriterType: type) type {
\\ = packed struct {{ \\ = packed struct {{
\\_reserved_bits: {s} = 0, \\_reserved_bits: {s} = 0,
\\pub usingnamespace FlagsMixin( \\pub usingnamespace FlagsMixin(
, .{ flags_type } , .{flags_type});
);
try self.renderName(name); try self.renderName(name);
try self.writer.print( try self.writer.print(
\\, {s}); \\, {s});
\\}}; \\}};
\\ \\
, .{ flags_type } , .{flags_type});
);
} }
} }
@@ -926,7 +924,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll("pub const "); try self.writer.writeAll("pub const ");
try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name)); try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name));
try self.writer.writeAll("= Info {\n"); try self.writer.writeAll("= Info {\n");
try self.writer.print(".name = \"{s}\", .version = {},", .{ext.name, ext.version}); try self.writer.print(".name = \"{s}\", .version = {},", .{ ext.name, ext.version });
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");
} }
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");
@@ -943,8 +941,7 @@ fn Renderer(comptime WriterType: type) type {
\\pub fn {s}(comptime Self: type) type {{ \\pub fn {s}(comptime Self: type) type {{
\\ return struct {{ \\ return struct {{
\\ \\
, .{name} , .{name});
);
try self.renderWrapperLoader(dispatch_type); try self.renderWrapperLoader(dispatch_type);
@@ -986,16 +983,15 @@ fn Renderer(comptime WriterType: type) type {
\\ return self; \\ return self;
\\}} \\}}
\\ \\
, .{params, loader_first_param} , .{ params, loader_first_param });
);
} }
fn derefName(name: []const u8) []const u8 { fn derefName(name: []const u8) []const u8 {
var it = id_render.SegmentIterator.init(name); var it = id_render.SegmentIterator.init(name);
return if (mem.eql(u8, it.next().?, "p")) return if (mem.eql(u8, it.next().?, "p"))
name[1..] name[1..]
else else
name; name;
} }
fn renderWrapperPrototype(self: *Self, name: []const u8, command: reg.Command, returns: []const ReturnValue) !void { fn renderWrapperPrototype(self: *Self, name: []const u8, command: reg.Command, returns: []const ReturnValue) !void {
@@ -1016,7 +1012,8 @@ fn Renderer(comptime WriterType: type) type {
.bitflags, // Special stuff handled in renderWrapperCall .bitflags, // Special stuff handled in renderWrapperCall
.buffer_len, .buffer_len,
.mut_buffer_len, .mut_buffer_len,
.other => { .other,
=> {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
try self.writer.writeAll(": "); try self.writer.writeAll(": ");
try self.renderTypeInfo(param.param_type); try self.renderTypeInfo(param.param_type);
@@ -1064,10 +1061,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
try self.writer.writeAll(".toInt()"); try self.writer.writeAll(".toInt()");
}, },
.in_out_pointer, .in_out_pointer, .buffer_len, .mut_buffer_len, .other => {
.buffer_len,
.mut_buffer_len,
.other => {
try self.writeIdentifierWithCase(.snake, param.name); try self.writeIdentifierWithCase(.snake, param.name);
}, },
} }
@@ -1131,16 +1125,13 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(": "); try self.writer.writeAll(": ");
try self.renderTypeInfo(ret.return_value_type); try self.renderTypeInfo(ret.return_value_type);
try self.writer.writeAll(", "); try self.writer.writeAll(", ");
} }
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");
} }
fn renderWrapper(self: *Self, name: []const u8, command: reg.Command) !void { fn renderWrapper(self: *Self, name: []const u8, command: reg.Command) !void {
const returns_vk_result = command.return_type.* == .name const returns_vk_result = command.return_type.* == .name and mem.eql(u8, command.return_type.name, "VkResult");
and mem.eql(u8, command.return_type.name, "VkResult"); const returns_void = command.return_type.* == .name and mem.eql(u8, command.return_type.name, "void");
const returns_void = command.return_type.* == .name
and mem.eql(u8, command.return_type.name, "void");
const returns = try self.extractReturns(command); const returns = try self.extractReturns(command);
@@ -1245,7 +1236,7 @@ fn Renderer(comptime WriterType: type) type {
fn renderResultAsErrorName(self: *Self, name: []const u8) !void { fn renderResultAsErrorName(self: *Self, name: []const u8) !void {
const error_prefix = "VK_ERROR_"; const error_prefix = "VK_ERROR_";
if (mem.startsWith(u8, name, error_prefix)) { if (mem.startsWith(u8, name, error_prefix)) {
try self.writeIdentifierWithCase(.title, name[error_prefix.len ..]); try self.writeIdentifierWithCase(.title, name[error_prefix.len..]);
} else { } else {
// Apparently some commands (VkAcquireProfilingLockInfoKHR) return // Apparently some commands (VkAcquireProfilingLockInfoKHR) return
// success codes as error... // success codes as error...

View File

@@ -7,13 +7,13 @@ const ArrayList = std.ArrayList;
pub const Attribute = struct { pub const Attribute = struct {
name: []const u8, name: []const u8,
value: []const u8 value: []const u8,
}; };
pub const Content = union(enum) { pub const Content = union(enum) {
CharData: []const u8, CharData: []const u8,
Comment: []const u8, Comment: []const u8,
Element: *Element Element: *Element,
}; };
pub const Element = struct { pub const Element = struct {
@@ -50,7 +50,7 @@ pub const Element = struct {
return switch (child.children.items[0]) { return switch (child.children.items[0]) {
.CharData => |char_data| char_data, .CharData => |char_data| char_data,
else => null else => null,
}; };
} }
@@ -74,7 +74,7 @@ pub const Element = struct {
pub fn findChildrenByTag(self: *Element, tag: []const u8) FindChildrenByTagIterator { pub fn findChildrenByTag(self: *Element, tag: []const u8) FindChildrenByTagIterator {
return .{ return .{
.inner = self.elements(), .inner = self.elements(),
.tag = tag .tag = tag,
}; };
} }
@@ -129,7 +129,7 @@ pub const Element = struct {
pub const XmlDecl = struct { pub const XmlDecl = struct {
version: []const u8, version: []const u8,
encoding: ?[]const u8, encoding: ?[]const u8,
standalone: ?bool standalone: ?bool,
}; };
pub const Document = struct { pub const Document = struct {
@@ -154,7 +154,7 @@ const ParseContext = struct {
.source = source, .source = source,
.offset = 0, .offset = 0,
.line = 0, .line = 0,
.column = 0 .column = 0,
}; };
} }
@@ -211,7 +211,7 @@ const ParseContext = struct {
fn expectStr(self: *ParseContext, text: []const u8) !void { fn expectStr(self: *ParseContext, text: []const u8) !void {
if (self.source.len < self.offset + text.len) { if (self.source.len < self.offset + text.len) {
return error.UnexpectedEof; return error.UnexpectedEof;
} else if (std.mem.startsWith(u8, self.source[self.offset ..], text)) { } else if (std.mem.startsWith(u8, self.source[self.offset..], text)) {
var i: usize = 0; var i: usize = 0;
while (i < text.len) : (i += 1) { while (i < text.len) : (i += 1) {
_ = self.consumeNoEof(); _ = self.consumeNoEof();
@@ -232,7 +232,7 @@ const ParseContext = struct {
ws = true; ws = true;
_ = self.consumeNoEof(); _ = self.consumeNoEof();
}, },
else => break else => break,
} }
} }
@@ -245,12 +245,12 @@ const ParseContext = struct {
fn currentLine(self: ParseContext) []const u8 { fn currentLine(self: ParseContext) []const u8 {
var begin: usize = 0; var begin: usize = 0;
if (mem.lastIndexOfScalar(u8, self.source[0 .. self.offset], '\n')) |prev_nl| { if (mem.lastIndexOfScalar(u8, self.source[0..self.offset], '\n')) |prev_nl| {
begin = prev_nl + 1; begin = prev_nl + 1;
} }
var end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse self.source.len; var end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse self.source.len;
return self.source[begin .. end]; return self.source[begin..end];
} }
}; };
@@ -300,7 +300,7 @@ test "ParseContext" {
} }
} }
pub const ParseError = error { pub const ParseError = error{
IllegalCharacter, IllegalCharacter,
UnexpectedEof, UnexpectedEof,
UnexpectedCharacter, UnexpectedCharacter,
@@ -311,7 +311,7 @@ pub const ParseError = error {
InvalidStandaloneValue, InvalidStandaloneValue,
NonMatchingClosingTag, NonMatchingClosingTag,
InvalidDocument, InvalidDocument,
OutOfMemory OutOfMemory,
}; };
pub fn parse(backing_allocator: *Allocator, source: []const u8) !Document { pub fn parse(backing_allocator: *Allocator, source: []const u8) !Document {
@@ -323,7 +323,7 @@ fn parseDocument(ctx: *ParseContext, backing_allocator: *Allocator) !Document {
var doc = Document{ var doc = Document{
.arena = ArenaAllocator.init(backing_allocator), .arena = ArenaAllocator.init(backing_allocator),
.xml_decl = null, .xml_decl = null,
.root = undefined .root = undefined,
}; };
errdefer doc.deinit(); errdefer doc.deinit();
@@ -356,7 +356,7 @@ fn parseAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 {
const end = ctx.offset - 1; const end = ctx.offset - 1;
return try dupeAndUnescape(alloc, ctx.source[begin .. end]); return try dupeAndUnescape(alloc, ctx.source[begin..end]);
} }
fn parseEqAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 { fn parseEqAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 {
@@ -376,14 +376,14 @@ fn parseNameNoDupe(ctx: *ParseContext) ![]const u8 {
switch (ch) { switch (ch) {
' ', '\t', '\n', '\r' => break, ' ', '\t', '\n', '\r' => break,
'&', '"', '\'', '<', '>', '?', '=', '/' => break, '&', '"', '\'', '<', '>', '?', '=', '/' => break,
else => _ = ctx.consumeNoEof() else => _ = ctx.consumeNoEof(),
} }
} }
const end = ctx.offset; const end = ctx.offset;
if (begin == end) return error.InvalidName; if (begin == end) return error.InvalidName;
return ctx.source[begin .. end]; return ctx.source[begin..end];
} }
fn tryParseCharData(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 { fn tryParseCharData(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
@@ -392,23 +392,23 @@ fn tryParseCharData(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
while (ctx.peek()) |ch| { while (ctx.peek()) |ch| {
switch (ch) { switch (ch) {
'<' => break, '<' => break,
else => _ = ctx.consumeNoEof() else => _ = ctx.consumeNoEof(),
} }
} }
const end = ctx.offset; const end = ctx.offset;
if (begin == end) return null; if (begin == end) return null;
return try dupeAndUnescape(alloc, ctx.source[begin .. end]); return try dupeAndUnescape(alloc, ctx.source[begin..end]);
} }
fn parseContent(ctx: *ParseContext, alloc: *Allocator) ParseError!Content { fn parseContent(ctx: *ParseContext, alloc: *Allocator) ParseError!Content {
if (try tryParseCharData(ctx, alloc)) |cd| { if (try tryParseCharData(ctx, alloc)) |cd| {
return Content{.CharData = cd}; return Content{ .CharData = cd };
} else if (try tryParseComment(ctx, alloc)) |comment| { } else if (try tryParseComment(ctx, alloc)) |comment| {
return Content{.Comment = comment}; return Content{ .Comment = comment };
} else if (try tryParseElement(ctx, alloc)) |elem| { } else if (try tryParseElement(ctx, alloc)) |elem| {
return Content{.Element = elem}; return Content{ .Element = elem };
} else { } else {
return error.UnexpectedCharacter; return error.UnexpectedCharacter;
} }
@@ -601,21 +601,18 @@ fn tryParseComment(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
} }
const end = ctx.offset - "-->".len; const end = ctx.offset - "-->".len;
return try mem.dupe(alloc, u8, ctx.source[begin .. end]); return try mem.dupe(alloc, u8, ctx.source[begin..end]);
} }
fn unescapeEntity(text: []const u8) !u8 { fn unescapeEntity(text: []const u8) !u8 {
const EntitySubstition = struct { const EntitySubstition = struct { text: []const u8, replacement: u8 };
text: []const u8,
replacement: u8
};
const entities = [_]EntitySubstition{ const entities = [_]EntitySubstition{
.{.text = "&lt;", .replacement = '<'}, .{ .text = "&lt;", .replacement = '<' },
.{.text = "&gt;", .replacement = '>'}, .{ .text = "&gt;", .replacement = '>' },
.{.text = "&amp;", .replacement = '&'}, .{ .text = "&amp;", .replacement = '&' },
.{.text = "&apos;", .replacement = '\''}, .{ .text = "&apos;", .replacement = '\'' },
.{.text = "&quot;", .replacement = '"'} .{ .text = "&quot;", .replacement = '"' },
}; };
for (entities) |entity| { for (entities) |entity| {
@@ -633,7 +630,7 @@ fn dupeAndUnescape(alloc: *Allocator, text: []const u8) ![]const u8 {
while (i < text.len) : (j += 1) { while (i < text.len) : (j += 1) {
if (text[i] == '&') { if (text[i] == '&') {
const entity_end = 1 + (mem.indexOfScalarPos(u8, text, i, ';') orelse return error.InvalidEntity); const entity_end = 1 + (mem.indexOfScalarPos(u8, text, i, ';') orelse return error.InvalidEntity);
str[j] = try unescapeEntity(text[i .. entity_end]); str[j] = try unescapeEntity(text[i..entity_end]);
i = entity_end; i = entity_end;
} else { } else {
str[j] = text[i]; str[j] = text[i];