CommandBuffer wrapper

This commit is contained in:
2025-11-28 17:09:37 +01:00
parent 94c43a170f
commit 2541dee18d
9 changed files with 461 additions and 289 deletions

View File

@@ -3,9 +3,11 @@ const std = @import("std");
const vk = @import("vulkan");
const CommandBuffer = @import("CommandBuffer.zig").CommandBuffer;
const Engine = @import("Engine.zig");
const QSM = @import("QueueSharingMode.zig");
const Texture = @import("Texture.zig");
const WaitSemaphore = @import("WaitSemaphore.zig");
params: Params,
render_pass: vk.RenderPass,
@@ -117,7 +119,7 @@ pub fn deinit(self: *Swapchain, engine: *Engine) void {
const allocator = engine.vk_allocator.allocator;
for (self.swapchain_images) |swapchain_image| {
for (self.swapchain_images) |*swapchain_image| {
swapchain_image.deinit(engine);
}
allocator.free(self.swapchain_images);
@@ -178,7 +180,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
// to revert on error. Instead, we set the current swapchain and images to
// null and deinit the old swapchain and images.
for (old_swapchain_images) |swapchain_image| {
for (old_swapchain_images) |*swapchain_image| {
swapchain_image.deinit(engine);
}
allocator.free(self.swapchain_images);
@@ -219,7 +221,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
var swapchain_images: std.ArrayList(SwapchainImage) = try .initCapacity(allocator, images.len);
errdefer swapchain_images.deinit(allocator);
errdefer for (swapchain_images.items) |x| x.deinit(engine);
errdefer for (swapchain_images.items) |*x| x.deinit(engine);
for (images) |image| {
swapchain_images.appendAssumeCapacity(try SwapchainImage.init(engine, .{
@@ -234,7 +236,7 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
break :blk try swapchain_images.toOwnedSlice(allocator);
};
errdefer {
for (new_swapchain_images) |swapchain_image| {
for (new_swapchain_images) |*swapchain_image| {
swapchain_image.deinit(engine);
}
allocator.free(new_swapchain_images);
@@ -262,14 +264,9 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
self.semaphore_image_acquired = semaphore_image_acquired;
}
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,
command_buffer: CommandBuffer(.graphics, .transient),
wait_semaphores: []const WaitSemaphore = &.{},
};
pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !PresentResult {
@@ -281,42 +278,29 @@ pub fn present(self: *Swapchain, engine: *Engine, present_info: PresentInfo) !Pr
const current_swapchain_image = &self.swapchain_images[self.image_index];
try engine.waitForFence(current_swapchain_image.fence);
if (current_swapchain_image.command_buffer != .null_handle) {
device.freeCommandBuffers(engine.graphics_command_pool, 1, @ptrCast(&current_swapchain_image.command_buffer));
current_swapchain_image.command_buffer = .null_handle;
if (current_swapchain_image.command_buffer) |*command_buffer| {
command_buffer.deinit(engine);
current_swapchain_image.command_buffer = null;
}
try engine.resetFence(current_swapchain_image.fence);
// --- SUBMIT COMMAND BUFFER -----------------------------------------------
var wait_semaphores = std.MultiArrayList(WaitSemaphore){};
var wait_semaphores: std.ArrayList(WaitSemaphore) = try .initCapacity(allocator, 1 + present_info.wait_semaphores.len);
defer wait_semaphores.deinit(allocator);
try wait_semaphores.ensureTotalCapacity(allocator, 1 + present_info.wait_semaphores.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,
};
wait_semaphores.appendSliceAssumeCapacity(present_info.wait_semaphores);
current_swapchain_image.command_buffer = present_info.command_buffer;
try device.queueSubmit(engine.graphics_queue.handle, 1, &.{
.{
.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(&present_info.command_buffer),
.signal_semaphore_count = signal_semaphores.len,
.p_signal_semaphores = &signal_semaphores,
},
}, current_swapchain_image.fence);
try present_info.command_buffer.submit(engine, .{
.wait_semaphores = wait_semaphores.items,
.signal_semaphores = &.{current_swapchain_image.semaphore_render_finished},
.fence = current_swapchain_image.fence,
});
// --- PRESENT CURRENT FRAME -----------------------------------------------
@@ -415,7 +399,7 @@ const SwapchainImage = struct {
semaphore_render_finished: vk.Semaphore,
fence: vk.Fence,
framebuffer: vk.Framebuffer,
command_buffer: vk.CommandBuffer,
command_buffer: ?CommandBuffer(.graphics, .transient),
const InitProps = struct {
image: vk.Image,
@@ -467,18 +451,23 @@ const SwapchainImage = struct {
.semaphore_render_finished = semaphore_render_finished,
.fence = fence,
.framebuffer = framebuffer,
.command_buffer = .null_handle,
.command_buffer = null,
};
}
fn deinit(self: SwapchainImage, engine: *Engine) void {
fn deinit(self: *SwapchainImage, engine: *Engine) void {
std.log.debug("Deinitializing {*} with {*}", .{ &self, engine });
engine.waitForFence(self.fence) catch {};
if (self.command_buffer) |*command_buffer| {
command_buffer.deinit(engine);
}
engine.destroyFramebuffer(self.framebuffer);
engine.destroyFence(self.fence);
engine.destroySemaphore(self.semaphore_render_finished);
engine.destroySemaphore(self.semaphore_image_acquired);
engine.destroyImageView(self.image_view);
self.* = undefined;
}
};