summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDario <dariosamo@gmail.com>2023-10-11 14:54:36 -0300
committerDario <dariosamo@gmail.com>2023-10-17 13:36:27 -0300
commit4890e965564bc70bba50b2773e43857a688ec02c (patch)
tree14d136851c685c9ce0135a1b5a1f706f93a55221
parent30f2a6d611b1c9a3decae8964c5737e63e63ebce (diff)
downloadredot-engine-4890e965564bc70bba50b2773e43857a688ec02c.tar.gz
Add an extra backbuffer color texture that can be used when an upscaler is in use.
Fixes issue #83152. Due to how BLUR_0 is reused for multiple purposes and requires being at native resolution for some post-processing effects to work, FSR2 will use an alternate texture at internal size to use as the screen texture read by shaders instead. The rendering pipeline will prefer using this texture if it exists.
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp7
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp26
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h12
3 files changed, 37 insertions, 8 deletions
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index efec3b5072..dce97808b1 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -2137,6 +2137,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_list_end();
}
+ if (rb_data.is_valid() && using_fsr2) {
+ // Make sure the upscaled texture is initialized, but not necessarily filled, before running screen copies
+ // so it properly detect if a dedicated copy texture should be used.
+ rb->ensure_upscaled();
+ }
+
if (scene_state.used_screen_texture) {
RENDER_TIMESTAMP("Copy Screen Texture");
@@ -2200,7 +2206,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (rb_data.is_valid() && (using_fsr2 || using_taa)) {
if (using_fsr2) {
- rb->ensure_upscaled();
rb_data->ensure_fsr2(fsr2_effect);
RID exposure;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 07d56eae0c..d10443d6ad 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -260,15 +260,29 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData
RD::get_singleton()->draw_command_begin_label("Copy screen texture");
- rb->allocate_blur_textures();
-
+ StringName texture_name;
bool can_use_storage = _render_buffers_can_be_storage();
Size2i size = rb->get_internal_size();
+ // When upscaling, the blur texture needs to be at the target size for post-processing to work. We prefer to use a
+ // dedicated backbuffer copy texture instead if the blur texture is not an option so shader effects work correctly.
+ Size2i target_size = rb->get_target_size();
+ bool internal_size_matches = (size.width == target_size.width) && (size.height == target_size.height);
+ bool reuse_blur_texture = !rb->has_upscaled_texture() || internal_size_matches;
+ if (reuse_blur_texture) {
+ rb->allocate_blur_textures();
+ texture_name = RB_TEX_BLUR_0;
+ } else {
+ uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ usage_bits |= can_use_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR, rb->get_base_data_format(), usage_bits);
+ texture_name = RB_TEX_BACK_COLOR;
+ }
+
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RID texture = rb->get_internal_texture(v);
- int mipmaps = int(rb->get_texture_format(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0).mipmaps);
- RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, 0);
+ int mipmaps = int(rb->get_texture_format(RB_SCOPE_BUFFERS, texture_name).mipmaps);
+ RID dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, texture_name, v, 0);
if (can_use_storage) {
copy_effects->copy_to_rect(texture, dest, Rect2i(0, 0, size.x, size.y));
@@ -279,8 +293,8 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData
for (int i = 1; i < mipmaps; i++) {
RID source = dest;
- dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i);
- Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, i);
+ dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, texture_name, v, i);
+ Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, texture_name, i);
if (can_use_storage) {
copy_effects->make_mipmap(source, dest, msize);
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
index 43704119e7..b2946e6bbc 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
@@ -58,6 +58,7 @@
#define RB_TEX_BLUR_1 SNAME("blur_1")
#define RB_TEX_HALF_BLUR SNAME("half_blur") // only for raster!
+#define RB_TEX_BACK_COLOR SNAME("back_color")
#define RB_TEX_BACK_DEPTH SNAME("back_depth")
class RenderSceneBuffersRD : public RenderSceneBuffers {
@@ -267,7 +268,16 @@ public:
}
// back buffer (color)
- RID get_back_buffer_texture() const { return has_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) ? get_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0) : RID(); } // We (re)use our blur texture here.
+ RID get_back_buffer_texture() const {
+ // Prefer returning the dedicated backbuffer color texture if it was created. Return the reused blur texture otherwise.
+ if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR)) {
+ return get_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_COLOR);
+ } else if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0)) {
+ return get_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0);
+ } else {
+ return RID();
+ }
+ }
// Upscaled.
void ensure_upscaled();