switch to dynamic rendering
This commit is contained in:
@@ -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 {
|
||||||
|
143
src/main.zig
143
src/main.zig
@@ -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;
|
||||||
|
Reference in New Issue
Block a user