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 1c052eb0130..c4c6edec30c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -689,7 +689,9 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat } } - p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, p_apply_alpha_multiplier); + float luminance_multiplier = rd.is_valid() ? rd->get_luminance_multiplier() : 1.0; + + p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, luminance_multiplier, p_opaque_render_buffers, p_apply_alpha_multiplier); // now do implementation UBO @@ -1434,7 +1436,7 @@ void RenderForwardClustered::_process_ssr(Ref p_render_buf RENDER_TIMESTAMP("Process SSR"); - ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, _render_buffers_get_color_format()); + ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, p_render_buffers->get_base_data_format()); Projection reprojections[RendererSceneRender::MAX_RENDER_VIEWS]; @@ -1946,7 +1948,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool draw_sky = false; bool draw_sky_fog_only = false; // We invert luminance_multiplier for sky so that we can combine it with exposure value. - float sky_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier(); + float sky_luminance_multiplier = 1.0 / rb->get_luminance_multiplier(); float sky_brightness_multiplier = 1.0; Color clear_color; @@ -2472,7 +2474,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } else if (using_taa) { RD::get_singleton()->draw_command_begin_label("TAA"); RENDER_TIMESTAMP("TAA"); - taa->process(rb, _render_buffers_get_color_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far); + taa->process(rb, rb->get_base_data_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far); RD::get_singleton()->draw_command_end_label(); } } @@ -4505,7 +4507,7 @@ void RenderForwardClustered::_mesh_compile_pipelines_for_surface(const SurfacePi // Retrieve from the scene shader which groups are currently enabled. const bool multiview_enabled = p_global.use_multiview && scene_shader.is_multiview_shader_group_enabled(); - const RD::DataFormat buffers_color_format = _render_buffers_get_color_format(); + const RD::DataFormat buffers_color_format = _render_buffers_get_preferred_color_format(); const bool buffers_can_be_storage = _render_buffers_can_be_storage(); // Set the attributes common to all pipelines. diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 8b63e0e443b..5dfcf29cbc9 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -414,19 +414,12 @@ void RenderForwardMobile::update() { /* Render functions */ -float RenderForwardMobile::_render_buffers_get_luminance_multiplier() { - // On mobile renderer we need to multiply source colors by 2 due to using a UNORM buffer - // and multiplying by the output color during 3D rendering by 0.5 - return 2.0; -} - -RD::DataFormat RenderForwardMobile::_render_buffers_get_color_format() { +RD::DataFormat RenderForwardMobile::_render_buffers_get_preferred_color_format() { // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) return RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; } bool RenderForwardMobile::_render_buffers_can_be_storage() { - // Using 32bit buffers enables AFBC on mobile devices which should have a definite performance improvement (MALI G710 and newer support this on 64bit RTs) // Doesn't support storage return false; } @@ -1002,8 +995,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color bool draw_sky = false; bool draw_sky_fog_only = false; // We invert luminance_multiplier for sky so that we can combine it with exposure value. - float inverse_luminance_multiplier = 1.0 / _render_buffers_get_luminance_multiplier(); - float sky_luminance_multiplier = inverse_luminance_multiplier; + float inverse_luminance_multiplier = 1.0 / rb->get_luminance_multiplier(); + float sky_luminance_multiplier = 1.0 / 2.0; // Hardcoded since sky always uses LDR in the mobile renderer float sky_brightness_multiplier = 1.0; Color clear_color = p_default_bg_color; @@ -1122,6 +1115,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap; base_specialization.scene_use_reflection_cubemap = use_reflection_cubemap; base_specialization.scene_roughness_limiter_enabled = p_render_data->render_buffers.is_valid() && screen_space_roughness_limiter_is_active(); + base_specialization.luminance_multiplier = p_render_data->render_buffers.is_valid() ? p_render_data->render_buffers->get_luminance_multiplier() : 1.0; } { @@ -2201,7 +2195,9 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, } } - p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers, false); + float luminance_multiplier = p_render_data->render_buffers.is_valid() ? p_render_data->render_buffers->get_luminance_multiplier() : 1.0; + + p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_pancake_shadows, p_screen_size, p_default_bg_color, luminance_multiplier, p_opaque_render_buffers, false); } /// RENDERING /// @@ -3141,7 +3137,6 @@ void RenderForwardMobile::_mesh_compile_pipelines_for_surface(const SurfacePipel pipeline_key.wireframe = false; const bool multiview_enabled = p_global.use_multiview && scene_shader.is_multiview_shader_group_enabled(); - const RD::DataFormat buffers_color_format = _render_buffers_get_color_format(); const bool buffers_can_be_storage = _render_buffers_can_be_storage(); const uint32_t vrs_iterations = p_global.use_vrs ? 2 : 1; @@ -3155,6 +3150,7 @@ void RenderForwardMobile::_mesh_compile_pipelines_for_surface(const SurfacePipel for (uint32_t use_post_pass = post_pass_start; use_post_pass < post_pass_iterations; use_post_pass++) { const uint32_t hdr_iterations = use_post_pass ? hdr_target_iterations : (hdr_start + 1); for (uint32_t use_hdr = hdr_start; use_hdr < hdr_iterations; use_hdr++) { + const RD::DataFormat buffers_color_format = use_hdr ? RD::DATA_FORMAT_R16G16B16A16_SFLOAT : _render_buffers_get_preferred_color_format(); pipeline_key.version = SceneShaderForwardMobile::SHADER_VERSION_COLOR_PASS; pipeline_key.framebuffer_format_id = _get_color_framebuffer_format_for_pipeline(buffers_color_format, buffers_can_be_storage, RD::TextureSamples(p_global.texture_samples), RD::TextureSamples(p_global.target_samples), use_vrs, use_post_pass, use_hdr, 1); _mesh_compile_pipeline_for_surface(p_surface.shader, p_surface.mesh_surface, p_surface.instanced, p_source, pipeline_key, r_pipeline_pairs); @@ -3340,7 +3336,7 @@ void RenderForwardMobile::_update_shader_quality_settings() { RenderForwardMobile::RenderForwardMobile() { singleton = this; - sky.set_texture_format(_render_buffers_get_color_format()); + sky.set_texture_format(_render_buffers_get_preferred_color_format()); String defines; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index 126fce3de6d..ba8409d7285 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -413,8 +413,7 @@ protected: /* setup */ virtual void _update_shader_quality_settings() override; - virtual float _render_buffers_get_luminance_multiplier() override; - virtual RD::DataFormat _render_buffers_get_color_format() override; + virtual RD::DataFormat _render_buffers_get_preferred_color_format() override; virtual bool _render_buffers_can_be_storage() override; virtual RID _render_buffers_get_normal_texture(Ref p_render_buffers) override; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 3479da4424b..b8a9561537c 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -242,7 +242,7 @@ Ref RendererSceneRenderRD::render_buffers_create() { rb->set_can_be_storage(_render_buffers_can_be_storage()); rb->set_max_cluster_elements(max_cluster_elements); - rb->set_base_data_format(_render_buffers_get_color_format()); + rb->set_preferred_data_format(_render_buffers_get_preferred_color_format()); if (vrs) { rb->set_vrs(vrs); } @@ -587,7 +587,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } } - float luminance_multiplier = _render_buffers_get_luminance_multiplier(); + float luminance_multiplier = rb->get_luminance_multiplier(); for (uint32_t l = 0; l < rb->get_view_count(); l++) { for (int i = 0; i < (max_glow_level + 1); i++) { Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i); @@ -693,7 +693,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } } - tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); + tonemap.luminance_multiplier = rb->get_luminance_multiplier(); tonemap.view_count = rb->get_view_count(); RID dest_fb; @@ -702,7 +702,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (spatial_upscaler != nullptr || use_smaa) { // If we use a spatial upscaler to upscale or SMAA to antialias we need to write our result into an intermediate buffer. // Note that this is cached so we only create the texture the first time. - dest_fb_format = _render_buffers_get_color_format(); + dest_fb_format = rb->get_base_data_format(); 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); dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture); if (use_smaa) { @@ -758,7 +758,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende bool using_hdr = texture_storage->render_target_is_using_hdr(render_target); RID dest_fb; if (spatial_upscaler) { - 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); + rb->create_texture(SNAME("SMAA"), SNAME("destination"), rb->get_base_data_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); } if (rb->get_view_count() > 1) { for (uint32_t v = 0; v < rb->get_view_count(); v++) { @@ -802,7 +802,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RD::DataFormat format_for_debanding; if (spatial_upscaler) { - 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); + RID dest_texture = rb->create_texture(SNAME("SMAA"), SNAME("destination"), rb->get_base_data_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); dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture); // Debanding is currently not supported when using spatial upscaling, so apply it before scaling. // This produces suboptimal results because the image will be modified by spatial upscaling after @@ -935,7 +935,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr tonemap.texture_size = Vector2i(target_size.x, target_size.y); - tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier(); + tonemap.luminance_multiplier = rb->get_luminance_multiplier(); tonemap.view_count = rb->get_view_count(); if (rb->get_use_debanding()) { @@ -1115,11 +1115,7 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() { return gi.default_voxel_gi_buffer; } -float RendererSceneRenderRD::_render_buffers_get_luminance_multiplier() { - return 1.0; -} - -RD::DataFormat RendererSceneRenderRD::_render_buffers_get_color_format() { +RD::DataFormat RendererSceneRenderRD::_render_buffers_get_preferred_color_format() { return RD::DATA_FORMAT_R16G16B16A16_SFLOAT; } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 0673562c039..cc55002b607 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -244,9 +244,7 @@ public: virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; } /* render buffers */ - - virtual float _render_buffers_get_luminance_multiplier(); - virtual RD::DataFormat _render_buffers_get_color_format(); + virtual RD::DataFormat _render_buffers_get_preferred_color_format(); virtual bool _render_buffers_can_be_storage(); virtual Ref render_buffers_create() override; virtual void gi_set_use_half_resolution(bool p_enable) override; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index 2d5bb47648c..dac841ba0b8 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -142,6 +142,8 @@ float sc_luminance_multiplier() { return 1.0; } +#define REFLECTION_MULTIPLIER 1.0 + #define SDFGI_MAX_CASCADES 8 /* Set 0: Base Pass (never changes) */ diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 8eca5a67fdd..b9f1018ccdb 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -1563,7 +1563,7 @@ void main() { indirect_specular_light = hvec3(textureLod(samplerCube(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec3(ref_vec), lod).rgb); #endif //USE_RADIANCE_CUBEMAP_ARRAY - indirect_specular_light *= sc_luminance_multiplier(); + indirect_specular_light *= REFLECTION_MULTIPLIER; indirect_specular_light *= half(scene_data.IBL_exposure_normalization); indirect_specular_light *= horizon * horizon; indirect_specular_light *= half(scene_data.ambient_light_color_energy.a); @@ -1585,7 +1585,7 @@ void main() { #else hvec3 cubemap_ambient = hvec3(textureLod(samplerCube(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), ambient_dir, MAX_ROUGHNESS_LOD).rgb); #endif //USE_RADIANCE_CUBEMAP_ARRAY - cubemap_ambient *= sc_luminance_multiplier(); + cubemap_ambient *= REFLECTION_MULTIPLIER; cubemap_ambient *= half(scene_data.IBL_exposure_normalization); ambient_light = mix(ambient_light, cubemap_ambient * half(scene_data.ambient_light_color_energy.a), half(scene_data.ambient_color_sky_mix)); } diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 2d907111c9a..a96921e68c9 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -215,6 +215,10 @@ half sc_luminance_multiplier() { return half(sc_packed_2()); } +// Like the luminance multiplier, but it is only for sky and reflection probes +// since they are always LDR. +#define REFLECTION_MULTIPLIER half(2.0) + /* Set 0: Base Pass (never changes) */ #include "../light_data_inc.glsl" diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 9b4643325af..726fdfcdf03 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -957,7 +957,7 @@ void reflection_process(uint ref_index, vec3 vertex, hvec3 ref_vec, hvec3 normal hvec4 reflection; half reflection_blend = max(half(0.0), blend - reflection_accum.a); - reflection.rgb = hvec3(textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb) * sc_luminance_multiplier(); + reflection.rgb = hvec3(textureLod(samplerCubeArray(reflection_atlas, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(local_ref_vec, reflections.data[ref_index].index), sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb) * REFLECTION_MULTIPLIER; reflection.rgb *= half(reflections.data[ref_index].exposure_normalization); reflection.a = reflection_blend; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 2704c547135..5702bc8b28e 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -1542,7 +1542,7 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ } atlas->reflections.resize(atlas->count); for (int i = 0; i < atlas->count; i++) { - atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format()); + atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, update_always, RendererSceneRenderRD::get_singleton()->get_sky()->roughness_layers, RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format()); for (int j = 0; j < 6; j++) { atlas->reflections.write[i].fbs[j] = RendererSceneRenderRD::get_singleton()->reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer); } @@ -1814,7 +1814,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c } RD::DataFormat LightStorage::get_reflection_probe_color_format() { - return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format(); + return RendererSceneRenderRD::get_singleton()->_render_buffers_get_preferred_color_format(); } uint32_t LightStorage::get_reflection_probe_color_usage_bits() { diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 27673a905d1..a10525be885 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -152,6 +152,8 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); render_target = p_config->get_render_target(); + force_hdr = texture_storage->render_target_is_using_hdr(render_target); + target_size = p_config->get_target_size(); internal_size = p_config->get_internal_size(); view_count = p_config->get_view_count(); @@ -177,7 +179,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co // Create our color buffer. const bool resolve_target = msaa_3d != RS::VIEWPORT_MSAA_DISABLED; - create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, base_data_format, get_color_usage_bits(resolve_target, false, can_be_storage)); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR, get_base_data_format(), get_color_usage_bits(resolve_target, false, can_be_storage)); // TODO: Detect when it is safe to use RD::TEXTURE_USAGE_TRANSIENT_BIT for RB_TEX_DEPTH, RB_TEX_COLOR_MSAA and/or RB_TEX_DEPTH_MSAA. // (it means we cannot sample from it, we cannot copy from/to it) to save VRAM (and maybe performance too). @@ -190,7 +192,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co texture_samples = RD::TEXTURE_SAMPLES_1; } else { texture_samples = msaa_to_samples(msaa_3d); - create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, base_data_format, get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, get_base_data_format(), get_color_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true); create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, get_depth_format(false, true, can_be_storage), get_depth_usage_bits(false, true, can_be_storage), texture_samples, Size2i(), 0, 1, true, true); } @@ -267,7 +269,7 @@ void RenderSceneBuffersRD::ensure_mfx(RendererRD::MFXSpatialEffect *p_effect) { RendererRD::MFXSpatialEffect::CreateParams params = { .input_size = internal_size, .output_size = target_size, - .input_format = base_data_format, + .input_format = get_base_data_format(), .output_format = output_format, }; @@ -525,12 +527,12 @@ void RenderSceneBuffersRD::allocate_blur_textures() { usage_bits += RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; } - create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required); - create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, blur_size, view_count, mipmaps_required); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y >> 1), view_count, mipmaps_required - 1); // if !can_be_storage we need a half width version if (!can_be_storage) { - create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_HALF_BLUR, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, Size2i(blur_size.x >> 1, blur_size.y), 1, mipmaps_required); } // TODO redo this: @@ -646,7 +648,7 @@ void RenderSceneBuffersRD::ensure_upscaled() { if (!has_upscaled_texture()) { uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (can_be_storage ? RD::TEXTURE_USAGE_STORAGE_BIT : 0) | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; usage_bits |= RD::TEXTURE_USAGE_INPUT_ATTACHMENT_BIT; - create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, base_data_format, usage_bits, RD::TEXTURE_SAMPLES_1, target_size); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_UPSCALED, get_base_data_format(), usage_bits, RD::TEXTURE_SAMPLES_1, target_size); } } @@ -775,3 +777,9 @@ RD::DataFormat RenderSceneBuffersRD::get_vrs_format() { uint32_t RenderSceneBuffersRD::get_vrs_usage_bits() { return RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT; } + +float RenderSceneBuffersRD::get_luminance_multiplier() const { + // On mobile renderer when not using HDR2D we need to scale HDR values by two + // to fit 0-2 range color values into a UNORM buffer. + return (force_hdr || can_be_storage) ? 1.0 : 2.0; +} 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 11c593001d9..8f07029c29e 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 @@ -65,8 +65,9 @@ class RenderSceneBuffersRD : public RenderSceneBuffers { private: bool can_be_storage = true; + bool force_hdr = false; uint32_t max_cluster_elements = 512; - RD::DataFormat base_data_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + RD::DataFormat preferred_data_format = RD::DATA_FORMAT_MAX; RendererRD::VRS *vrs = nullptr; uint64_t auto_exposure_version = 1; RS::ViewportVRSMode vrs_mode = RS::VIEWPORT_VRS_DISABLED; @@ -186,8 +187,10 @@ public: bool get_can_be_storage() const { return can_be_storage; } void set_max_cluster_elements(const uint32_t p_max_elements) { max_cluster_elements = p_max_elements; } uint32_t get_max_cluster_elements() { return max_cluster_elements; } - void set_base_data_format(const RD::DataFormat p_base_data_format) { base_data_format = p_base_data_format; } - RD::DataFormat get_base_data_format() const { return base_data_format; } + void set_preferred_data_format(const RD::DataFormat p_preferred_data_format) { preferred_data_format = p_preferred_data_format; } + RD::DataFormat get_preferred_data_format() const { return preferred_data_format; } + RD::DataFormat get_base_data_format() const { return force_hdr ? RD::DATA_FORMAT_R16G16B16A16_SFLOAT : preferred_data_format; } + float get_luminance_multiplier() const; void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; } RS::ViewportVRSMode get_vrs_mode() { return vrs_mode; } diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 97fd1cb1bf7..d398bf25b87 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1504,8 +1504,7 @@ Ref TextureStorage::texture_2d_get(RID p_texture) const { ERR_FAIL_COND_V(data.is_empty(), Ref()); Ref image; - // Expand RGB10_A2 into RGBAH. This is needed for capturing viewport data - // when using the mobile renderer with HDR mode on. + // Expand RGB10_A2 into RGBAH. if (tex->rd_format == RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32) { Vector new_data; new_data.resize(data.size() * 2); @@ -4533,7 +4532,7 @@ RID TextureStorage::render_target_get_vrs_texture(RID p_render_target) const { RD::DataFormat TextureStorage::render_target_get_color_format(bool p_use_hdr, bool p_srgb) { if (p_use_hdr) { - return RendererSceneRenderRD::get_singleton()->_render_buffers_get_color_format(); + return RD::DATA_FORMAT_R16G16B16A16_SFLOAT; } else { return p_srgb ? RD::DATA_FORMAT_R8G8B8A8_SRGB : RD::DATA_FORMAT_R8G8B8A8_UNORM; }