From 5a48cdd936014303a01ff41cec671dbcf9af5123 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Fri, 29 Mar 2024 23:43:15 -0400 Subject: [PATCH] debugging swapchain create with hardcoded values seems to work? --- build.zig | 5 + src/graphics_context.zig | 11 +- src/inspect.zig | 89 +++++++++- src/main.zig | 375 +++++++++++++++++++++------------------ 4 files changed, 291 insertions(+), 189 deletions(-) diff --git a/build.zig b/build.zig index 0317b85..523bea7 100644 --- a/build.zig +++ b/build.zig @@ -97,6 +97,11 @@ pub fn build(b: *std.Build) void { .needed = true, .preferred_link_mode = .dynamic, }); + inspect.linkSystemLibrary2("glfw3", .{ + .needed = true, + .preferred_link_mode = .static, + .use_pkg_config = .force, + }); exe_unit_tests.linkLibC(); inspect.root_module.addImport("vk", vkmod); inspect.linkLibC(); diff --git a/src/graphics_context.zig b/src/graphics_context.zig index 959da98..16f7acc 100644 --- a/src/graphics_context.zig +++ b/src/graphics_context.zig @@ -85,15 +85,6 @@ pub const Queue = struct { } }; -fn createSurface(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; -} - fn initializeCandidate(vki: InstanceDispatch, candidate: DeviceCandidate) !vk.Device { const priority = [_]f32{1}; const qci = [_]vk.DeviceQueueCreateInfo{ @@ -164,6 +155,8 @@ fn checkSuitable( ) !?DeviceCandidate { const props = vki.getPhysicalDeviceProperties(pdev); + if (props.device_type != .discrete_gpu) return null; + if (!try checkExtensionSupport(vki, pdev, allocator)) { return null; } diff --git a/src/inspect.zig b/src/inspect.zig index 7f936d2..9aead49 100644 --- a/src/inspect.zig +++ b/src/inspect.zig @@ -1,6 +1,11 @@ const std = @import("std"); const vk = @import("vk"); +const c = @cImport({ + @cDefine("GLFW_INCLUDE_NONE", {}); + @cInclude("GLFW/glfw3.h"); +}); + const BaseWrapper = vk.BaseWrapper(.{ .getInstanceProcAddr = true, .createInstance = true, @@ -11,17 +16,44 @@ const InstanceWrapper = vk.InstanceWrapper(.{ .enumeratePhysicalDevices = true, .getPhysicalDeviceProperties = true, .getPhysicalDeviceQueueFamilyProperties = true, + .getPhysicalDeviceSurfaceFormatsKHR = true, + .getPhysicalDeviceSurfacePresentModesKHR = true, + .getPhysicalDeviceSurfaceSupportKHR = true, + .getPhysicalDeviceSurfaceCapabilitiesKHR = true, + .destroySurfaceKHR = true, }); +extern fn glfwGetRequiredInstanceExtensions(count: *u32) [*]const [*:0]const u8; + +extern fn glfwCreateWindowSurface( + instance: vk.Instance, + window: *c.GLFWwindow, + allocation_callbacks: ?*const vk.AllocationCallbacks, + surface: *vk.SurfaceKHR, +) vk.Result; + extern fn vkGetInstanceProcAddr(instance: vk.Instance, procname: [*:0]const u8) vk.PfnVoidFunction; extern fn vkGetDeviceProcAddr(device: vk.Device, procname: [*:0]const u8) vk.PfnVoidFunction; pub fn main() !void { + if (c.glfwInit() == c.GLFW_FALSE) return error.glfwInitFailed; + defer c.glfwTerminate(); + + c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API); + c.glfwWindowHintString(c.GLFW_X11_CLASS_NAME, "floating_window"); + c.glfwWindowHintString(c.GLFW_X11_INSTANCE_NAME, "floating_window"); + const window = c.glfwCreateWindow(400, 300, "vkinspect", null, null) orelse + return error.glfwWindowCreateFailed; + defer c.glfwDestroyWindow(window); + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const ally = gpa.allocator(); const vkb = try BaseWrapper.load(vkGetInstanceProcAddr); + var ext_count: u32 = undefined; + const exts = glfwGetRequiredInstanceExtensions(&ext_count); + const instance = try vkb.createInstance(&.{ .p_application_info = &.{ .p_application_name = "vkinspect", @@ -30,12 +62,20 @@ pub fn main() !void { .engine_version = 0, .api_version = vk.API_VERSION_1_3, }, - .enabled_extension_count = 0, + .enabled_extension_count = ext_count, + .pp_enabled_extension_names = exts, .enabled_layer_count = 0, }, null); const vki = try InstanceWrapper.load(instance, vkGetInstanceProcAddr); defer vki.destroyInstance(instance, null); + var surface: vk.SurfaceKHR = undefined; + switch (glfwCreateWindowSurface(instance, window, null, &surface)) { + .success => {}, + else => return error.Unknown, + } + defer vki.destroySurfaceKHR(instance, surface, null); + var pdev_count: u32 = undefined; _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, null); const pdevs = try ally.alloc(vk.PhysicalDevice, pdev_count); @@ -46,7 +86,12 @@ pub fn main() !void { for (pdevs) |pdev| { const props = vki.getPhysicalDeviceProperties(pdev); const name = std.mem.sliceTo(&props.device_name, 0); - std.debug.print("- {s}\n", .{name}); + std.debug.print("=" ** 30 ++ "\n", .{}); + std.debug.print("= {s}\n", .{name}); + std.debug.print("=" ** 30 ++ "\n", .{}); + + std.debug.print("type: {any}\n", .{props.device_type}); + // props.device_type var family_count: u32 = undefined; vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null); @@ -55,9 +100,45 @@ pub fn main() !void { vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, families.ptr); std.debug.print(" {d} queue families:\n", .{family_count}); - for (families) |family| { + for (families, 0..) |family, idx| { + const support = try vki.getPhysicalDeviceSurfaceSupportKHR(pdev, @intCast(idx), surface); std.debug.print(" - {any}\n", .{family.queue_flags}); - std.debug.print(" (max {d})\n", .{family.queue_count}); + std.debug.print(" (max {d}, surface {any})\n", .{ + family.queue_count, + support != 0, + }); } + + var format_count: u32 = undefined; + _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null); + const formats = try ally.alloc(vk.SurfaceFormatKHR, format_count); + defer ally.free(formats); + _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, formats.ptr); + + var mode_count: u32 = undefined; + _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &mode_count, null); + const modes = try ally.alloc(vk.PresentModeKHR, mode_count); + defer ally.free(modes); + _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &mode_count, modes.ptr); + + std.debug.print(" {d} formats\n", .{format_count}); + for (formats) |format| { + std.debug.print(" - {any}\n", .{format}); + } + std.debug.print(" {d} present modes\n", .{mode_count}); + for (modes) |mode| { + std.debug.print(" - {any}\n", .{mode}); + } + + const caps = try vki.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface); + std.debug.print(" surface capabilities:\n", .{}); + std.debug.print(" {any}\n", .{caps.current_extent}); + std.debug.print(" current: {any}\n", .{caps.current_transform}); + std.debug.print(" supported: {any}\n", .{caps.supported_transforms}); + std.debug.print(" {any}\n", .{caps.supported_usage_flags}); + std.debug.print(" {} - {} images\n", .{ caps.min_image_count, caps.max_image_count }); + std.debug.print(" {} - {} extent\n", .{ caps.min_image_extent, caps.max_image_extent }); + std.debug.print(" 1 - {} arrays\n", .{caps.max_image_array_layers}); + std.debug.print(" {}\n", .{caps.supported_composite_alpha}); } } diff --git a/src/main.zig b/src/main.zig index 4e2eda3..7d97f11 100644 --- a/src/main.zig +++ b/src/main.zig @@ -100,40 +100,51 @@ fn create_window(extent: vk.Extent2D, title: [*:0]const u8) !*c.GLFWwindow { ) orelse error.WindowInitFailed; } -const DevicePair = struct { - pdev: vk.PhysicalDevice, - dev: vk.Device, - graphics: vk.Queue, - present: vk.Queue, - present_sharing_mode: vk.SharingMode, -}; +const DevicePair = std.meta.Tuple(&.{ vk.PhysicalDevice, vk.Device, gfx.DeviceDispatch, vk.Queue }); -fn create_device(ally: std.mem.Allocator, instance: vk.Instance, vki: gfx.InstanceDispatch, surface: vk.SurfaceKHR) !DevicePair { - const required_device_extensions = [_][*:0]const u8{ +/// note: destroy with vkd.destroyDevice(dev, null) +fn create_device( + ally: std.mem.Allocator, + instance: vk.Instance, + surface: vk.SurfaceKHR, + vki: gfx.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); + _ = try vki.enumeratePhysicalDevices(instance, &pdev_count, pdevs.ptr); - pdev_search: for (pdevs[0..pdev_count]) |pdev| { - // const props = vki.getPhysicalDeviceProperties(pdev); - // const feats = vki.getPhysicalDeviceFeatures(pdev); + pdev_search: for (pdevs) |pdev| { + const props = vki.getPhysicalDeviceProperties(pdev); + if (props.device_type != .discrete_gpu) continue :pdev_search; - var ext_prop_count: u32 = undefined; - _ = try vki.enumerateDeviceExtensionProperties(pdev, null, &ext_prop_count, null); - const ext_props = try ally.alloc(vk.ExtensionProperties, ext_prop_count); - defer ally.free(ext_props); - _ = try vki.enumerateDeviceExtensionProperties(pdev, null, &ext_prop_count, ext_props); + var format_count: u32 = undefined; + _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null); + if (format_count == 0) continue :pdev_search; - for (required_device_extensions) |required| { - for (ext_props) |prop| { - if (std.mem.eql(u8, std.mem.span(required), std.mem.sliceTo(&prop.extension_name, 0))) { + 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 { @@ -141,80 +152,61 @@ fn create_device(ally: std.mem.Allocator, instance: vk.Instance, vki: gfx.Instan } } - var format_count: u32 = undefined; - _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null); - if (format_count == 0) 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); - var present_mode_count: u32 = undefined; - _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &present_mode_count, null); - if (present_mode_count == 0) continue :pdev_search; + // 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. - var fam_prop_count: u32 = undefined; - vki.getPhysicalDeviceQueueFamilyProperties(pdev, &fam_prop_count, null); - const fam_props = try ally.alloc(vk.QueueFamilyProperties, fam_prop_count); - defer ally.free(fam_props); - vki.getPhysicalDeviceQueueFamilyProperties(pdev, &fam_prop_count, fam_props); - - var graphics_families = std.ArrayList(u32).init(ally); - var present_families = std.ArrayList(u32).init(ally); - - for (fam_props, 0..) |fam, idx| { - if (fam.queue_flags.graphics_bit) { - graphics_families.append(idx); + 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); } - if (try vki.getPhysicalDeviceSurfaceSupportKHR(pdev, idx, surface)) { - present_families.append(idx); - } - } + } else { + continue :pdev_search; + }; - // only choose the same family if we really have to. + std.log.debug("selecting device {s}", .{std.mem.sliceTo(&props.device_name, 0)}); - // at this point, we know this pdev can support _a_ swap chain and has required extensions. try to make a - // logical device and queues out of it. + 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, + }, null); + const vkd = try gfx.DeviceDispatch.load(dev, vki.dispatch.vkGetDeviceProcAddr); + errdefer vkd.destroyDevice(dev, null); + + const queue = vkd.getDeviceQueue(dev, graphics_family, 0); + + return .{ pdev, dev, vkd, queue }; } return error.NoSuitableDevice; } -pub fn includes(comptime T: type, us: []const T, vs: []const T) bool { - var vidx: usize = 0; - var uidx: usize = 0; - while (uidx < us.len) { - while (vidx < vs.len) : (vidx += 1) { - if (us[uidx] == vs[vidx]) break; - vidx += 1; - } else { - return false; - } - uidx += 1; - vidx += 1; - } - return true; -} - -test "includes" { - const u = &.{ 0, 1, 7 }; - const v = &.{11}; - const w = &.{}; - const x = &.{ 0, 1, 3, 5, 7, 9, 11 }; - const y = &.{2}; - const z = &.{ 0, 1, 3, 5, 7, 9, 11, 12 }; - - const full = &.{ 0, 1, 3, 5, 7, 9, 11 }; - - try std.testing.expectEqual(true, includes(usize, u, full)); - try std.testing.expectEqual(true, includes(usize, v, full)); - try std.testing.expectEqual(true, includes(usize, w, full)); - try std.testing.expectEqual(true, includes(usize, x, full)); - try std.testing.expectEqual(false, includes(usize, y, full)); - try std.testing.expectEqual(false, includes(usize, z, full)); -} - pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); - const allocator = gpa.allocator(); + const ally = gpa.allocator(); if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed; defer c.glfwTerminate(); @@ -237,108 +229,139 @@ pub fn main() !void { const surface = try create_surface(instance, window); defer vki.destroySurfaceKHR(instance, surface, null); - const gc = try GraphicsContext.init(allocator, instance, surface, vki); - defer gc.deinit(); + const pdev: vk.PhysicalDevice, const dev: vk.Device, const vkd: gfx.DeviceDispatch, const queue: vk.Queue = + try create_device(ally, instance, surface, vki); + defer vkd.destroyDevice(dev, null); - std.log.debug("Using device: {s}", .{gc.deviceName()}); + var swapchain: vk.SwapchainKHR = .null_handle; + defer vkd.destroySwapchainKHR(dev, swapchain, null); - var swapchain = try Swapchain.init(&gc, allocator, extent); - defer swapchain.deinit(); - - const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{ - .flags = .{}, - .set_layout_count = 0, - .p_set_layouts = undefined, - .push_constant_range_count = 0, - .p_push_constant_ranges = undefined, + swapchain = try vkd.createSwapchainKHR(dev, &.{ + .surface = surface, + .min_image_count = 3, // todo compute + .image_format = .r8g8b8a8_sint, // todo compute + // .image_format = .r8g8b8a8_sint, // todo compute + .image_color_space = .srgb_nonlinear_khr, // todo compute + .image_extent = extent, // todo compute + .image_array_layers = 1, + .image_usage = .{ .color_attachment_bit = true, .transfer_dst_bit = true }, + .image_sharing_mode = .exclusive, // since we only choose one queue family + .pre_transform = .{ .identity_bit_khr = true }, // todo compute + .composite_alpha = .{ .opaque_bit_khr = true }, + .present_mode = .mailbox_khr, // todo compute + .clipped = vk.TRUE, + .old_swapchain = swapchain, }, null); - defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null); - const pipeline = try createPipeline(&gc, pipeline_layout, swapchain); - defer gc.vkd.destroyPipeline(gc.dev, pipeline, null); + _ = try vkd.queuePresentKHR(queue, &.{ + .wait_semaphore_count = 0, + .swapchain_count = 1, + .p_swapchains = &[_]vk.SwapchainKHR{swapchain}, + .p_image_indices = &[_]u32{0}, + }); - const pool = try gc.vkd.createCommandPool(gc.dev, &.{ - .queue_family_index = gc.graphics_queue.family, - }, null); - defer gc.vkd.destroyCommandPool(gc.dev, pool, null); + try vkd.deviceWaitIdle(dev); - const vertex_buffer = try gc.vkd.createBuffer(gc.dev, &.{ - .size = @sizeOf(@TypeOf(vertices)), - .usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true }, - .sharing_mode = .exclusive, - }, null); - defer gc.vkd.destroyBuffer(gc.dev, vertex_buffer, null); - const vertex_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, vertex_buffer); - const vertex_memory = try gc.allocate(vertex_mem_reqs, .{ .device_local_bit = true }); - defer gc.vkd.freeMemory(gc.dev, vertex_memory, null); - try gc.vkd.bindBufferMemory(gc.dev, vertex_buffer, vertex_memory, 0); + _ = pdev; + extent = undefined; - try uploadData(Vertex, &gc, pool, vertex_buffer, &vertices); + // var swapchain = try Swapchain.init(&gc, ally, extent); + // defer swapchain.deinit(); - const index_buffer = try gc.vkd.createBuffer(gc.dev, &.{ - .size = @sizeOf(@TypeOf(indices)), - .usage = .{ .transfer_dst_bit = true, .index_buffer_bit = true }, - .sharing_mode = .exclusive, - }, null); - defer gc.vkd.destroyBuffer(gc.dev, index_buffer, null); - const index_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, index_buffer); - const index_memory = try gc.allocate(index_mem_reqs, .{ .device_local_bit = true }); - defer gc.vkd.freeMemory(gc.dev, index_memory, null); - try gc.vkd.bindBufferMemory(gc.dev, index_buffer, index_memory, 0); - - try uploadData(Index, &gc, pool, index_buffer, &indices); - - var cmdbufs = try createCommandBuffers( - &gc, - pool, - allocator, - vertex_buffer, - index_buffer, - pipeline, - swapchain, - ); - defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs); - - while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) { - var w: c_int = undefined; - var h: c_int = undefined; - c.glfwGetFramebufferSize(window, &w, &h); - - // Don't present or resize swapchain while the window is minimized - if (w == 0 or h == 0) { - c.glfwPollEvents(); - continue; - } - - const cmdbuf = cmdbufs[swapchain.image_index]; - - const state = swapchain.present(cmdbuf) catch |err| switch (err) { - error.OutOfDateKHR => Swapchain.PresentState.suboptimal, - else => |narrow| return narrow, - }; - - if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) { - extent.width = @intCast(w); - extent.height = @intCast(h); - try swapchain.recreate(extent); - - destroyCommandBuffers(&gc, pool, allocator, cmdbufs); - cmdbufs = try createCommandBuffers( - &gc, - pool, - allocator, - vertex_buffer, - index_buffer, - pipeline, - swapchain, - ); - } - - c.glfwPollEvents(); - } - - try swapchain.waitForAllFences(); - try gc.vkd.deviceWaitIdle(gc.dev); + // const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{ + // .flags = .{}, + // .set_layout_count = 0, + // .p_set_layouts = undefined, + // .push_constant_range_count = 0, + // .p_push_constant_ranges = undefined, + // }, null); + // defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null); + // + // const pipeline = try createPipeline(&gc, pipeline_layout, swapchain); + // defer gc.vkd.destroyPipeline(gc.dev, pipeline, null); + // + // const pool = try gc.vkd.createCommandPool(gc.dev, &.{ + // .queue_family_index = gc.graphics_queue.family, + // }, null); + // defer gc.vkd.destroyCommandPool(gc.dev, pool, null); + // + // const vertex_buffer = try gc.vkd.createBuffer(gc.dev, &.{ + // .size = @sizeOf(@TypeOf(vertices)), + // .usage = .{ .transfer_dst_bit = true, .vertex_buffer_bit = true }, + // .sharing_mode = .exclusive, + // }, null); + // defer gc.vkd.destroyBuffer(gc.dev, vertex_buffer, null); + // const vertex_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, vertex_buffer); + // const vertex_memory = try gc.allocate(vertex_mem_reqs, .{ .device_local_bit = true }); + // defer gc.vkd.freeMemory(gc.dev, vertex_memory, null); + // try gc.vkd.bindBufferMemory(gc.dev, vertex_buffer, vertex_memory, 0); + // + // try uploadData(Vertex, &gc, pool, vertex_buffer, &vertices); + // + // const index_buffer = try gc.vkd.createBuffer(gc.dev, &.{ + // .size = @sizeOf(@TypeOf(indices)), + // .usage = .{ .transfer_dst_bit = true, .index_buffer_bit = true }, + // .sharing_mode = .exclusive, + // }, null); + // defer gc.vkd.destroyBuffer(gc.dev, index_buffer, null); + // const index_mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, index_buffer); + // const index_memory = try gc.allocate(index_mem_reqs, .{ .device_local_bit = true }); + // defer gc.vkd.freeMemory(gc.dev, index_memory, null); + // try gc.vkd.bindBufferMemory(gc.dev, index_buffer, index_memory, 0); + // + // try uploadData(Index, &gc, pool, index_buffer, &indices); + // + // var cmdbufs = try createCommandBuffers( + // &gc, + // pool, + // ally, + // vertex_buffer, + // index_buffer, + // pipeline, + // swapchain, + // ); + // defer destroyCommandBuffers(&gc, pool, ally, cmdbufs); + // + // while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) { + // var w: c_int = undefined; + // var h: c_int = undefined; + // c.glfwGetFramebufferSize(window, &w, &h); + // + // // Don't present or resize swapchain while the window is minimized + // if (w == 0 or h == 0) { + // c.glfwPollEvents(); + // continue; + // } + // + // const cmdbuf = cmdbufs[swapchain.image_index]; + // + // const state = swapchain.present(cmdbuf) catch |err| switch (err) { + // error.OutOfDateKHR => Swapchain.PresentState.suboptimal, + // else => |narrow| return narrow, + // }; + // + // if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) { + // extent.width = @intCast(w); + // extent.height = @intCast(h); + // try swapchain.recreate(extent); + // + // destroyCommandBuffers(&gc, pool, ally, cmdbufs); + // cmdbufs = try createCommandBuffers( + // &gc, + // pool, + // ally, + // vertex_buffer, + // index_buffer, + // pipeline, + // swapchain, + // ); + // } + // + // c.glfwPollEvents(); + // } + // + // try swapchain.waitForAllFences(); + // try gc.vkd.deviceWaitIdle(gc.dev); } fn uploadData(comptime T: type, gc: *const GraphicsContext, pool: vk.CommandPool, buffer: vk.Buffer, source: []const T) !void {