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,6 +3,7 @@ const std = @import("std");
const vk = @import("vulkan");
const CommandBuffer = @import("CommandBuffer.zig").CommandBuffer;
const Engine = @import("Engine.zig");
const StagingBuffer = @import("StagingBuffer.zig");
const TargetQueue = @import("TargetQueue.zig").TargetQueue;
@@ -194,64 +195,53 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
// --- TRANSITION TO TRANSFER_DST_OPTIMAL AND COPY -----------------
const transfer_command_buffer = try engine.allocateTransientTransferCommandBuffer();
defer engine.freeTransientTransferCommandBuffer(transfer_command_buffer);
var transfer_command_buffer: CommandBuffer(.transfer, .transient) = try .init(engine);
defer transfer_command_buffer.deinit(engine);
try transfer_command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
try transfer_command_buffer.beginCommandBuffer(.{});
const transfer_transition_barriers = [_]vk.ImageMemoryBarrier{
.{
.src_access_mask = .{},
.dst_access_mask = .{ .transfer_write_bit = true },
.old_layout = .undefined,
.new_layout = .transfer_dst_optimal,
.src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.image = self.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
transfer_command_buffer.pipelineBarrier(.{
.src_stage_mask = .{ .top_of_pipe_bit = true },
.dst_stage_mask = .{ .transfer_bit = true },
.image_memory_barriers = &.{
.{
.src_access_mask = .{},
.dst_access_mask = .{ .transfer_write_bit = true },
.old_layout = .undefined,
.new_layout = .transfer_dst_optimal,
.src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.image = self.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
},
},
};
transfer_command_buffer.pipelineBarrier(
.{ .top_of_pipe_bit = true },
.{ .transfer_bit = true },
.{},
0,
null,
0,
null,
transfer_transition_barriers.len,
&transfer_transition_barriers,
);
const regions = [_]vk.BufferImageCopy{
.{
.buffer_offset = 0,
.buffer_row_length = self.width,
.buffer_image_height = self.height,
.image_subresource = .{
.aspect_mask = .{ .color_bit = true },
.mip_level = 0,
.base_array_layer = 0,
.layer_count = 1,
},
.image_offset = .{ .x = 0, .y = 0, .z = 0 },
.image_extent = .{ .width = self.width, .height = self.height, .depth = 1 },
},
};
});
transfer_command_buffer.copyBufferToImage(
staging_buffer.buffer,
self.image,
.transfer_dst_optimal,
regions.len,
&regions,
&.{
.{
.buffer_offset = 0,
.buffer_row_length = self.width,
.buffer_image_height = self.height,
.image_subresource = .{
.aspect_mask = .{ .color_bit = true },
.mip_level = 0,
.base_array_layer = 0,
.layer_count = 1,
},
.image_offset = .{ .x = 0, .y = 0, .z = 0 },
.image_extent = .{ .width = self.width, .height = self.height, .depth = 1 },
},
},
);
try transfer_command_buffer.endCommandBuffer();
@@ -259,73 +249,48 @@ pub fn writeRaw(self: Texture, engine: *Engine, data: []const u8) !void {
const semaphore = try engine.createSemaphore();
defer engine.destroySemaphore(semaphore);
const transfer_submits = [_]vk.SubmitInfo{
.{
.command_buffer_count = 1,
.p_command_buffers = @ptrCast(&transfer_command_buffer.handle),
.signal_semaphore_count = 1,
.p_signal_semaphores = @ptrCast(&semaphore),
},
};
try engine.device.queueSubmit(engine.transfer_queue.handle, transfer_submits.len, &transfer_submits, .null_handle);
try transfer_command_buffer.submit(engine, .{
.signal_semaphores = &.{semaphore},
});
// --- TRANSITION TO SHADER_READ_ONLY_OPTIMAL ----------------------
const graphics_command_buffer = try engine.allocateGraphicsCommandBuffer();
defer engine.freeGraphicsCommandBuffer(graphics_command_buffer);
var graphics_command_buffer: CommandBuffer(.graphics, .transient) = try .init(engine);
defer graphics_command_buffer.deinit(engine);
try graphics_command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
try graphics_command_buffer.beginCommandBuffer(.{});
const graphics_transition_barriers = [_]vk.ImageMemoryBarrier{
.{
.src_access_mask = .{ .transfer_write_bit = true },
.dst_access_mask = .{ .shader_read_bit = true },
.old_layout = .transfer_dst_optimal,
.new_layout = .shader_read_only_optimal,
.src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.image = self.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
graphics_command_buffer.pipelineBarrier(.{
.src_stage_mask = .{ .transfer_bit = true },
.dst_stage_mask = .{ .fragment_shader_bit = true },
.image_memory_barriers = &.{
.{
.src_access_mask = .{ .transfer_write_bit = true },
.dst_access_mask = .{ .shader_read_bit = true },
.old_layout = .transfer_dst_optimal,
.new_layout = .shader_read_only_optimal,
.src_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.dst_queue_family_index = vk.QUEUE_FAMILY_IGNORED,
.image = self.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
},
},
};
graphics_command_buffer.pipelineBarrier(
.{ .transfer_bit = true },
.{ .fragment_shader_bit = true },
.{},
0,
null,
0,
null,
graphics_transition_barriers.len,
&graphics_transition_barriers,
);
});
try graphics_command_buffer.endCommandBuffer();
const wait_stage_masks = [_]vk.PipelineStageFlags{
.{ .top_of_pipe_bit = true },
};
const graphics_submits = [_]vk.SubmitInfo{
.{
.command_buffer_count = 1,
.p_command_buffers = @ptrCast(&graphics_command_buffer.handle),
.wait_semaphore_count = 1,
.p_wait_semaphores = @ptrCast(&semaphore),
.p_wait_dst_stage_mask = &wait_stage_masks,
},
};
const fence = try engine.createFence(.{});
defer engine.destroyFence(fence);
try engine.device.queueSubmit(engine.graphics_queue.handle, graphics_submits.len, &graphics_submits, fence);
try graphics_command_buffer.submit(engine, .{
.wait_semaphores = &.{.{ .semaphore = semaphore }},
.fence = fence,
});
try engine.waitForFence(fence);
}