engine: add render pass / encoder / queue management

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2023-09-10 19:03:07 -07:00 committed by Stephen Gutekanst
parent 4d2c917b66
commit b83b71e2b2

View file

@ -9,20 +9,34 @@ const allocator = gpa.allocator();
/// The main Mach engine ECS module.
pub const Engine = struct {
device: *gpu.Device,
queue: *gpu.Queue,
exit: bool,
pass: *gpu.RenderPassEncoder,
encoder: *gpu.CommandEncoder,
pub const name = .engine;
pub fn engineInit(world: *World) !void {
core.allocator = allocator;
try core.init(.{});
world.mod.engine.state.device = core.device;
world.mod.engine.state.exit = false;
const state = &world.mod.engine.state;
state.device = core.device;
state.queue = core.device.getQueue();
state.exit = false;
state.encoder = state.device.createCommandEncoder(&gpu.CommandEncoder.Descriptor{
.label = "engine.state.encoder",
});
try world.send(.init, .{});
}
pub fn engineDeinit(world: *World) !void {
pub fn engineDeinit(
world: *World,
engine: *World.Mod(.engine),
) !void {
// TODO: this triggers a device loss error, which we should handle correctly
// engine.state.device.release();
engine.state.queue.release();
try world.send(.deinit, .{});
core.deinit();
world.deinit();
@ -33,6 +47,48 @@ pub const Engine = struct {
try world.send(.exit, .{});
world.mod.engine.state.exit = true;
}
pub fn engineBeginPass(
engine: *World.Mod(.engine),
clear_color: gpu.Color,
) !void {
const back_buffer_view = core.swap_chain.getCurrentTextureView().?;
defer back_buffer_view.release();
// TODO: expose options
const color_attachment = gpu.RenderPassColorAttachment{
.view = back_buffer_view,
.clear_value = clear_color,
.load_op = .clear,
.store_op = .store,
};
const pass_info = gpu.RenderPassDescriptor.init(.{
.color_attachments = &.{color_attachment},
});
engine.state.pass = engine.state.encoder.beginRenderPass(&pass_info);
}
pub fn engineEndPass(
engine: *World.Mod(.engine),
) !void {
// End this pass
engine.state.pass.end();
engine.state.pass.release();
var command = engine.state.encoder.finish(null);
defer command.release();
engine.state.queue.submit(&[_]*gpu.CommandBuffer{command});
// Prepare for next pass
engine.state.encoder = engine.state.device.createCommandEncoder(&gpu.CommandEncoder.Descriptor{
.label = "engine.state.encoder",
});
}
pub fn enginePresent() !void {
core.swap_chain.present();
}
};
pub const App = struct {