From c1253d3aad0ae0195c1ffc8583dc20fba5ef9c8c Mon Sep 17 00:00:00 2001 From: clayjohn Date: Mon, 8 Dec 2025 15:47:42 -0800 Subject: [PATCH] Mark more textures as discardable This allows the ARG to better optimize their usage for mobile devices. In particular, this allows the ARG to avoid loading the contents of the texture into tile memory when rendering into the texture if the contents won't be used anyway. --- servers/rendering/renderer_rd/effects/vrs.cpp | 2 +- .../storage_rd/render_scene_buffers_rd.cpp | 16 ++++++++-------- .../renderer_rd/storage_rd/texture_storage.cpp | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 98ff01cd37..4f6e119773 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -98,7 +98,7 @@ void VRS::copy_vrs(RID p_source_rd_texture, RID p_dest_framebuffer, bool p_multi RID shader = vrs_shader.shader.version_get_shader(vrs_shader.shader_version, mode); ERR_FAIL_COND(shader.is_null()); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_ALL); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, vrs_shader.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(VRSPushConstant)); 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 45fe456f55..0b23686579 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 @@ -179,13 +179,13 @@ 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, get_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), RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true); // 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). // Create our depth buffer. - create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, get_depth_format(resolve_target, false, can_be_storage), get_depth_usage_bits(resolve_target, false, can_be_storage)); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH, get_depth_format(resolve_target, false, can_be_storage), get_depth_usage_bits(resolve_target, false, can_be_storage), RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true); // Create our MSAA buffers. if (msaa_3d == RS::VIEWPORT_MSAA_DISABLED) { @@ -199,7 +199,7 @@ void RenderSceneBuffersRD::configure(const RenderSceneBuffersConfiguration *p_co // VRS (note, our vrs object will only be set if VRS is supported) RID vrs_texture; if (vrs && vrs_mode != RS::VIEWPORT_VRS_DISABLED) { - vrs_texture = create_texture(RB_SCOPE_VRS, RB_TEXTURE, get_vrs_format(), get_vrs_usage_bits(), RD::TEXTURE_SAMPLES_1, vrs->get_vrs_texture_size(internal_size)); + vrs_texture = create_texture(RB_SCOPE_VRS, RB_TEXTURE, get_vrs_format(), get_vrs_usage_bits(), RD::TEXTURE_SAMPLES_1, vrs->get_vrs_texture_size(internal_size), 0, 1, true, true); } // (re-)configure any named buffers @@ -527,8 +527,8 @@ void RenderSceneBuffersRD::allocate_blur_textures() { usage_bits += RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; } - 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); + 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, true, true); + 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, true, true); // TODO redo this: if (!can_be_storage) { @@ -643,7 +643,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, get_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, 0, 1, true, true); } } @@ -652,10 +652,10 @@ void RenderSceneBuffersRD::ensure_upscaled() { void RenderSceneBuffersRD::ensure_velocity() { if (!has_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY)) { const bool msaa = msaa_3d != RS::VIEWPORT_MSAA_DISABLED; - create_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY, get_velocity_format(), get_velocity_usage_bits(msaa, false, can_be_storage)); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY, get_velocity_format(), get_velocity_usage_bits(msaa, false, can_be_storage), RD::TEXTURE_SAMPLES_1, Size2i(), 0, 1, true, true); if (msaa) { - create_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA, get_velocity_format(), get_velocity_usage_bits(false, msaa, can_be_storage), texture_samples); + create_texture(RB_SCOPE_BUFFERS, RB_TEX_VELOCITY_MSAA, get_velocity_format(), get_velocity_usage_bits(false, msaa, can_be_storage), texture_samples, Size2i(), 0, 1, true, true); } } } diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 083ade50c3..92c9c307d9 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3591,6 +3591,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { if (rt->msaa != RS::VIEWPORT_MSAA_DISABLED) { rd_color_attachment_format.is_resolve_buffer = true; } + rd_color_attachment_format.is_discardable = true; } // TODO see if we can lazy create this once we actually use it as we may not need to create this if we have an overridden color buffer... @@ -3610,6 +3611,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) { rd_color_multisample_format.usage_bits = render_target_get_color_usage_bits(true); RD::TextureView rd_view_multisample; rd_color_multisample_format.is_resolve_buffer = false; + rd_color_multisample_format.is_discardable = true; rt->color_multisample = RD::get_singleton()->texture_create(rd_color_multisample_format, rd_view_multisample); ERR_FAIL_COND(rt->color_multisample.is_null()); } @@ -3670,6 +3672,7 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) { tf.texture_type = RD::TEXTURE_TYPE_2D; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; + tf.is_discardable = true; rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer"); @@ -4155,6 +4158,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) { tformat.height = size.height; tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; tformat.texture_type = RD::TEXTURE_TYPE_2D; + tformat.is_discardable = true; rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());