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 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(.{
.createInstance = true,
@@ -53,12 +56,8 @@ const DeviceDispatch = vk.DeviceWrapper(.{
.destroyShaderModule = true,
.createPipelineLayout = true,
.destroyPipelineLayout = true,
.createRenderPass = true,
.destroyRenderPass = true,
.createGraphicsPipelines = true,
.destroyPipeline = true,
.createFramebuffer = true,
.destroyFramebuffer = true,
.beginCommandBuffer = true,
.endCommandBuffer = true,
.allocateMemory = true,
@@ -79,6 +78,8 @@ const DeviceDispatch = vk.DeviceWrapper(.{
.cmdBindVertexBuffers = true,
.cmdBindIndexBuffer = true,
.cmdCopyBuffer = true,
.cmdBeginRenderingKHR = true,
.cmdEndRenderingKHR = true,
});
pub const GraphicsContext = struct {

View File

@@ -35,14 +35,10 @@ const Vertex = extern struct {
};
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 = .{ 0, 1, 0 } },
.{ .pos = .{ 0.5, -0.5 }, .color = .{ 0, 0, 1 } },
.{ .pos = .{ 0.5, 0.5 }, .color = .{ 1, 1, 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, 0, 1 } },
.{ .pos = .{ 0.5, 0.5 }, .color = .{ 1, 1, 0 } },
};
const Index = u16;
@@ -91,15 +87,9 @@ pub fn main() !void {
}, null);
defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null);
const render_pass = try createRenderPass(&gc, swapchain);
defer gc.vkd.destroyRenderPass(gc.dev, render_pass, null);
const pipeline = try createPipeline(&gc, pipeline_layout, render_pass);
const pipeline = try createPipeline(&gc, pipeline_layout, swapchain);
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, &.{
.queue_family_index = gc.graphics_queue.family,
}, null);
@@ -137,10 +127,8 @@ pub fn main() !void {
allocator,
vertex_buffer,
index_buffer,
swapchain.extent,
render_pass,
pipeline,
framebuffers,
swapchain,
);
defer destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
@@ -167,9 +155,6 @@ pub fn main() !void {
extent.height = @intCast(h);
try swapchain.recreate(extent);
destroyFramebuffers(&gc, allocator, framebuffers);
framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain);
destroyCommandBuffers(&gc, pool, allocator, cmdbufs);
cmdbufs = try createCommandBuffers(
&gc,
@@ -177,10 +162,8 @@ pub fn main() !void {
allocator,
vertex_buffer,
index_buffer,
swapchain.extent,
render_pass,
pipeline,
framebuffers,
swapchain,
);
}
@@ -263,12 +246,12 @@ fn createCommandBuffers(
allocator: Allocator,
vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer,
extent: vk.Extent2D,
render_pass: vk.RenderPass,
pipeline: vk.Pipeline,
framebuffers: []vk.Framebuffer,
swapchain: Swapchain,
) ![]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);
try gc.vkd.allocateCommandBuffers(gc.dev, &.{
@@ -296,34 +279,43 @@ fn createCommandBuffers(
.extent = extent,
};
for (cmdbufs, framebuffers) |cmdbuf, framebuffer| {
for (cmdbufs, swapchain.swap_images) |cmdbuf, image| {
try gc.vkd.beginCommandBuffer(cmdbuf, &.{});
gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
// This needs to be a separate definition - see https://github.com/ziglang/zig/issues/7627.
const render_area = vk.Rect2D{
.offset = .{ .x = 0, .y = 0 },
.extent = extent,
const color_attachments = [_]vk.RenderingAttachmentInfoKHR{
.{
.image_view = image.view,
.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, &.{
.render_pass = render_pass,
.framebuffer = framebuffer,
.render_area = render_area,
.clear_value_count = 1,
.p_clear_values = @as([*]const vk.ClearValue, @ptrCast(&clear)),
}, .@"inline");
const render_info = vk.RenderingInfoKHR{
.render_area = scissor, // since we always do full-frame changes
.layer_count = 1,
.view_mask = 0,
.color_attachment_count = color_attachments.len,
.p_color_attachments = &color_attachments,
};
gc.vkd.cmdBeginRenderingKHR(cmdbuf, &render_info);
gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline);
const offset = [_]vk.DeviceSize{0};
gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast(&vertex_buffer), &offset);
gc.vkd.cmdBindIndexBuffer(cmdbuf, index_buffer, 0, .uint16);
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);
}
@@ -335,69 +327,7 @@ fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, alloc
allocator.free(cmdbufs);
}
fn createFramebuffers(gc: *const GraphicsContext, allocator: Allocator, render_pass: vk.RenderPass, swapchain: Swapchain) ![]vk.Framebuffer {
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 {
fn createPipeline(gc: *const GraphicsContext, layout: vk.PipelineLayout, swapchain: Swapchain) !vk.Pipeline {
const vert = try gc.vkd.createShaderModule(gc.dev, &.{
.code_size = shaders.triangle_vert.len,
.p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)),
@@ -489,6 +419,14 @@ fn createPipeline(
.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{
.flags = .{},
.stage_count = 2,
@@ -503,10 +441,11 @@ fn createPipeline(
.p_color_blend_state = &pcbsci,
.p_dynamic_state = &pdsci,
.layout = layout,
.render_pass = render_pass,
.render_pass = .null_handle,
.subpass = 0,
.base_pipeline_handle = .null_handle,
.base_pipeline_index = -1,
.p_next = &prci,
};
var pipeline: vk.Pipeline = undefined;