diff --git a/src/gfx.zig b/src/gfx.zig index e3b51c9..2574e64 100644 --- a/src/gfx.zig +++ b/src/gfx.zig @@ -4,29 +4,6 @@ const builtin = @import("builtin"); const vk = @import("vk"); const c = @import("c.zig"); -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 const use_debug_messenger = switch (builtin.mode) { - .Debug, .ReleaseSafe => true, - .ReleaseSmall, .ReleaseFast => false, -}; - -pub const apis: []const vk.ApiInfo = &.{ - vk.features.version_1_0, - vk.features.version_1_1, - vk.features.version_1_2, - vk.features.version_1_3, - vk.extensions.khr_surface, - vk.extensions.khr_swapchain, - vk.extensions.khr_dynamic_rendering, - if (use_debug_messenger) vk.extensions.ext_debug_utils else .{}, -}; - pub fn uploadData( comptime T: type, pdev: vk.PhysicalDevice, diff --git a/src/gfx/Swapchain.zig b/src/gfx/Swapchain.zig deleted file mode 100644 index 64ea09f..0000000 --- a/src/gfx/Swapchain.zig +++ /dev/null @@ -1,169 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); - -const vk = @import("vk"); -const c = @import("../c.zig"); - -const Instance = @import("Instance.zig"); -const Window = @import("Window.zig"); -const Device = @import("Device.zig"); - -const Self = @This(); - -pub const ChainImage = struct { - image: vk.Image = .null_handle, - view: vk.ImageView = .null_handle, - cmdbuf: vk.CommandBuffer = .null_handle, - fence: vk.Fence = .null_handle, - image_available: vk.Semaphore = .null_handle, - render_finished: vk.Semaphore = .null_handle, -}; - -ally: std.mem.Allocator, - -ref: vk.SwapchainKHR, -dev: *const Device, - -extent: vk.Extent2D, -min_image_count: u32, -chain: std.MultiArrayList(ChainImage), - -pub fn create(ally: std.mem.Allocator, dev: *const Device) !Self { - const caps = try dev.inst.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(dev.pdev, dev.win.surface); - var min_image_count = @max(3, caps.min_image_count + 1); - if (caps.max_image_count > 0) { - min_image_count = @min(min_image_count, caps.max_image_count); - } - - return .{ - .ally = ally, - .ref = .null_handle, - .dev = dev, - .extent = undefined, - .min_image_count = min_image_count, - .chain = .{}, - }; -} - -pub fn init(self: *Self) !void { - const caps = try self.dev.inst.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(self.dev.pdev, self.dev.win.surface); - - self.extent = caps.current_extent; - if (caps.current_extent.width == std.math.maxInt(u32)) { - c.glfwGetFramebufferSize(self.dev.win.ref, @ptrCast(&self.extent.width), @ptrCast(&self.extent.height)); - } - self.extent.width = std.math.clamp(self.extent.width, caps.min_image_extent.width, caps.max_image_extent.width); - self.extent.height = std.math.clamp(self.extent.height, caps.min_image_extent.height, caps.max_image_extent.height); - - const prev = self.ref; - self.ref = try self.dev.vkd.createSwapchainKHR(self.dev.dev, &.{ - .surface = self.dev.win.surface, - .min_image_count = self.min_image_count, - .image_format = self.dev.format.format, - .image_color_space = self.dev.format.color_space, - .image_extent = self.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 = self.dev.mode, - .clipped = vk.TRUE, - .old_swapchain = prev, - }, null); - self.dev.vkd.destroySwapchainKHR(self.dev.dev, prev, null); - - var image_count: u32 = undefined; - _ = try self.dev.vkd.getSwapchainImagesKHR(self.dev.dev, self.ref, &image_count, null); - - // todo try to reuse contents if possible. - // not even sure at this point which parts can be safely reused. the trick to fix the tearing while resizing - // on laptop is probably in doing this correctly, to present any remaining images that can be presented. - - self.deinit_chain(); - - try self.chain.resize(self.ally, image_count); - _ = try self.dev.vkd.getSwapchainImagesKHR( - self.dev.dev, - self.ref, - &image_count, - self.chain.items(.image).ptr, - ); - - try self.init_chain(); -} - -// requires self.chain.len and self.chain.items(.image) be populated by getSwapchainImagesKHR -fn init_chain(self: *Self) !void { - @memset(self.chain.items(.view), .null_handle); - @memset(self.chain.items(.cmdbuf), .null_handle); - @memset(self.chain.items(.fence), .null_handle); - @memset(self.chain.items(.image_available), .null_handle); - @memset(self.chain.items(.render_finished), .null_handle); - errdefer self.deinit_chain(); - - for (self.chain.items(.image), self.chain.items(.view)) |image, *view| { - view.* = try self.dev.vkd.createImageView(self.dev.dev, &.{ - .image = image, - .view_type = .@"2d", - .format = self.dev.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 (self.chain.items(.fence)) |*fence| { - fence.* = try self.dev.vkd.createFence(self.dev.dev, &.{ - .flags = .{ .signaled_bit = true }, - }, null); - } - - for (self.chain.items(.image_available)) |*sem| { - sem.* = try self.dev.vkd.createSemaphore(self.dev.dev, &.{}, null); - } - - for (self.chain.items(.render_finished)) |*sem| { - sem.* = try self.dev.vkd.createSemaphore(self.dev.dev, &.{}, null); - } - - try self.dev.vkd.allocateCommandBuffers(self.dev.dev, &.{ - .command_pool = self.dev.pool, - .command_buffer_count = @intCast(self.chain.len), - .level = .primary, - }, self.chain.items(.cmdbuf).ptr); -} - -fn deinit_chain(self: Self) void { - for (self.chain.items(.view)) |view| { - self.dev.vkd.destroyImageView(self.dev.dev, view, null); - } - for (self.chain.items(.fence)) |fence| { - self.dev.vkd.destroyFence(self.dev.dev, fence, null); - } - for (self.chain.items(.image_available)) |sem| { - self.dev.vkd.destroySemaphore(self.dev.dev, sem, null); - } - for (self.chain.items(.render_finished)) |sem| { - self.dev.vkd.destroySemaphore(self.dev.dev, sem, null); - } - if (self.chain.len > 0) { - self.dev.vkd.freeCommandBuffers( - self.dev.dev, - self.dev.pool, - @intCast(self.chain.len), - self.chain.items(.cmdbuf).ptr, - ); - } -} - -pub fn deinit(self: *Self) void { - self.deinit_chain(); - self.chain.deinit(self.ally); - self.dev.vkd.destroySwapchainKHR(self.dev.dev, self.ref, null); -}