engine: add render pass / encoder / queue management
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
4d2c917b66
commit
b83b71e2b2
1 changed files with 59 additions and 3 deletions
|
|
@ -9,20 +9,34 @@ const allocator = gpa.allocator();
|
||||||
/// The main Mach engine ECS module.
|
/// The main Mach engine ECS module.
|
||||||
pub const Engine = struct {
|
pub const Engine = struct {
|
||||||
device: *gpu.Device,
|
device: *gpu.Device,
|
||||||
|
queue: *gpu.Queue,
|
||||||
exit: bool,
|
exit: bool,
|
||||||
|
pass: *gpu.RenderPassEncoder,
|
||||||
|
encoder: *gpu.CommandEncoder,
|
||||||
|
|
||||||
pub const name = .engine;
|
pub const name = .engine;
|
||||||
|
|
||||||
pub fn engineInit(world: *World) !void {
|
pub fn engineInit(world: *World) !void {
|
||||||
core.allocator = allocator;
|
core.allocator = allocator;
|
||||||
try core.init(.{});
|
try core.init(.{});
|
||||||
world.mod.engine.state.device = core.device;
|
const state = &world.mod.engine.state;
|
||||||
world.mod.engine.state.exit = false;
|
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, .{});
|
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, .{});
|
try world.send(.deinit, .{});
|
||||||
core.deinit();
|
core.deinit();
|
||||||
world.deinit();
|
world.deinit();
|
||||||
|
|
@ -33,6 +47,48 @@ pub const Engine = struct {
|
||||||
try world.send(.exit, .{});
|
try world.send(.exit, .{});
|
||||||
world.mod.engine.state.exit = true;
|
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 {
|
pub const App = struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue