Remove unnecessary backbuffer copy
continuous-integration/drone/push Build is passing Details

This commit is contained in:
kayomn 2024-07-25 01:24:13 +01:00
parent 9f0f565b0b
commit db0e08d530
5 changed files with 70 additions and 131 deletions

2
.vscode/launch.json vendored
View File

@ -5,7 +5,7 @@
"name": "Runner", "name": "Runner",
"type": "gdb", "type": "gdb",
"request": "launch", "request": "launch",
"target": "${workspaceRoot}/demos/inputs.out", "target": "${workspaceRoot}/demos/effects.out",
"cwd": "${workspaceRoot}/demos/", "cwd": "${workspaceRoot}/demos/",
"valuesFormatting": "prettyPrinters", "valuesFormatting": "prettyPrinters",
"preLaunchTask": "Build All" "preLaunchTask": "Build All"

View File

@ -72,7 +72,7 @@ fn render(commands: gfx.Commands, effects: ona.Write(Effects), app: ona.Read(ona
}); });
try commands.set_target(.{ try commands.set_target(.{
.texture = .backbuffer, .texture = null,
.clear_color = null, .clear_color = null,
.clear_depth = null, .clear_depth = null,
.clear_stencil = null, .clear_stencil = null,

View File

@ -249,7 +249,6 @@ pub const Texture = struct {
access: Access, access: Access,
pub const Access = union (enum) { pub const Access = union (enum) {
empty,
render: RenderAccess, render: RenderAccess,
static: StaticAccess, static: StaticAccess,
}; };
@ -275,8 +274,6 @@ pub const Texture = struct {
.static => |static| { .static => |static| {
sokol.gfx.destroyImage(static.image); sokol.gfx.destroyImage(static.image);
}, },
.empty => {},
} }
self.* = undefined; self.* = undefined;
@ -290,14 +287,6 @@ pub const Texture = struct {
switch (desc.access) { switch (desc.access) {
.render => |render| { .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(.{ const color_image = sokol.gfx.makeImage(.{
.pixel_format = pixel_format, .pixel_format = pixel_format,
.width = render.width, .width = render.width,
@ -345,14 +334,6 @@ pub const Texture = struct {
return error.OutOfMemory; 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: { const image = sokol.gfx.makeImage(image_desc: {
var image_desc = sokol.gfx.ImageDesc{ var image_desc = sokol.gfx.ImageDesc{
.height = height, .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; return pools;
} }

View File

@ -186,7 +186,7 @@ pub const Commands = struct {
}; };
pub const SetTargetCommand = struct { pub const SetTargetCommand = struct {
texture: Texture, texture: ?Texture = null,
clear_color: ?Color, clear_color: ?Color,
clear_depth: ?f32, clear_depth: ?f32,
clear_stencil: ?u8, clear_stencil: ?u8,
@ -309,7 +309,6 @@ pub const Rect = struct {
pub const Texture = enum (u32) { pub const Texture = enum (u32) {
default, default,
backbuffer,
_, _,
pub const Desc = struct { pub const Desc = struct {

View File

@ -21,8 +21,10 @@ const Frame = struct {
drawn_count: usize = 0, drawn_count: usize = 0,
flushed_count: usize = 0, flushed_count: usize = 0,
current_source_texture: gfx.Texture = .default, current_source_texture: gfx.Texture = .default,
current_target_texture: gfx.Texture = .backbuffer, current_target_texture: ?gfx.Texture = null,
current_effect: gfx.Effect = .default, current_effect: gfx.Effect = .default,
width: u16 = 0,
height: u16 = 0,
const DrawTexture = extern struct { const DrawTexture = extern struct {
transform: gfx.Transform2D, transform: gfx.Transform2D,
@ -103,11 +105,13 @@ const Frame = struct {
pub fn finish(self: *Frame, resources: *Resources) void { pub fn finish(self: *Frame, resources: *Resources) void {
self.flush(resources); self.flush(resources);
sokol.gfx.endPass();
sokol.gfx.commit();
self.drawn_count = 0; self.drawn_count = 0;
self.flushed_count = 0; self.flushed_count = 0;
self.current_source_texture = .default; self.current_source_texture = .default;
self.current_target_texture = .backbuffer; self.current_target_texture = null;
self.current_effect = .default; self.current_effect = .default;
} }
@ -132,17 +136,14 @@ const Frame = struct {
bindings.fs.images[0] = static.image; bindings.fs.images[0] = static.image;
bindings.fs.samplers[0] = default_sampler; bindings.fs.samplers[0] = default_sampler;
}, },
.empty => {
@panic("Cannot render empty textures");
},
} }
const effect = resources.get_effect(self.current_effect).?; const effect = resources.get_effect(self.current_effect).?;
sokol.gfx.applyPipeline(effect.pipeline); 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, .{ sokol.gfx.applyUniforms(.VS, 0, sokol.gfx.asRange(&orthographic_projection(-1.0, 1.0, .{
.left = 0, .left = 0,
@ -150,6 +151,14 @@ const Frame = struct {
.right = @floatFromInt(texture.width), .right = @floatFromInt(texture.width),
.bottom = @floatFromInt(texture.height), .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) { if (effect.properties.len != 0) {
sokol.gfx.applyUniforms(.FS, 0, sokol.gfx.asRange(effect.properties)); sokol.gfx.applyUniforms(.FS, 0, sokol.gfx.asRange(effect.properties));
@ -214,16 +223,53 @@ const Frame = struct {
pass.action.depth = .{.load_action = .LOAD}; 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; 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); 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 { 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| { .render_frame => |render_frame| {
const backbuffer = resources.get_texture(.backbuffer).?; frame.start(render_frame.width, render_frame.height);
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;
});
var has_command_params = render_frame.has_command_params; 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); frame.flush(&resources);
if (frame.current_target_texture != .backbuffer) { if (frame.current_target_texture != null) {
frame.set_target(&resources, .{ frame.set_target(&resources, .{
.texture = .backbuffer,
.clear_color = null, .clear_color = null,
.clear_depth = null, .clear_depth = null,
.clear_stencil = 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); frame.finish(&resources);
sokol.gfx.endPass();
sokol.gfx.commit();
ext.SDL_GL_SwapWindow(window); ext.SDL_GL_SwapWindow(window);
render_frame.finished.set(); render_frame.finished.set();
}, },