Switch to bgra, handle swapchain out of date error

This commit is contained in:
sergeypdev 2025-01-01 23:45:01 +04:00
parent f4b4dd653a
commit 54b9caab78
5 changed files with 33 additions and 9 deletions

View File

@ -100,7 +100,7 @@ const AssetWatcher = struct {
}
pub fn startWatching(self: *AssetWatcher) void {
self.thread = sdl.SDL_CreateThread(watcherThread, "AssetManager Watcher", @ptrCast(self), null, null) orelse {
self.thread = sdl.SDL_CreateThread(watcherThread, "AssetManager Watcher", @ptrCast(self)) orelse {
std.log.err("SDL Error: {s}\n", .{sdl.SDL_GetError()});
@panic("SDL_CreateThread");
};
@ -428,7 +428,7 @@ fn loadShaderProgramErr(self: *AssetManager, id: AssetId) !LoadedShaderProgram {
.color_attachment_count = 1,
.p_color_attachment_formats = &[_]vk.Format{switch (graphics_pipeline.color_attachment_type) {
.main => .r16g16b16a16_sfloat,
.swapchain => .r8g8b8a8_unorm,
.swapchain => .b8g8r8a8_unorm,
}},
.depth_attachment_format = if (graphics_pipeline.depth_stencil_attachment) .d24_unorm_s8_uint else .undefined,
.stencil_attachment_format = if (graphics_pipeline.depth_stencil_attachment) .d24_unorm_s8_uint else .undefined,

View File

@ -532,7 +532,7 @@ fn maybeResizeSwapchain(self: *GraphicsContext) !void {
self.swapchain = try self.device.createSwapchainKHR(&.{
.surface = self.surface,
.min_image_count = std.math.clamp(3, surface_caps.min_image_count, if (surface_caps.max_image_count == 0) std.math.maxInt(u32) else surface_caps.max_image_count),
.image_format = .r8g8b8a8_unorm, // tonemapping handles srgb
.image_format = .b8g8r8a8_unorm, // tonemapping handles srgb
.image_color_space = .srgb_nonlinear_khr,
.image_extent = self.swapchain_extent,
.image_array_layers = 1,

View File

@ -5,6 +5,7 @@ const DescriptorManager = @import("DescriptorManager.zig");
const vk = @import("vk");
const a = @import("asset_manifest");
const za = @import("zalgebra");
const tracy = @import("tracy");
const Vec3 = za.Vec3;
const Vec4 = za.Vec4;
const Mat4 = za.Mat4;
@ -469,7 +470,15 @@ pub fn finish(self: *Render2) !void {
try frame.waitForDrawAndReset(self.gc.device, self.descriptorman);
const swapchain_image_index: u32 = try gc.acquireSwapchainImage(frame.acquire_swapchain_image, .null_handle);
const swapchain_image_index: u32 = gc.acquireSwapchainImage(frame.acquire_swapchain_image, .null_handle) catch |err| switch (err) {
error.OutOfDateKHR => {
// whoops, skip this frame
return;
},
else => {
return err;
},
};
self.vulkan_frame_arena.startFrame(self.frame_state.frame);
@ -505,7 +514,7 @@ pub fn finish(self: *Render2) !void {
const color_image: *GraphicsContext.Image = &main_render_target.color;
const depth_image: *GraphicsContext.Image = &main_render_target.depth;
var swapchain_image = GraphicsContext.Image{ .handle = gc.swapchain_images[swapchain_image_index], .mip_count = 1, .layer_count = 1, .format = .r8g8b8a8_unorm };
var swapchain_image = GraphicsContext.Image{ .handle = gc.swapchain_images[swapchain_image_index], .mip_count = 1, .layer_count = 1, .format = .b8g8r8a8_unorm };
// NOTE: I don't think this is actually needed, but validation is screaming at me
swapchain_image.sync_state.sync_state.last_writer.stage_mask = .{ .color_attachment_output_bit = true };
const swapchain_image_view = try swapchain_image.createView(gc.device, .{ .color_bit = true });
@ -760,13 +769,18 @@ pub fn finish(self: *Render2) !void {
frame.draw_submitted = true;
_ = try gc.device.queuePresentKHR(gc.queues.graphics.handle, &.{
_ = gc.device.queuePresentKHR(gc.queues.graphics.handle, &.{
.swapchain_count = 1,
.wait_semaphore_count = 1,
.p_wait_semaphores = &.{frame.draw_sema},
.p_swapchains = &.{gc.swapchain},
.p_image_indices = &.{swapchain_image_index},
});
}) catch |err| switch (err) {
error.OutOfDateKHR => {
// whoops swapchain is lost
},
else => return err,
};
self.frame_state.frame = (self.frame_state.frame + 1) % MAX_FRAME_LAG;
}

View File

@ -2,6 +2,7 @@ const std = @import("std");
const vk = @import("vk");
const GraphicsContext = @import("GraphicsContext.zig");
const DescriptorManager = @import("DescriptorManager.zig");
const tracy = @import("tracy");
pub const MAX_FRAME_LAG = 3;
@ -124,10 +125,19 @@ pub const FrameData = struct {
}
pub fn waitForDrawAndReset(self: *FrameData, device: GraphicsContext.Device, descriptorman: *DescriptorManager) !void {
const zone = tracy.initZone(@src(), .{ .name = "FrameData.waitForDrawAndReset" });
defer zone.deinit();
if (!self.draw_submitted) return;
self.draw_submitted = false;
{
const zone2 = tracy.initZone(@src(), .{ .name = "waitForFences" });
defer zone2.deinit();
_ = try device.waitForFences(1, &.{self.end_draw_fence}, vk.TRUE, std.math.maxInt(u64));
}
try self.destroy_queue.destroy(device, descriptorman);