Vertical movement, deinit logs, persistent global uniform transfers

This commit is contained in:
2025-11-27 17:07:22 +01:00
parent b9a804ead6
commit 6069249bf8
11 changed files with 212 additions and 82 deletions

View File

@@ -17,6 +17,7 @@ pub const Mode = union(enum) {
},
pub fn deinit(self: *Mode, instance: vk.InstanceProxy, vk_allocator: *VkAllocator) void {
std.log.debug("Deinitializing {*} with InstanceProxy@{{{X},{*}}} and {*}", .{ self, instance.handle, instance.wrapper, vk_allocator });
switch (self.*) {
.headless => {},
.surface => |x| {
@@ -103,6 +104,7 @@ transfer_queue: Queue,
graphics_command_pool: vk.CommandPool,
compute_command_pool: vk.CommandPool,
transfer_command_pool: vk.CommandPool,
transient_transfer_command_pool: vk.CommandPool,
prng_ptr: *std.Random.Pcg,
random: std.Random,
@@ -320,29 +322,27 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
// --- CREATE COMMAND POOLS, GET QUEUES ------------------------------------
const command_pool_create_flags: vk.CommandPoolCreateFlags = .{
.transient_bit = true,
.reset_command_buffer_bit = true,
};
const graphics_command_pool = try device.createCommandPool(&.{
.flags = command_pool_create_flags,
.queue_family_index = queue_allocations.graphics_queue.family,
}, &vk_allocator.interface);
errdefer device.destroyCommandPool(graphics_command_pool, &vk_allocator.interface);
const compute_command_pool = try device.createCommandPool(&.{
.flags = command_pool_create_flags,
.queue_family_index = queue_allocations.compute_queue.family,
}, &vk_allocator.interface);
errdefer device.destroyCommandPool(compute_command_pool, &vk_allocator.interface);
const transfer_command_pool = try device.createCommandPool(&.{
.flags = command_pool_create_flags,
.queue_family_index = queue_allocations.transfer_queue.family,
}, &vk_allocator.interface);
errdefer device.destroyCommandPool(transfer_command_pool, &vk_allocator.interface);
const transient_transfer_command_pool = try device.createCommandPool(&.{
.flags = .{ .transient_bit = true },
.queue_family_index = queue_allocations.transfer_queue.family,
}, &vk_allocator.interface);
errdefer device.destroyCommandPool(transient_transfer_command_pool, &vk_allocator.interface);
const graphics_queue: Queue = .initAllocation(device, queue_allocations.graphics_queue);
const compute_queue: Queue = .initAllocation(device, queue_allocations.compute_queue);
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
@@ -383,6 +383,7 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
.graphics_command_pool = graphics_command_pool,
.compute_command_pool = compute_command_pool,
.transfer_command_pool = transfer_command_pool,
.transient_transfer_command_pool = transient_transfer_command_pool,
.prng_ptr = prng_ptr,
.random = random,
@@ -390,6 +391,8 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
}
pub fn deinit(self: *Engine) void {
std.log.debug("Deinitializing {*}", .{self});
const allocator = self.vk_allocator.allocator;
allocator.destroy(self.prng_ptr);
@@ -397,6 +400,7 @@ pub fn deinit(self: *Engine) void {
self.device.destroyCommandPool(self.graphics_command_pool, &self.vk_allocator.interface);
self.device.destroyCommandPool(self.compute_command_pool, &self.vk_allocator.interface);
self.device.destroyCommandPool(self.transfer_command_pool, &self.vk_allocator.interface);
self.device.destroyCommandPool(self.transient_transfer_command_pool, &self.vk_allocator.interface);
self.device.destroyDevice(&self.vk_allocator.interface);
allocator.destroy(self.device.wrapper);
@@ -433,6 +437,16 @@ pub fn allocate(self: *const Engine, memory_requirements: vk.MemoryRequirements,
return error.NoSuitableMemoryType;
}
pub fn allocateTransientTransferCommandBuffer(self: *const Engine) !vk.CommandBufferProxy {
var command_buffer: vk.CommandBuffer = undefined;
try self.device.allocateCommandBuffers(&.{
.command_pool = self.transient_transfer_command_pool,
.level = .primary,
.command_buffer_count = 1,
}, @ptrCast(&command_buffer));
return .init(command_buffer, self.device.wrapper);
}
pub fn allocateTransferCommandBuffer(self: *const Engine) !vk.CommandBufferProxy {
var command_buffer: vk.CommandBuffer = undefined;
try self.device.allocateCommandBuffers(&.{
@@ -457,6 +471,10 @@ pub fn freeTransferCommandBuffer(self: *const Engine, command_buffer: vk.Command
self.device.freeCommandBuffers(self.transfer_command_pool, 1, @ptrCast(&command_buffer));
}
pub fn freeTransientTransferCommandBuffer(self: *const Engine, command_buffer: vk.CommandBufferProxy) void {
self.device.freeCommandBuffers(self.transient_transfer_command_pool, 1, @ptrCast(&command_buffer));
}
pub fn freeGraphicsCommandBuffer(self: *const Engine, command_buffer: vk.CommandBufferProxy) void {
self.device.freeCommandBuffers(self.graphics_command_pool, 1, @ptrCast(&command_buffer));
}
@@ -1125,5 +1143,5 @@ pub fn updateDescriptorSets(self: *Engine, update_info: DescriptorSetsUpdateInfo
}
pub fn waitForFence(self: *Engine, fence: vk.Fence) !void {
_ = try self.device.waitForFences(1, @ptrCast(&fence), .true, std.math.maxInt(u64));
_ = try self.device.waitForFences(1, @ptrCast(&fence), .true, 1 * std.time.ns_per_s);
}

View File

@@ -81,6 +81,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
}
pub fn deinit(self: *Self, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
engine.freeMemory(self.device_memory);
engine.destroyBuffer(self.buffer);
@@ -144,8 +146,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
@memcpy(staging_memory[array_write_offset..write_size], std.mem.sliceAsBytes(write_info.elements));
staging_buffer.unmap(engine);
const command_buffer = try engine.allocateTransferCommandBuffer();
defer engine.freeTransferCommandBuffer(command_buffer);
const command_buffer = try engine.allocateTransientTransferCommandBuffer();
defer engine.freeTransientTransferCommandBuffer(command_buffer);
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
command_buffer.copyBuffer(
@@ -188,8 +190,8 @@ pub fn GenericBuffer(comptime Header: type, comptime Element: type) type {
@memcpy(staging_memory, data);
staging_buffer.unmap(engine);
const command_buffer = try engine.allocateTransferCommandBuffer();
defer engine.freeTransferCommandBuffer(command_buffer);
const command_buffer = try engine.allocateTransientTransferCommandBuffer();
defer engine.freeTransientTransferCommandBuffer(command_buffer);
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
command_buffer.copyBuffer(

View File

@@ -51,6 +51,8 @@ pub fn init(engine: *Engine, init_info: InitInfo) !StagingBuffer {
}
pub fn deinit(self: *StagingBuffer, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
engine.freeMemory(self.device_memory);
engine.destroyBuffer(self.buffer);

View File

@@ -71,6 +71,8 @@ pub fn init(engine: *Engine) !Swapchain {
}
pub fn deinit(self: *Swapchain, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
const allocator = engine.vk_allocator.allocator;
for (self.swapchain_images) |swapchain_image| {
@@ -197,7 +199,18 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
self.semaphore_image_acquired = semaphore_image_acquired;
}
pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuffer) !PresentResult {
pub const WaitSemaphore = struct {
semaphore: vk.Semaphore,
stage_flags: vk.PipelineStageFlags = .{ .top_of_pipe_bit = true },
};
pub const PresentInfo = struct {
command_buffer: vk.CommandBuffer,
wait_semaphores: []const WaitSemaphore,
};
pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !PresentResult {
const allocator = engine.vk_allocator.allocator;
const device = engine.device;
const mode = &engine.mode.surface;
@@ -213,28 +226,30 @@ pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuff
// --- SUBMIT COMMAND BUFFER -----------------------------------------------
const wait_semaphores = [_]vk.Semaphore{
current_swapchain_image.semaphore_image_acquired,
};
var wait_semaphores = std.MultiArrayList(WaitSemaphore){};
defer wait_semaphores.deinit(allocator);
try wait_semaphores.ensureTotalCapacity(allocator, 1 + present_info.wait_semaphores.len);
const pipeline_stages_flags = [_]vk.PipelineStageFlags{
.{ .top_of_pipe_bit = true },
};
std.debug.assert(wait_semaphores.len == pipeline_stages_flags.len);
wait_semaphores.appendAssumeCapacity(.{
.semaphore = current_swapchain_image.semaphore_image_acquired,
.stage_flags = .{ .top_of_pipe_bit = true },
});
for (present_info.wait_semaphores) |wait_semaphore| {
wait_semaphores.appendAssumeCapacity(wait_semaphore);
}
const signal_semaphores = [_]vk.Semaphore{
current_swapchain_image.semaphore_render_finished,
};
current_swapchain_image.command_buffer = command_buffer;
current_swapchain_image.command_buffer = present_info.command_buffer;
try device.queueSubmit(engine.graphics_queue.handle, 1, &.{
.{
.wait_semaphore_count = wait_semaphores.len,
.p_wait_semaphores = &wait_semaphores,
.p_wait_dst_stage_mask = &pipeline_stages_flags,
.wait_semaphore_count = @intCast(wait_semaphores.len),
.p_wait_semaphores = wait_semaphores.items(.semaphore).ptr,
.p_wait_dst_stage_mask = wait_semaphores.items(.stage_flags).ptr,
.command_buffer_count = 1,
.p_command_buffers = @ptrCast(&command_buffer),
.p_command_buffers = @ptrCast(&present_info.command_buffer),
.signal_semaphore_count = signal_semaphores.len,
.p_signal_semaphores = &signal_semaphores,
},
@@ -393,6 +408,8 @@ const SwapchainImage = struct {
}
fn deinit(self: SwapchainImage, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ &self, engine });
engine.waitForFence(self.fence) catch {};
engine.destroyFramebuffer(self.framebuffer);
engine.destroyFence(self.fence);

View File

@@ -133,6 +133,8 @@ pub fn init(engine: *Engine, init_info: InitInfo) !Texture {
}
pub fn deinit(self: *Texture, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ self, engine });
engine.destroyImageView(self.image_view);
engine.freeMemory(self.device_memory);
engine.destroyImage(self.image);
@@ -178,8 +180,8 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
// --- TRANSITION TO TRANSFER_DST_OPTIMAL AND COPY -----------------
const transfer_command_buffer = try engine.allocateTransferCommandBuffer();
defer engine.freeTransferCommandBuffer(transfer_command_buffer);
const transfer_command_buffer = try engine.allocateTransientTransferCommandBuffer();
defer engine.freeTransientTransferCommandBuffer(transfer_command_buffer);
try transfer_command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });

View File

@@ -32,6 +32,8 @@ pub fn init(allocator: std.mem.Allocator) !*VkAllocator {
}
pub fn deinit(self: *VkAllocator) void {
std.log.debug("Deinitializing {*}", .{self});
const allocator = self.allocator;
self.allocations.deinit(allocator);

View File

@@ -21,6 +21,8 @@ pub fn init(_allocator: std.mem.Allocator) void {
}
pub fn deinit() void {
std.log.debug("Deinitializing atoms", .{});
string_arena.deinit();
map.deinit(allocator);
array.deinit(allocator);