switch to dynamic rendering

This commit is contained in:
David Allemang
2024-03-27 14:05:44 -04:00
parent 7bcc460d9b
commit 2f70c43c00
2 changed files with 51 additions and 111 deletions

View File

@@ -3,7 +3,10 @@ const vk = @import("vk");
const c = @import("c.zig"); const c = @import("c.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const required_device_extensions = [_][*:0]const u8{vk.extension_info.khr_swapchain.name}; const required_device_extensions = [_][*:0]const u8{
vk.extension_info.khr_swapchain.name,
vk.extension_info.khr_dynamic_rendering.name,
};
const BaseDispatch = vk.BaseWrapper(.{ const BaseDispatch = vk.BaseWrapper(.{
.createInstance = true, .createInstance = true,
@@ -53,12 +56,8 @@ const DeviceDispatch = vk.DeviceWrapper(.{
.destroyShaderModule = true, .destroyShaderModule = true,
.createPipelineLayout = true, .createPipelineLayout = true,
.destroyPipelineLayout = true, .destroyPipelineLayout = true,
.createRenderPass = true,
.destroyRenderPass = true,
.createGraphicsPipelines = true, .createGraphicsPipelines = true,
.destroyPipeline = true, .destroyPipeline = true,
.createFramebuffer = true,
.destroyFramebuffer = true,
.beginCommandBuffer = true, .beginCommandBuffer = true,
.endCommandBuffer = true, .endCommandBuffer = true,
.allocateMemory = true, .allocateMemory = true,
@@ -79,6 +78,8 @@ const DeviceDispatch = vk.DeviceWrapper(.{
.cmdBindVertexBuffers = true, .cmdBindVertexBuffers = true,
.cmdBindIndexBuffer = true, .cmdBindIndexBuffer = true,
.cmdCopyBuffer = true, .cmdCopyBuffer = true,
.cmdBeginRenderingKHR = true,
.cmdEndRenderingKHR = true,
}); });
pub const GraphicsContext = struct { pub const GraphicsContext = struct {

View File

@@ -35,10 +35,6 @@ const Vertex = extern struct {
}; };
const vertices = [_]Vertex{ const vertices = [_]Vertex{
// .{ .pos = .{ -0.5, -0.5 }, .color = .{ 1, 0, 0 } },
// .{ .pos = .{ 0.5, 0.5 }, .color = .{ 0, 1, 0 } },
// .{ .pos = .{ -0.5, 0.5 }, .color = .{ 0, 0, 1 } },
.{ .pos = .{ -0.5, -0.5 }, .color = .{ 1, 0, 0 } }, .{ .pos = .{ -0.5, -0.5 }, .color = .{ 1, 0, 0 } },
.{ .pos = .{ -0.5, 0.5 }, .color = .{ 0, 1, 0 } }, .{ .pos = .{ -0.5, 0.5 }, .color = .{ 0, 1, 0 } },
.{ .pos = .{ 0.5, -0.5 }, .color = .{ 0, 0, 1 } }, .{ .pos = .{ 0.5, -0.5 }, .color = .{ 0, 0, 1 } },
@@ -91,15 +87,9 @@ pub fn main() !void {
}, null); }, null);
defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null); defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null);
const render_pass = try createRenderPass(&gc, swapchain); const pipeline = try createPipeline(&gc, pipeline_layout, swapchain);
defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null);
const pipeline = try createPipeline(&gc, pipeline_layout, render_pass);
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null); defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
defer destroyFramebuffers(&gc, allocator, framebuffers);
const pool = try gc.vkd.createCommandPool(gc.dev, &.{ const pool = try gc.vkd.createCommandPool(gc.dev, &.{
.queue_family_index = gc.graphics_queue.family, .queue_family_index = gc.graphics_queue.family,
}, null); }, null);
@@ -137,10 +127,8 @@ pub fn main() !void {
allocator, allocator,
vertex_buffer, vertex_buffer,
index_buffer, index_buffer,
swapchain.extent,
render_pass,
pipeline, pipeline,
framebuffers, swapchain,
); );
defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs); defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
@@ -167,9 +155,6 @@ pub fn main() !void {
extent.height = @intCast(h); extent.height = @intCast(h);
try swapchain.recreate(extent); try swapchain.recreate(extent);
destroyFramebuffers(&gc, allocator, framebuffers);
framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
destroyCommandBuffers(&gc, pool, allocator, cmdbufs); destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
cmdbufs = try createCommandBuffers( cmdbufs = try createCommandBuffers(
&gc, &gc,
@@ -177,10 +162,8 @@ pub fn main() !void {
allocator, allocator,
vertex_buffer, vertex_buffer,
index_buffer, index_buffer,
swapchain.extent,
render_pass,
pipeline, pipeline,
framebuffers, swapchain,
); );
} }
@@ -263,12 +246,12 @@ fn createCommandBuffers(
allocator: Allocator, allocator: Allocator,
vertex_buffer: vk.Buffer, vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer, index_buffer: vk.Buffer,
extent: vk.Extent2D,
render_pass: vk.RenderPass,
pipeline: vk.Pipeline, pipeline: vk.Pipeline,
framebuffers: []vk.Framebuffer, swapchain: Swapchain,
) ![]vk.CommandBuffer { ) ![]vk.CommandBuffer {
const cmdbufs = try allocator.alloc(vk.CommandBuffer, framebuffers.len); const extent = swapchain.extent;
const cmdbufs = try allocator.alloc(vk.CommandBuffer, swapchain.swap_images.len);
errdefer allocator.free(cmdbufs); errdefer allocator.free(cmdbufs);
try gc.vkd.allocateCommandBuffers(gc.dev, &.{ try gc.vkd.allocateCommandBuffers(gc.dev, &.{
@@ -296,34 +279,43 @@ fn createCommandBuffers(
.extent = extent, .extent = extent,
}; };
for (cmdbufs, framebuffers) |cmdbuf, framebuffer| { for (cmdbufs, swapchain.swap_images) |cmdbuf, image| {
try gc.vkd.beginCommandBuffer(cmdbuf, &.{}); try gc.vkd.beginCommandBuffer(cmdbuf, &.{});
gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport)); gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor)); gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
// This needs to be a separate definition - see https://github.com/ziglang/zig/issues/7627. const color_attachments = [_]vk.RenderingAttachmentInfoKHR{
const render_area = vk.Rect2D{ .{
.offset = .{ .x = 0, .y = 0 }, .image_view = image.view,
.extent = extent, .image_layout = .present_src_khr,
.resolve_mode = .{},
.resolve_image_view = .null_handle,
.resolve_image_layout = .undefined,
.load_op = .clear,
.store_op = .store,
.clear_value = clear,
},
}; };
gc.vkd.cmdBeginRenderPass(cmdbuf, &.{ const render_info = vk.RenderingInfoKHR{
.render_pass = render_pass, .render_area = scissor, // since we always do full-frame changes
.framebuffer = framebuffer, .layer_count = 1,
.render_area = render_area, .view_mask = 0,
.clear_value_count = 1, .color_attachment_count = color_attachments.len,
.p_clear_values = @as([*]const vk.ClearValue, @ptrCast(&clear)), .p_color_attachments = &color_attachments,
}, .@"inline"); };
gc.vkd.cmdBeginRenderingKHR(cmdbuf, &render_info);
gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline); gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
const offset = [_]vk.DeviceSize{0}; const offset = [_]vk.DeviceSize{0};
gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&vertex_buffer), &offset); gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&vertex_buffer), &offset);
gc.vkd.cmdBindIndexBuffer(cmdbuf, index_buffer, 0, .uint16); gc.vkd.cmdBindIndexBuffer(cmdbuf, index_buffer, 0, .uint16);
gc.vkd.cmdDrawIndexed(cmdbuf, indices.len, 1, 0, 0, 0); gc.vkd.cmdDrawIndexed(cmdbuf, indices.len, 1, 0, 0, 0);
// gc.vkd.cmdDraw(cmdbuf, vertices.len, 1, 0, 0);
gc.vkd.cmdEndRenderPass(cmdbuf); gc.vkd.cmdEndRenderingKHR(cmdbuf);
try gc.vkd.endCommandBuffer(cmdbuf); try gc.vkd.endCommandBuffer(cmdbuf);
} }
@@ -335,69 +327,7 @@ fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, alloc
allocator.free(cmdbufs); allocator.free(cmdbufs);
} }
fn createFramebuffers(gc: *const GraphicsContext, allocator: Allocator, render_pass: vk.RenderPass, swapchain: Swapchain) ![]vk.Framebuffer { fn createPipeline(gc: *const GraphicsContext, layout: vk.PipelineLayout, swapchain: Swapchain) !vk.Pipeline {
const framebuffers = try allocator.alloc(vk.Framebuffer, swapchain.swap_images.len);
errdefer allocator.free(framebuffers);
var i: usize = 0;
errdefer for (framebuffers[0..i]) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
for (framebuffers) |*fb| {
fb.* = try gc.vkd.createFramebuffer(gc.dev, &.{
.render_pass = render_pass,
.attachment_count = 1,
.p_attachments = @as([*]const vk.ImageView, @ptrCast(&swapchain.swap_images[i].view)),
.width = swapchain.extent.width,
.height = swapchain.extent.height,
.layers = 1,
}, null);
i += 1;
}
return framebuffers;
}
fn destroyFramebuffers(gc: *const GraphicsContext, allocator: Allocator, framebuffers: []const vk.Framebuffer) void {
for (framebuffers) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
allocator.free(framebuffers);
}
fn createRenderPass(gc: *const GraphicsContext, swapchain: Swapchain) !vk.RenderPass {
const color_attachment = vk.AttachmentDescription{
.format = swapchain.surface_format.format,
.samples = .{ .@"1_bit" = true },
.load_op = .clear,
.store_op = .store,
.stencil_load_op = .dont_care,
.stencil_store_op = .dont_care,
.initial_layout = .undefined,
.final_layout = .present_src_khr,
};
const color_attachment_ref = vk.AttachmentReference{
.attachment = 0,
.layout = .color_attachment_optimal,
};
const subpass = vk.SubpassDescription{
.pipeline_bind_point = .graphics,
.color_attachment_count = 1,
.p_color_attachments = @ptrCast(&color_attachment_ref),
};
return try gc.vkd.createRenderPass(gc.dev, &.{
.attachment_count = 1,
.p_attachments = @as([*]const vk.AttachmentDescription, @ptrCast(&color_attachment)),
.subpass_count = 1,
.p_subpasses = @as([*]const vk.SubpassDescription, @ptrCast(&subpass)),
}, null);
}
fn createPipeline(
gc: *const GraphicsContext,
layout: vk.PipelineLayout,
render_pass: vk.RenderPass,
) !vk.Pipeline {
const vert = try gc.vkd.createShaderModule(gc.dev, &.{ const vert = try gc.vkd.createShaderModule(gc.dev, &.{
.code_size = shaders.triangle_vert.len, .code_size = shaders.triangle_vert.len,
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)), .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
@@ -489,6 +419,14 @@ fn createPipeline(
.p_dynamic_states = &dynstate, .p_dynamic_states = &dynstate,
}; };
const prci = vk.PipelineRenderingCreateInfoKHR{
.color_attachment_count = 1,
.p_color_attachment_formats = @ptrCast(&swapchain.surface_format.format),
.depth_attachment_format = .undefined,
.stencil_attachment_format = .undefined,
.view_mask = 0,
};
const gpci = vk.GraphicsPipelineCreateInfo{ const gpci = vk.GraphicsPipelineCreateInfo{
.flags = .{}, .flags = .{},
.stage_count = 2, .stage_count = 2,
@@ -503,10 +441,11 @@ fn createPipeline(
.p_color_blend_state = &pcbsci, .p_color_blend_state = &pcbsci,
.p_dynamic_state = &pdsci, .p_dynamic_state = &pdsci,
.layout = layout, .layout = layout,
.render_pass = render_pass, .render_pass = .null_handle,
.subpass = 0, .subpass = 0,
.base_pipeline_handle = .null_handle, .base_pipeline_handle = .null_handle,
.base_pipeline_index = -1, .base_pipeline_index = -1,
.p_next = &prci,
}; };
var pipeline: vk.Pipeline = undefined; var pipeline: vk.Pipeline = undefined;