From 2f70c43c00abddaa4cf64bc7e7903b71f308ef98 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Wed, 27 Mar 2024 14:05:44 -0400 Subject: [PATCH] switch to dynamic rendering --- src/graphics_context.zig | 11 +-- src/main.zig | 151 ++++++++++++--------------------------- 2 files changed, 51 insertions(+), 111 deletions(-) diff --git a/src/graphics_context.zig b/src/graphics_context.zig index 2c2cd30..a77e00f 100644 --- a/src/graphics_context.zig +++ b/src/graphics_context.zig @@ -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 { diff --git a/src/main.zig b/src/main.zig index cce1c18..ac48b66 100644 --- a/src/main.zig +++ b/src/main.zig @@ -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;