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