From db0e08d530c901c570fff72f3d54361906a0da54 Mon Sep 17 00:00:00 2001 From: kayomn Date: Thu, 25 Jul 2024 01:24:13 +0100 Subject: [PATCH] Remove unnecessary backbuffer copy --- .vscode/launch.json | 2 +- demos/effects.zig | 2 +- src/gfx/Resources.zig | 30 -------- src/gfx/gfx.zig | 3 +- src/gfx/rendering.zig | 164 +++++++++++++++++------------------------- 5 files changed, 70 insertions(+), 131 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index bddb4ae..62345d6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "name": "Runner", "type": "gdb", "request": "launch", - "target": "${workspaceRoot}/demos/inputs.out", + "target": "${workspaceRoot}/demos/effects.out", "cwd": "${workspaceRoot}/demos/", "valuesFormatting": "prettyPrinters", "preLaunchTask": "Build All" diff --git a/demos/effects.zig b/demos/effects.zig index 5e75f2b..6412815 100644 --- a/demos/effects.zig +++ b/demos/effects.zig @@ -72,7 +72,7 @@ fn render(commands: gfx.Commands, effects: ona.Write(Effects), app: ona.Read(ona }); try commands.set_target(.{ - .texture = .backbuffer, + .texture = null, .clear_color = null, .clear_depth = null, .clear_stencil = null, diff --git a/src/gfx/Resources.zig b/src/gfx/Resources.zig index a566c65..8039883 100644 --- a/src/gfx/Resources.zig +++ b/src/gfx/Resources.zig @@ -249,7 +249,6 @@ pub const Texture = struct { access: Access, pub const Access = union (enum) { - empty, render: RenderAccess, static: StaticAccess, }; @@ -275,8 +274,6 @@ pub const Texture = struct { .static => |static| { sokol.gfx.destroyImage(static.image); }, - - .empty => {}, } self.* = undefined; @@ -290,14 +287,6 @@ pub const Texture = struct { switch (desc.access) { .render => |render| { - if (render.width == 0 or render.height == 0) { - return .{ - .width = render.width, - .height = render.height, - .access = .empty, - }; - } - const color_image = sokol.gfx.makeImage(.{ .pixel_format = pixel_format, .width = render.width, @@ -345,14 +334,6 @@ pub const Texture = struct { return error.OutOfMemory; }; - if (static.width == 0 or height == 0) { - return .{ - .width = static.width, - .height = height, - .access = .empty, - }; - } - const image = sokol.gfx.makeImage(image_desc: { var image_desc = sokol.gfx.ImageDesc{ .height = height, @@ -503,16 +484,5 @@ pub fn init() !Self { }, })); - assert.is_handle(gfx.Texture.backbuffer, try pools.create_texture(.{ - .format = .rgba8, - - .access = .{ - .render = .{ - .width = 0, - .height = 0, - }, - } - })); - return pools; } diff --git a/src/gfx/gfx.zig b/src/gfx/gfx.zig index 48b8736..be09af3 100644 --- a/src/gfx/gfx.zig +++ b/src/gfx/gfx.zig @@ -186,7 +186,7 @@ pub const Commands = struct { }; pub const SetTargetCommand = struct { - texture: Texture, + texture: ?Texture = null, clear_color: ?Color, clear_depth: ?f32, clear_stencil: ?u8, @@ -309,7 +309,6 @@ pub const Rect = struct { pub const Texture = enum (u32) { default, - backbuffer, _, pub const Desc = struct { diff --git a/src/gfx/rendering.zig b/src/gfx/rendering.zig index 161a991..c8f1d49 100644 --- a/src/gfx/rendering.zig +++ b/src/gfx/rendering.zig @@ -21,8 +21,10 @@ const Frame = struct { drawn_count: usize = 0, flushed_count: usize = 0, current_source_texture: gfx.Texture = .default, - current_target_texture: gfx.Texture = .backbuffer, + current_target_texture: ?gfx.Texture = null, current_effect: gfx.Effect = .default, + width: u16 = 0, + height: u16 = 0, const DrawTexture = extern struct { transform: gfx.Transform2D, @@ -103,11 +105,13 @@ const Frame = struct { pub fn finish(self: *Frame, resources: *Resources) void { self.flush(resources); + sokol.gfx.endPass(); + sokol.gfx.commit(); self.drawn_count = 0; self.flushed_count = 0; self.current_source_texture = .default; - self.current_target_texture = .backbuffer; + self.current_target_texture = null; self.current_effect = .default; } @@ -132,24 +136,29 @@ const Frame = struct { bindings.fs.images[0] = static.image; bindings.fs.samplers[0] = default_sampler; }, - - .empty => { - @panic("Cannot render empty textures"); - }, } const effect = resources.get_effect(self.current_effect).?; sokol.gfx.applyPipeline(effect.pipeline); - const texture = resources.get_texture(self.current_target_texture).?; + if (self.current_target_texture) |target_texture| { + const texture = resources.get_texture(target_texture).?; - sokol.gfx.applyUniforms(.VS, 0, sokol.gfx.asRange(&orthographic_projection(-1.0, 1.0, .{ - .left = 0, - .top = 0, - .right = @floatFromInt(texture.width), - .bottom = @floatFromInt(texture.height), - }))); + sokol.gfx.applyUniforms(.VS, 0, sokol.gfx.asRange(&orthographic_projection(-1.0, 1.0, .{ + .left = 0, + .top = 0, + .right = @floatFromInt(texture.width), + .bottom = @floatFromInt(texture.height), + }))); + } else { + sokol.gfx.applyUniforms(.VS, 0, sokol.gfx.asRange(&orthographic_projection(-1.0, 1.0, .{ + .left = 0, + .top = 0, + .right = @floatFromInt(self.width), + .bottom = @floatFromInt(self.height), + }))); + } if (effect.properties.len != 0) { sokol.gfx.applyUniforms(.FS, 0, sokol.gfx.asRange(effect.properties)); @@ -214,16 +223,53 @@ const Frame = struct { pass.action.depth = .{.load_action = .LOAD}; } - pass.attachments = switch (resources.get_texture(self.current_target_texture).?.access) { - .static => @panic("Cannot render to static textures"), - .empty => @panic("Cannot render to empty textures"), - .render => |render| render.attachments, - }; - self.current_target_texture = command.texture; + if (self.current_target_texture) |target_texture| { + pass.attachments = switch (resources.get_texture(target_texture).?.access) { + .static => @panic("Cannot render to static textures"), + .render => |render| render.attachments, + }; + } else { + pass.swapchain = .{ + .width = self.width, + .height = self.height, + .sample_count = 1, + .color_format = .RGBA8, + .depth_format = .DEPTH_STENCIL, + .gl = .{.framebuffer = 0}, + }; + } + sokol.gfx.beginPass(pass); } + + pub fn start(self: *Frame, width: u16, height: u16) void { + self.width = width; + self.height = height; + + sokol.gfx.beginPass(pass: { + var pass = sokol.gfx.Pass{ + .swapchain = .{ + .width = width, + .height = height, + .sample_count = 1, + .color_format = .RGBA8, + .depth_format = .DEPTH_STENCIL, + .gl = .{.framebuffer = 0}, + }, + + .action = .{ + .stencil = .{.load_action = .CLEAR}, + .depth = .{.load_action = .CLEAR}, + }, + }; + + pass.action.colors[0] = .{.load_action = .CLEAR}; + + break: pass pass; + }); + } }; fn Matrix(comptime n: usize, comptime Element: type) type { @@ -319,46 +365,7 @@ pub fn process_work(pending_work: *gfx.Assets.WorkQueue, window: *ext.SDL_Window }, .render_frame => |render_frame| { - const backbuffer = resources.get_texture(.backbuffer).?; - - if (backbuffer.width != render_frame.width or backbuffer.height != render_frame.height) { - backbuffer.deinit(); - - backbuffer.* = try Resources.Texture.init(.{ - .format = .rgba8, - - .access = .{ - .render = .{ - .width = render_frame.width, - .height = render_frame.height, - }, - }, - }); - } - - sokol.gfx.beginPass(pass: { - var pass = sokol.gfx.Pass{ - .action = .{ - .stencil = .{ - .load_action = .CLEAR, - }, - - .depth = .{ - .load_action = .CLEAR, - .clear_value = 0, - } - }, - }; - - pass.action.colors[0] = .{ - .load_action = .CLEAR, - .clear_value = @bitCast(render_frame.clear_color), - }; - - pass.attachments = resources.get_texture(.backbuffer).?.access.render.attachments; - - break: pass pass; - }); + frame.start(render_frame.width, render_frame.height); var has_command_params = render_frame.has_command_params; @@ -373,9 +380,8 @@ pub fn process_work(pending_work: *gfx.Assets.WorkQueue, window: *ext.SDL_Window frame.flush(&resources); - if (frame.current_target_texture != .backbuffer) { + if (frame.current_target_texture != null) { frame.set_target(&resources, .{ - .texture = .backbuffer, .clear_color = null, .clear_depth = null, .clear_stencil = null, @@ -383,43 +389,7 @@ pub fn process_work(pending_work: *gfx.Assets.WorkQueue, window: *ext.SDL_Window } } - sokol.gfx.endPass(); - - sokol.gfx.beginPass(swapchain_pass: { - var pass = sokol.gfx.Pass{ - .swapchain = .{ - .width = render_frame.width, - .height = render_frame.height, - .sample_count = 1, - .color_format = .RGBA8, - .depth_format = .DEPTH_STENCIL, - .gl = .{.framebuffer = 0}, - }, - - .action = .{ - .stencil = .{.load_action = .CLEAR}, - .depth = .{.load_action = .CLEAR}, - }, - }; - - pass.action.colors[0] = .{.load_action = .CLEAR}; - - break: swapchain_pass pass; - }); - - try frame.draw_texture(&resources, .{ - .texture = .backbuffer, - - .transform = .{ - .origin = .{@as(f32, @floatFromInt(render_frame.width)) / 2, @as(f32, @floatFromInt(render_frame.height)) / 2}, - .xbasis = .{@floatFromInt(render_frame.width), 0}, - .ybasis = .{0, @floatFromInt(render_frame.height)}, - }, - }); - frame.finish(&resources); - sokol.gfx.endPass(); - sokol.gfx.commit(); ext.SDL_GL_SwapWindow(window); render_frame.finished.set(); },