Skip to content

Commit

Permalink
Merge pull request #83192 from DarioSamo/fsr2-shader-backbuffer-fix
Browse files Browse the repository at this point in the history
Add an extra backbuffer color texture that can be used when an upscaler is in use.
  • Loading branch information
akien-mga committed Oct 20, 2023
2 parents a434062 + 4890e96 commit ecc2bd6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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;
Expand Down
26 changes: 20 additions & 6 deletions servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -267,7 +268,16 @@ class RenderSceneBuffersRD : public RenderSceneBuffers {
}

// 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();
Expand Down

0 comments on commit ecc2bd6

Please sign in to comment.