forked from mirror/vulkan-zig
Compare commits
14 Commits
zig-0.8.0-
...
zig-0.8.1-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d87813312e | ||
|
|
e17c3593d1 | ||
|
|
9513d33bf8 | ||
|
|
59c5b88d17 | ||
|
|
4588c0fcad | ||
|
|
f55409f98a | ||
|
|
cbf06a8d42 | ||
|
|
c5bb254766 | ||
|
|
5980bac303 | ||
|
|
3bfacc7e16 | ||
|
|
1e594c0f09 | ||
|
|
397e663296 | ||
|
|
933010cfff | ||
|
|
0eccd593ce |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -2,9 +2,9 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ zig-0.8.0-compat ]
|
||||
branches: [ zig-0.8.1-compat ]
|
||||
pull_request:
|
||||
branches: [ zig-0.8.0-compat ]
|
||||
branches: [ zig-0.8.1-compat ]
|
||||
schedule:
|
||||
- cron: '0 6 * * *'
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
- name: Fetch Vulkan SDK
|
||||
run: |
|
||||
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
|
||||
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.176-focal.list https://packages.lunarg.com/vulkan/1.2.176/lunarg-vulkan-1.2.176-focal.list
|
||||
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.189-focal.list https://packages.lunarg.com/vulkan/1.2.189/lunarg-vulkan-1.2.189-focal.list
|
||||
sudo apt update
|
||||
sudo apt install shaderc libglfw3 libglfw3-dev
|
||||
|
||||
|
||||
10
README.md
10
README.md
@@ -36,10 +36,10 @@ pub fn build(b: *Builder) void {
|
||||
exe.step.dependOn(&gen.step);
|
||||
|
||||
// Add the generated file as package to the final executable
|
||||
exe.addPackagePath("vulkan", gen.full_out_path);
|
||||
exe.addPackage(gen.package);
|
||||
}
|
||||
```
|
||||
This reads vk.xml, parses its contents, and renders the Vulkan bindings to "vk.zig", which is then formatted and placed in `zig-cache`. The resulting file can then be added to an executable by using `addPackagePath`.
|
||||
This reads vk.xml, parses its contents, and renders the Vulkan bindings to "vk.zig", which is then formatted and placed in `zig-cache`. The resulting file can then be added to an executable by using `addPackage`, after which the bindings will be made available to the executable under the name `vulkan`.
|
||||
|
||||
### Function & field renaming
|
||||
Functions and fields are renamed to be more or less in line with [Zig's standard library style](https://ziglang.org/documentation/master/#Style-Guide):
|
||||
@@ -231,7 +231,7 @@ pub fn build(b: *Builder) void {
|
||||
|
||||
const gen = vkgen.VkGenerateStep(b, "path/to/vk.xml", "vk.zig");
|
||||
exe.step.dependOn(&gen.step);
|
||||
exe.addPackagePath("vulkan", gen.full_out_path);
|
||||
exe.addPackage(gen.package);
|
||||
|
||||
const shader_comp = vkgen.ShaderCompileStep.init(
|
||||
builder,
|
||||
@@ -252,5 +252,7 @@ Upon compilation, glslc is then invoked to compile each shader, and the result i
|
||||
A partial implementation of https://vulkan-tutorial.org is implemented in [examples/triangle.zig](examples/triangle.zig). This example can be ran by executing `zig build run-triangle` in vulkan-zig's root.
|
||||
|
||||
## See also
|
||||
* Implementation of https://vulkan-tutorial.org: https://github.com/andrewrk/zig-vulkan-triangle.
|
||||
* Implementation of https://vulkan-tutorial.org using `@cImport`'ed bindings: https://github.com/andrewrk/zig-vulkan-triangle.
|
||||
* Alternative binding generator: https://github.com/SpexGuy/Zig-Vulkan-Headers
|
||||
* Zig bindings for GLFW: https://github.com/hexops/mach-glfw
|
||||
* With vulkan-zig integration example: https://github.com/hexops/mach-glfw-vulkan-example
|
||||
|
||||
@@ -5,77 +5,77 @@ const Allocator = std.mem.Allocator;
|
||||
|
||||
const required_device_extensions = [_][]const u8{vk.extension_info.khr_swapchain.name};
|
||||
|
||||
const BaseDispatch = vk.BaseWrapper(.{
|
||||
.CreateInstance,
|
||||
const BaseDispatch = vk.BaseWrapper(&.{
|
||||
.createInstance,
|
||||
});
|
||||
|
||||
const InstanceDispatch = vk.InstanceWrapper(.{
|
||||
.DestroyInstance,
|
||||
.CreateDevice,
|
||||
.DestroySurfaceKHR,
|
||||
.EnumeratePhysicalDevices,
|
||||
.GetPhysicalDeviceProperties,
|
||||
.EnumerateDeviceExtensionProperties,
|
||||
.GetPhysicalDeviceSurfaceFormatsKHR,
|
||||
.GetPhysicalDeviceSurfacePresentModesKHR,
|
||||
.GetPhysicalDeviceSurfaceCapabilitiesKHR,
|
||||
.GetPhysicalDeviceQueueFamilyProperties,
|
||||
.GetPhysicalDeviceSurfaceSupportKHR,
|
||||
.GetPhysicalDeviceMemoryProperties,
|
||||
.GetDeviceProcAddr,
|
||||
const InstanceDispatch = vk.InstanceWrapper(&.{
|
||||
.destroyInstance,
|
||||
.createDevice,
|
||||
.destroySurfaceKHR,
|
||||
.enumeratePhysicalDevices,
|
||||
.getPhysicalDeviceProperties,
|
||||
.enumerateDeviceExtensionProperties,
|
||||
.getPhysicalDeviceSurfaceFormatsKHR,
|
||||
.getPhysicalDeviceSurfacePresentModesKHR,
|
||||
.getPhysicalDeviceSurfaceCapabilitiesKHR,
|
||||
.getPhysicalDeviceQueueFamilyProperties,
|
||||
.getPhysicalDeviceSurfaceSupportKHR,
|
||||
.getPhysicalDeviceMemoryProperties,
|
||||
.getDeviceProcAddr,
|
||||
});
|
||||
|
||||
const DeviceDispatch = vk.DeviceWrapper(.{
|
||||
.DestroyDevice,
|
||||
.GetDeviceQueue,
|
||||
.CreateSemaphore,
|
||||
.CreateFence,
|
||||
.CreateImageView,
|
||||
.DestroyImageView,
|
||||
.DestroySemaphore,
|
||||
.DestroyFence,
|
||||
.GetSwapchainImagesKHR,
|
||||
.CreateSwapchainKHR,
|
||||
.DestroySwapchainKHR,
|
||||
.AcquireNextImageKHR,
|
||||
.DeviceWaitIdle,
|
||||
.WaitForFences,
|
||||
.ResetFences,
|
||||
.QueueSubmit,
|
||||
.QueuePresentKHR,
|
||||
.CreateCommandPool,
|
||||
.DestroyCommandPool,
|
||||
.AllocateCommandBuffers,
|
||||
.FreeCommandBuffers,
|
||||
.QueueWaitIdle,
|
||||
.CreateShaderModule,
|
||||
.DestroyShaderModule,
|
||||
.CreatePipelineLayout,
|
||||
.DestroyPipelineLayout,
|
||||
.CreateRenderPass,
|
||||
.DestroyRenderPass,
|
||||
.CreateGraphicsPipelines,
|
||||
.DestroyPipeline,
|
||||
.CreateFramebuffer,
|
||||
.DestroyFramebuffer,
|
||||
.BeginCommandBuffer,
|
||||
.EndCommandBuffer,
|
||||
.AllocateMemory,
|
||||
.FreeMemory,
|
||||
.CreateBuffer,
|
||||
.DestroyBuffer,
|
||||
.GetBufferMemoryRequirements,
|
||||
.MapMemory,
|
||||
.UnmapMemory,
|
||||
.BindBufferMemory,
|
||||
.CmdBeginRenderPass,
|
||||
.CmdEndRenderPass,
|
||||
.CmdBindPipeline,
|
||||
.CmdDraw,
|
||||
.CmdSetViewport,
|
||||
.CmdSetScissor,
|
||||
.CmdBindVertexBuffers,
|
||||
.CmdCopyBuffer,
|
||||
const DeviceDispatch = vk.DeviceWrapper(&.{
|
||||
.destroyDevice,
|
||||
.getDeviceQueue,
|
||||
.createSemaphore,
|
||||
.createFence,
|
||||
.createImageView,
|
||||
.destroyImageView,
|
||||
.destroySemaphore,
|
||||
.destroyFence,
|
||||
.getSwapchainImagesKHR,
|
||||
.createSwapchainKHR,
|
||||
.destroySwapchainKHR,
|
||||
.acquireNextImageKHR,
|
||||
.deviceWaitIdle,
|
||||
.waitForFences,
|
||||
.resetFences,
|
||||
.queueSubmit,
|
||||
.queuePresentKHR,
|
||||
.createCommandPool,
|
||||
.destroyCommandPool,
|
||||
.allocateCommandBuffers,
|
||||
.freeCommandBuffers,
|
||||
.queueWaitIdle,
|
||||
.createShaderModule,
|
||||
.destroyShaderModule,
|
||||
.createPipelineLayout,
|
||||
.destroyPipelineLayout,
|
||||
.createRenderPass,
|
||||
.destroyRenderPass,
|
||||
.createGraphicsPipelines,
|
||||
.destroyPipeline,
|
||||
.createFramebuffer,
|
||||
.destroyFramebuffer,
|
||||
.beginCommandBuffer,
|
||||
.endCommandBuffer,
|
||||
.allocateMemory,
|
||||
.freeMemory,
|
||||
.createBuffer,
|
||||
.destroyBuffer,
|
||||
.getBufferMemoryRequirements,
|
||||
.mapMemory,
|
||||
.unmapMemory,
|
||||
.bindBufferMemory,
|
||||
.cmdBeginRenderPass,
|
||||
.cmdEndRenderPass,
|
||||
.cmdBindPipeline,
|
||||
.cmdDraw,
|
||||
.cmdSetViewport,
|
||||
.cmdSetScissor,
|
||||
.cmdBindVertexBuffers,
|
||||
.cmdCopyBuffer,
|
||||
});
|
||||
|
||||
pub const GraphicsContext = struct {
|
||||
|
||||
@@ -251,7 +251,7 @@ fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, f
|
||||
_ = try gc.vkd.getSwapchainImagesKHR(gc.dev, swapchain, &count, images.ptr);
|
||||
|
||||
const swap_images = try allocator.alloc(SwapImage, count);
|
||||
errdefer allocator.free(images);
|
||||
errdefer allocator.free(swap_images);
|
||||
|
||||
var i: usize = 0;
|
||||
errdefer for (swap_images[0..i]) |si| si.deinit(gc);
|
||||
|
||||
@@ -150,7 +150,6 @@ pub fn main() !void {
|
||||
);
|
||||
}
|
||||
|
||||
c.glfwSwapBuffers(window);
|
||||
c.glfwPollEvents();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ pub const GenerateStep = struct {
|
||||
try generate(self.builder.allocator, spec, out_buffer.writer());
|
||||
|
||||
const tree = try std.zig.parse(self.builder.allocator, out_buffer.items);
|
||||
std.debug.assert(tree.errors.len == 0); // If this triggers, vulkan-zig produced invalid code.
|
||||
|
||||
var formatted = try tree.render(self.builder.allocator);
|
||||
|
||||
|
||||
@@ -9,41 +9,30 @@ const Allocator = mem.Allocator;
|
||||
const FeatureLevel = reg.FeatureLevel;
|
||||
|
||||
const EnumFieldMerger = struct {
|
||||
const EnumExtensionMap = std.StringArrayHashMap(std.ArrayListUnmanaged(reg.Enum.Field));
|
||||
const FieldSet = std.StringArrayHashMap(void);
|
||||
const EnumExtensionMap = std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(reg.Enum.Field));
|
||||
const FieldSet = std.StringArrayHashMapUnmanaged(void);
|
||||
|
||||
gpa: *Allocator,
|
||||
reg_arena: *Allocator,
|
||||
arena: *Allocator,
|
||||
registry: *reg.Registry,
|
||||
enum_extensions: EnumExtensionMap,
|
||||
field_set: FieldSet,
|
||||
|
||||
fn init(gpa: *Allocator, reg_arena: *Allocator, registry: *reg.Registry) EnumFieldMerger {
|
||||
fn init(arena: *Allocator, registry: *reg.Registry) EnumFieldMerger {
|
||||
return .{
|
||||
.gpa = gpa,
|
||||
.reg_arena = reg_arena,
|
||||
.arena = arena,
|
||||
.registry = registry,
|
||||
.enum_extensions = EnumExtensionMap.init(gpa),
|
||||
.field_set = FieldSet.init(gpa),
|
||||
.enum_extensions = .{},
|
||||
.field_set = .{},
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *EnumFieldMerger) void {
|
||||
for (self.enum_extensions.values()) |*value| {
|
||||
value.deinit(self.gpa);
|
||||
}
|
||||
|
||||
self.field_set.deinit();
|
||||
self.enum_extensions.deinit();
|
||||
}
|
||||
|
||||
fn putEnumExtension(self: *EnumFieldMerger, enum_name: []const u8, field: reg.Enum.Field) !void {
|
||||
const res = try self.enum_extensions.getOrPut(enum_name);
|
||||
const res = try self.enum_extensions.getOrPut(self.arena, enum_name);
|
||||
if (!res.found_existing) {
|
||||
res.value_ptr.* = std.ArrayListUnmanaged(reg.Enum.Field){};
|
||||
}
|
||||
|
||||
try res.value_ptr.append(self.gpa, field);
|
||||
try res.value_ptr.append(self.arena, field);
|
||||
}
|
||||
|
||||
fn addRequires(self: *EnumFieldMerger, reqs: []const reg.Require) !void {
|
||||
@@ -61,11 +50,11 @@ const EnumFieldMerger = struct {
|
||||
self.field_set.clearRetainingCapacity();
|
||||
|
||||
const n_fields_upper_bound = base_enum.fields.len + extensions.items.len;
|
||||
const new_fields = try self.reg_arena.alloc(reg.Enum.Field, n_fields_upper_bound);
|
||||
const new_fields = try self.arena.alloc(reg.Enum.Field, n_fields_upper_bound);
|
||||
var i: usize = 0;
|
||||
|
||||
for (base_enum.fields) |field| {
|
||||
const res = try self.field_set.getOrPut(field.name);
|
||||
const res = try self.field_set.getOrPut(self.arena, field.name);
|
||||
if (!res.found_existing) {
|
||||
new_fields[i] = field;
|
||||
i += 1;
|
||||
@@ -74,16 +63,16 @@ const EnumFieldMerger = struct {
|
||||
|
||||
// Assume that if a field name clobbers, the value is the same
|
||||
for (extensions.items) |field| {
|
||||
const res = try self.field_set.getOrPut(field.name);
|
||||
const res = try self.field_set.getOrPut(self.arena, field.name);
|
||||
if (!res.found_existing) {
|
||||
new_fields[i] = field;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Existing base_enum.fields was allocatued by `self.reg_arena`, so
|
||||
// Existing base_enum.fields was allocated by `self.arena`, so
|
||||
// it gets cleaned up whenever that is deinited.
|
||||
base_enum.fields = self.reg_arena.shrink(new_fields, i);
|
||||
base_enum.fields = self.arena.shrink(new_fields, i);
|
||||
}
|
||||
|
||||
fn merge(self: *EnumFieldMerger) !void {
|
||||
@@ -106,8 +95,7 @@ const EnumFieldMerger = struct {
|
||||
};
|
||||
|
||||
pub const Generator = struct {
|
||||
gpa: *Allocator,
|
||||
reg_arena: std.heap.ArenaAllocator,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
registry: reg.Registry,
|
||||
id_renderer: IdRenderer,
|
||||
|
||||
@@ -118,16 +106,14 @@ pub const Generator = struct {
|
||||
for (tags) |*tag, i| tag.* = result.registry.tags[i].name;
|
||||
|
||||
return Generator{
|
||||
.gpa = allocator,
|
||||
.reg_arena = result.arena,
|
||||
.arena = result.arena,
|
||||
.registry = result.registry,
|
||||
.id_renderer = IdRenderer.init(allocator, tags),
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: Generator) void {
|
||||
self.gpa.free(self.id_renderer.tags);
|
||||
self.reg_arena.deinit();
|
||||
self.arena.deinit();
|
||||
}
|
||||
|
||||
fn stripFlagBits(self: Generator, name: []const u8) []const u8 {
|
||||
@@ -142,14 +128,13 @@ pub const Generator = struct {
|
||||
|
||||
// Solve `registry.declarations` according to `registry.extensions` and `registry.features`.
|
||||
fn mergeEnumFields(self: *Generator) !void {
|
||||
var merger = EnumFieldMerger.init(self.gpa, &self.reg_arena.allocator, &self.registry);
|
||||
defer merger.deinit();
|
||||
var merger = EnumFieldMerger.init(&self.arena.allocator, &self.registry);
|
||||
try merger.merge();
|
||||
}
|
||||
|
||||
// https://github.com/KhronosGroup/Vulkan-Docs/pull/1556
|
||||
fn fixupBitFlags(self: *Generator) !void {
|
||||
var seen_bits = std.StringArrayHashMap(void).init(&self.reg_arena.allocator);
|
||||
var seen_bits = std.StringArrayHashMap(void).init(&self.arena.allocator);
|
||||
defer seen_bits.deinit();
|
||||
|
||||
for (self.registry.decls) |decl| {
|
||||
@@ -181,7 +166,7 @@ pub const Generator = struct {
|
||||
}
|
||||
|
||||
fn render(self: *Generator, writer: anytype) !void {
|
||||
try renderRegistry(writer, &self.reg_arena.allocator, &self.registry, &self.id_renderer);
|
||||
try renderRegistry(writer, &self.arena.allocator, &self.registry, &self.id_renderer);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -205,6 +205,18 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
|
||||
|
||||
members = allocator.shrink(members, i);
|
||||
|
||||
var maybe_extends: ?[][]const u8 = null;
|
||||
if (ty.getAttribute("structextends")) |extends| {
|
||||
const n_structs = std.mem.count(u8, extends, ",") + 1;
|
||||
maybe_extends = try allocator.alloc([]const u8, n_structs);
|
||||
var struct_extends = std.mem.split(extends, ",");
|
||||
var j: usize = 0;
|
||||
while (struct_extends.next()) |struct_extend| {
|
||||
maybe_extends.?[j] = struct_extend;
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
it = ty.findChildrenByTag("member");
|
||||
for (members) |*member| {
|
||||
const member_elem = it.next().?;
|
||||
@@ -218,6 +230,7 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
|
||||
.stype = maybe_stype,
|
||||
.fields = members,
|
||||
.is_union = is_union,
|
||||
.extends = maybe_extends,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -65,6 +65,7 @@ pub const Container = struct {
|
||||
};
|
||||
|
||||
stype: ?[]const u8,
|
||||
extends: ?[]const []const u8,
|
||||
fields: []Field,
|
||||
is_union: bool,
|
||||
};
|
||||
|
||||
@@ -185,10 +185,6 @@ fn Renderer(comptime WriterType: type) type {
|
||||
declarations_by_name: std.StringHashMap(*const reg.DeclarationType),
|
||||
|
||||
fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !Self {
|
||||
const tags = try allocator.alloc([]const u8, registry.tags.len);
|
||||
errdefer allocator.free(tags);
|
||||
for (tags) |*tag, i| tag.* = registry.tags[i].name;
|
||||
|
||||
var declarations_by_name = std.StringHashMap(*const reg.DeclarationType).init(allocator);
|
||||
errdefer declarations_by_name.deinit();
|
||||
|
||||
@@ -212,8 +208,6 @@ fn Renderer(comptime WriterType: type) type {
|
||||
|
||||
fn deinit(self: *Self) void {
|
||||
self.declarations_by_name.deinit();
|
||||
self.allocator.free(self.id_renderer.tags);
|
||||
self.id_renderer.deinit();
|
||||
}
|
||||
|
||||
fn writeIdentifier(self: Self, id: []const u8) !void {
|
||||
@@ -446,19 +440,70 @@ fn Renderer(comptime WriterType: type) type {
|
||||
|
||||
try self.writer.print("pub const {s}Command = enum {{\n", .{dispatch_type_name});
|
||||
for (self.registry.decls) |decl| {
|
||||
if (decl.decl_type == .command) {
|
||||
const command = decl.decl_type.command;
|
||||
const command = switch (decl.decl_type) {
|
||||
.command => |cmd| cmd,
|
||||
else => continue,
|
||||
};
|
||||
|
||||
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
|
||||
try self.writer.print("{s},\n", .{trimVkNamespace(decl.name)});
|
||||
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
|
||||
try self.writer.writeAll(",\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
try self.writer.writeAll("};\n");
|
||||
|
||||
{
|
||||
try self.writer.print(
|
||||
\\fn {s}CommandToString(cmd: {s}Command) []const u8 {{
|
||||
\\ return std.meta.tagName(cmd);
|
||||
\\}}
|
||||
, .{ dispatch_type_name, dispatch_type_name });
|
||||
\\
|
||||
\\pub fn symbol(self: {s}Command) [:0]const u8 {{
|
||||
\\ return switch (self) {{
|
||||
\\
|
||||
, .{dispatch_type_name}
|
||||
);
|
||||
|
||||
for (self.registry.decls) |decl| {
|
||||
const command = switch (decl.decl_type) {
|
||||
.command => |cmd| cmd,
|
||||
else => continue,
|
||||
};
|
||||
|
||||
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
|
||||
try self.writer.writeAll(".");
|
||||
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
|
||||
try self.writer.print(" => \"{s}\",\n", .{ decl.name });
|
||||
}
|
||||
}
|
||||
|
||||
try self.writer.writeAll("};\n}\n");
|
||||
}
|
||||
|
||||
{
|
||||
try self.writer.print(
|
||||
\\
|
||||
\\pub fn PfnType(comptime self: {s}Command) type {{
|
||||
\\ return switch (self) {{
|
||||
\\
|
||||
, .{dispatch_type_name}
|
||||
);
|
||||
|
||||
for (self.registry.decls) |decl| {
|
||||
const command = switch (decl.decl_type) {
|
||||
.command => |cmd| cmd,
|
||||
else => continue,
|
||||
};
|
||||
|
||||
if (classifyCommandDispatch(decl.name, command) == dispatch_type) {
|
||||
try self.writer.writeAll(".");
|
||||
try self.writeIdentifierWithCase(.camel, trimVkNamespace(decl.name));
|
||||
try self.writer.writeAll(" => ");
|
||||
try self.renderCommandPtrName(decl.name);
|
||||
try self.writer.writeAll(",\n");
|
||||
}
|
||||
}
|
||||
|
||||
try self.writer.writeAll("};\n}\n");
|
||||
}
|
||||
|
||||
try self.writer.writeAll("};\n");
|
||||
}
|
||||
|
||||
fn renderCopyright(self: *Self) !void {
|
||||
@@ -705,7 +750,7 @@ fn Renderer(comptime WriterType: type) type {
|
||||
}
|
||||
} else {
|
||||
try self.renderTypeInfo(field.field_type);
|
||||
try self.renderContainerDefaultField(container, field);
|
||||
try self.renderContainerDefaultField(name, container, field);
|
||||
try self.writer.writeAll(", ");
|
||||
}
|
||||
}
|
||||
@@ -713,7 +758,7 @@ fn Renderer(comptime WriterType: type) type {
|
||||
try self.writer.writeAll("};\n");
|
||||
}
|
||||
|
||||
fn renderContainerDefaultField(self: *Self, container: reg.Container, field: reg.Container.Field) !void {
|
||||
fn renderContainerDefaultField(self: *Self, name: []const u8, container: reg.Container, field: reg.Container.Field) !void {
|
||||
if (mem.eql(u8, field.name, "pNext")) {
|
||||
try self.writer.writeAll(" = null");
|
||||
} else if (mem.eql(u8, field.name, "sType")) {
|
||||
@@ -728,9 +773,21 @@ fn Renderer(comptime WriterType: type) type {
|
||||
|
||||
try self.writer.writeAll(" = .");
|
||||
try self.writeIdentifierWithCase(.snake, stype["VK_STRUCTURE_TYPE_".len..]);
|
||||
} else if (field.field_type == .name and !container.is_union and mem.eql(u8, "VkBool32", field.field_type.name) and isFeatureStruct(name, container.extends)) {
|
||||
try self.writer.writeAll(" = FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
fn isFeatureStruct(name: []const u8, maybe_extends: ?[]const []const u8) bool {
|
||||
if (std.mem.eql(u8, name, "VkPhysicalDeviceFeatures")) return true;
|
||||
if (maybe_extends) |extends| {
|
||||
return for (extends) |extend| {
|
||||
if (mem.eql(u8, extend, "VkDeviceCreateInfo")) break true;
|
||||
} else false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn renderEnumFieldName(self: *Self, name: []const u8, field_name: []const u8) !void {
|
||||
try self.writeIdentifierWithCase(.snake, try self.extractEnumFieldName(name, field_name));
|
||||
}
|
||||
@@ -743,7 +800,7 @@ fn Renderer(comptime WriterType: type) type {
|
||||
|
||||
try self.writer.writeAll("pub const ");
|
||||
try self.renderName(name);
|
||||
try self.writer.writeAll(" = enum(c_int) {");
|
||||
try self.writer.writeAll(" = enum(i32) {");
|
||||
|
||||
for (enumeration.fields) |field| {
|
||||
if (field.value == .alias)
|
||||
@@ -958,18 +1015,16 @@ fn Renderer(comptime WriterType: type) type {
|
||||
};
|
||||
|
||||
try self.writer.print(
|
||||
\\pub fn {s}Wrapper(comptime cmds: anytype) type {{
|
||||
\\pub fn {s}Wrapper(comptime cmds: []const {s}Command) type {{
|
||||
\\ comptime var fields: [cmds.len]std.builtin.TypeInfo.StructField = undefined;
|
||||
\\ inline for (cmds) |cmd, i| {{
|
||||
\\ const cmd_name = {s}CommandToString(cmd);
|
||||
\\ const cmd_type_name = "Pfn" ++ cmd_name;
|
||||
\\ const cmd_type = @field(GlobalScope, cmd_type_name);
|
||||
\\ const PfnType = cmd.PfnType();
|
||||
\\ fields[i] = .{{
|
||||
\\ .name = "vk" ++ cmd_name,
|
||||
\\ .field_type = cmd_type,
|
||||
\\ .name = cmd.symbol(),
|
||||
\\ .field_type = PfnType,
|
||||
\\ .default_value = null,
|
||||
\\ .is_comptime = false,
|
||||
\\ .alignment = @alignOf(*cmd_type),
|
||||
\\ .alignment = @alignOf(PfnType),
|
||||
\\ }};
|
||||
\\ }}
|
||||
\\ const Dispatch = @Type(.{{
|
||||
|
||||
Reference in New Issue
Block a user