Make use of some globals to stop typing engine everywhere.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
const Swapchain = @This();
|
||||
const std = @import("std");
|
||||
|
||||
const ctx = @import("../AppContext.zig");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const CommandBuffer = @import("CommandBuffer.zig");
|
||||
const Engine = @import("Engine.zig");
|
||||
const QSM = @import("QueueSharingMode.zig");
|
||||
const Texture = @import("Texture.zig");
|
||||
const WaitSemaphore = @import("WaitSemaphore.zig");
|
||||
|
||||
@@ -13,6 +13,7 @@ params: Params,
|
||||
|
||||
extent: vk.Extent2D = .{ .width = 0, .height = 0 },
|
||||
swapchain: vk.SwapchainKHR = .null_handle,
|
||||
/// Allocated with `allocator_general`.
|
||||
swapchain_images: []SwapchainImage = &.{},
|
||||
depth_texture: ?Texture = null,
|
||||
image_index: ?u32 = null,
|
||||
@@ -24,28 +25,33 @@ pub const PresentResult = enum {
|
||||
suboptimal,
|
||||
};
|
||||
|
||||
pub fn init(engine: *Engine) !Swapchain {
|
||||
const params: Params = try .init(engine);
|
||||
var swapchain: Swapchain = .{
|
||||
.params = params,
|
||||
pub fn init() !*Swapchain {
|
||||
const allocator_persistent = ctx.allocator_persistent;
|
||||
|
||||
const swapchain = try allocator_persistent.create(Swapchain);
|
||||
errdefer allocator_persistent.destroy(swapchain);
|
||||
|
||||
swapchain.* = .{
|
||||
.params = try .init(),
|
||||
};
|
||||
|
||||
try recreate(&swapchain, engine);
|
||||
try swapchain.recreate();
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Swapchain, engine: *Engine) void {
|
||||
std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||
pub fn deinit(self: *Swapchain) void {
|
||||
const allocator_general = ctx.allocator_general;
|
||||
const engine = ctx.engine;
|
||||
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
std.log.scoped(.deinit).debug("Deinitializing {*}", .{self});
|
||||
|
||||
for (self.swapchain_images) |*swapchain_image| {
|
||||
swapchain_image.deinit(engine);
|
||||
swapchain_image.deinit();
|
||||
}
|
||||
allocator.free(self.swapchain_images);
|
||||
allocator_general.free(self.swapchain_images);
|
||||
|
||||
if (self.depth_texture) |*depth_texture| {
|
||||
depth_texture.deinit(engine);
|
||||
depth_texture.deinit();
|
||||
}
|
||||
|
||||
if (self.swapchain != .null_handle) {
|
||||
@@ -58,11 +64,15 @@ pub fn deinit(self: *Swapchain, engine: *Engine) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
try engine.deviceWaitIdle(); // TODO LMAO
|
||||
pub fn recreate(self: *Swapchain) !void {
|
||||
const allocator_general = ctx.allocator_general;
|
||||
const allocator_frame = ctx.allocator_frame;
|
||||
const engine = ctx.engine;
|
||||
|
||||
const mode = &engine.mode.surface;
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
// TODO This is very "LMAO just wait for all" way to synchronize. It might
|
||||
// be the only viable option, though. Either way, we should research what
|
||||
// is "the way".
|
||||
try engine.deviceWaitIdle();
|
||||
|
||||
const old_swapchain = self.swapchain;
|
||||
const old_swapchain_images = self.swapchain_images;
|
||||
@@ -70,7 +80,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
const old_semaphore_image_acquired = self.semaphore_image_acquired;
|
||||
const old_fence = self.fence;
|
||||
|
||||
const extent = try getCurrentExtent(engine);
|
||||
const extent = try getCurrentExtent();
|
||||
|
||||
std.log.debug("Recreating swapchain with extent of {d}×{d}...", .{ extent.width, extent.height });
|
||||
|
||||
@@ -78,7 +88,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
|
||||
const surface_capabilities = try engine.getPhysicalDeviceSurfaceCapabilities();
|
||||
const new_swapchain = try engine.createSwapchain(.{
|
||||
.surface = mode.surface,
|
||||
.surface = engine.surface,
|
||||
.min_image_count = self.params.image_count,
|
||||
.image_format = self.params.surface_format.format,
|
||||
.image_color_space = self.params.surface_format.color_space,
|
||||
@@ -87,7 +97,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
.image_usage = .{ .color_attachment_bit = true },
|
||||
.queue_family_indices = &.{
|
||||
engine.graphics_queue.allocation.family,
|
||||
mode.presentation_queue.allocation.family,
|
||||
engine.presentation_queue.allocation.family,
|
||||
},
|
||||
.pre_transform = surface_capabilities.current_transform,
|
||||
.composite_alpha = .{ .opaque_bit_khr = true },
|
||||
@@ -105,13 +115,13 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
// null and deinit the old swapchain and images.
|
||||
|
||||
for (old_swapchain_images) |*swapchain_image| {
|
||||
swapchain_image.deinit(engine);
|
||||
swapchain_image.deinit();
|
||||
}
|
||||
allocator.free(self.swapchain_images);
|
||||
allocator_general.free(self.swapchain_images);
|
||||
self.swapchain_images = &.{};
|
||||
|
||||
if (old_depth_texture.*) |*depth_texture| {
|
||||
depth_texture.deinit(engine);
|
||||
depth_texture.deinit();
|
||||
}
|
||||
|
||||
if (old_swapchain != .null_handle) {
|
||||
@@ -134,28 +144,27 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
|
||||
// --- CREATE DEPTH TEXTURE ------------------------------------------------
|
||||
|
||||
var new_depth_texture = try Texture.init(engine, .{
|
||||
var new_depth_texture = try Texture.init(.{
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.target_queue = .graphics,
|
||||
.usage = .depth,
|
||||
.name = "@Depth",
|
||||
});
|
||||
errdefer new_depth_texture.deinit(engine);
|
||||
errdefer new_depth_texture.deinit();
|
||||
|
||||
// --- CREATE NEW SWAPCHAIN IMAGES -----------------------------------------
|
||||
|
||||
const new_swapchain_images = blk: {
|
||||
const images = try engine.getSwapchainImagesAlloc(new_swapchain, allocator);
|
||||
defer allocator.free(images);
|
||||
const images = try engine.getSwapchainImagesAlloc(new_swapchain, allocator_frame);
|
||||
|
||||
var swapchain_images: std.ArrayList(SwapchainImage) = try .initCapacity(allocator, images.len);
|
||||
errdefer swapchain_images.deinit(allocator);
|
||||
var swapchain_images: std.ArrayList(SwapchainImage) = try .initCapacity(allocator_general, images.len);
|
||||
errdefer swapchain_images.deinit(allocator_general);
|
||||
|
||||
errdefer for (swapchain_images.items) |*x| x.deinit(engine);
|
||||
errdefer for (swapchain_images.items) |*x| x.deinit();
|
||||
|
||||
for (images, 0..) |image, index| {
|
||||
swapchain_images.appendAssumeCapacity(try SwapchainImage.init(engine, .{
|
||||
swapchain_images.appendAssumeCapacity(try SwapchainImage.init(.{
|
||||
.image = image,
|
||||
.format = self.params.surface_format.format,
|
||||
.extent = extent,
|
||||
@@ -164,13 +173,13 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
}));
|
||||
}
|
||||
|
||||
break :blk try swapchain_images.toOwnedSlice(allocator);
|
||||
break :blk try swapchain_images.toOwnedSlice(allocator_general);
|
||||
};
|
||||
errdefer {
|
||||
for (new_swapchain_images) |*swapchain_image| {
|
||||
swapchain_image.deinit(engine);
|
||||
swapchain_image.deinit();
|
||||
}
|
||||
allocator.free(new_swapchain_images);
|
||||
allocator_general.free(new_swapchain_images);
|
||||
}
|
||||
|
||||
// --- CREATE SEMAPHORES AND FENCES ----------------------------------------
|
||||
@@ -196,7 +205,9 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
||||
self.fence = fence;
|
||||
}
|
||||
|
||||
pub fn acquire(self: *Swapchain, engine: *Engine) !void {
|
||||
pub fn acquire(self: *Swapchain) !void {
|
||||
const engine = ctx.engine;
|
||||
|
||||
try engine.waitForFence(self.fence);
|
||||
try engine.resetFence(self.fence);
|
||||
|
||||
@@ -212,14 +223,15 @@ pub const PresentInfo = struct {
|
||||
wait_semaphores: []const WaitSemaphore = &.{},
|
||||
};
|
||||
|
||||
pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !void {
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
pub fn present(self: *Swapchain, present_info: PresentInfo) !void {
|
||||
const allocator_frame = ctx.allocator_frame;
|
||||
const engine = ctx.engine;
|
||||
|
||||
const current_swapchain_image = &self.swapchain_images[self.image_index.?];
|
||||
|
||||
// --- SUBMIT COMMAND BUFFER -----------------------------------------------
|
||||
|
||||
var wait_semaphores: std.ArrayList(WaitSemaphore) = try .initCapacity(allocator, 1 + present_info.wait_semaphores.len);
|
||||
defer wait_semaphores.deinit(allocator);
|
||||
var wait_semaphores: std.ArrayList(WaitSemaphore) = try .initCapacity(allocator_frame, 1 + present_info.wait_semaphores.len);
|
||||
|
||||
wait_semaphores.appendAssumeCapacity(.{
|
||||
.semaphore = current_swapchain_image.semaphore_image_acquired,
|
||||
@@ -227,7 +239,7 @@ pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !vo
|
||||
});
|
||||
wait_semaphores.appendSliceAssumeCapacity(present_info.wait_semaphores);
|
||||
|
||||
try present_info.command_buffer.submit(engine, .{
|
||||
try present_info.command_buffer.submit(.{
|
||||
.wait_semaphores = wait_semaphores.items,
|
||||
.signal_semaphores = &.{current_swapchain_image.semaphore_render_finished},
|
||||
.fence = self.fence,
|
||||
@@ -242,15 +254,17 @@ pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !vo
|
||||
});
|
||||
}
|
||||
|
||||
fn getCurrentExtent(engine: *Engine) !vk.Extent2D {
|
||||
const mode = &engine.mode.surface;
|
||||
fn getCurrentExtent() !vk.Extent2D {
|
||||
const window = ctx.window;
|
||||
const engine = ctx.engine;
|
||||
|
||||
const surface_capabilities = try engine.getPhysicalDeviceSurfaceCapabilities();
|
||||
|
||||
if (surface_capabilities.current_extent.width != std.math.maxInt(u32) and surface_capabilities.current_extent.height != std.math.maxInt(u32)) {
|
||||
return surface_capabilities.current_extent;
|
||||
}
|
||||
|
||||
const framebuffer_width, const framebuffer_height = mode.window.getFramebufferSize();
|
||||
const framebuffer_width, const framebuffer_height = window.getFramebufferSize();
|
||||
|
||||
return .{
|
||||
.width = std.math.clamp(
|
||||
@@ -270,14 +284,14 @@ const Params = struct {
|
||||
surface_format: vk.SurfaceFormatKHR,
|
||||
image_count: u32,
|
||||
|
||||
pub fn init(engine: *Engine) !Params {
|
||||
const allocator = engine.vk_allocator.allocator;
|
||||
pub fn init() !Params {
|
||||
const allocator_frame = ctx.allocator_frame;
|
||||
const engine = ctx.engine;
|
||||
|
||||
const surface_capabilities = try engine.getPhysicalDeviceSurfaceCapabilities();
|
||||
|
||||
const surface_format = blk: {
|
||||
const surface_formats = try engine.getPhysicalDeviceSurfaceFormatsAlloc(allocator);
|
||||
defer allocator.free(surface_formats);
|
||||
const surface_formats = try engine.getPhysicalDeviceSurfaceFormatsAlloc(allocator_frame);
|
||||
|
||||
// Look for 8-bit BGRA sRGB surface format.
|
||||
|
||||
@@ -323,7 +337,9 @@ const SwapchainImage = struct {
|
||||
index: usize,
|
||||
};
|
||||
|
||||
fn init(engine: *Engine, props: InitProps) !SwapchainImage {
|
||||
fn init(props: InitProps) !SwapchainImage {
|
||||
const engine = ctx.engine;
|
||||
|
||||
const image_view = try engine.createImageView(.{
|
||||
.image = props.image,
|
||||
.view_type = .@"2d",
|
||||
@@ -355,8 +371,10 @@ const SwapchainImage = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *SwapchainImage, engine: *Engine) void {
|
||||
std.log.scoped(.deinit).debug("Deinitializing {*} with {*}", .{ self, engine });
|
||||
fn deinit(self: *SwapchainImage) void {
|
||||
const engine = ctx.engine;
|
||||
|
||||
std.log.scoped(.deinit).debug("Deinitializing {*}", .{self});
|
||||
|
||||
engine.destroySemaphore(self.semaphore_render_finished);
|
||||
engine.destroySemaphore(self.semaphore_image_acquired);
|
||||
|
||||
Reference in New Issue
Block a user