diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index ab6e0a6942ff8..9948e70880e8b 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -532,7 +532,22 @@ void SkyRD::Sky::free() { } } -RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref p_render_buffers) { +RID SkyRD::SkyShader::get_default_shader_rd(bool p_is_multiview) { + RID &shader_rd = p_is_multiview ? default_multiview_shader_rd : default_shader_rd; + + if (shader_rd.is_null()) { + RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + ERR_FAIL_NULL_V(material_storage, RID()); + ERR_FAIL_COND_V(!default_material.is_valid(), RID()); + + SkyMaterialData *md = static_cast(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); + shader_rd = shader.version_get_shader(md->shader_data->version, p_is_multiview ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND); + } + + return shader_rd; +} + +RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, bool p_is_multiview, Ref p_render_buffers) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); thread_local LocalVector uniforms; @@ -564,7 +579,7 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade if (half_texture.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES) { u.append_id(half_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(p_is_multiview ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } } uniforms.push_back(u); @@ -584,7 +599,7 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade if (quarter_texture.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES) { u.append_id(quarter_texture); } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(p_is_multiview ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); } } uniforms.push_back(u); @@ -895,6 +910,14 @@ void sky() { material_storage->material_initialize(sky_scene_state.fog_material); material_storage->material_set_shader(sky_scene_state.fog_material, sky_scene_state.fog_shader); + } +} + +RID SkyRD::SkySceneState::get_fog_only_texture_uniform_set(RID p_default_shader_rd, bool p_is_multiview) { + RID &uniform_set_rid = p_is_multiview ? fog_only_texture_multiview_uniform_set : fog_only_texture_uniform_set; + + if (uniform_set_rid.is_null()) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); Vector uniforms; { @@ -908,19 +931,21 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(p_is_multiview ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_storage->texture_rd_get_default(p_is_multiview ? RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE : RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } - sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES); + uniform_set_rid = RD::get_singleton()->uniform_set_create(uniforms, p_default_shader_rd, SKY_SET_TEXTURES); } + + return uniform_set_rid; } void SkyRD::set_texture_format(RD::DataFormat p_texture_format) { @@ -950,9 +975,13 @@ SkyRD::~SkyRD() { RD::get_singleton()->free_rid(sky_scene_state.default_fog_uniform_set); } - if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_only_texture_uniform_set)) { + if (sky_scene_state.fog_only_texture_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_only_texture_uniform_set)) { RD::get_singleton()->free_rid(sky_scene_state.fog_only_texture_uniform_set); } + + if (sky_scene_state.fog_only_texture_multiview_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_only_texture_multiview_uniform_set)) { + RD::get_singleton()->free_rid(sky_scene_state.fog_only_texture_multiview_uniform_set); + } } void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size) { @@ -1290,7 +1319,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, clear_colors.push_back(Color(0.0, 0.0, 0.0)); RD::DrawListID octmap_draw_list; - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP_QUARTER_RES, sky_shader.default_shader_rd, false, p_render_buffers); octmap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffer, RD::DRAW_IGNORE_COLOR_ALL); _render_sky(octmap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffer, pipeline, material->uniform_set, texture_uniform_set, cm, Basis(), p_global_pos, p_luminance_multiplier, p_brightness_multiplier, sky->uv_border_size); @@ -1309,7 +1338,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, clear_colors.push_back(Color(0.0, 0.0, 0.0)); RD::DrawListID octmap_draw_list; - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP_HALF_RES, sky_shader.default_shader_rd, false, p_render_buffers); octmap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffer, RD::DRAW_IGNORE_COLOR_ALL); _render_sky(octmap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffer, pipeline, material->uniform_set, texture_uniform_set, cm, Basis(), p_global_pos, p_luminance_multiplier, p_brightness_multiplier, sky->uv_border_size); @@ -1325,7 +1354,7 @@ void SkyRD::update_radiance_buffers(Ref p_render_buffers, RD::get_singleton()->draw_command_begin_label("Render Sky Octmap"); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP, sky_shader.default_shader_rd, p_render_buffers); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_OCTMAP, sky_shader.default_shader_rd, false, p_render_buffers); octmap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffer, RD::DRAW_IGNORE_COLOR_ALL, Vector(), 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::SKY_PASS); _render_sky(octmap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffer, pipeline, material->uniform_set, texture_uniform_set, cm, Basis(), p_global_pos, p_luminance_multiplier, p_brightness_multiplier, sky->uv_border_size); @@ -1426,8 +1455,10 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p sky_transform = sky_transform * sky_scene_state.cam_transform.basis; + bool is_multiview = sky_scene_state.view_count > 1; + if (shader_data->uses_quarter_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[is_multiview ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES]; // Grab texture and framebuffer from cache, create if needed... uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; @@ -1435,7 +1466,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, quarter_size); RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.get_default_shader_rd(is_multiview), is_multiview, p_render_buffers); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_IGNORE_COLOR_ALL); _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier, sky->uv_border_size); @@ -1443,7 +1474,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p } if (shader_data->uses_half_res) { - PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; + PipelineCacheRD *pipeline = &shader_data->pipelines[is_multiview ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES]; // Grab texture and framebuffer from cache, create if needed... uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; @@ -1451,7 +1482,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, half_size); RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture); - RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd, p_render_buffers); + RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.get_default_shader_rd(is_multiview), is_multiview, p_render_buffers); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_IGNORE_COLOR_ALL); _render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier, sky->uv_border_size); @@ -1510,15 +1541,19 @@ void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref p_ren sky_transform = sky_transform * sky_scene_state.cam_transform.basis; - PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; + bool is_multiview = sky_scene_state.view_count > 1; + + PipelineCacheRD *pipeline = &shader_data->pipelines[is_multiview ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND]; + + RID default_shader_rd = sky_shader.get_default_shader_rd(is_multiview); RID texture_uniform_set; float border_size = 0.0; if (sky) { - texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd, p_render_buffers); + texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, default_shader_rd, is_multiview, p_render_buffers); border_size = sky->uv_border_size; } else { - texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set; + texture_uniform_set = sky_scene_state.get_fog_only_texture_uniform_set(default_shader_rd, is_multiview); } _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier, p_brightness_multiplier, border_size); diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index 14ea88f83e25d..7d58dae277918 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -180,7 +180,12 @@ class SkyRD { RID fog_shader; RID fog_material; + + // These are lazily initialized, use "get_fog_only_texture_uniform_set" instead. RID fog_only_texture_uniform_set; + RID fog_only_texture_multiview_uniform_set; + + RID get_fog_only_texture_uniform_set(RID p_default_shader_rd, bool p_is_multiview); } sky_scene_state; struct ReflectionData { @@ -231,6 +236,9 @@ class SkyRD { RID default_shader; RID default_material; RID default_shader_rd; + RID default_multiview_shader_rd; // This is lazily initialized, use "get_default_shader_rd" instead. + + RID get_default_shader_rd(bool p_is_multiview = false); } sky_shader; struct SkyMaterialData : public RendererRD::MaterialStorage::MaterialData { @@ -280,7 +288,7 @@ class SkyRD { void free(); - RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref p_render_buffers); + RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, bool p_is_multiview, Ref p_render_buffers); bool set_radiance_size(int p_radiance_size); int get_radiance_size() const; bool set_mode(RSE::SkyMode p_mode); 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 7ed902187ecbb..22515f5a12143 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1718,6 +1718,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co rb_data = rb->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED); } bool is_reflection_probe = p_render_data->reflection_probe.is_valid(); + bool is_multiview = rb->get_view_count() > 1; static const int texture_multisamples[RSE::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 }; @@ -2135,7 +2136,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers, depth_prepass_uniform_buffer_index); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, is_multiview, RID(), samplers, depth_prepass_uniform_buffer_index); bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi || ce_pre_opaque_resolved_depth || ce_post_opaque_resolved_depth; RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RSE::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, base_specialization); @@ -2198,7 +2199,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co uint32_t opaque_pass_uniform_buffer_index = _setup_environment(p_render_data, is_reflection_probe, screen_size, screen_size, p_default_bg_color, true, using_motion_pass); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, opaque_pass_uniform_buffer_index, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, is_multiview, radiance_texture, samplers, opaque_pass_uniform_buffer_index, true); { bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty(); @@ -2244,7 +2245,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RENDER_TIMESTAMP("Render Motion Pass"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_MOTION, p_render_data, radiance_texture, samplers, opaque_pass_uniform_buffer_index, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_MOTION, p_render_data, is_multiview, radiance_texture, samplers, opaque_pass_uniform_buffer_index, true); RenderListParameters render_list_params(render_list[RENDER_LIST_MOTION].elements.ptr(), render_list[RENDER_LIST_MOTION].element_info.ptr(), render_list[RENDER_LIST_MOTION].elements.size(), reverse_cull, PASS_MODE_COLOR, color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RSE::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, base_specialization); _render_list_with_draw_list(&render_list_params, color_framebuffer); @@ -2414,7 +2415,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co uint32_t transparent_pass_uniform_buffer_index = _setup_environment(p_render_data, is_reflection_probe, screen_size, screen_size, p_default_bg_color, false); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, transparent_pass_uniform_buffer_index, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, is_multiview, radiance_texture, samplers, transparent_pass_uniform_buffer_index, true); { uint32_t transparent_color_pass_flags = (color_pass_flags | uint32_t(COLOR_PASS_FLAG_TRANSPARENT)) & ~uint32_t(COLOR_PASS_FLAG_SEPARATE_SPECULAR); @@ -2890,7 +2891,7 @@ void RenderForwardClustered::_render_shadow_process() { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { //render passes need to be configured after instance buffer is done, since they need the latest version SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), shadow_pass.uniform_buffer_index, false); + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), shadow_pass.uniform_buffer_index, false); } RD::get_singleton()->draw_command_end_label(); @@ -2942,7 +2943,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), uniform_buffer_index); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), uniform_buffer_index); RENDER_TIMESTAMP("Render Collider Heightfield"); @@ -2993,7 +2994,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), uniform_buffer_index); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), uniform_buffer_index); RENDER_TIMESTAMP("Render 3D Material"); @@ -3049,7 +3050,7 @@ void RenderForwardClustered::_render_uv2(const PagedArraysamplers_rd_get_default(), uniform_buffer_index); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), uniform_buffer_index); RENDER_TIMESTAMP("Render 3D Material"); @@ -3378,17 +3379,16 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } } -RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_uniform_buffer_index, bool p_use_directional_shadow_atlas) { +RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, bool p_is_multiview, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_uniform_buffer_index, bool p_use_directional_shadow_atlas) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); - bool is_multiview = false; + bool is_multiview = p_is_multiview; Ref rb; // handy for not having to fully type out p_render_data->render_buffers all the time... Ref rb_data; if (p_render_data && p_render_data->render_buffers.is_valid()) { rb = p_render_data->render_buffers; - is_multiview = rb->get_view_count() > 1; if (rb->has_custom_data(RB_SCOPE_FORWARD_CLUSTERED)) { // Our forward clustered custom data buffer will only be available when we're rendering our normal view. // This will not be available when rendering reflection probes. diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index be97ee2d96af1..7dec40d892d75 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -176,7 +176,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _update_render_base_uniform_set(); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_uniform_buffer_index); - RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_uniform_buffer_index, bool p_use_directional_shadow_atlas = false); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, bool p_is_multiview, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, uint32_t p_uniform_buffer_index, bool p_use_directional_shadow_atlas = false); struct BestFitNormal { BestFitNormalShaderRD shader; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 78527add2a1b5..856f1001b6a89 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -1048,16 +1048,22 @@ uint32_t SceneShaderForwardClustered::get_pipeline_compilations(RSE::PipelineSou return pipeline_compilations[p_source]; } -RID SceneShaderForwardClustered::get_default_shader_rd(bool is_multiview) { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_NULL_V(material_storage, RID()); - ERR_FAIL_COND_V(!default_material.is_valid(), RID()); +RID SceneShaderForwardClustered::get_default_shader_rd(bool p_is_multiview) { + RID &shader_rd = p_is_multiview ? default_multiview_shader_rd : default_shader_rd; + + if (shader_rd.is_null()) { + RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + ERR_FAIL_NULL_V(material_storage, RID()); + ERR_FAIL_COND_V(!default_material.is_valid(), RID()); - uint32_t flags = 0; - if (is_multiview) { - flags |= SHADER_COLOR_PASS_FLAG_MULTIVIEW; + uint32_t flags = 0; + if (p_is_multiview) { + flags |= SHADER_COLOR_PASS_FLAG_MULTIVIEW; + } + + MaterialData *md = static_cast(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); + shader_rd = md->shader_data->get_shader_variant(PIPELINE_VERSION_COLOR_PASS, flags, false); } - MaterialData *md = static_cast(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); - return md->shader_data->get_shader_variant(PIPELINE_VERSION_COLOR_PASS, flags, false); + return shader_rd; } diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 638d6623d99ec..5e1af939eb9f9 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -355,6 +355,7 @@ class SceneShaderForwardClustered { RID debug_shadow_splits_material_shader; RID debug_shadow_splits_material; RID default_shader_rd; + RID default_multiview_shader_rd; // This is lazily initialized, use "get_default_shader_rd" instead. RID default_shader_sdfgi_rd; RID default_vec4_xform_buffer; @@ -385,7 +386,7 @@ class SceneShaderForwardClustered { bool is_multiview_shader_group_enabled() const; bool is_advanced_shader_group_enabled(bool p_multiview) const; uint32_t get_pipeline_compilations(RSE::PipelineSource p_source); - RID get_default_shader_rd(bool is_multiview = false); + RID get_default_shader_rd(bool p_is_multiview = false); }; } // namespace RendererSceneRenderImplementation 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 d6fdb458e67a6..9efb98754e2b2 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -466,17 +466,16 @@ bool RenderForwardMobile::_render_buffers_can_be_storage() { return false; } -RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas, uint32_t p_pass_offset) { +RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, bool p_is_multiview, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas, uint32_t p_pass_offset) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - bool is_multiview = false; + bool is_multiview = p_is_multiview; Ref rb_data; Ref rb; if (p_render_data && p_render_data->render_buffers.is_valid()) { rb = p_render_data->render_buffers; - is_multiview = rb->get_view_count() > 1; if (rb->has_custom_data(RB_SCOPE_MOBILE)) { // Our forward mobile custom data buffer will only be available when we're rendering our normal view. // This will not be available when rendering reflection probes. @@ -840,6 +839,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color rb_data = rb->get_custom_data(RB_SCOPE_MOBILE); } bool is_reflection_probe = p_render_data->reflection_probe.is_valid(); + bool is_multiview = rb->get_view_count() > 1; RENDER_TIMESTAMP("Prepare 3D Scene"); @@ -1203,7 +1203,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Motion Vectors"); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, is_multiview, RID(), samplers); RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_MOTION_VECTORS, rp_uniform_set, base_specialization); _render_list_with_draw_list(&render_list_params, mv_fb, RD::DRAW_CLEAR_ALL, mv_pass_clear); @@ -1229,7 +1229,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RENDER_TIMESTAMP("Render Opaque"); } - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, is_multiview, radiance_texture, samplers, true); // Set clear colors. Vector c; @@ -1290,7 +1290,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Transparent"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, is_multiview, radiance_texture, samplers, true); RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, base_specialization, get_debug_draw_mode() == RSE::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count); render_list_params.framebuffer_format = fb_format; @@ -1356,7 +1356,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); RENDER_TIMESTAMP("Render Transparent"); - rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, samplers, true); + rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, is_multiview, radiance_texture, samplers, true); // this may be needed if we re-introduced steps that change info, not sure which do so in the previous implementation //_setup_environment(p_render_data, is_reflection_probe, screen_size, screen_size, p_default_bg_color, false); @@ -1676,7 +1676,7 @@ void RenderForwardMobile::_render_shadow_process() { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { //render passes need to be configured after instance buffer is done, since they need the latest version SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; - shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), false, scene_state.shadow_passes.size() - 1u - i); + shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default(), false, scene_state.shadow_passes.size() - 1u - i); } RD::get_singleton()->draw_command_end_label(); @@ -1730,7 +1730,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); RENDER_TIMESTAMP("Render 3D Material"); @@ -1780,7 +1780,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); RENDER_TIMESTAMP("Render 3D Material"); @@ -1864,7 +1864,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const render_list[RENDER_LIST_SECONDARY].sort_by_key(); _fill_instance_data(RENDER_LIST_SECONDARY); - RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); + RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, false, RID(), RendererRD::MaterialStorage::get_singleton()->samplers_rd_get_default()); RENDER_TIMESTAMP("Render Collider Heightfield"); 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 0b156b05f1a7f..1d7bd719a580e 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -168,7 +168,7 @@ class RenderForwardMobile : public RendererSceneRenderRD { /* Render Scene */ - RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas = false, uint32_t p_pass_offset = 0u); + RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, bool p_is_multiview, RID p_radiance_texture, const RendererRD::MaterialStorage::Samplers &p_samplers, bool p_use_directional_shadow_atlas = false, uint32_t p_pass_offset = 0u); void _pre_opaque_render(RenderDataRD *p_render_data); uint64_t lightmap_texture_array_version = 0xFFFFFFFF; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 31f43d689d6b4..bd0b6ab6d9606 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -988,18 +988,24 @@ bool SceneShaderForwardMobile::is_multiview_shader_group_enabled() const { return shader.is_group_enabled(SHADER_GROUP_FP32_MULTIVIEW) || shader.is_group_enabled(SHADER_GROUP_FP16_MULTIVIEW); } -RID SceneShaderForwardMobile::get_default_shader_rd(bool is_multiview) { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_NULL_V(material_storage, RID()); - ERR_FAIL_COND_V(!default_material.is_valid(), RID()); +RID SceneShaderForwardMobile::get_default_shader_rd(bool p_is_multiview) { + RID &shader_rd = p_is_multiview ? default_multiview_shader_rd : default_shader_rd; + + if (shader_rd.is_null()) { + RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + ERR_FAIL_NULL_V(material_storage, RID()); + ERR_FAIL_COND_V(!default_material.is_valid(), RID()); - int variant = is_multiview ? SHADER_VERSION_COLOR_PASS_MULTIVIEW : SHADER_VERSION_COLOR_PASS; - if (use_fp16) { - variant += SHADER_VERSION_MAX * 2; + int variant = p_is_multiview ? SHADER_VERSION_COLOR_PASS_MULTIVIEW : SHADER_VERSION_COLOR_PASS; + if (use_fp16) { + variant += SHADER_VERSION_MAX * 2; + } + + MaterialData *md = static_cast(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); + shader_rd = shader.version_get_shader(md->shader_data->version, variant); } - MaterialData *md = static_cast(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); - return shader.version_get_shader(md->shader_data->version, variant); + return shader_rd; } SceneShaderForwardMobile::~SceneShaderForwardMobile() { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 1d37beddc4787..bef0e806f4a40 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -357,6 +357,7 @@ class SceneShaderForwardMobile { RID debug_shadow_splits_material_shader; RID debug_shadow_splits_material; RID default_shader_rd; + RID default_multiview_shader_rd; // This is lazily initialized, use "get_default_shader_rd" instead. RID default_vec4_xform_buffer; RID default_vec4_xform_uniform_set; @@ -386,7 +387,7 @@ class SceneShaderForwardMobile { void enable_fp16_shader_group(); void enable_multiview_shader_group(); bool is_multiview_shader_group_enabled() const; - RID get_default_shader_rd(bool is_multiview = false); + RID get_default_shader_rd(bool p_is_multiview = false); }; } // namespace RendererSceneRenderImplementation diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index ed8ba43dd2d31..2915828a99860 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -4109,6 +4109,7 @@ static const char *SHADER_UNIFORM_NAMES[RenderingDevice::UNIFORM_TYPE_MAX] = { "InputAttachment", "UniformBufferDynamic", "StorageBufferDynamic", + "AccelerationStructure", }; String RenderingDevice::_shader_uniform_debug(RID p_shader, int p_set) { @@ -4125,6 +4126,16 @@ String RenderingDevice::_shader_uniform_debug(RID p_shader, int p_set) { ret += "\n"; } ret += "Set: " + itos(i) + " Binding: " + itos(ui.binding) + " Type: " + SHADER_UNIFORM_NAMES[ui.type] + " Writable: " + (ui.writable ? "Y" : "N") + " Length: " + itos(ui.length); + + if (ui.texture_type != TEXTURE_TYPE_MAX) { + ret += " Texture Type: "; + ret += TEXTURE_TYPE_NAMES[ui.texture_type]; + } + + if (ui.texture_format != DATA_FORMAT_MAX) { + ret += " Texture Format: "; + ret += FORMAT_NAMES[ui.texture_format]; + } } } return ret; diff --git a/servers/rendering/rendering_device_commons.cpp b/servers/rendering/rendering_device_commons.cpp index ca2fd13b98d34..8315cfcbd3b44 100644 --- a/servers/rendering/rendering_device_commons.cpp +++ b/servers/rendering/rendering_device_commons.cpp @@ -273,6 +273,16 @@ const char *const RenderingDeviceCommons::FORMAT_NAMES[DATA_FORMAT_MAX] = { /**** TEXTURE ****/ /*****************/ +const char *const RenderingDeviceCommons::TEXTURE_TYPE_NAMES[TEXTURE_TYPE_MAX] = { + "1D", + "2D", + "3D", + "Cube", + "1DArray", + "2DArray", + "CubeArray", +}; + const uint32_t RenderingDeviceCommons::TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX] = { 1, 2, 4, 8, 16, 32, 64 }; uint32_t RenderingDeviceCommons::get_image_format_pixel_size(DataFormat p_format) { diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index a49dd00137d1c..082ea4d75a79c 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -1072,6 +1072,8 @@ class RenderingDeviceCommons : public Object { /**** TEXTURE ****/ /*****************/ + static const char *const TEXTURE_TYPE_NAMES[TEXTURE_TYPE_MAX]; + static const uint32_t MAX_IMAGE_FORMAT_PLANES = 2; static const uint32_t TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX]; @@ -1120,7 +1122,7 @@ class RenderingDeviceCommons : public Object { DataFormat texture_format = DATA_FORMAT_MAX; bool operator!=(const ShaderUniform &p_other) const { - return binding != p_other.binding || type != p_other.type || writable != p_other.writable || stages != p_other.stages || length != p_other.length; + return binding != p_other.binding || type != p_other.type || writable != p_other.writable || stages != p_other.stages || length != p_other.length || texture_type != p_other.texture_type || texture_format != p_other.texture_format; } bool operator<(const ShaderUniform &p_other) const { @@ -1139,6 +1141,12 @@ class RenderingDeviceCommons : public Object { if (length != p_other.length) { return length < p_other.length; } + if (texture_type != p_other.texture_type) { + return texture_type < p_other.texture_type; + } + if (texture_format != p_other.texture_format) { + return texture_format < p_other.texture_format; + } return false; } };