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

@@ -8,6 +8,7 @@ const math = @import("math.zig");
const Materials = @import("assets/Materials.zig");
const Textures = @import("assets/Textures.zig");
const CommandBuffer = @import("engine/CommandBuffer.zig").CommandBuffer;
const Engine = @import("engine/Engine.zig");
const GenericBuffer = @import("engine/GenericBuffer.zig").GenericBuffer;
const StagingBuffer = @import("engine/StagingBuffer.zig");
@@ -115,7 +116,7 @@ index_buffer: IndexBuffer,
global_uniforms: GlobalUniformsBuffer,
global_uniforms_staging_buffer: StagingBuffer,
global_uniforms_transfer_command_buffer: vk.CommandBuffer,
global_uniforms_transfer_command_buffer: CommandBuffer(.graphics, .persistent),
global_uniforms_transfer_semaphores: []vk.Semaphore,
point_lights: PointLightBuffer,
directional_lights: DirectionalLightBuffer,
@@ -305,14 +306,13 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
});
errdefer global_uniforms_staging_buffer.deinit(engine);
const global_uniforms_transfer_command_buffer = try engine.allocateTransferCommandBuffer();
errdefer engine.freeTransferCommandBuffer(global_uniforms_transfer_command_buffer);
var global_uniforms_transfer_command_buffer: CommandBuffer(.graphics, .persistent) = try .init(engine);
errdefer global_uniforms_transfer_command_buffer.deinit(engine);
try global_uniforms_transfer_command_buffer.beginCommandBuffer(&.{});
try global_uniforms_transfer_command_buffer.beginCommandBuffer(.{});
global_uniforms_transfer_command_buffer.copyBuffer(
global_uniforms_staging_buffer.buffer,
global_uniforms.buffer,
1,
&.{
.{
.src_offset = 0,
@@ -685,7 +685,7 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
.global_uniforms = global_uniforms,
.global_uniforms_staging_buffer = global_uniforms_staging_buffer,
.global_uniforms_transfer_command_buffer = global_uniforms_transfer_command_buffer.handle,
.global_uniforms_transfer_command_buffer = global_uniforms_transfer_command_buffer,
.global_uniforms_transfer_semaphores = global_uniforms_transfer_semaphores,
.point_lights = point_lights,
.directional_lights = directional_lights,
@@ -706,6 +706,7 @@ pub fn deinit(self: *Game) void {
self.global_uniforms.deinit(self.engine);
self.global_uniforms_staging_buffer.deinit(self.engine);
self.global_uniforms_transfer_command_buffer.deinit(self.engine);
self.point_lights.deinit(self.engine);
self.directional_lights.deinit(self.engine);
self.object_uniforms.deinit(self.engine);
@@ -782,16 +783,9 @@ pub fn update(self: *Game, dt: f32) void {
@memcpy(staging_memory, std.mem.asBytes(&global_uniforms_data));
self.global_uniforms_staging_buffer.unmap(self.engine);
const submits = [_]vk.SubmitInfo{
.{
.command_buffer_count = 1,
.p_command_buffers = @ptrCast(&self.global_uniforms_transfer_command_buffer),
.signal_semaphore_count = 1,
.p_signal_semaphores = @ptrCast(&self.global_uniforms_transfer_semaphores[self.swapchain.image_index]),
},
};
self.engine.device.queueSubmit(self.engine.transfer_queue.handle, submits.len, &submits, .null_handle) catch |err| {
self.global_uniforms_transfer_command_buffer.submit(self.engine, .{
.signal_semaphores = &.{self.global_uniforms_transfer_semaphores[self.swapchain.image_index]},
}) catch |err| {
std.log.err("Failed to submit global uniforms transfer: {s}", .{@errorName(err)});
@panic("Frame update failed");
};
@@ -877,41 +871,37 @@ pub fn onMouseUp(self: *Game, button: glfw.MouseButton, mods: glfw.Mods) void {
}
fn render(self: *Game) !void {
const engine = self.engine;
const extent = self.swapchain.extent;
const command_buffer = try engine.allocateGraphicsCommandBuffer();
const command_buffer: CommandBuffer(.graphics, .transient) = try .init(self.engine);
// NOTE Do not free command buffer yet
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
try command_buffer.beginCommandBuffer(.{});
{
const clear_values = [_]vk.ClearValue{
.{
.color = .{
.float_32 = .{ 0, 0, 0, 0 },
},
},
.{
.depth_stencil = .{
.depth = 0,
.stencil = 0,
},
},
};
command_buffer.beginRenderPass(&.{
command_buffer.beginRenderPass(.{
.render_pass = self.swapchain.render_pass,
.framebuffer = self.swapchain.swapchain_images[self.swapchain.image_index].framebuffer,
.render_area = .{
.offset = .{ .x = 0, .y = 0 },
.extent = extent,
},
.clear_value_count = clear_values.len,
.p_clear_values = &clear_values,
.clear_values = &.{
.{
.color = .{
.float_32 = .{ 0, 0, 0, 0 },
},
},
.{
.depth_stencil = .{
.depth = 0,
.stencil = 0,
},
},
},
}, .@"inline");
defer command_buffer.endRenderPass();
const viewports = [_]vk.Viewport{
command_buffer.setViewport(0, &.{
.{
.x = 0,
.y = 0,
@@ -920,29 +910,33 @@ fn render(self: *Game) !void {
.min_depth = 0,
.max_depth = 1,
},
};
command_buffer.setViewport(0, viewports.len, &viewports);
const scissors = [_]vk.Rect2D{
});
command_buffer.setScissor(0, &.{
.{
.offset = .{ .x = 0, .y = 0 },
.extent = extent,
},
};
command_buffer.setScissor(0, scissors.len, &scissors);
});
command_buffer.bindPipeline(.graphics, self.pipeline);
command_buffer.bindVertexBuffers(0, 1, @ptrCast(&self.vertex_buffer.buffer), &.{0});
try command_buffer.bindVertexBuffers(0, &.{
.{
.buffer = self.vertex_buffer.buffer,
.offset = 0,
},
});
command_buffer.bindIndexBuffer(self.index_buffer.buffer, 0, .uint16);
command_buffer.bindDescriptorSets(.graphics, self.pipeline_layout, 0, self.descriptor_sets.len, &self.descriptor_sets, 0, null);
command_buffer.bindDescriptorSets(.graphics, self.pipeline_layout, 0, &self.descriptor_sets, &.{});
command_buffer.drawIndexed(@intCast(self.index_buffer.array_capacity), self.object_count, 0, 0, 0);
command_buffer.drawIndexed(.{
.index_count = self.index_buffer.array_capacity,
.instance_count = self.object_count,
});
}
try command_buffer.endCommandBuffer();
const res = try self.swapchain.present(self.engine, .{
.command_buffer = command_buffer.handle,
.command_buffer = command_buffer,
.wait_semaphores = &.{
.{
.semaphore = self.global_uniforms_transfer_semaphores[self.swapchain.image_index],