commit 9c9f54c06951604f8b7821a082693fb9a2e00a8d
parent 3f164f4e03c5760ada8c0169014b5aeec9b23e09
Author: Christian Ermann <christianermann@gmail.com>
Date: Sat, 18 May 2024 14:40:42 -0400
Add render pass struct
Diffstat:
M | src/main.zig | | | 41 | ++++++++++++----------------------------- |
A | src/render_pass.zig | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 91 insertions(+), 29 deletions(-)
diff --git a/src/main.zig b/src/main.zig
@@ -3,6 +3,8 @@ const glfw = @import("mach_glfw");
const gpu = @import("mach_gpu");
const builtin = @import("builtin");
+const RenderPass = @import("render_pass.zig").RenderPass;
+const ForwardScreenPass = @import("render_pass.zig").ForwardScreenPass;
const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
const MeshRenderPipeline = @import("render_pipeline.zig").MeshRenderPipeline;
const SkyBoxRenderPipeline = @import("render_pipeline.zig").SkyBoxRenderPipeline;
@@ -240,7 +242,7 @@ pub const App = struct {
return sc.gpu_swap_chain.?;
}
- pub fn frame(app: *App, pipelines: []const RenderPipeline) !void {
+ pub fn frame(app: *App, passes: []const RenderPass) !void {
app.device.tick();
const swap_chain = app.getCurrentSwapChain();
defer swap_chain.present();
@@ -251,32 +253,8 @@ pub const App = struct {
{
const encoder = app.device.createCommandEncoder(null);
defer encoder.release();
-
- const color_attachment = gpu.RenderPassColorAttachment{
- .view = back_buffer_view,
- .resolve_target = null,
- .clear_value = gpu.Color{ .r = 1, .g = 1, .b = 1, .a = 1 },
- .load_op = .clear,
- .store_op = .store,
- };
- const render_pass_info = gpu.RenderPassDescriptor.init(.{
- .color_attachments = &.{color_attachment},
- .depth_stencil_attachment = &.{
- .view = app.depth_texture_view,
- .depth_clear_value = 1.0,
- .depth_load_op = .clear,
- .depth_store_op = .store,
- },
- });
-
- {
- const pass = encoder.beginRenderPass(&render_pass_info);
- defer pass.release();
- defer pass.end();
-
- for (pipelines) |pipeline| {
- pipeline.frame(pass);
- }
+ for (passes) |pass| {
+ pass.frame(encoder, back_buffer_view);
}
{
@@ -575,7 +553,12 @@ pub fn main() !void {
var rp = try MeshRenderPipeline.init(&app, &mesh_buffer, allocator);
var skybox = SkyBoxRenderPipeline.init(&app, cube_map);
- const pipelines = [_]RenderPipeline{ rp.pipeline(), skybox.pipeline() };
+ var fp = ForwardScreenPass.init(.{
+ .depth = app.depth_texture_view,
+ .pipelines = &.{ rp.pipeline(), skybox.pipeline() },
+ });
+
+ const passes = [_]RenderPass{fp.renderPass()};
try app.inputs.append(camera.input.userInput());
@@ -600,7 +583,7 @@ pub fn main() !void {
camera.invProj(&skybox_uniform.inv_proj);
app.queue.writeBuffer(skybox.uniform_buffer, 0, &[1]SkyBoxRenderPipeline.UniformData{skybox_uniform});
- try app.frame(&pipelines);
+ try app.frame(&passes);
}
}
diff --git a/src/render_pass.zig b/src/render_pass.zig
@@ -0,0 +1,79 @@
+const std = @import("std");
+const gpu = @import("mach_gpu");
+
+const RenderPipeline = @import("render_pipeline.zig").RenderPipeline;
+
+pub const RenderPass = struct {
+ ptr: *anyopaque,
+ frameFn: *const fn (
+ ptr: *anyopaque,
+ encoder: *gpu.CommandEncoder,
+ current_view: *gpu.TextureView,
+ ) void,
+
+ pub fn frame(
+ self: *const RenderPass,
+ encoder: *gpu.CommandEncoder,
+ current_view: *gpu.TextureView,
+ ) void {
+ return self.frameFn(self.ptr, encoder, current_view);
+ }
+};
+
+pub const ForwardScreenPass = struct {
+ depth: gpu.RenderPassDepthStencilAttachment,
+ pipelines: []const RenderPipeline,
+
+ const Self = @This();
+
+ pub const Args = struct {
+ depth: *gpu.TextureView,
+ pipelines: []const RenderPipeline,
+ };
+
+ pub fn init(args: Args) Self {
+ return .{
+ .depth = .{
+ .view = args.depth,
+ .depth_clear_value = 1.0,
+ .depth_load_op = .clear,
+ .depth_store_op = .store,
+ },
+ .pipelines = args.pipelines,
+ };
+ }
+
+ pub fn frame(
+ ptr: *anyopaque,
+ encoder: *gpu.CommandEncoder,
+ current_view: *gpu.TextureView,
+ ) void {
+ const self: *Self = @ptrCast(@alignCast(ptr));
+
+ const color_attachment = gpu.RenderPassColorAttachment{
+ .view = current_view,
+ .resolve_target = null,
+ .clear_value = gpu.Color{ .r = 1, .g = 1, .b = 1, .a = 1 },
+ .load_op = .clear,
+ .store_op = .store,
+ };
+ const descriptor = gpu.RenderPassDescriptor.init(.{
+ .color_attachments = &.{color_attachment},
+ .depth_stencil_attachment = &self.depth,
+ });
+ const pass = encoder.beginRenderPass(&descriptor);
+ defer pass.release();
+ defer pass.end();
+
+ for (self.pipelines) |pipeline| {
+ pipeline.frame(pass);
+ }
+ }
+
+ pub fn renderPass(self: *Self) RenderPass {
+ return .{
+ .ptr = self,
+ .frameFn = frame,
+ };
+ }
+};