@@ -685,36 +685,48 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
685685
686686 RID dest_fb;
687687 RD::DataFormat dest_fb_format;
688+ RD::DataFormat format_for_debanding;
688689 if (spatial_upscaler != nullptr || use_smaa) {
689690 // If we use a spatial upscaler to upscale or SMAA to antialias we need to write our result into an intermediate buffer.
690691 // Note that this is cached so we only create the texture the first time.
691692 dest_fb_format = _render_buffers_get_color_format ();
692693 RID dest_texture = rb->create_texture (SNAME (" Tonemapper" ), SNAME (" destination" ), dest_fb_format, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i (), 0 , 1 , true , true );
693694 dest_fb = FramebufferCacheRD::get_singleton ()->get_cache (dest_texture);
695+ if (use_smaa) {
696+ format_for_debanding = dest_fb_format;
697+ } else {
698+ // Debanding is currently not supported when using spatial upscaling, so apply it before scaling.
699+ // This produces suboptimal results because the image will be modified by spatial upscaling after
700+ // debanding has been applied. Ideally, debanding should be applied as the final step before quantization
701+ // to integer values, but in the case of MetalFX, it may not be worth the performance cost of creating a new
702+ // intermediate buffer. In the case of FSR 1.0, the work of adding debanding support hasn't been done yet.
703+ // Assume that the DataFormat that will be used by spatial_upscaler is the same as render_target_get_color_format.
704+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, tonemap.convert_to_srgb );
705+ }
694706 } else {
695707 // If we do a bilinear upscale we just render into our render target and our shader will upscale automatically.
696708 // Target size in this case is lying as we never get our real target size communicated.
697709 // Bit nasty but...
698710
699711 if (dest_is_msaa_2d) {
700- // Assume that the DataFormat of render_target_get_rd_texture_msaa is the same as render_target_get_color_format.
701- dest_fb_format = texture_storage->render_target_get_color_format (using_hdr, tonemap.convert_to_srgb );
702712 dest_fb = FramebufferCacheRD::get_singleton ()->get_cache (texture_storage->render_target_get_rd_texture_msaa (render_target));
713+ // Assume that the DataFormat of render_target_get_rd_texture_msaa is the same as render_target_get_color_format.
714+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, tonemap.convert_to_srgb );
703715 texture_storage->render_target_set_msaa_needs_resolve (render_target, true ); // Make sure this gets resolved.
704716 } else {
705- // Assume that the DataFormat of render_target_get_rd_framebuffer is the same as render_target_get_color_format.
706- dest_fb_format = texture_storage->render_target_get_color_format (using_hdr, tonemap.convert_to_srgb );
707717 dest_fb = texture_storage->render_target_get_rd_framebuffer (render_target);
718+ // Assume that the DataFormat of render_target_get_rd_framebuffer is the same as render_target_get_color_format.
719+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, tonemap.convert_to_srgb );
708720 }
709721 }
710722
711723 if (rb->get_use_debanding ()) {
712- if (dest_fb_format >= RD::DATA_FORMAT_R8_UNORM && dest_fb_format <= RD::DATA_FORMAT_A8B8G8R8_SRGB_PACK32 ) {
724+ if (_is_8bit_data_format (format_for_debanding) ) {
713725 tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_8_BIT;
714- } else if (dest_fb_format >= RD::DATA_FORMAT_A2R10G10B10_UNORM_PACK32 && dest_fb_format <= RD::DATA_FORMAT_A2B10G10R10_SINT_PACK32 ) {
726+ } else if (_is_10bit_data_format (format_for_debanding) ) {
715727 tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_10_BIT;
716728 } else {
717- // In this case, debanding will be handled later when quantizing to an integer data format. (During blit, for example.)
729+ // In this case, debanding will be handled later when quantizing to an integer data format. (During blit or SMAA , for example.)
718730 tonemap.debanding_mode = RendererRD::ToneMapper::TonemapSettings::DebandingMode::DEBANDING_MODE_DISABLED;
719731 }
720732 } else {
@@ -730,6 +742,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
730742 RENDER_TIMESTAMP (" SMAA" );
731743 RD::get_singleton ()->draw_command_begin_label (" SMAA" );
732744
745+ bool using_hdr = texture_storage->render_target_is_using_hdr (render_target);
733746 RID dest_fb;
734747 if (spatial_upscaler) {
735748 rb->create_texture (SNAME (" SMAA" ), SNAME (" destination" ), _render_buffers_get_color_format (), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i (), 0 , 1 , true , true );
@@ -739,30 +752,78 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
739752 RID source_texture = rb->get_texture_slice (SNAME (" Tonemapper" ), SNAME (" destination" ), v, 0 );
740753
741754 RID dest_texture;
755+ RD::DataFormat format_for_debanding;
742756 if (spatial_upscaler) {
743757 dest_texture = rb->get_texture_slice (SNAME (" SMAA" ), SNAME (" destination" ), v, 0 );
758+ // Debanding is currently not supported when using spatial upscaling, so apply it before scaling.
759+ // This produces suboptimal results because the image will be modified by spatial upscaling after
760+ // debanding has been applied. Ideally, debanding should be applied as the final step before quantization
761+ // to integer values, but in the case of MetalFX, it may not be worth the performance cost of creating a new
762+ // intermediate buffer. In the case of FSR 1.0, the work of adding debanding support hasn't been done yet.
763+ // Assume that the DataFormat that will be used by spatial_upscaler is the same as render_target_get_color_format.
764+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, !using_hdr);
744765 } else {
745766 dest_texture = texture_storage->render_target_get_rd_texture_slice (render_target, v);
767+ // Assume that the DataFormat is the same as render_target_get_color_format.
768+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, !using_hdr);
746769 }
747770 dest_fb = FramebufferCacheRD::get_singleton ()->get_cache (dest_texture);
748771
772+ if (rb->get_use_debanding ()) {
773+ if (_is_8bit_data_format (format_for_debanding)) {
774+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_8_BIT;
775+ } else if (_is_10bit_data_format (format_for_debanding)) {
776+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_10_BIT;
777+ } else {
778+ // In this case, debanding will be handled later when quantizing to an integer data format. (During blit, for example.)
779+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_DISABLED;
780+ }
781+ } else {
782+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_DISABLED;
783+ }
784+
749785 smaa->process (rb, source_texture, dest_fb);
750786 }
751787 } else {
752788 RID source_texture = rb->get_texture (SNAME (" Tonemapper" ), SNAME (" destination" ));
789+ RD::DataFormat format_for_debanding;
753790
754791 if (spatial_upscaler) {
755792 RID dest_texture = rb->create_texture (SNAME (" SMAA" ), SNAME (" destination" ), _render_buffers_get_color_format (), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT, RD::TEXTURE_SAMPLES_1, Size2i (), 0 , 1 , true , true );
756793 dest_fb = FramebufferCacheRD::get_singleton ()->get_cache (dest_texture);
794+ // Debanding is currently not supported when using spatial upscaling, so apply it before scaling.
795+ // This produces suboptimal results because the image will be modified by spatial upscaling after
796+ // debanding has been applied. Ideally, debanding should be applied as the final step before quantization
797+ // to integer values, but in the case of MetalFX, it may not be worth the performance cost of creating a new
798+ // intermediate buffer. In the case of FSR 1.0, the work of adding debanding support hasn't been done yet.
799+ // Assume that the DataFormat that will be used by spatial_upscaler is the same as render_target_get_color_format.
800+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, !using_hdr);
757801 } else {
758802 if (dest_is_msaa_2d) {
759803 dest_fb = FramebufferCacheRD::get_singleton ()->get_cache (texture_storage->render_target_get_rd_texture_msaa (render_target));
804+ // Assume that the DataFormat of render_target_get_rd_texture_msaa is the same as render_target_get_color_format.
805+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, !using_hdr);
760806 texture_storage->render_target_set_msaa_needs_resolve (render_target, true ); // Make sure this gets resolved.
761807 } else {
762808 dest_fb = texture_storage->render_target_get_rd_framebuffer (render_target);
809+ // Assume that the DataFormat of render_target_get_rd_framebuffer is the same as render_target_get_color_format.
810+ format_for_debanding = texture_storage->render_target_get_color_format (using_hdr, !using_hdr);
763811 }
764812 }
765813
814+ if (rb->get_use_debanding ()) {
815+ if (_is_8bit_data_format (format_for_debanding)) {
816+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_8_BIT;
817+ } else if (_is_10bit_data_format (format_for_debanding)) {
818+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_10_BIT;
819+ } else {
820+ // In this case, debanding will be handled later when quantizing to an integer data format. (During blit, for example.)
821+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_DISABLED;
822+ }
823+ } else {
824+ smaa->debanding_mode = RendererRD::SMAA::DebandingMode::DEBANDING_MODE_DISABLED;
825+ }
826+
766827 smaa->process (rb, source_texture, dest_fb);
767828 }
768829
0 commit comments