better separation of swapchain, flight, and uber

This commit is contained in:
David Allemang
2024-07-08 14:25:10 -04:00
parent 53d063246b
commit 8fd94e631d
7 changed files with 220 additions and 271 deletions

View File

@@ -24,7 +24,7 @@ const vertices = [_]Uber.Vertex{
const indices = [_]Uber.Index{ 4, 5, 6, 6, 5, 7 };
const uniform = Uber.Uniform{
.proj = .{
.mat = .{
0.5, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
@@ -32,157 +32,30 @@ const uniform = Uber.Uniform{
},
};
const Frame = struct {
pub fn init() !Frame {
return .{};
}
fn record_render(
cmd: au.CommandBufferProxy,
uber: Uber,
area: vk.Rect2D, // render area, scissor, and viewport.
vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer,
descriptor_set: vk.DescriptorSet,
) void {
cmd.setViewport(0, 1, &.{.{
.x = @floatFromInt(area.offset.x),
.y = @floatFromInt(area.offset.y),
.width = @floatFromInt(area.extent.width),
.height = @floatFromInt(area.extent.height),
.min_depth = 0,
.max_depth = 1,
}});
cmd.setScissor(0, 1, &.{area});
pub fn deinit(self: Frame) void {
_ = self;
}
pub fn record_render(
self: Frame,
cmd: au.CommandBufferProxy,
image: vk.Image,
view: vk.ImageView,
scissor: vk.Rect2D,
pipeline: vk.Pipeline,
layout: vk.PipelineLayout,
vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer,
uniform_buffer: vk.Buffer,
descriptor_set: vk.DescriptorSet,
) !void {
_ = self;
cmd.pipelineBarrier(
.{ .top_of_pipe_bit = true },
.{ .color_attachment_output_bit = true },
.{},
0,
null,
0,
null,
1,
@ptrCast(&vk.ImageMemoryBarrier{
.src_access_mask = .{},
.dst_access_mask = .{ .color_attachment_write_bit = true },
.old_layout = .undefined,
.new_layout = .color_attachment_optimal,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
.image = image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
}),
);
const info = vk.RenderingInfoKHR{
.render_area = scissor,
.layer_count = 1,
.view_mask = 0,
.color_attachment_count = 1,
.p_color_attachments = &.{vk.RenderingAttachmentInfo{
.image_view = view,
.image_layout = .color_attachment_optimal,
.resolve_mode = .{},
.resolve_image_view = .null_handle,
.resolve_image_layout = .undefined,
.load_op = .clear,
.store_op = .store,
.clear_value = .{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } },
}},
};
cmd.setViewport(0, 1, &.{.{
.x = @floatFromInt(scissor.offset.x),
.y = @floatFromInt(scissor.offset.y),
.width = @floatFromInt(scissor.extent.width),
.height = @floatFromInt(scissor.extent.height),
.min_depth = 0,
.max_depth = 1,
}});
cmd.setScissor(0, 1, &.{scissor});
cmd.beginRendering(&info);
cmd.bindDescriptorSets(.graphics, layout, 0, 1, &.{descriptor_set}, 0, null);
cmd.bindPipeline(.graphics, pipeline);
cmd.bindVertexBuffers(0, 1, &.{vertex_buffer}, &.{0});
cmd.bindIndexBuffer(index_buffer, 0, .uint16);
cmd.drawIndexed(indices.len, 1, 0, 0, 0);
im.c.ImGui_ImplVulkan_RenderDrawData(im.c.igGetDrawData(), @ptrFromInt(@intFromEnum(cmd.handle)), null);
cmd.endRendering();
// vulkan implicitly ensures the host writes all data before the host reads it
// be sure the shader reads all the vertex data before the host might modify it
cmd.pipelineBarrier(
.{ .all_graphics_bit = true },
.{ .host_bit = true },
.{},
0,
null,
2,
&.{
vk.BufferMemoryBarrier{
.buffer = vertex_buffer,
.src_access_mask = .{ .shader_read_bit = true },
.dst_access_mask = .{ .host_write_bit = true },
.offset = 0,
.size = vk.WHOLE_SIZE,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
},
vk.BufferMemoryBarrier{
.buffer = uniform_buffer,
.src_access_mask = .{ .shader_read_bit = true },
.dst_access_mask = .{ .host_write_bit = true },
.offset = 0,
.size = vk.WHOLE_SIZE,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
},
},
0,
null,
);
cmd.pipelineBarrier(
.{ .color_attachment_output_bit = true },
.{ .bottom_of_pipe_bit = true },
.{},
0,
null,
0,
null,
1,
@ptrCast(&vk.ImageMemoryBarrier{
.src_access_mask = .{ .color_attachment_write_bit = true },
.dst_access_mask = .{},
.old_layout = .color_attachment_optimal,
.new_layout = .present_src_khr,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
.image = image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
}),
);
}
};
cmd.bindPipeline(.graphics, uber.pipeline);
cmd.bindDescriptorSets(.graphics, uber.layout, 0, 1, &.{descriptor_set}, 0, null);
cmd.bindVertexBuffers(0, 1, &.{vertex_buffer}, &.{0});
cmd.bindIndexBuffer(index_buffer, 0, .uint16);
cmd.drawIndexed(indices.len, 1, 0, 0, 0);
}
pub fn loader_wrapper(procname: [*c]const u8, _: ?*anyopaque) callconv(.C) vk.PfnVoidFunction {
return c.glfwGetInstanceProcAddress(au.I.handle, procname);
@@ -199,7 +72,7 @@ pub fn main() !void {
var sc = try au.SwapChain.init(alloc);
defer sc.deinit();
var flights = try au.Flights(Frame).init(alloc, 3); // FRAMES IN FLIGHT
var flights = try au.Flights.init(alloc, 3); // FRAMES IN FLIGHT
defer flights.deinit();
const ctx = im.c.igCreateContext(null) orelse return error.igCreateContextFailed;
@@ -328,8 +201,8 @@ pub fn main() !void {
.dst_array_element = 0,
.descriptor_type = .uniform_buffer,
.descriptor_count = 1,
.p_image_info = &[0]vk.DescriptorImageInfo{},
.p_texel_buffer_view = &[0]vk.BufferView{},
.p_image_info = undefined,
.p_texel_buffer_view = undefined,
.p_buffer_info = &.{
vk.DescriptorBufferInfo{
.buffer = uniform_buffer,
@@ -381,25 +254,26 @@ pub fn main() !void {
flight.acquire,
.null_handle,
);
const image = sc.getImage(acq.image_index);
const view = sc.getView(acq.image_index);
var cmd = au.CommandBufferProxy.init(flight.cmd, au.D.wrapper);
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
try flight.ctx.record_render(
const render_area: vk.Rect2D = .{
.offset = .{ .x = 0, .y = 0 },
.extent = sc.cinfo.image_extent,
};
sc.beginRendering(cmd, render_area, acq.image_index);
record_render(
cmd,
image,
view,
vk.Rect2D{ .offset = .{ .x = 0, .y = 0 }, .extent = sc.cinfo.image_extent },
uber.pipeline,
uber.layout,
uber,
render_area,
vertex_buffer,
index_buffer,
uniform_buffer,
descriptorSet,
);
im.c.ImGui_ImplVulkan_RenderDrawData(im.c.igGetDrawData(), @ptrFromInt(@intFromEnum(cmd.handle)), null);
sc.endRendering(cmd, acq.image_index);
for (vertex_data) |*v| {
for (v.pos[0..2]) |*f| {