forked from vv/efemra
1
0
Fork 0
efemra/src/rendering/vulkan/Renderer.zig

175 lines
4.3 KiB
Zig

const std = @import("std");
const Base = @import("Base.zig");
const Instance = @import("instance.zig").Instance;
const Display = @import("display.zig").Display;
const Window = @import("display.zig").Window;
const Device = @import("device.zig").Device;
const memory = @import("memory.zig");
const framebuffer = @import("framebuffer.zig");
const Swapchain = @import("swapchain.zig").Swapchain;
const Context = @import("Context.zig");
const MainPass = @import("MainPass.zig");
const Command = @import("Command.zig");
const Targets = @import("Targets.zig");
const Bindings = @import("Bindings.zig");
const meshes = @import("meshes.zig");
const ui = @import("../../ui/ui.zig");
instance: Instance,
window: Window,
device: Device,
swapchain: Swapchain,
// sampler: Sampler, TODO
// tex_table: TexTable, TODO
// im_sys: ImSys, TODO
const Self = @This();
pub fn init() !Self {
errdefer {
std.debug.print("failed to init VulkanRenderer\n", .{});
}
try Base.init();
const instance = try Instance.init();
errdefer instance.deinit();
var window = try windowInit(&instance);
errdefer window.deinit(&instance);
try ui.init(&window.handle);
const device = try Device.init(&instance, &window);
errdefer device.deinit();
try memory.init(&instance, &device);
errdefer memory.deinit(&device);
try framebuffer.init();
errdefer framebuffer.deinit(&device);
var swapchain = try Swapchain.init(&instance, &window, &device, null);
errdefer swapchain.deinit(&device);
Context.init();
errdefer Context.deinit();
// try self.sampler.init();
// try self.texTable.init();
try Bindings.init(&device);
try Targets.init(&device, &swapchain);
try meshes.init();
// try self.imSys.init();
try MainPass.init(&device, &swapchain);
return Self{
.instance = instance,
.window = window,
.device = device,
.swapchain = swapchain,
};
}
pub fn update(self: *Self) !void {
// TODO profiling
// base system update
{
_ = try self.swapchain.acquireSync(&self.device);
_ = try self.swapchain.acquireImage(&self.device);
try memory.update(&self.device);
}
// system update
{
// TODO: sampler/meshsys/imsys update
}
// setup phase
{
try MainPass.setup(&self.device, &self.swapchain);
// TODO textable update
try Command.flush(&self.device);
Bindings.update(&self.device, &self.swapchain);
}
// execute phase
try MainPass.execute(&self.device, &self.swapchain);
// present phase
// currently only graphics queue
try self.swapchain.submit(try Command.Buffer.get(.graphics, &self.device), &self.device);
// background work
{
// TODO upload lightmaps, imsys clear
try Command.flush(&self.device);
}
}
pub fn deinit(self: Self) void {
self.device.waitIdle() catch {};
// TODO: delete lightmap pack
MainPass.deinit(&self.device);
// self.imSys.deinit();
meshes.deinit();
Targets.deinit(&self.device);
Bindings.deinit(&self.device);
// self.texTable.deinit();
// self.sampler.deinit();
// clear other passes here.
memory.finalize(&self.device) catch {};
Context.deinit();
self.swapchain.deinit(&self.device);
framebuffer.deinit(&self.device);
self.window.deinit(&self.instance);
memory.deinit(&self.device);
self.device.deinit();
self.instance.deinit();
}
fn windowInit(instance: *const Instance) !Window {
// TODO: convar cv_fullscreen
const fullscreen = false;
const extents = try Display.getSize(fullscreen);
var window = try Window.init(instance, "efemra", extents.width, extents.height, fullscreen);
return window;
}
fn windowUpdate(self: Self) !void {
if (!self.window.isOpen()) {
return error.WindowNotOpen;
}
// TODO: convar fullscreen change check
if (0) {
self.device.waitIdle();
// TODO: UI pass del
self.swapchain.deinit(&self.device);
self.window.deinit();
self.window.init();
self.swapchain.init(null);
// TODO: UI pass new
}
if (self.window.updateSize()) {
try self.swapchain.recreate();
// TODO set r_width/r_height convar
}
if (!self.swapchain.handle) {
return error.NoSwapchainHandle;
}
self.targets.maybeRecreate();
}