Make duck-typing easier

* Use flag struct based on command enum to enable commands
* Include cmds argument as public declaration inside Wrapper structs
* Include Dispatch type as public declaration inside Wrapper structs
This commit is contained in:
InKryption
2021-12-28 12:52:52 +01:00
parent eb4373bb7c
commit fd4302f848
2 changed files with 112 additions and 88 deletions

View File

@@ -5,77 +5,81 @@ 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 = true,
});
const InstanceDispatch = vk.InstanceWrapper(&.{
.destroyInstance,
.createDevice,
.destroySurfaceKHR,
.enumeratePhysicalDevices,
.getPhysicalDeviceProperties,
.enumerateDeviceExtensionProperties,
.getPhysicalDeviceSurfaceFormatsKHR,
.getPhysicalDeviceSurfacePresentModesKHR,
.getPhysicalDeviceSurfaceCapabilitiesKHR,
.getPhysicalDeviceQueueFamilyProperties,
.getPhysicalDeviceSurfaceSupportKHR,
.getPhysicalDeviceMemoryProperties,
.getDeviceProcAddr,
comptime {
std.debug.assert(vk.BaseWrapper(vk.BaseCommandFlags{}) == vk.BaseWrapper(.{}));
}
const InstanceDispatch = vk.InstanceWrapper(.{
.destroyInstance = true,
.createDevice = true,
.destroySurfaceKHR = true,
.enumeratePhysicalDevices = true,
.getPhysicalDeviceProperties = true,
.enumerateDeviceExtensionProperties = true,
.getPhysicalDeviceSurfaceFormatsKHR = true,
.getPhysicalDeviceSurfacePresentModesKHR = true,
.getPhysicalDeviceSurfaceCapabilitiesKHR = true,
.getPhysicalDeviceQueueFamilyProperties = true,
.getPhysicalDeviceSurfaceSupportKHR = true,
.getPhysicalDeviceMemoryProperties = true,
.getDeviceProcAddr = true,
});
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 = true,
.getDeviceQueue = true,
.createSemaphore = true,
.createFence = true,
.createImageView = true,
.destroyImageView = true,
.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 {

View File

@@ -1006,31 +1006,51 @@ fn Renderer(comptime WriterType: type) type {
};
try self.writer.print(
\\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 PfnType = cmd.PfnType();
\\ fields[i] = .{{
\\ .name = cmd.symbol(),
\\ .field_type = PfnType,
\\ .default_value = null,
\\ .is_comptime = false,
\\ .alignment = @alignOf(PfnType),
\\ }};
\\ }}
\\ const Dispatch = @Type(.{{
\\ .Struct = .{{
\\ .layout = .Auto,
\\ .fields = &fields,
\\ .decls = &[_]std.builtin.TypeInfo.Declaration{{}},
\\ .is_tuple = false,
\\ }},
\\ }});
\\pub const {0s}CommandFlags = std.enums.EnumFieldStruct({0s}Command, bool, false);
\\pub fn {0s}Wrapper(comptime cmds: {0s}CommandFlags) type {{
\\ return struct {{
\\ dispatch: Dispatch,
\\
\\ const Self = @This();
, .{ name, name });
\\ pub const commands = cmds;
\\ pub const Dispatch = Dispatch: {{
\\ @setEvalBranchQuota(2000);
\\ const TypeInfo = std.builtin.TypeInfo;
\\ const fields_len = fields_len: {{
\\ var fields_len = 0;
\\ for (std.meta.fieldNames({0s}Command)) |field_name| {{
\\ fields_len += @boolToInt(@field(cmds, field_name));
\\ }}
\\ break :fields_len fields_len;
\\ }};
\\ var fields_array: [fields_len]TypeInfo.StructField = undefined;
\\ var fields: []TypeInfo.StructField = fields_array[0..];
\\ fields.len = 0;
\\
\\ for (std.enums.values({0s}Command)) |cmd_tag| {{
\\ if (@field(cmds, @tagName(cmd_tag))) {{
\\ const PfnType = cmd_tag.PfnType();
\\ fields.len += 1;
\\ fields[fields.len - 1] = TypeInfo.StructField{{
\\ .name = cmd_tag.symbol(),
\\ .field_type = PfnType,
\\ .default_value = null,
\\ .is_comptime = false,
\\ .alignment = @alignOf(PfnType),
\\ }};
\\ }}
\\ }}
\\ break :Dispatch @Type(.{{
\\ .Struct = .{{
\\ .layout = .Auto,
\\ .fields = fields,
\\ .decls = &[_]std.builtin.TypeInfo.Declaration{{}},
\\ .is_tuple = false,
\\ }},
\\ }});
\\ }};
\\
, .{ name });
try self.renderWrapperLoader(dispatch_type);