diff --git a/src/gfx.zig b/src/gfx.zig index 4770709..208312e 100644 --- a/src/gfx.zig +++ b/src/gfx.zig @@ -4,275 +4,12 @@ const builtin = @import("builtin"); const vk = @import("vk"); const c = @import("c.zig"); -const Base = @import("gfx/Base.zig"); -const Instance = @import("gfx/Instance.zig"); -const Device = @import("gfx/Device.zig"); - -// const InstancePair = std.meta.Tuple(&.{ vk.Instance, InstanceDispatch, vk.DebugUtilsMessengerEXT }); - -// /// note: destroy with vki.destroyInstance(instance, null) -// pub fn create_instance(vkb: BaseDispatch, app_name: [*:0]const u8) !InstancePair { -// var exts = std.BoundedArray([*:0]const u8, 32){}; -// var layers = std.BoundedArray([*:0]const u8, 32){}; -// -// if (use_debug_messenger) { -// try exts.appendSlice(&.{ -// vk.extension_info.ext_debug_utils.name, -// }); -// -// try layers.appendSlice(&.{ -// "VK_LAYER_KHRONOS_validation", -// }); -// } -// -// var glfw_exts_count: u32 = 0; -// const glfw_exts: [*]const [*:0]const u8 = -// @ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_exts_count)); -// try exts.appendSlice(glfw_exts[0..glfw_exts_count]); -// -// const dumci: vk.DebugUtilsMessengerCreateInfoEXT = .{ -// .message_severity = .{ -// .error_bit_ext = true, -// .info_bit_ext = true, -// .verbose_bit_ext = true, -// .warning_bit_ext = true, -// }, -// .message_type = .{ -// .device_address_binding_bit_ext = true, -// .general_bit_ext = false, -// .performance_bit_ext = true, -// .validation_bit_ext = true, -// }, -// .pfn_user_callback = &debug_callback, -// .p_user_data = null, -// }; -// -// const instance = try vkb.createInstance(&vk.InstanceCreateInfo{ -// .p_application_info = &vk.ApplicationInfo{ -// .p_application_name = app_name, -// .application_version = vk.makeApiVersion(0, 0, 0, 0), -// .p_engine_name = app_name, -// .engine_version = vk.makeApiVersion(0, 0, 0, 0), -// .api_version = vk.API_VERSION_1_3, -// }, -// .enabled_extension_count = @intCast(exts.len), -// .pp_enabled_extension_names = &exts.buffer, -// .enabled_layer_count = @intCast(layers.len), -// .pp_enabled_layer_names = &layers.buffer, -// .p_next = if (use_debug_messenger) &dumci else null, -// }, null); -// -// const vki = try InstanceDispatch.load(instance, vkb.dispatch.vkGetInstanceProcAddr); -// errdefer vki.destroyInstance(instance, null); -// -// const messenger: vk.DebugUtilsMessengerEXT = if (use_debug_messenger) -// try vki.createDebugUtilsMessengerEXT(instance, &dumci, null) -// else -// .null_handle; -// errdefer if (use_debug_messenger) -// vki.destroyDebugUtilsMessengerEXT(instance, messenger, null); -// -// return .{ instance, vki, messenger }; -// } - -// /// note: destroy with vki.destroySurfaceKHR(instance, surface, null) -// pub fn create_surface(instance: vk.Instance, window: *c.GLFWwindow) !vk.SurfaceKHR { -// var surface: vk.SurfaceKHR = undefined; -// if (c.glfwCreateWindowSurface(instance, window, null, &surface) != .success) { -// return error.SurfaceInitFailed; -// } -// return surface; -// } - -// /// note: destroy with c.glfwDestroyWindow(window) -// pub fn create_window(extent: vk.Extent2D, title: [*:0]const u8) !*c.GLFWwindow { - // c.glfwWindowHintString(c.GLFW_X11_CLASS_NAME, "floating_window"); - // c.glfwWindowHintString(c.GLFW_X11_INSTANCE_NAME, "floating_window"); - // c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API); -// -// return c.glfwCreateWindow( -// @intCast(extent.width), -// @intCast(extent.height), -// title, -// null, -// null, -// ) orelse error.WindowInitFailed; -// } - -// const DevicePair = std.meta.Tuple(&.{ vk.PhysicalDevice, vk.Device, Device.Wrapper, u32 }); -// -// /// note: destroy with vkd.destroyDevice(dev, null) -// pub fn cr eate_device( -// ally: std.mem.Allocator, -// instance: vk.Instance, -// surface: vk.SurfaceKHR, -// vki: InstanceDispatch, -// ) !DevicePair { -// const required_device_extensions: []const [*:0]const u8 = &.{ -// vk.extension_info.khr_swapchain.name, -// vk.extension_info.khr_dynamic_rendering.name, -// }; -// -// var pdev_count: u32 = undefined; -// _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, null); -// const pdevs = try ally.alloc(vk.PhysicalDevice, pdev_count); -// defer ally.free(pdevs); -// _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, pdevs.ptr); -// -// pdev_search: for (pdevs) |pdev| { -// const props = vki.getPhysicalDeviceProperties(pdev); -// if (props.device_type != .discrete_gpu) continue :pdev_search; -// -// var format_count: u32 = undefined; -// _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null); -// if (format_count == 0) continue :pdev_search; -// -// var mode_count: u32 = undefined; -// _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &mode_count, null); -// if (mode_count == 0) continue :pdev_search; -// -// var ext_count: u32 = undefined; -// _ = try vki.enumerateDeviceExtensionProperties(pdev, null, &ext_count, null); -// const exts = try ally.alloc(vk.ExtensionProperties, ext_count); -// defer ally.free(exts); -// _ = try vki.enumerateDeviceExtensionProperties(pdev, null, &ext_count, exts.ptr); -// -// for (required_device_extensions) |name| { -// for (exts) |ext| { -// if (std.mem.eql( -// u8, -// std.mem.span(name), -// std.mem.sliceTo(&ext.extension_name, 0), -// )) { -// break; -// } -// } else { -// continue :pdev_search; -// } -// } -// -// var family_count: u32 = undefined; -// vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null); -// const families = try ally.alloc(vk.QueueFamilyProperties, family_count); -// defer ally.free(families); -// vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr); -// -// // just find one family that does graphics and present, so we can use exclusive sharing -// // on the swapchain. apparently most hardware supports this. logic for queue allocation -// // and swapchain creation is so much simpler this way. swapchain creation needs to know -// // the list of queue family indices which will have access to the images, and there's a -// // performance penalty to allow concurrent access to multiple queue families. -// // -// // multiple _queues_ may have exclusive access, but only if they're in the smae family. -// -// const graphics_family: u32 = for (families, 0..) |family, idx| { -// const graphics = family.queue_flags.graphics_bit; -// const present = try vki.getPhysicalDeviceSurfaceSupportKHR(pdev, @intCast(idx), surface) == vk.TRUE; -// if (graphics and present) { -// break @intCast(idx); -// } -// } else { -// continue :pdev_search; -// }; -// -// std.log.debug("selecting device {s}", .{std.mem.sliceTo(&props.device_name, 0)}); -// -// const qci: []const vk.DeviceQueueCreateInfo = &.{ -// vk.DeviceQueueCreateInfo{ -// .queue_family_index = graphics_family, -// .queue_count = 1, -// .p_queue_priorities = &[_]f32{1.0}, -// }, -// }; -// -// const dev = try vki.createDevice(pdev, &.{ -// .queue_create_info_count = @intCast(qci.len), -// .p_queue_create_infos = qci.ptr, -// .enabled_extension_count = @intCast(required_device_extensions.len), -// .pp_enabled_extension_names = required_device_extensions.ptr, -// .p_next = &vk.PhysicalDeviceDynamicRenderingFeaturesKHR{ -// .dynamic_rendering = vk.TRUE, -// }, -// }, null); -// const vkd = try Device.Wrapper.load(dev, vki.dispatch.vkGetDeviceProcAddr); -// errdefer vkd.destroyDevice(dev, null); -// -// return .{ pdev, dev, vkd, graphics_family }; -// } -// -// return error.NoSuitableDevice; -// } -// -// pub fn find_surface_format( -// pdev: vk.PhysicalDevice, -// vki: InstanceDispatch, -// surface: vk.SurfaceKHR, -// preferred: vk.SurfaceFormatKHR, -// ) !vk.SurfaceFormatKHR { -// var formats_buf: [64]vk.SurfaceFormatKHR = undefined; -// var formats_count: u32 = @intCast(formats_buf.len); -// _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats_buf); -// const formats = formats_buf[0..formats_count]; -// -// for (formats) |format| { -// if (std.meta.eql(format, preferred)) { -// return format; -// } -// } -// -// return formats[0]; -// } -// -// pub fn find_present_mode( -// pdev: vk.PhysicalDevice, -// vki: InstanceDispatch, -// surface: vk.SurfaceKHR, -// preferred: vk.PresentModeKHR, -// ) !vk.PresentModeKHR { -// var modes_buf: [8]vk.PresentModeKHR = undefined; -// var modes_count: u32 = @intCast(modes_buf.len); -// _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &modes_count, &modes_buf); -// const modes = modes_buf[0..modes_count]; -// -// for (modes) |mode| { -// if (std.meta.eql(mode, preferred)) { -// return mode; -// } -// } -// -// return .mailbox_khr; -// } -// -// pub fn find_swap_extent( -// pdev: vk.PhysicalDevice, -// vki: InstanceDispatch, -// surface: vk.SurfaceKHR, -// window: *c.GLFWwindow, -// ) !vk.Extent2D { -// const caps = try vki.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface); -// var extent = caps.current_extent; -// -// if (extent.width == std.math.maxInt(u32)) { -// c.glfwGetFramebufferSize(window, @ptrCast(&extent.width), @ptrCast(&extent.height)); -// extent.width = std.math.clamp(extent.width, caps.min_image_extent.width, caps.max_image_extent.width); -// extent.height = std.math.clamp(extent.height, caps.min_image_extent.height, caps.max_image_extent.height); -// } -// -// return extent; -// } -// -// pub fn find_swap_image_count( -// pdev: vk.PhysicalDevice, -// vki: InstanceDispatch, -// surface: vk.SurfaceKHR, -// ) !u32 { -// const caps = try vki.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface); -// var count = @max(3, caps.min_image_count + 1); -// if (caps.max_image_count > 0) { -// count = @min(count, caps.max_image_count); -// } -// return count; -// } +pub const Base = @import("gfx/Base.zig"); +pub const Context = @import("gfx/Context.zig"); +pub const Device = @import("gfx/Device.zig"); +pub const Instance = @import("gfx/Instance.zig"); +pub const Swapchain = @import("gfx/Swapchain.zig"); +pub const Window = @import("gfx/Window.zig"); pub fn uploadData( comptime T: type, @@ -402,127 +139,3 @@ pub const VkAllocator = struct { return error.NoSuitableMemoryType; } }; - -// pub const BaseDispatch = vk.BaseWrapper(.{ -// .createInstance = true, -// .getInstanceProcAddr = true, -// }); - -// pub const Instance.Wrapper = 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, -// .createDebugUtilsMessengerEXT = use_debug_messenger, -// .destroyDebugUtilsMessengerEXT = use_debug_messenger, -// }); - -// pub const Device.Wrapper = 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, -// .createGraphicsPipelines = true, -// .destroyPipeline = 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, -// .cmdDrawIndexed = true, -// .cmdSetViewport = true, -// .cmdSetScissor = true, -// .cmdBindVertexBuffers = true, -// .cmdBindIndexBuffer = true, -// .cmdCopyBuffer = true, -// .cmdBeginRenderingKHR = true, -// .cmdEndRenderingKHR = true, -// .cmdPipelineBarrier = true, -// }); - -pub fn debug_callback( - msg_severity: vk.DebugUtilsMessageSeverityFlagsEXT, - msg_type: vk.DebugUtilsMessageTypeFlagsEXT, - p_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT, - _: ?*anyopaque, -) callconv(vk.vulkan_call_conv) vk.Bool32 { - // ripped from std.log.defaultLog - - const data = p_data orelse return vk.FALSE; - const message = data.p_message orelse return vk.FALSE; - - const severity_prefix = if (msg_severity.verbose_bit_ext) - "verbose:" - else if (msg_severity.info_bit_ext) - "info:" - else if (msg_severity.warning_bit_ext) - "warning:" - else if (msg_severity.error_bit_ext) - "error:" - else - "?:"; - - const type_prefix = if (msg_type.general_bit_ext) - "" - else if (msg_type.validation_bit_ext) - "validation:" - else if (msg_type.performance_bit_ext) - "performance:" - else if (msg_type.device_address_binding_bit_ext) - "device_address_binding:" - else - "?:"; - - const stderr = std.io.getStdErr().writer(); - var bw = std.io.bufferedWriter(stderr); - const writer = bw.writer(); - - std.debug.getStderrMutex().lock(); - defer std.debug.getStderrMutex().unlock(); - nosuspend { - writer.print("vk-{s}{s} {s}\n", .{ severity_prefix, type_prefix, message }) catch return vk.FALSE; - bw.flush() catch return vk.FALSE; - } - - return vk.FALSE; -} diff --git a/src/main.zig b/src/main.zig index 806ca08..25489c6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -50,104 +50,13 @@ const vertices = [_]Vertex{ const indices = [_]Index{ 4, 5, 6, 6, 5, 7 }; -// pub fn create_swapchain( -// chain: *std.MultiArrayList(ChainImage), -// swapchain: *vk.SwapchainKHR, -// ally: std.mem.Allocator, -// pdev: vk.PhysicalDevice, -// vki: gfx.InstanceDispatch, -// window: *c.GLFWwindow, -// dev: vk.Device, -// vkd: Device.Wrapper, -// pool: vk.CommandPool, -// surface: vk.SurfaceKHR, -// swap_image_count: u32, -// format: vk.SurfaceFormatKHR, -// present_mode: vk.PresentModeKHR, -// ) !vk.Extent2D { -// const extent = try gfx.find_swap_extent(pdev, vki, surface, window); -// -// const prev_swapchain = swapchain.*; -// swapchain.* = try vkd.createSwapchainKHR(dev, &.{ -// .surface = surface, -// .min_image_count = swap_image_count, -// .image_format = format.format, -// .image_color_space = format.color_space, -// .image_extent = extent, -// .image_array_layers = 1, -// .image_usage = .{ .color_attachment_bit = true }, -// .image_sharing_mode = .exclusive, -// .pre_transform = .{ .identity_bit_khr = true }, -// .composite_alpha = .{ .opaque_bit_khr = true }, -// .present_mode = present_mode, -// .clipped = vk.TRUE, -// .old_swapchain = prev_swapchain, -// }, null); -// vkd.destroySwapchainKHR(dev, prev_swapchain, null); -// -// var image_count: u32 = undefined; -// _ = try vkd.getSwapchainImagesKHR(dev, swapchain.*, &image_count, null); -// try chain.resize(ally, image_count); -// _ = try vkd.getSwapchainImagesKHR(dev, swapchain.*, &image_count, chain.items(.image).ptr); -// -// // memset so that deinit_chain will succeed with .null_handle if error part-way through a loop. -// @memset(chain.items(.view), .null_handle); -// @memset(chain.items(.cmdbuf), .null_handle); -// @memset(chain.items(.fence), .null_handle); -// @memset(chain.items(.image_available), .null_handle); -// errdefer deinit_chain(chain.*, dev, vkd, pool); -// -// for (chain.items(.image), chain.items(.view)) |image, *view| { -// view.* = try vkd.createImageView(dev, &.{ -// .image = image, -// .view_type = .@"2d", -// .format = format.format, -// .components = .{ .r = .identity, .g = .identity, .b = .identity, .a = .identity }, -// .subresource_range = .{ -// .aspect_mask = .{ .color_bit = true }, -// .base_mip_level = 0, -// .level_count = 1, -// .base_array_layer = 0, -// .layer_count = 1, -// }, -// }, null); -// } -// -// for (chain.items(.fence)) |*fence| { -// fence.* = try vkd.createFence(dev, &.{ .flags = .{ .signaled_bit = true } }, null); -// } -// -// for (chain.items(.image_available)) |*sem| { -// sem.* = try vkd.createSemaphore(dev, &.{}, null); -// } -// -// for (chain.items(.render_finished)) |*sem| { -// sem.* = try vkd.createSemaphore(dev, &.{}, null); -// } -// -// try vkd.allocateCommandBuffers(dev, &.{ -// .command_buffer_count = @intCast(chain.len), -// .command_pool = pool, -// .level = .primary, -// }, chain.items(.cmdbuf).ptr); -// -// return extent; -// } -// -// pub fn deinit_chain( -// chain: std.MultiArrayList(ChainImage), -// dev: vk.Device, -// vkd: Device.Wrapper, -// pool: vk.CommandPool, -// ) void { -// vkd.freeCommandBuffers(dev, pool, @intCast(chain.len), chain.items(.cmdbuf).ptr); -// for (chain.items(.view)) |view| vkd.destroyImageView(dev, view, null); -// for (chain.items(.fence)) |fence| vkd.destroyFence(dev, fence, null); -// for (chain.items(.image_available)) |sem| vkd.destroySemaphore(dev, sem, null); -// for (chain.items(.render_finished)) |sem| vkd.destroySemaphore(dev, sem, null); -// } - -fn render(dev: vk.Device, vkd: Device.Wrapper, swapchain: vk.SwapchainKHR, frame: Swapchain.ChainImage, queue: vk.Queue) !void { +fn render( + dev: vk.Device, + vkd: gfx.Device.Wrapper, + swapchain: vk.SwapchainKHR, + frame: gfx.Swapchain.ChainImage, + queue: vk.Queue, +) !void { _ = try vkd.waitForFences(dev, 1, @ptrCast(&frame.fence), vk.TRUE, std.math.maxInt(u64)); const result = try vkd.acquireNextImageKHR( @@ -180,31 +89,24 @@ fn render(dev: vk.Device, vkd: Device.Wrapper, swapchain: vk.SwapchainKHR, frame }); } -const Base = @import("gfx/Base.zig"); -const Instance = @import("gfx/Instance.zig"); -const Context = @import("gfx/Context.zig"); -const Window = @import("gfx/Window.zig"); -const Device = @import("gfx/Device.zig"); -const Swapchain = @import("gfx/Swapchain.zig"); - pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const ally = gpa.allocator(); - const base = try Base.init(); + const base = try gfx.Base.init(); defer base.deinit(); - const inst = try Instance.init(&base); + const inst = try gfx.Instance.init(&base); defer inst.deinit(); - const win = try Window.init(&inst, "zig-glfw-vulkan", .{ .width = 800, .height = 600 }); + const win = try gfx.Window.init(&inst, "zig-glfw-vulkan", .{ .width = 800, .height = 600 }); defer win.deinit(); - const dev = try Device.init(ally, &inst, &win); + const dev = try gfx.Device.init(ally, &inst, &win); defer dev.deinit(); - var sc = try Swapchain.create(ally, &dev); + var sc = try gfx.Swapchain.create(ally, &dev); defer sc.deinit(); const device_local = gfx.VkAllocator.init(dev.pdev, inst.vki); @@ -228,7 +130,6 @@ pub fn main() !void { }, null); defer dev.vkd.destroyBuffer(dev.dev, vertex_buffer, null); const vertex_mem_reqs = dev.vkd.getBufferMemoryRequirements(dev.dev, vertex_buffer); - // const vertex_memory = try gfx.allocate(pdev, vki, dev, dev.vkd, vertex_mem_reqs, .{ .device_local_bit = true }); const vertex_memory = try device_local.alloc(dev.dev, dev.vkd, vertex_mem_reqs, .{ .device_local_bit = true }); defer dev.vkd.freeMemory(dev.dev, vertex_memory, null); try dev.vkd.bindBufferMemory(dev.dev, vertex_buffer, vertex_memory, 0); @@ -242,7 +143,6 @@ pub fn main() !void { }, null); defer dev.vkd.destroyBuffer(dev.dev, index_buffer, null); const index_mem_reqs = dev.vkd.getBufferMemoryRequirements(dev.dev, index_buffer); - // const index_memory = try gfx.allocate(pdev, vki, dev, dev.vkd, index_mem_reqs, .{ .device_local_bit = true }); const index_memory = try device_local.alloc(dev.dev, dev.vkd, index_mem_reqs, .{ .device_local_bit = true }); defer dev.vkd.freeMemory(dev.dev, index_memory, null); try dev.vkd.bindBufferMemory(dev.dev, index_buffer, index_memory, 0); @@ -295,7 +195,7 @@ pub fn main() !void { fn record_cmdbuf( cmdbuf: vk.CommandBuffer, - vkd: Device.Wrapper, + vkd: gfx.Device.Wrapper, image: vk.Image, view: vk.ImageView, extent: vk.Extent2D, @@ -416,7 +316,12 @@ fn record_cmdbuf( try vkd.endCommandBuffer(cmdbuf); } -fn createPipeline(dev: vk.Device, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR, vkd: Device.Wrapper) !vk.Pipeline { +fn createPipeline( + dev: vk.Device, + layout: vk.PipelineLayout, + format: vk.SurfaceFormatKHR, + vkd: gfx.Device.Wrapper, +) !vk.Pipeline { const vert = try vkd.createShaderModule(dev, &.{ .code_size = shaders.triangle_vert.len, .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),