diff options
author | Spartan322 <Megacake1234@gmail.com> | 2024-11-20 16:20:16 -0500 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2024-11-20 18:02:42 -0500 |
commit | 9857e4762b8d076259c4be863ba9f53df306d940 (patch) | |
tree | b03c5b5de96e29ffb7e1b008912d21aba5629bc5 /servers | |
parent | fd9045fe09e9bea691f0169c16d45cbebddb6bba (diff) | |
parent | 9e6098432aac35bae42c9089a29ba2a80320d823 (diff) | |
download | redot-engine-9857e4762b8d076259c4be863ba9f53df306d940.tar.gz |
Merge commit godotengine/godot@9e6098432aac35bae42c9089a29ba2a80320d823
Diffstat (limited to 'servers')
8 files changed, 109 insertions, 112 deletions
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index e71e3f6efb..0ecc0f39f5 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -974,26 +974,26 @@ SkyRD::~SkyRD() { } } -void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const Size2i p_screen_size, Vector2 p_jitter, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(p_env.is_null()); + ERR_FAIL_COND(p_render_data->environment.is_null()); - ERR_FAIL_COND(p_render_buffers.is_null()); + ERR_FAIL_COND(p_render_data->render_buffers.is_null()); // make sure we support our view count - ERR_FAIL_COND(p_view_count == 0); - ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); + ERR_FAIL_COND(p_render_data->scene_data->view_count == 0); + ERR_FAIL_COND(p_render_data->scene_data->view_count > RendererSceneRender::MAX_RENDER_VIEWS); SkyMaterialData *material = nullptr; - Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_render_data->environment)); RID sky_material; SkyShaderData *shader_data = nullptr; if (sky) { - sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_render_data->environment)); if (sky_material.is_valid()) { material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY)); @@ -1027,8 +1027,8 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con update_dirty_skys(); } - if (shader_data->uses_time && p_scene_render->time - sky->prev_time > 0.00001) { - sky->prev_time = p_scene_render->time; + if (shader_data->uses_time && p_render_data->scene_data->time - sky->prev_time > 0.00001) { + sky->prev_time = p_render_data->scene_data->time; sky->reflection.dirty = true; RenderingServerDefault::redraw_request(); } @@ -1043,29 +1043,30 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con sky->reflection.dirty = true; } - if (!p_cam_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) { - sky->prev_position = p_cam_transform.origin; + if (!p_render_data->scene_data->cam_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) { + sky->prev_position = p_render_data->scene_data->cam_transform.origin; sky->reflection.dirty = true; } } sky_scene_state.ubo.directional_light_count = 0; if (shader_data->uses_light) { + const PagedArray<RID> &lights = *p_render_data->lights; // Run through the list of lights in the scene and pick out the Directional Lights. // This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called // after the depth prepass, but this runs before the depth prepass. - for (int i = 0; i < (int)p_lights.size(); i++) { - if (!light_storage->owns_light_instance(p_lights[i])) { + for (int i = 0; i < (int)lights.size(); i++) { + if (!light_storage->owns_light_instance(lights[i])) { continue; } - RID base = light_storage->light_instance_get_base_light(p_lights[i]); + RID base = light_storage->light_instance_get_base_light(lights[i]); ERR_CONTINUE(base.is_null()); RS::LightType type = light_storage->light_get_type(base); if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) { SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count]; - Transform3D light_transform = light_storage->light_instance_get_base_transform(p_lights[i]); + Transform3D light_transform = light_storage->light_instance_get_base_transform(lights[i]); Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); sky_light_data.direction[0] = world_direction.x; @@ -1075,12 +1076,12 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con float sign = light_storage->light_is_negative(base) ? -1 : 1; sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); - if (p_scene_render->is_using_physical_light_units()) { + if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) { sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY); } - if (p_camera_attributes.is_valid()) { - sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes); + if (p_render_data->camera_attributes.is_valid()) { + sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes); } Color linear_col = light_storage->light_get_color(base).srgb_to_linear(); @@ -1151,43 +1152,48 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con // Setup fog variables. sky_scene_state.ubo.volumetric_fog_enabled = false; - if (p_render_buffers.is_valid()) { - if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) { - Ref<RendererRD::Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG); - sky_scene_state.ubo.volumetric_fog_enabled = true; - - float fog_end = fog->length; - if (fog_end > 0.0) { - sky_scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end; - } else { - sky_scene_state.ubo.volumetric_fog_inv_length = 1.0; - } + if (p_render_data->render_buffers->has_custom_data(RB_SCOPE_FOG)) { + Ref<RendererRD::Fog::VolumetricFog> fog = p_render_data->render_buffers->get_custom_data(RB_SCOPE_FOG); + sky_scene_state.ubo.volumetric_fog_enabled = true; - float fog_detail_spread = fog->spread; // Reverse lookup. - if (fog_detail_spread > 0.0) { - sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread; - } else { - sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0; - } + float fog_end = fog->length; + if (fog_end > 0.0) { + sky_scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end; + } else { + sky_scene_state.ubo.volumetric_fog_inv_length = 1.0; + } - sky_scene_state.fog_uniform_set = fog->sky_uniform_set; + float fog_detail_spread = fog->spread; // Reverse lookup. + if (fog_detail_spread > 0.0) { + sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread; + } else { + sky_scene_state.ubo.volumetric_fog_detail_spread = 1.0; } + + sky_scene_state.fog_uniform_set = fog->sky_uniform_set; } + sky_scene_state.view_count = p_render_data->scene_data->view_count; + sky_scene_state.cam_transform = p_render_data->scene_data->cam_transform; + Projection correction; - correction.set_depth_correction(false, true); - correction.add_jitter_offset(p_jitter); + correction.set_depth_correction(p_render_data->scene_data->flip_y, true); + correction.add_jitter_offset(p_render_data->scene_data->taa_jitter); + + Projection projection = p_render_data->scene_data->cam_projection; + if (p_render_data->scene_data->cam_frustum) { + // We don't use a full projection matrix for the sky, this is enough to make up for it. + projection[2].y = -projection[2].y; + } - sky_scene_state.view_count = p_view_count; - sky_scene_state.cam_transform = p_cam_transform; - sky_scene_state.cam_projection = correction * p_cam_projection; // We only use this when rendering a single view. + sky_scene_state.cam_projection = correction * projection; // Our info in our UBO is only used if we're rendering stereo. - for (uint32_t i = 0; i < p_view_count; i++) { - Projection view_inv_projection = (correction * p_view_projections[i]).inverse(); - if (p_view_count > 1) { + for (uint32_t i = 0; i < p_render_data->scene_data->view_count; i++) { + Projection view_inv_projection = (correction * p_render_data->scene_data->view_projection[i]).inverse(); + if (p_render_data->scene_data->view_count > 1) { // Reprojection is used when we need to have things in combined space. - RendererRD::MaterialStorage::store_camera(p_cam_projection * view_inv_projection, sky_scene_state.ubo.combined_reprojection[i]); + RendererRD::MaterialStorage::store_camera(p_render_data->scene_data->cam_projection * view_inv_projection, sky_scene_state.ubo.combined_reprojection[i]); } else { // This is unused so just reset to identity. Projection ident; @@ -1195,25 +1201,25 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con } RendererRD::MaterialStorage::store_camera(view_inv_projection, sky_scene_state.ubo.view_inv_projections[i]); - sky_scene_state.ubo.view_eye_offsets[i][0] = p_view_eye_offsets[i].x; - sky_scene_state.ubo.view_eye_offsets[i][1] = p_view_eye_offsets[i].y; - sky_scene_state.ubo.view_eye_offsets[i][2] = p_view_eye_offsets[i].z; + sky_scene_state.ubo.view_eye_offsets[i][0] = p_render_data->scene_data->view_eye_offset[i].x; + sky_scene_state.ubo.view_eye_offsets[i][1] = p_render_data->scene_data->view_eye_offset[i].y; + sky_scene_state.ubo.view_eye_offsets[i][2] = p_render_data->scene_data->view_eye_offset[i].z; sky_scene_state.ubo.view_eye_offsets[i][3] = 0.0; } - sky_scene_state.ubo.z_far = p_view_projections[0].get_z_far(); // Should be the same for all projection. - sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env); - sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env); - sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env); - Color fog_color = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_color(p_env).srgb_to_linear(); - float fog_energy = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_energy(p_env); + sky_scene_state.ubo.z_far = p_render_data->scene_data->view_projection[0].get_z_far(); // Should be the same for all projection. + sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_render_data->environment); + sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_render_data->environment); + sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_render_data->environment); + Color fog_color = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); + float fog_energy = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_energy(p_render_data->environment); sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env); + sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_render_data->environment); - sky_scene_state.ubo.fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_fog_sky_affect(p_env); - sky_scene_state.ubo.volumetric_fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_sky_affect(p_env); + sky_scene_state.ubo.fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_fog_sky_affect(p_render_data->environment); + sky_scene_state.ubo.volumetric_fog_sky_affect = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_sky_affect(p_render_data->environment); RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } @@ -1294,7 +1300,7 @@ void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); Projection correction; - correction.set_depth_correction(true); + correction.set_depth_correction(false); cm = correction * cm; // Note, we ignore environment_get_sky_orientation here as this is applied when we do our lookup in our scene shader. diff --git a/servers/rendering/renderer_rd/environment/sky.h b/servers/rendering/renderer_rd/environment/sky.h index c74144734e..608afa1852 100644 --- a/servers/rendering/renderer_rd/environment/sky.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -38,6 +38,7 @@ #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/render_data_rd.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/shader_compiler.h" @@ -296,7 +297,7 @@ public: void set_texture_format(RD::DataFormat p_texture_format); ~SkyRD(); - void setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const Size2i p_screen_size, Vector2 p_jitter, RendererSceneRenderRD *p_scene_render); + void setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size); void update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0); void update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0); void draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0); 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 73c2b8aa39..0eb99feaac 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1959,22 +1959,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Setup Sky"); // Setup our sky render information for this frame/viewport - if (is_reflection_probe) { - Vector3 eye_offset; - Projection correction; - correction.set_depth_correction(true); - Projection projection = correction * p_render_data->scene_data->cam_projection; - - sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this); - } else { - Projection projection = p_render_data->scene_data->cam_projection; - if (p_render_data->scene_data->cam_frustum) { - // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. - projection[2].y = -projection[2].y; - } - - sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this); - } + sky.setup_sky(p_render_data, screen_size); sky_energy_multiplier *= bg_energy_multiplier; 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 d7e4d31e43..18a673e15a 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -974,23 +974,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - // Setup our sky render information for this frame/viewport - if (is_reflection_probe) { - Vector3 eye_offset; - Projection correction; - correction.set_depth_correction(true); - Projection projection = correction * p_render_data->scene_data->cam_projection; - - sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this); - } else { - Projection projection = p_render_data->scene_data->cam_projection; - if (p_render_data->scene_data->cam_frustum) { - // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. - projection[2].y = -projection[2].y; - } - - sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this); - } + sky.setup_sky(p_render_data, screen_size); sky_energy_multiplier *= bg_energy_multiplier; diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index cc1c40cad1..7bb2e0a539 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -189,7 +189,7 @@ void main() { vec3 cube_normal; #ifdef USE_MULTIVIEW // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject. - vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 0.0, 1.0); // unproject at the far plane + vec4 unproject = vec4(uv_interp.x, uv_interp.y, 0.0, 1.0); // unproject at the far plane vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject; cube_normal = unprojected.xyz / unprojected.w; @@ -198,7 +198,7 @@ void main() { #else cube_normal.z = -1.0; cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y; - cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projection.z)) / params.projection.w; + cube_normal.y = -(cube_normal.z * (uv_interp.y - params.projection.z)) / params.projection.w; #endif cube_normal = mat3(params.orientation) * cube_normal; cube_normal = normalize(cube_normal); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index f564ca64a5..cd0c23564c 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -948,6 +948,7 @@ RID RenderingDevice::texture_create_shared(const TextureView &p_view, RID p_with RDG::ResourceTracker *tracker = RDG::resource_tracker_create(); tracker->texture_driver_id = texture.shared_fallback->texture; + tracker->texture_size = Size2i(texture.width, texture.height); tracker->texture_subresources = texture.barrier_range(); tracker->texture_usage = alias_format.usage_bits; tracker->reference_count = 1; @@ -1127,6 +1128,7 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view, RDG::ResourceTracker *tracker = RDG::resource_tracker_create(); tracker->texture_driver_id = texture.shared_fallback->texture; + tracker->texture_size = Size2i(texture.width, texture.height); tracker->texture_subresources = slice_range; tracker->texture_usage = slice_format.usage_bits; tracker->reference_count = 1; @@ -5417,6 +5419,7 @@ bool RenderingDevice::_texture_make_mutable(Texture *p_texture, RID p_texture_id draw_tracker = RDG::resource_tracker_create(); draw_tracker->parent = owner_texture->draw_tracker; draw_tracker->texture_driver_id = p_texture->driver_id; + draw_tracker->texture_size = Size2i(p_texture->width, p_texture->height); draw_tracker->texture_subresources = p_texture->barrier_range(); draw_tracker->texture_usage = p_texture->usage_flags; draw_tracker->texture_slice_or_dirty_rect = p_texture->slice_rect; @@ -5439,6 +5442,7 @@ bool RenderingDevice::_texture_make_mutable(Texture *p_texture, RID p_texture_id // Regular texture. p_texture->draw_tracker = RDG::resource_tracker_create(); p_texture->draw_tracker->texture_driver_id = p_texture->driver_id; + p_texture->draw_tracker->texture_size = Size2i(p_texture->width, p_texture->height); p_texture->draw_tracker->texture_subresources = p_texture->barrier_range(); p_texture->draw_tracker->texture_usage = p_texture->usage_flags; p_texture->draw_tracker->reference_count = 1; diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp index bf0530b565..f7d4f3e31f 100644 --- a/servers/rendering/rendering_device_graph.cpp +++ b/servers/rendering/rendering_device_graph.cpp @@ -142,7 +142,7 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage #endif } -bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const { +bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const { if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) { // We don't check possible intersections for usages that aren't consecutive color or depth writes. return true; @@ -157,15 +157,27 @@ bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resour return true; } - if (!r_intersection_partial_coverage) { - // Indicate if this draw list only partially covers the region of the previous draw list. - r_intersection_partial_coverage = !current_draw_list_command.region.encloses(previous_draw_list_command.region); - } - // We check if the region used by both draw lists have an intersection. return previous_draw_list_command.region.intersects(current_draw_list_command.region); } +bool RenderingDeviceGraph::_check_command_partial_coverage(ResourceTracker *p_resource_tracker, int32_t p_command_index) const { + if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) { + // We don't check for partial coverage in usages that aren't attachment writes. + return true; + } + + const uint32_t command_data_offset = command_data_offsets[p_command_index]; + const RecordedDrawListCommand &draw_list_command = *reinterpret_cast<const RecordedDrawListCommand *>(&command_data[command_data_offset]); + if (draw_list_command.type != RecordedCommand::TYPE_DRAW_LIST) { + // We don't check for partial coverage on commands that aren't draw lists. + return false; + } + + Rect2i texture_region(Point2i(0, 0), p_resource_tracker->texture_size); + return !draw_list_command.region.encloses(texture_region); +} + int32_t RenderingDeviceGraph::_add_to_command_list(int32_t p_command_index, int32_t p_list_index) { DEV_ASSERT(p_command_index < int32_t(command_count)); DEV_ASSERT(p_list_index < int32_t(command_list_nodes.size())); @@ -201,7 +213,7 @@ int32_t RenderingDeviceGraph::_add_to_slice_read_list(int32_t p_command_index, R return next_index; } -int32_t RenderingDeviceGraph::_add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index) { +int32_t RenderingDeviceGraph::_add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index, bool p_partial_coverage) { DEV_ASSERT(p_command_index < int32_t(command_count)); DEV_ASSERT(p_list_index < int32_t(write_slice_list_nodes.size())); @@ -212,6 +224,7 @@ int32_t RenderingDeviceGraph::_add_to_write_list(int32_t p_command_index, Rect2i new_node.command_index = p_command_index; new_node.next_list_index = p_list_index; new_node.subresources = p_subresources; + new_node.partial_coverage = p_partial_coverage; return next_index; } @@ -478,7 +491,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr resource_tracker->usage = new_resource_usage; } - bool intersection_partial_coverage = false; + bool write_usage_has_partial_coverage = !different_usage && _check_command_partial_coverage(resource_tracker, p_command_index); if (search_tracker->write_command_or_list_index >= 0) { if (search_tracker->write_command_list_enabled) { // Make this command adjacent to any commands that wrote to this resource and intersect with the slice if it applies. @@ -490,11 +503,11 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr if (!resource_has_parent || search_tracker_rect.intersects(write_list_node.subresources)) { if (write_list_node.command_index == p_command_index) { ERR_FAIL_COND_MSG(!resource_has_parent, "Command can't have itself as a dependency."); - } else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index, intersection_partial_coverage)) { + } else if (!write_list_node.partial_coverage || _check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index)) { // Command is dependent on this command. Add this command to the adjacency list of the write command. _add_adjacent_command(write_list_node.command_index, p_command_index, r_command); - if (resource_has_parent && write_usage && search_tracker_rect.encloses(write_list_node.subresources)) { + if (resource_has_parent && write_usage && search_tracker_rect.encloses(write_list_node.subresources) && !write_usage_has_partial_coverage) { // Eliminate redundant writes from the list. if (previous_write_list_index >= 0) { RecordedSliceListNode &previous_list_node = write_slice_list_nodes[previous_write_list_index]; @@ -516,22 +529,23 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr // The index is just the latest command index that wrote to the resource. if (search_tracker->write_command_or_list_index == p_command_index) { ERR_FAIL_MSG("Command can't have itself as a dependency."); - } else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index, intersection_partial_coverage)) { + } else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index)) { _add_adjacent_command(search_tracker->write_command_or_list_index, p_command_index, r_command); } } } if (write_usage) { - if (resource_has_parent || intersection_partial_coverage) { + bool use_write_list = resource_has_parent || write_usage_has_partial_coverage; + if (use_write_list) { if (!search_tracker->write_command_list_enabled && search_tracker->write_command_or_list_index >= 0) { // Write command list was not being used but there was a write command recorded. Add a new node with the entire parent resource's subresources and the recorded command index to the list. const RDD::TextureSubresourceRange &tracker_subresources = search_tracker->texture_subresources; Rect2i tracker_rect(tracker_subresources.base_mipmap, tracker_subresources.base_layer, tracker_subresources.mipmap_count, tracker_subresources.layer_count); - search_tracker->write_command_or_list_index = _add_to_write_list(search_tracker->write_command_or_list_index, tracker_rect, -1); + search_tracker->write_command_or_list_index = _add_to_write_list(search_tracker->write_command_or_list_index, tracker_rect, -1, false); } - search_tracker->write_command_or_list_index = _add_to_write_list(p_command_index, search_tracker_rect, search_tracker->write_command_or_list_index); + search_tracker->write_command_or_list_index = _add_to_write_list(p_command_index, search_tracker_rect, search_tracker->write_command_or_list_index, write_usage_has_partial_coverage); search_tracker->write_command_list_enabled = true; } else { search_tracker->write_command_or_list_index = p_command_index; @@ -556,7 +570,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr read_full_command_list_index = read_full_next_index; } - if (!resource_has_parent) { + if (!use_write_list) { // Clear the full list if this resource is not a slice. search_tracker->read_full_command_list_index = -1; } @@ -566,7 +580,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr int32_t read_slice_command_list_index = search_tracker->read_slice_command_list_index; while (read_slice_command_list_index >= 0) { const RecordedSliceListNode &read_list_node = read_slice_list_nodes[read_slice_command_list_index]; - if (!resource_has_parent || search_tracker_rect.encloses(read_list_node.subresources)) { + if (!use_write_list || search_tracker_rect.encloses(read_list_node.subresources)) { if (previous_slice_command_list_index >= 0) { // Erase this element and connect the previous one to the next element. read_slice_list_nodes[previous_slice_command_list_index].next_list_index = read_list_node.next_list_index; diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h index 222bff8f95..3cb43b3931 100644 --- a/servers/rendering/rendering_device_graph.h +++ b/servers/rendering/rendering_device_graph.h @@ -169,6 +169,7 @@ public: RDD::BufferID buffer_driver_id; RDD::TextureID texture_driver_id; RDD::TextureSubresourceRange texture_subresources; + Size2i texture_size; uint32_t texture_usage = 0; int32_t texture_slice_command_index = -1; ResourceTracker *parent = nullptr; @@ -273,6 +274,7 @@ private: int32_t command_index = -1; int32_t next_list_index = -1; Rect2i subresources; + bool partial_coverage = false; }; struct RecordedBufferClearCommand : RecordedCommand { @@ -651,11 +653,12 @@ private: static bool _is_write_usage(ResourceUsage p_usage); static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage); static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage); - bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const; + bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const; + bool _check_command_partial_coverage(ResourceTracker *p_resource_tracker, int32_t p_command_index) const; int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index); void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command); int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index); - int32_t _add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index); + int32_t _add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index, bool p_partial_coverage); RecordedCommand *_allocate_command(uint32_t p_command_size, int32_t &r_command_index); DrawListInstruction *_allocate_draw_list_instruction(uint32_t p_instruction_size); ComputeListInstruction *_allocate_compute_list_instruction(uint32_t p_instruction_size); |