forked from mirror/vulkan-zig
Merge pull request #127 from bluesillybeard/master
Add extension function metadata for #112
This commit is contained in:
@@ -5,78 +5,29 @@ const Allocator = std.mem.Allocator;
|
|||||||
|
|
||||||
const required_device_extensions = [_][*:0]const u8{vk.extension_info.khr_swapchain.name};
|
const required_device_extensions = [_][*:0]const u8{vk.extension_info.khr_swapchain.name};
|
||||||
|
|
||||||
const BaseDispatch = vk.BaseWrapper(.{
|
const BaseDispatch = vk.BaseWrapper(blk: {
|
||||||
.createInstance = true,
|
var commands = vk.feature_info.version_1_0.base_functions;
|
||||||
.getInstanceProcAddr = true,
|
commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_1.base_functions);
|
||||||
|
commands = vk.BaseCommandFlags.merge(commands, vk.feature_info.version_1_2.base_functions);
|
||||||
|
break :blk commands;
|
||||||
});
|
});
|
||||||
|
|
||||||
const InstanceDispatch = vk.InstanceWrapper(.{
|
const InstanceDispatch = vk.InstanceWrapper(blk: {
|
||||||
.destroyInstance = true,
|
var commands = vk.feature_info.version_1_0.instance_functions;
|
||||||
.createDevice = true,
|
commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_1.instance_functions);
|
||||||
.destroySurfaceKHR = true,
|
commands = vk.InstanceCommandFlags.merge(commands, vk.feature_info.version_1_2.instance_functions);
|
||||||
.enumeratePhysicalDevices = true,
|
commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_surface.instance_functions);
|
||||||
.getPhysicalDeviceProperties = true,
|
commands = vk.InstanceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.instance_functions);
|
||||||
.enumerateDeviceExtensionProperties = true,
|
break :blk commands;
|
||||||
.getPhysicalDeviceSurfaceFormatsKHR = true,
|
|
||||||
.getPhysicalDeviceSurfacePresentModesKHR = true,
|
|
||||||
.getPhysicalDeviceSurfaceCapabilitiesKHR = true,
|
|
||||||
.getPhysicalDeviceQueueFamilyProperties = true,
|
|
||||||
.getPhysicalDeviceSurfaceSupportKHR = true,
|
|
||||||
.getPhysicalDeviceMemoryProperties = true,
|
|
||||||
.getDeviceProcAddr = true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const DeviceDispatch = vk.DeviceWrapper(.{
|
const DeviceDispatch = vk.DeviceWrapper(blk: {
|
||||||
.destroyDevice = true,
|
var commands = vk.feature_info.version_1_0.device_functions;
|
||||||
.getDeviceQueue = true,
|
commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_1.device_functions);
|
||||||
.createSemaphore = true,
|
commands = vk.DeviceCommandFlags.merge(commands, vk.feature_info.version_1_2.device_functions);
|
||||||
.createFence = true,
|
commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_surface.device_functions);
|
||||||
.createImageView = true,
|
commands = vk.DeviceCommandFlags.merge(commands, vk.extension_info.khr_swapchain.device_functions);
|
||||||
.destroyImageView = true,
|
break :blk commands;
|
||||||
.destroySemaphore = true,
|
|
||||||
.destroyFence = true,
|
|
||||||
.getSwapchainImagesKHR = true,
|
|
||||||
.createSwapchainKHR = true,
|
|
||||||
.destroySwapchainKHR = true,
|
|
||||||
.acquireNextImageKHR = true,
|
|
||||||
.deviceWaitIdle = true,
|
|
||||||
.waitForFences = true,
|
|
||||||
.resetFences = true,
|
|
||||||
.queueSubmit = true,
|
|
||||||
.queuePresentKHR = true,
|
|
||||||
.createCommandPool = true,
|
|
||||||
.destroyCommandPool = true,
|
|
||||||
.allocateCommandBuffers = true,
|
|
||||||
.freeCommandBuffers = true,
|
|
||||||
.queueWaitIdle = true,
|
|
||||||
.createShaderModule = true,
|
|
||||||
.destroyShaderModule = true,
|
|
||||||
.createPipelineLayout = true,
|
|
||||||
.destroyPipelineLayout = true,
|
|
||||||
.createRenderPass = true,
|
|
||||||
.destroyRenderPass = true,
|
|
||||||
.createGraphicsPipelines = true,
|
|
||||||
.destroyPipeline = true,
|
|
||||||
.createFramebuffer = true,
|
|
||||||
.destroyFramebuffer = true,
|
|
||||||
.beginCommandBuffer = true,
|
|
||||||
.endCommandBuffer = true,
|
|
||||||
.allocateMemory = true,
|
|
||||||
.freeMemory = true,
|
|
||||||
.createBuffer = true,
|
|
||||||
.destroyBuffer = true,
|
|
||||||
.getBufferMemoryRequirements = true,
|
|
||||||
.mapMemory = true,
|
|
||||||
.unmapMemory = true,
|
|
||||||
.bindBufferMemory = true,
|
|
||||||
.cmdBeginRenderPass = true,
|
|
||||||
.cmdEndRenderPass = true,
|
|
||||||
.cmdBindPipeline = true,
|
|
||||||
.cmdDraw = true,
|
|
||||||
.cmdSetViewport = true,
|
|
||||||
.cmdSetScissor = true,
|
|
||||||
.cmdBindVertexBuffers = true,
|
|
||||||
.cmdCopyBuffer = true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
pub const GraphicsContext = struct {
|
pub const GraphicsContext = struct {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ const preamble =
|
|||||||
\\ ) !void {
|
\\ ) !void {
|
||||||
\\ try writer.writeAll(@typeName(FlagsType) ++ "{");
|
\\ try writer.writeAll(@typeName(FlagsType) ++ "{");
|
||||||
\\ var first = true;
|
\\ var first = true;
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (comptime std.meta.fieldNames(FlagsType)) |name| {
|
\\ inline for (comptime std.meta.fieldNames(FlagsType)) |name| {
|
||||||
\\ if (name[0] == '_') continue;
|
\\ if (name[0] == '_') continue;
|
||||||
\\ if (@field(self, name)) {
|
\\ if (@field(self, name)) {
|
||||||
@@ -469,6 +470,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
try self.renderCommandPtrs();
|
try self.renderCommandPtrs();
|
||||||
try self.renderExtensionInfo();
|
try self.renderExtensionInfo();
|
||||||
|
try self.renderFeatureInfo();
|
||||||
try self.renderWrappers();
|
try self.renderWrappers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,24 +1037,141 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
\\ const Info = struct {
|
\\ const Info = struct {
|
||||||
\\ name: [:0]const u8,
|
\\ name: [:0]const u8,
|
||||||
\\ version: u32,
|
\\ version: u32,
|
||||||
|
\\ instance_functions: InstanceCommandFlags,
|
||||||
|
\\ device_functions: DeviceCommandFlags,
|
||||||
\\ };
|
\\ };
|
||||||
);
|
);
|
||||||
|
// The commands in an extension are not pre-sorted based on if they are instance or device functions.
|
||||||
|
var instance_commands = std.BufSet.init(self.allocator);
|
||||||
|
defer instance_commands.deinit();
|
||||||
|
var device_commands = std.BufSet.init(self.allocator);
|
||||||
|
defer device_commands.deinit();
|
||||||
for (self.registry.extensions) |ext| {
|
for (self.registry.extensions) |ext| {
|
||||||
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 });
|
||||||
|
// collect extension functions
|
||||||
|
for (ext.requires) |require| {
|
||||||
|
for (require.commands) |command_name| {
|
||||||
|
const decl = self.resolveDeclaration(command_name) orelse continue;
|
||||||
|
// If the target type does not exist, it was likely an empty enum -
|
||||||
|
// assume spec is correct and that this was not a function alias.
|
||||||
|
const decl_type = self.resolveAlias(decl) catch continue;
|
||||||
|
const command = switch (decl_type) {
|
||||||
|
.command => |cmd| cmd,
|
||||||
|
else => continue,
|
||||||
|
};
|
||||||
|
const class = classifyCommandDispatch(command_name, command);
|
||||||
|
switch (class) {
|
||||||
|
// Vulkan extensions cannot add base functions.
|
||||||
|
.base => return error.InvalidRegistry,
|
||||||
|
.instance => {
|
||||||
|
try instance_commands.insert(command_name);
|
||||||
|
},
|
||||||
|
.device => {
|
||||||
|
try device_commands.insert(command_name);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// and write them out
|
||||||
|
try self.writer.writeAll(".instance_functions = ");
|
||||||
|
try self.renderCommandFlags(&instance_commands);
|
||||||
|
instance_commands.hash_map.clearRetainingCapacity();
|
||||||
|
|
||||||
|
try self.writer.writeAll(".device_functions = ");
|
||||||
|
try self.renderCommandFlags(&device_commands);
|
||||||
|
device_commands.hash_map.clearRetainingCapacity();
|
||||||
|
|
||||||
try self.writer.writeAll("};\n");
|
try self.writer.writeAll("};\n");
|
||||||
}
|
}
|
||||||
try self.writer.writeAll("};\n");
|
try self.writer.writeAll("};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn renderFeatureInfo(self: *Self) !void {
|
||||||
|
try self.writer.writeAll(
|
||||||
|
\\pub const feature_info = struct {
|
||||||
|
\\ const Info = struct {
|
||||||
|
\\ base_functions: BaseCommandFlags,
|
||||||
|
\\ instance_functions: InstanceCommandFlags,
|
||||||
|
\\ device_functions: DeviceCommandFlags,
|
||||||
|
\\ };
|
||||||
|
);
|
||||||
|
// The commands in a feature level are not pre-sorted based on if they are instance or device functions.
|
||||||
|
var base_commands = std.BufSet.init(self.allocator);
|
||||||
|
defer base_commands.deinit();
|
||||||
|
var instance_commands = std.BufSet.init(self.allocator);
|
||||||
|
defer instance_commands.deinit();
|
||||||
|
var device_commands = std.BufSet.init(self.allocator);
|
||||||
|
defer device_commands.deinit();
|
||||||
|
for (self.registry.features) |feature| {
|
||||||
|
try self.writer.writeAll("pub const ");
|
||||||
|
try self.writeIdentifierWithCase(.snake, trimVkNamespace(feature.name));
|
||||||
|
try self.writer.writeAll("= Info {\n");
|
||||||
|
// collect feature information
|
||||||
|
for (feature.requires) |require| {
|
||||||
|
for (require.commands) |command_name| {
|
||||||
|
const decl = self.resolveDeclaration(command_name) orelse continue;
|
||||||
|
// If the target type does not exist, it was likely an empty enum -
|
||||||
|
// assume spec is correct and that this was not a function alias.
|
||||||
|
const decl_type = self.resolveAlias(decl) catch continue;
|
||||||
|
const command = switch (decl_type) {
|
||||||
|
.command => |cmd| cmd,
|
||||||
|
else => continue,
|
||||||
|
};
|
||||||
|
const class = classifyCommandDispatch(command_name, command);
|
||||||
|
switch (class) {
|
||||||
|
.base => {
|
||||||
|
try base_commands.insert(command_name);
|
||||||
|
},
|
||||||
|
.instance => {
|
||||||
|
try instance_commands.insert(command_name);
|
||||||
|
},
|
||||||
|
.device => {
|
||||||
|
try device_commands.insert(command_name);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// and write them out
|
||||||
|
// clear command lists for next iteration
|
||||||
|
try self.writer.writeAll(".base_functions = ");
|
||||||
|
try self.renderCommandFlags(&base_commands);
|
||||||
|
base_commands.hash_map.clearRetainingCapacity();
|
||||||
|
|
||||||
|
try self.writer.writeAll(".instance_functions = ");
|
||||||
|
try self.renderCommandFlags(&instance_commands);
|
||||||
|
instance_commands.hash_map.clearRetainingCapacity();
|
||||||
|
|
||||||
|
try self.writer.writeAll(".device_functions = ");
|
||||||
|
try self.renderCommandFlags(&device_commands);
|
||||||
|
device_commands.hash_map.clearRetainingCapacity();
|
||||||
|
|
||||||
|
try self.writer.writeAll("};\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
try self.writer.writeAll("};\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn renderCommandFlags(self: *Self, commands: *const std.BufSet) !void {
|
||||||
|
try self.writer.writeAll(".{\n");
|
||||||
|
var iterator = commands.iterator();
|
||||||
|
while (iterator.next()) |command_name| {
|
||||||
|
try self.writer.writeAll(".");
|
||||||
|
try self.writeIdentifierWithCase(.camel, trimVkNamespace(command_name.*));
|
||||||
|
try self.writer.writeAll(" = true, \n");
|
||||||
|
}
|
||||||
|
try self.writer.writeAll("},\n");
|
||||||
|
}
|
||||||
|
|
||||||
fn renderWrappers(self: *Self) !void {
|
fn renderWrappers(self: *Self) !void {
|
||||||
try self.writer.writeAll(
|
try self.writer.writeAll(
|
||||||
\\pub fn CommandFlagsMixin(comptime CommandFlags: type) type {
|
\\pub fn CommandFlagsMixin(comptime CommandFlags: type) type {
|
||||||
\\ return struct {
|
\\ return struct {
|
||||||
\\ pub fn merge(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
\\ pub fn merge(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
||||||
\\ var result: CommandFlags = .{};
|
\\ var result: CommandFlags = .{};
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
||||||
\\ @field(result, field.name) = @field(lhs, field.name) or @field(rhs, field.name);
|
\\ @field(result, field.name) = @field(lhs, field.name) or @field(rhs, field.name);
|
||||||
\\ }
|
\\ }
|
||||||
@@ -1060,6 +1179,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
\\ }
|
\\ }
|
||||||
\\ pub fn intersect(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
\\ pub fn intersect(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
||||||
\\ var result: CommandFlags = .{};
|
\\ var result: CommandFlags = .{};
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
||||||
\\ @field(result, field.name) = @field(lhs, field.name) and @field(rhs, field.name);
|
\\ @field(result, field.name) = @field(lhs, field.name) and @field(rhs, field.name);
|
||||||
\\ }
|
\\ }
|
||||||
@@ -1067,6 +1187,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
\\ }
|
\\ }
|
||||||
\\ pub fn complement(self: CommandFlags) CommandFlags {
|
\\ pub fn complement(self: CommandFlags) CommandFlags {
|
||||||
\\ var result: CommandFlags = .{};
|
\\ var result: CommandFlags = .{};
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
||||||
\\ @field(result, field.name) = !@field(self, field.name);
|
\\ @field(result, field.name) = !@field(self, field.name);
|
||||||
\\ }
|
\\ }
|
||||||
@@ -1074,12 +1195,14 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
\\ }
|
\\ }
|
||||||
\\ pub fn subtract(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
\\ pub fn subtract(lhs: CommandFlags, rhs: CommandFlags) CommandFlags {
|
||||||
\\ var result: CommandFlags = .{};
|
\\ var result: CommandFlags = .{};
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
||||||
\\ @field(result, field.name) = @field(lhs, field.name) and !@field(rhs, field.name);
|
\\ @field(result, field.name) = @field(lhs, field.name) and !@field(rhs, field.name);
|
||||||
\\ }
|
\\ }
|
||||||
\\ return result;
|
\\ return result;
|
||||||
\\ }
|
\\ }
|
||||||
\\ pub fn contains(lhs: CommandFlags, rhs: CommandFlags) bool {
|
\\ pub fn contains(lhs: CommandFlags, rhs: CommandFlags) bool {
|
||||||
|
\\ @setEvalBranchQuota(10_000);
|
||||||
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
\\ inline for (@typeInfo(CommandFlags).Struct.fields) |field| {
|
||||||
\\ if (!@field(lhs, field.name) and @field(rhs, field.name)) {
|
\\ if (!@field(lhs, field.name) and @field(rhs, field.name)) {
|
||||||
\\ return false;
|
\\ return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user