incremental - dropping swapchain
This commit is contained in:
42
src/main.zig
42
src/main.zig
@@ -246,6 +246,26 @@ fn create_device(
|
||||
return error.NoSuitableDevice;
|
||||
}
|
||||
|
||||
fn find_surface_format(
|
||||
pdev: vk.PhysicalDevice,
|
||||
surface: vk.SurfaceKHR,
|
||||
preferred: vk.SurfaceFormatKHR,
|
||||
vki: gfx.InstanceDispatch,
|
||||
) !vk.SurfaceFormatKHR {
|
||||
var formats_buf: [64]vk.SurfaceFormatKHR = undefined;
|
||||
var formats_count: u32 = 64;
|
||||
_ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats_buf);
|
||||
const formats = formats_buf[0..formats_count];
|
||||
|
||||
for (formats) |format| {
|
||||
if (std.meta.eql(format, preferred)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return formats[0];
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
@@ -278,6 +298,12 @@ pub fn main() !void {
|
||||
try create_device(ally, instance, surface, vki);
|
||||
defer vkd.destroyDevice(dev, null);
|
||||
|
||||
const preferred_format: vk.SurfaceFormatKHR = .{
|
||||
.format = .b8g8r8a8_srgb,
|
||||
.color_space = .srgb_nonlinear_khr,
|
||||
};
|
||||
const format = try find_surface_format(pdev, surface, preferred_format, vki);
|
||||
|
||||
const queue = vkd.getDeviceQueue(dev, family, 0);
|
||||
|
||||
const gc: Context = .{
|
||||
@@ -290,7 +316,7 @@ pub fn main() !void {
|
||||
.family = family,
|
||||
};
|
||||
|
||||
var swapchain = try Swapchain.init(&gc, ally, extent);
|
||||
var swapchain = try Swapchain.init(&gc, ally, extent, format);
|
||||
defer swapchain.deinit();
|
||||
|
||||
const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{
|
||||
@@ -302,7 +328,7 @@ pub fn main() !void {
|
||||
}, null);
|
||||
defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null);
|
||||
|
||||
const pipeline = try createPipeline(&gc, pipeline_layout, swapchain);
|
||||
const pipeline = try createPipeline(&gc, pipeline_layout, format);
|
||||
defer gc.vkd.destroyPipeline(gc.dev, pipeline, null);
|
||||
|
||||
const pool = try gc.vkd.createCommandPool(gc.dev, &.{
|
||||
@@ -348,7 +374,6 @@ pub fn main() !void {
|
||||
defer destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
|
||||
while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) {
|
||||
std.log.debug("new frame", .{ });
|
||||
var w: c_int = undefined;
|
||||
var h: c_int = undefined;
|
||||
c.glfwGetFramebufferSize(window, &w, &h);
|
||||
@@ -366,18 +391,13 @@ pub fn main() !void {
|
||||
else => |narrow| return narrow,
|
||||
};
|
||||
|
||||
std.log.debug("state: {}", .{state});
|
||||
|
||||
if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) {
|
||||
extent.width = @intCast(w);
|
||||
extent.height = @intCast(h);
|
||||
std.log.debug("about to recreate", .{ });
|
||||
try swapchain.recreate(extent);
|
||||
try swapchain.recreate(extent, format);
|
||||
|
||||
std.log.debug("about to destroy command buffers", .{ });
|
||||
destroyCommandBuffers(&gc, pool, ally, cmdbufs);
|
||||
|
||||
std.log.debug("about to create command buffers", .{ });
|
||||
cmdbufs = try createCommandBuffers(
|
||||
&gc,
|
||||
pool,
|
||||
@@ -607,7 +627,7 @@ fn destroyCommandBuffers(gc: *const Context, pool: vk.CommandPool, allocator: Al
|
||||
allocator.free(cmdbufs);
|
||||
}
|
||||
|
||||
fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, swapchain: Swapchain) !vk.Pipeline {
|
||||
fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR) !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)),
|
||||
@@ -701,7 +721,7 @@ fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, swapchain: Swap
|
||||
|
||||
const prci = vk.PipelineRenderingCreateInfoKHR{
|
||||
.color_attachment_count = 1,
|
||||
.p_color_attachment_formats = @ptrCast(&swapchain.surface_format.format),
|
||||
.p_color_attachment_formats = @ptrCast(&format),
|
||||
.depth_attachment_format = .undefined,
|
||||
.stencil_attachment_format = .undefined,
|
||||
.view_mask = 0,
|
||||
|
@@ -52,7 +52,6 @@ pub const Swapchain = struct {
|
||||
gc: *const Context,
|
||||
allocator: Allocator,
|
||||
|
||||
surface_format: vk.SurfaceFormatKHR,
|
||||
present_mode: vk.PresentModeKHR,
|
||||
extent: vk.Extent2D,
|
||||
handle: vk.SwapchainKHR,
|
||||
@@ -61,18 +60,28 @@ pub const Swapchain = struct {
|
||||
image_index: u32,
|
||||
next_image_acquired: vk.Semaphore,
|
||||
|
||||
pub fn init(gc: *const Context, allocator: Allocator, extent: vk.Extent2D) !Swapchain {
|
||||
return try initRecycle(gc, allocator, extent, .null_handle);
|
||||
pub fn init(
|
||||
gc: *const Context,
|
||||
allocator: Allocator,
|
||||
extent: vk.Extent2D,
|
||||
format: vk.SurfaceFormatKHR,
|
||||
) !Swapchain {
|
||||
return try initRecycle(gc, allocator, extent, format, .null_handle);
|
||||
}
|
||||
|
||||
pub fn initRecycle(gc: *const Context, allocator: Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain {
|
||||
pub fn initRecycle(
|
||||
gc: *const Context,
|
||||
allocator: Allocator,
|
||||
extent: vk.Extent2D,
|
||||
format: vk.SurfaceFormatKHR,
|
||||
old_handle: vk.SwapchainKHR,
|
||||
) !Swapchain {
|
||||
const caps = try gc.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface);
|
||||
const actual_extent = findActualExtent(caps, extent);
|
||||
if (actual_extent.width == 0 or actual_extent.height == 0) {
|
||||
return error.InvalidSurfaceDimensions;
|
||||
}
|
||||
|
||||
const surface_format = try findSurfaceFormat(gc, allocator);
|
||||
const present_mode = try findPresentMode(gc, allocator);
|
||||
|
||||
var image_count = caps.min_image_count + 1;
|
||||
@@ -83,8 +92,8 @@ pub const Swapchain = struct {
|
||||
const handle = try gc.vkd.createSwapchainKHR(gc.dev, &.{
|
||||
.surface = gc.surface,
|
||||
.min_image_count = image_count,
|
||||
.image_format = surface_format.format,
|
||||
.image_color_space = surface_format.color_space,
|
||||
.image_format = format.format,
|
||||
.image_color_space = format.color_space,
|
||||
.image_extent = actual_extent,
|
||||
.image_array_layers = 1,
|
||||
.image_usage = .{ .color_attachment_bit = true, .transfer_dst_bit = true },
|
||||
@@ -102,7 +111,7 @@ pub const Swapchain = struct {
|
||||
gc.vkd.destroySwapchainKHR(gc.dev, old_handle, null);
|
||||
}
|
||||
|
||||
const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator);
|
||||
const swap_images = try initSwapchainImages(gc, handle, format.format, allocator);
|
||||
errdefer {
|
||||
for (swap_images) |si| si.deinit(gc);
|
||||
allocator.free(swap_images);
|
||||
@@ -129,7 +138,6 @@ pub const Swapchain = struct {
|
||||
return Swapchain{
|
||||
.gc = gc,
|
||||
.allocator = allocator,
|
||||
.surface_format = surface_format,
|
||||
.present_mode = present_mode,
|
||||
.extent = actual_extent,
|
||||
.handle = handle,
|
||||
@@ -154,12 +162,16 @@ pub const Swapchain = struct {
|
||||
self.gc.vkd.destroySwapchainKHR(self.gc.dev, self.handle, null);
|
||||
}
|
||||
|
||||
pub fn recreate(self: *Swapchain, new_extent: vk.Extent2D) !void {
|
||||
pub fn recreate(
|
||||
self: *Swapchain,
|
||||
new_extent: vk.Extent2D,
|
||||
format: vk.SurfaceFormatKHR,
|
||||
) !void {
|
||||
const gc = self.gc;
|
||||
const allocator = self.allocator;
|
||||
const old_handle = self.handle;
|
||||
self.deinitExceptSwapchain();
|
||||
self.* = try initRecycle(gc, allocator, new_extent, old_handle);
|
||||
self.* = try initRecycle(gc, allocator, new_extent, format, old_handle);
|
||||
}
|
||||
|
||||
pub fn currentImage(self: Swapchain) vk.Image {
|
||||
@@ -318,27 +330,6 @@ fn initSwapchainImages(gc: *const Context, swapchain: vk.SwapchainKHR, format: v
|
||||
return swap_images;
|
||||
}
|
||||
|
||||
fn findSurfaceFormat(gc: *const Context, allocator: Allocator) !vk.SurfaceFormatKHR {
|
||||
const preferred = vk.SurfaceFormatKHR{
|
||||
.format = .b8g8r8a8_srgb,
|
||||
.color_space = .srgb_nonlinear_khr,
|
||||
};
|
||||
|
||||
var count: u32 = undefined;
|
||||
_ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, null);
|
||||
const surface_formats = try allocator.alloc(vk.SurfaceFormatKHR, count);
|
||||
defer allocator.free(surface_formats);
|
||||
_ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, surface_formats.ptr);
|
||||
|
||||
for (surface_formats) |sfmt| {
|
||||
if (std.meta.eql(sfmt, preferred)) {
|
||||
return preferred;
|
||||
}
|
||||
}
|
||||
|
||||
return surface_formats[0]; // There must always be at least one supported surface format
|
||||
}
|
||||
|
||||
fn findPresentMode(gc: *const Context, allocator: Allocator) !vk.PresentModeKHR {
|
||||
var count: u32 = undefined;
|
||||
_ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);
|
||||
|
Reference in New Issue
Block a user