summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorDario <dariosamo@gmail.com>2024-10-24 16:01:00 -0300
committerDario <dariosamo@gmail.com>2024-11-25 11:27:48 -0300
commit6d5ac8f7ef4a3ddaf50720ab473b9dffece21674 (patch)
tree944b63cb05590c207f242025bae3aabc02e0b656 /servers
parent0c45ace151f25de2ca54fe7a46b6f077be32ba6f (diff)
downloadredot-engine-6d5ac8f7ef4a3ddaf50720ab473b9dffece21674.tar.gz
Resolve load and store ops automatically for render passes for discardable textures.
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/effects/bokeh_dof.cpp12
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp24
-rw-r--r--servers/rendering/renderer_rd/effects/debug_effects.cpp6
-rw-r--r--servers/rendering/renderer_rd/effects/fsr2.cpp1
-rw-r--r--servers/rendering/renderer_rd/effects/luminance.cpp2
-rw-r--r--servers/rendering/renderer_rd/effects/tone_mapper.cpp2
-rw-r--r--servers/rendering/renderer_rd/effects/vrs.cpp2
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp2
-rw-r--r--servers/rendering/renderer_rd/environment/sky.cpp10
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp38
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h6
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp22
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp9
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp9
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp6
-rw-r--r--servers/rendering/rendering_device.compat.inc24
-rw-r--r--servers/rendering/rendering_device.cpp406
-rw-r--r--servers/rendering/rendering_device.h138
-rw-r--r--servers/rendering/rendering_device_binds.h5
-rw-r--r--servers/rendering/rendering_device_commons.h5
-rw-r--r--servers/rendering/rendering_device_graph.cpp262
-rw-r--r--servers/rendering/rendering_device_graph.h81
27 files changed, 647 insertions, 443 deletions
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 41df6107a8..752e0fe453 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -452,7 +452,7 @@ void ClusterBuilderRD::bake_cluster() {
// Render elements.
{
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
ClusterBuilderSharedDataRD::ClusterRender::PushConstant push_constant = {};
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, shared->cluster_render.shader_pipelines[use_msaa ? ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_MSAA : ClusterBuilderSharedDataRD::ClusterRender::PIPELINE_NORMAL]);
diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
index e6262c83e2..398718e79f 100644
--- a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
+++ b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
@@ -356,7 +356,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
ERR_FAIL_COND(shader.is_null());
RID framebuffer = p_buffers.base_weight_fb;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[BOKEH_GEN_BLUR_SIZE].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_depth_texture), 0);
@@ -388,7 +388,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb;
// Pass 1
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_base_texture), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture0), 1);
@@ -412,7 +412,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
RD::Uniform texture = bokeh.push_constant.half_size ? u_half_texture0 : u_secondary_texture;
RD::Uniform weight = bokeh.push_constant.half_size ? u_weight_texture2 : u_weight_texture1;
- draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, texture), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, weight), 1);
@@ -430,7 +430,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
framebuffer = p_buffers.base_fb;
- draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture1), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture3), 1);
@@ -463,7 +463,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_base_texture), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture0), 1);
@@ -481,7 +481,7 @@ void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, RID p_camera_attr
framebuffer = p_buffers.base_fb;
- draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture0), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture2), 1);
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index 808c82f712..a3a873a2d1 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -591,7 +591,7 @@ void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffe
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, p_rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_rect);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.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);
if (p_secondary.is_valid()) {
@@ -658,7 +658,7 @@ void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) {
ERR_FAIL_COND(shader.is_null());
// Just copy it back (we use our blur raster shader here)..
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].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_texture), 0);
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
@@ -731,7 +731,7 @@ void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_textu
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
@@ -833,7 +833,7 @@ void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_textu
ERR_FAIL_COND(shader.is_null());
//HORIZONTAL
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(half_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(half_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(half_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
if (p_auto_exposure.is_valid() && p_first_pass) {
@@ -853,7 +853,7 @@ void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, RID p_half_textu
ERR_FAIL_COND(shader.is_null());
//VERTICAL
- draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture), 0);
@@ -923,7 +923,7 @@ void CopyEffects::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(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, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
@@ -988,7 +988,7 @@ void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, con
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_region);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
@@ -1025,7 +1025,7 @@ void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuf
RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, Vector<Color>(), 1.0f, 0, screen_rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, screen_rect);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_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_bind_index_array(draw_list, material_storage->get_quad_index_array());
@@ -1090,7 +1090,7 @@ void CopyEffects::cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_fra
RID shader = cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cubemap_downsampler.raster_pipeline.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_cubemap), 0);
@@ -1169,7 +1169,7 @@ void CopyEffects::cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebu
RID shader = filter.raster_shader.version_get_shader(filter.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_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_cubemap), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1);
@@ -1247,7 +1247,7 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f
RID shader = roughness.raster_shader.version_get_shader(roughness.shader_version, 0);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.raster_pipeline.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);
@@ -1267,7 +1267,7 @@ void CopyEffects::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_b
RD::get_singleton()->draw_command_begin_label("Merge specular");
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, Vector<Color>());
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
int mode;
if (p_reflection.is_valid()) {
diff --git a/servers/rendering/renderer_rd/effects/debug_effects.cpp b/servers/rendering/renderer_rd/effects/debug_effects.cpp
index 04afaf63d7..ac06f28f4c 100644
--- a/servers/rendering/renderer_rd/effects/debug_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/debug_effects.cpp
@@ -282,7 +282,7 @@ void DebugEffects::draw_shadow_frustum(RID p_light, const Projection &p_cam_proj
// And draw our frustum.
RD::FramebufferFormatID fb_format_id = RD::get_singleton()->framebuffer_get_format(p_dest_fb);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, rect);
RID pipeline = shadow_frustum.pipelines[SFP_TRANSPARENT].get_render_pipeline(frustum.vertex_format, fb_format_id);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, pipeline);
@@ -326,7 +326,7 @@ void DebugEffects::draw_shadow_frustum(RID p_light, const Projection &p_cam_proj
rect.size.x *= atlas_rect_norm.size.x;
rect.size.y *= atlas_rect_norm.size.y;
- draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, rect);
+ draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, rect);
pipeline = shadow_frustum.pipelines[SFP_TRANSPARENT].get_render_pipeline(frustum.vertex_format, fb_format_id);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, pipeline);
@@ -351,7 +351,7 @@ void DebugEffects::draw_motion_vectors(RID p_velocity, RID p_depth, RID p_dest_f
RD::Uniform u_source_velocity(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_velocity }));
RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_depth }));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, motion_vectors.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_fb), false, RD::get_singleton()->draw_list_get_current_pass()));
Projection correction;
diff --git a/servers/rendering/renderer_rd/effects/fsr2.cpp b/servers/rendering/renderer_rd/effects/fsr2.cpp
index 551ea5dd97..294754f7cb 100644
--- a/servers/rendering/renderer_rd/effects/fsr2.cpp
+++ b/servers/rendering/renderer_rd/effects/fsr2.cpp
@@ -235,6 +235,7 @@ static FfxErrorCode create_resource_rd(FfxFsr2Interface *p_backend_interface, co
texture_format.height = res_desc.height;
texture_format.depth = res_desc.depth;
texture_format.mipmaps = res_desc.mipCount;
+ texture_format.is_discardable = true;
RID texture = rd->texture_create(texture_format, RD::TextureView(), initial_data);
ERR_FAIL_COND_V(texture.is_null(), FFX_ERROR_BACKEND_API_ERROR);
diff --git a/servers/rendering/renderer_rd/effects/luminance.cpp b/servers/rendering/renderer_rd/effects/luminance.cpp
index 61b2248b5c..4727e8fd9a 100644
--- a/servers/rendering/renderer_rd/effects/luminance.cpp
+++ b/servers/rendering/renderer_rd/effects/luminance.cpp
@@ -184,7 +184,7 @@ void Luminance::luminance_reduction(RID p_source_texture, const Size2i p_source_
RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, i == 0 ? p_source_texture : p_luminance_buffers->reduce[i - 1] }));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, luminance_reduce_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
if (final) {
diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp
index e943071f0e..83cf2ed719 100644
--- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp
+++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp
@@ -166,7 +166,7 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton
RID shader = tonemap.shader.version_get_shader(tonemap.shader_version, mode);
ERR_FAIL_COND(shader.is_null());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer), false, RD::get_singleton()->draw_list_get_current_pass()));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_color), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1);
diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp
index 94453bf95f..9cc22f6f5e 100644
--- a/servers/rendering/renderer_rd/effects/vrs.cpp
+++ b/servers/rendering/renderer_rd/effects/vrs.cpp
@@ -94,7 +94,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::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>());
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
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/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index 235aa9f828..c4a89996b5 100644
--- a/servers/rendering/renderer_rd/environment/gi.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -1721,7 +1721,7 @@ void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, con
SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer);
RD::get_singleton()->draw_command_begin_label("Debug SDFGI");
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[mode].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index 83ec52ea75..c59332626d 100644
--- a/servers/rendering/renderer_rd/environment/sky.cpp
+++ b/servers/rendering/renderer_rd/environment/sky.cpp
@@ -1315,7 +1315,7 @@ void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers,
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers);
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i]);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
@@ -1336,7 +1336,7 @@ void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers,
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers);
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i]);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
@@ -1353,7 +1353,7 @@ void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers,
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd, p_render_buffers);
- cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), RDD::BreadcrumbMarker::SKY_PASS | uint32_t(i));
+ cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::SKY_PASS | uint32_t(i));
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
@@ -1477,7 +1477,7 @@ void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, 0.0);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_CLEAR_ALL, clear_colors);
_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);
RD::get_singleton()->draw_list_end();
}
@@ -1496,7 +1496,7 @@ void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, 0.0);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_CLEAR_ALL, clear_colors);
_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);
RD::get_singleton()->draw_list_end();
}
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 b867e844c7..fbe19dfe7b 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -643,11 +643,11 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis
}
}
-void RenderForwardClustered::_render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
+void RenderForwardClustered::_render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, BitField<RD::DrawFlags> p_draw_flags, const Vector<Color> &p_clear_color_values, float p_clear_depth_value, uint32_t p_clear_stencil_value, const Rect2 &p_region) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
p_params->framebuffer_format = fb_format;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_draw_flags, p_clear_color_values, p_clear_depth_value, p_clear_stencil_value, p_region);
_render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
RD::get_singleton()->draw_list_end();
}
@@ -1476,7 +1476,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
if (p_render_data->directional_shadows.size()) {
//open the pass for directional shadows
light_storage->update_directional_shadow_atlas();
- RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0);
+ RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::DRAW_CLEAR_DEPTH, Vector<Color>(), 0.0f);
RD::get_singleton()->draw_list_end();
}
}
@@ -2010,7 +2010,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
if (needs_pre_resolve) {
//pre clear the depth framebuffer, as AMD (and maybe others?) use compute for it, and barrier other compute shaders.
- RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, depth_pass_clear, 0.0);
+ RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::DRAW_CLEAR_ALL, depth_pass_clear, 0.0f);
RD::get_singleton()->draw_list_end();
//start compute processes here, so they run at the same time as depth pre-pass
_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
@@ -2022,7 +2022,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
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() == RS::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, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
+ _render_list_with_draw_list(&render_list_params, depth_framebuffer, RD::DrawFlags(needs_pre_resolve ? RD::DRAW_DEFAULT_ALL : RD::DRAW_CLEAR_ALL), depth_pass_clear, 0.0f);
RD::get_singleton()->draw_command_end_label();
@@ -2084,7 +2084,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
{
Vector<Color> c;
- {
+ if (!load_color) {
Color cc = clear_color.srgb_to_linear();
if (using_separate_specular || rb_data.is_valid()) {
// Effects that rely on separate specular, like subsurface scattering, must clear the alpha to zero.
@@ -2101,7 +2101,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
uint32_t opaque_color_pass_flags = using_motion_pass ? (color_pass_flags & ~COLOR_PASS_FLAG_MOTION_VECTORS) : color_pass_flags;
RID opaque_framebuffer = using_motion_pass ? rb_data->get_color_pass_fb(opaque_color_pass_flags) : color_framebuffer;
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_COLOR, opaque_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::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, opaque_framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, depth_pre_pass ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 0.0, 0);
+ _render_list_with_draw_list(&render_list_params, opaque_framebuffer, RD::DrawFlags(load_color ? RD::DRAW_DEFAULT_ALL : RD::DRAW_CLEAR_COLOR_ALL) | (depth_pre_pass ? RD::DRAW_DEFAULT_ALL : RD::DRAW_CLEAR_DEPTH), c, 0.0f);
}
RD::get_singleton()->draw_command_end_label();
@@ -2109,7 +2109,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (using_motion_pass) {
Vector<Color> motion_vector_clear_colors;
motion_vector_clear_colors.push_back(Color(-1, -1, 0, 0));
- RD::get_singleton()->draw_list_begin(rb_data->get_velocity_only_fb(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, motion_vector_clear_colors);
+ RD::get_singleton()->draw_list_begin(rb_data->get_velocity_only_fb(), RD::DRAW_CLEAR_ALL, motion_vector_clear_colors);
RD::get_singleton()->draw_list_end();
}
@@ -2121,7 +2121,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_MOTION, p_render_data, radiance_texture, samplers, 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() == RS::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, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE);
+ _render_list_with_draw_list(&render_list_params, color_framebuffer);
RD::get_singleton()->draw_command_end_label();
}
@@ -2148,7 +2148,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
Projection dc;
dc.set_depth_correction(true);
Projection cm = (dc * p_render_data->scene_data->cam_projection) * Projection(p_render_data->scene_data->cam_transform.affine_inverse());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer);
RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs");
for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) {
gi.debug_voxel_gi((*p_render_data->voxel_gi_instances)[i], draw_list, color_only_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, 1.0);
@@ -2171,7 +2171,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Render Sky");
RD::get_singleton()->draw_command_begin_label("Draw Sky");
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer);
sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_energy_multiplier);
@@ -2236,7 +2236,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Clear Separate Specular (Canvas Background Mode)");
Vector<Color> blank_clear_color;
blank_clear_color.push_back(Color(0.0, 0.0, 0.0));
- RD::get_singleton()->draw_list_begin(rb_data->get_specular_only_fb(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, blank_clear_color);
+ RD::get_singleton()->draw_list_begin(rb_data->get_specular_only_fb(), RD::DRAW_CLEAR_ALL, blank_clear_color);
RD::get_singleton()->draw_list_end();
}
@@ -2300,7 +2300,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RID alpha_framebuffer = rb_data.is_valid() ? rb_data->get_color_pass_fb(transparent_color_pass_flags) : color_only_framebuffer;
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_color_pass_flags, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::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, alpha_framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE);
+ _render_list_with_draw_list(&render_list_params, alpha_framebuffer);
}
RD::get_singleton()->draw_command_end_label();
@@ -2699,7 +2699,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier;
shadow_pass.framebuffer = p_framebuffer;
- shadow_pass.initial_depth_action = p_begin ? RD::INITIAL_ACTION_CLEAR : (p_clear_region ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD);
+ shadow_pass.clear_depth = p_begin || p_clear_region;
shadow_pass.rect = p_rect;
scene_state.shadow_passes.push_back(shadow_pass);
@@ -2723,7 +2723,7 @@ void RenderForwardClustered::_render_shadow_end() {
for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) {
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, 0, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from);
- _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0, 0, shadow_pass.rect);
+ _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, shadow_pass.clear_depth ? RD::DRAW_CLEAR_DEPTH : RD::DRAW_DEFAULT_ALL, Vector<Color>(), 0.0f, 0, shadow_pass.rect);
}
RD::get_singleton()->draw_command_end_label();
@@ -2770,7 +2770,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
{
//regular forward for now
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, 0, true, false, rp_uniform_set);
- _render_list_with_draw_list(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE);
+ _render_list_with_draw_list(&render_list_params, p_fb);
}
RD::get_singleton()->draw_command_end_label();
}
@@ -2824,7 +2824,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
Color(0, 0, 0, 0)
};
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::DRAW_CLEAR_ALL, clear, 0.0f, 0, p_region);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
}
@@ -2874,7 +2874,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance
Color(0, 0, 0, 0),
Color(0, 0, 0, 0)
};
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::DRAW_CLEAR_ALL, clear, 0.0f, 0, p_region);
const int uv_offset_count = 9;
static const Vector2 uv_offsets[uv_offset_count] = {
@@ -2983,7 +2983,7 @@ void RenderForwardClustered::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_bu
}
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set, false);
- _render_list_with_draw_list(&render_list_params, E->value, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 0.0, 0, Rect2());
+ _render_list_with_draw_list(&render_list_params, E->value);
}
RD::get_singleton()->draw_command_end_label();
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 ebc291e803..728164c38e 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -350,7 +350,6 @@ private:
struct ShadowPass {
uint32_t element_from;
uint32_t element_count;
- bool flip_cull;
PassMode pass_mode;
RID rp_uniform_set;
@@ -358,8 +357,9 @@ private:
float screen_mesh_lod_threshold;
RID framebuffer;
- RD::InitialAction initial_depth_action;
Rect2i rect;
+ bool clear_depth;
+ bool flip_cull;
};
LocalVector<ShadowPass> shadow_passes;
@@ -385,7 +385,7 @@ private:
template <PassMode p_pass_mode, uint32_t p_color_pass_flags = 0>
_FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
- void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 0.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
+ void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, BitField<RD::DrawFlags> p_draw_flags = RD::DRAW_DEFAULT_ALL, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth_value = 0.0, uint32_t p_clear_stencil_value = 0, const Rect2 &p_region = Rect2());
void _update_instance_data_buffer(RenderListType p_render_list);
void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
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 411f0fe6a4..ef08c83c96 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -689,7 +689,7 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
if (p_render_data->directional_shadows.size()) {
//open the pass for directional shadows
light_storage->update_directional_shadow_atlas();
- RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0);
+ RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::DRAW_CLEAR_DEPTH, Vector<Color>(), 0.0f);
RD::get_singleton()->draw_list_end();
}
}
@@ -1051,7 +1051,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// Set clear colors.
Vector<Color> c;
- {
+ if (!load_color) {
Color cc = clear_color.srgb_to_linear() * inverse_luminance_multiplier;
if (rb_data.is_valid()) {
cc.a = 0; // For transparent viewport backgrounds.
@@ -1068,7 +1068,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
}
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, c, 0.0, 0, Rect2(), breadcrumb);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, load_color ? RD::DRAW_CLEAR_DEPTH : (RD::DRAW_CLEAR_COLOR_0 | RD::DRAW_CLEAR_DEPTH), c, 0.0f, 0, Rect2(), breadcrumb);
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
if (copy_canvas) {
@@ -1165,7 +1165,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
render_list_params.framebuffer_format = fb_format;
render_list_params.subpass = RD::get_singleton()->draw_list_get_current_pass(); // Should now always be 0.
- draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, Vector<Color>(), 0, 0, Rect2(), breadcrumb);
+ draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, Rect2(), breadcrumb);
_render_list(draw_list, fb_format, &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
@@ -1445,7 +1445,7 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier;
shadow_pass.framebuffer = p_framebuffer;
- shadow_pass.initial_depth_action = p_begin ? RD::INITIAL_ACTION_CLEAR : (p_clear_region ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD);
+ shadow_pass.clear_depth = p_begin || p_clear_region;
shadow_pass.rect = p_rect;
scene_state.shadow_passes.push_back(shadow_pass);
@@ -1469,7 +1469,7 @@ void RenderForwardMobile::_render_shadow_end() {
for (SceneState::ShadowPass &shadow_pass : scene_state.shadow_passes) {
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, scene_shader.default_specialization, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from);
- _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, RD::FINAL_ACTION_STORE, Vector<Color>(), 0.0, 0, shadow_pass.rect);
+ _render_list_with_draw_list(&render_list_parameters, shadow_pass.framebuffer, shadow_pass.clear_depth ? RD::DRAW_CLEAR_DEPTH : RD::DRAW_DEFAULT_ALL, Vector<Color>(), 0.0f, 0, shadow_pass.rect);
}
RD::get_singleton()->draw_command_end_label();
@@ -1521,7 +1521,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
Color(0, 0, 0, 0),
Color(0, 0, 0, 0)
};
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::DRAW_CLEAR_ALL, clear, 0.0f, 0, p_region);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
}
@@ -1567,7 +1567,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *>
Color(0, 0, 0, 0)
};
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, clear, 0.0, 0, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::DRAW_CLEAR_ALL, clear, 0.0f, 0, p_region);
const int uv_offset_count = 9;
static const Vector2 uv_offsets[uv_offset_count] = {
@@ -1642,7 +1642,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
{
//regular forward for now
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, pass_mode, rp_uniform_set, scene_shader.default_specialization);
- _render_list_with_draw_list(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE);
+ _render_list_with_draw_list(&render_list_params, p_fb);
}
RD::get_singleton()->draw_command_end_label();
}
@@ -2094,11 +2094,11 @@ void RenderForwardMobile::_render_list(RenderingDevice::DrawListID p_draw_list,
}
}
-void RenderForwardMobile::_render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
+void RenderForwardMobile::_render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, BitField<RD::DrawFlags> p_draw_flags, const Vector<Color> &p_clear_color_values, float p_clear_depth_value, uint32_t p_clear_stencil_value, const Rect2 &p_region) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
p_params->framebuffer_format = fb_format;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, p_draw_flags, p_clear_color_values, p_clear_depth_value, p_clear_stencil_value, p_region);
_render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
RD::get_singleton()->draw_list_end();
}
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 96f535ef45..5a4c114041 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -257,8 +257,8 @@ private:
float screen_mesh_lod_threshold;
RID framebuffer;
- RD::InitialAction initial_depth_action;
Rect2i rect;
+ bool clear_depth;
};
LocalVector<ShadowPass> shadow_passes;
@@ -332,7 +332,7 @@ private:
template <PassMode p_pass_mode>
_FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
- void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 0.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
+ void _render_list_with_draw_list(RenderListParameters *p_params, RID p_framebuffer, BitField<RD::DrawFlags> p_clear_colors = RD::DRAW_DEFAULT_ALL, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth_value = 0.0, uint32_t p_clear_stencil_value = 0, const Rect2 &p_region = Rect2());
RenderList render_list[RENDER_LIST_MAX];
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 165168cb29..e0383f7e85 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -975,6 +975,7 @@ void RendererCanvasRenderRD::_update_shadow_atlas() {
tf.height = state.max_lights_per_render * 2;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
tf.format = RD::DATA_FORMAT_D32_SFLOAT;
+ tf.is_discardable = true;
//chunks to write
state.shadow_depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
fb_textures.push_back(state.shadow_depth_texture);
@@ -1026,7 +1027,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
for (int i = 0; i < 4; i++) {
Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::DRAW_CLEAR_ALL, cc, 1.0f, 0, rect);
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
@@ -1097,7 +1098,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
cc.push_back(Color(1, 1, 1, 1));
Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::DRAW_CLEAR_ALL, cc, 1.0f, 0, rect);
Projection projection;
projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance);
@@ -1167,7 +1168,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan
Vector<Color> cc;
cc.push_back(Color(0, 0, 0, 0));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(fb, RD::DRAW_CLEAR_ALL, cc);
Projection projection;
@@ -2174,7 +2175,7 @@ void RendererCanvasRenderRD::_render_batch_items(RenderTarget p_to_render_target
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, clear_colors, 1, 0, Rect2(), RDD::BreadcrumbMarker::UI_PASS);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::DRAW_CLEAR_COLOR_ALL : RD::DRAW_DEFAULT_ALL, clear_colors, 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::UI_PASS);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, fb_uniform_set, BASE_UNIFORM_SET);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.default_transforms_uniform_set, TRANSFORMS_UNIFORM_SET);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 4417f6832c..7ef42aa791 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -646,7 +646,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
if (use_intermediate_fb) {
// If we use FSR to upscale we need to write our result into an intermediate buffer.
// Note that this is cached so we only create the texture the first time.
- RID dest_texture = rb->create_texture(SNAME("Tonemapper"), SNAME("destination"), _render_buffers_get_color_format(), RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
+ RID dest_texture = rb->create_texture(SNAME("Tonemapper"), 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);
dest_fb = FramebufferCacheRD::get_singleton()->get_cache(dest_texture);
} else {
// If we do a bilinear upscale we just render into our render target and our shader will upscale automatically.
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc
index 75b9ee2da7..dc49366de3 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc
@@ -54,6 +54,10 @@ RID RenderSceneBuffersRD::_get_velocity_layer_compat_80214(const uint32_t p_laye
return _get_velocity_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
}
+RID RenderSceneBuffersRD::_create_texture_bind_compat_98670(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples, const Size2i p_size, const uint32_t p_layers, const uint32_t p_mipmaps, bool p_unique) {
+ return create_texture(p_context, p_texture_name, p_data_format, p_usage_bits, p_texture_samples, p_size, p_layers, p_mipmaps, p_unique, false);
+}
+
void RenderSceneBuffersRD::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer_compat_80214);
@@ -61,6 +65,8 @@ void RenderSceneBuffersRD::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture_compat_80214);
ClassDB::bind_compatibility_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer_compat_80214);
+
+ ClassDB::bind_compatibility_method(D_METHOD("create_texture", "context", "name", "data_format", "usage_bits", "texture_samples", "size", "layers", "mipmaps", "unique"), &RenderSceneBuffersRD::_create_texture_bind_compat_98670);
}
#endif // DISABLE_DEPRECATED
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 ca44f4dd7e..6e1259eac1 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
@@ -48,7 +48,7 @@ RenderSceneBuffersRD::~RenderSceneBuffersRD() {
void RenderSceneBuffersRD::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_texture", "context", "name"), &RenderSceneBuffersRD::has_texture);
- ClassDB::bind_method(D_METHOD("create_texture", "context", "name", "data_format", "usage_bits", "texture_samples", "size", "layers", "mipmaps", "unique"), &RenderSceneBuffersRD::create_texture);
+ ClassDB::bind_method(D_METHOD("create_texture", "context", "name", "data_format", "usage_bits", "texture_samples", "size", "layers", "mipmaps", "unique", "discardable"), &RenderSceneBuffersRD::create_texture);
ClassDB::bind_method(D_METHOD("create_texture_from_format", "context", "name", "format", "view", "unique"), &RenderSceneBuffersRD::_create_texture_from_format);
ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::_create_texture_view);
ClassDB::bind_method(D_METHOD("get_texture", "context", "name"), &RenderSceneBuffersRD::get_texture);
@@ -179,8 +179,8 @@ 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);
- 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);
+ 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_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);
}
// VRS (note, our vrs object will only be set if VRS is supported)
@@ -242,7 +242,7 @@ bool RenderSceneBuffersRD::has_texture(const StringName &p_context, const String
return named_textures.has(key);
}
-RID RenderSceneBuffersRD::create_texture(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples, const Size2i p_size, const uint32_t p_layers, const uint32_t p_mipmaps, bool p_unique) {
+RID RenderSceneBuffersRD::create_texture(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples, const Size2i p_size, const uint32_t p_layers, const uint32_t p_mipmaps, bool p_unique, bool p_discardable) {
// Keep some useful data, we use default values when these are 0.
Size2i size = p_size == Size2i(0, 0) ? internal_size : p_size;
uint32_t layers = p_layers == 0 ? view_count : p_layers;
@@ -262,6 +262,7 @@ RID RenderSceneBuffersRD::create_texture(const StringName &p_context, const Stri
tf.mipmaps = mipmaps;
tf.usage_bits = p_usage_bits;
tf.samples = p_texture_samples;
+ tf.is_discardable = p_discardable;
return create_texture_from_format(p_context, p_texture_name, tf, RD::TextureView(), p_unique);
}
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 187dbab445..0af3a75270 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
@@ -195,7 +195,7 @@ public:
// Named Textures
bool has_texture(const StringName &p_context, const StringName &p_texture_name) const;
- RID create_texture(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples = RD::TEXTURE_SAMPLES_1, const Size2i p_size = Size2i(0, 0), const uint32_t p_layers = 0, const uint32_t p_mipmaps = 1, bool p_unique = true);
+ RID create_texture(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples = RD::TEXTURE_SAMPLES_1, const Size2i p_size = Size2i(0, 0), const uint32_t p_layers = 0, const uint32_t p_mipmaps = 1, bool p_unique = true, bool p_discardable = false);
RID create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const RD::TextureFormat &p_texture_format, RD::TextureView p_view = RD::TextureView(), bool p_unique = true);
RID create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName &p_view_name, RD::TextureView p_view = RD::TextureView());
RID get_texture(const StringName &p_context, const StringName &p_texture_name) const;
@@ -423,6 +423,8 @@ private:
RID _get_velocity_texture_compat_80214();
RID _get_velocity_layer_compat_80214(const uint32_t p_layer);
+ RID _create_texture_bind_compat_98670(const StringName &p_context, const StringName &p_texture_name, const RD::DataFormat p_data_format, const uint32_t p_usage_bits, const RD::TextureSamples p_texture_samples, const Size2i p_size, const uint32_t p_layers, const uint32_t p_mipmaps, bool p_unique);
+
static void _bind_compatibility_methods();
#endif // DISABLE_DEPRECATED
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 8a9499dfc9..209be3d867 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -2894,7 +2894,7 @@ void TextureStorage::update_decal_atlas() {
Vector<Color> cc;
cc.push_back(clear_color);
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_DISCARD, RD::FINAL_ACTION_DISCARD, cc);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::DRAW_CLEAR_ALL, cc);
for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
@@ -3575,7 +3575,7 @@ void TextureStorage::render_target_do_msaa_resolve(RID p_render_target) {
if (!rt->msaa_needs_resolve) {
return;
}
- RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_begin(rt->get_framebuffer());
RD::get_singleton()->draw_list_end();
rt->msaa_needs_resolve = false;
}
@@ -3692,7 +3692,7 @@ void TextureStorage::render_target_do_clear_request(RID p_render_target) {
}
Vector<Color> clear_colors;
clear_colors.push_back(rt->use_hdr ? rt->clear_color.srgb_to_linear() : rt->clear_color);
- RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_DISCARD, clear_colors);
+ RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::DRAW_CLEAR_ALL, clear_colors);
RD::get_singleton()->draw_list_end();
rt->clear_requested = false;
rt->msaa_needs_resolve = false;
diff --git a/servers/rendering/rendering_device.compat.inc b/servers/rendering/rendering_device.compat.inc
index 77e44bbc5e..11aede7133 100644
--- a/servers/rendering/rendering_device.compat.inc
+++ b/servers/rendering/rendering_device.compat.inc
@@ -86,11 +86,29 @@ RenderingDevice::FinalAction RenderingDevice::_convert_final_action_84976(FinalA
}
RenderingDevice::DrawListID RenderingDevice::_draw_list_begin_bind_compat_84976(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray<RID> &p_storage_textures) {
- return draw_list_begin(p_framebuffer, _convert_initial_action_84976(p_initial_color_action), _convert_final_action_84976(p_final_color_action), _convert_initial_action_84976(p_initial_depth_action), _convert_final_action_84976(p_final_depth_action), p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, RDD::BreadcrumbMarker::NONE);
+ return _draw_list_begin_bind_compat_98670(p_framebuffer, _convert_initial_action_84976(p_initial_color_action), _convert_final_action_84976(p_final_color_action), _convert_initial_action_84976(p_initial_depth_action), _convert_final_action_84976(p_final_depth_action), p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, RDD::BreadcrumbMarker::NONE);
}
RenderingDevice::DrawListID RenderingDevice::_draw_list_begin_bind_compat_90993(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
- return draw_list_begin(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, RDD::BreadcrumbMarker::NONE);
+ return _draw_list_begin_bind_compat_98670(p_framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, RDD::BreadcrumbMarker::NONE);
+}
+
+RenderingDevice::DrawListID RenderingDevice::_draw_list_begin_bind_compat_98670(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, uint32_t p_breadcrumb) {
+ // Deduce flags from initial and final actions.
+ BitField<DrawFlags> draw_flags = RD::DRAW_DEFAULT_ALL;
+ if (p_initial_color_action == RD::INITIAL_ACTION_CLEAR) {
+ draw_flags.set_flag(DrawFlags(RD::DRAW_CLEAR_COLOR_ALL));
+ } else if (p_initial_color_action == RD::INITIAL_ACTION_DISCARD) {
+ draw_flags.set_flag(DrawFlags(RD::DRAW_IGNORE_COLOR_ALL));
+ }
+
+ if (p_initial_depth_action == RD::INITIAL_ACTION_CLEAR) {
+ draw_flags.set_flag(DrawFlags(RD::DRAW_CLEAR_DEPTH | RD::DRAW_CLEAR_STENCIL));
+ } else if (p_initial_depth_action == RD::INITIAL_ACTION_DISCARD) {
+ draw_flags.set_flag(DrawFlags(RD::DRAW_IGNORE_DEPTH | RD::DRAW_IGNORE_STENCIL));
+ }
+
+ return draw_list_begin(p_framebuffer, draw_flags, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_breadcrumb);
}
RenderingDevice::ComputeListID RenderingDevice::_compute_list_begin_bind_compat_84976(bool p_allow_draw_overlap) {
@@ -146,6 +164,8 @@ void RenderingDevice::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::_screen_get_framebuffer_format_bind_compat_87340);
ClassDB::bind_compatibility_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_bind_compat_90993, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()));
+
+ ClassDB::bind_compatibility_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "breadcrumb"), &RenderingDevice::_draw_list_begin_bind_compat_98670, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(0));
}
#endif
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index e9fa38475e..0761af9260 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -846,6 +846,7 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
texture.base_mipmap = 0;
texture.base_layer = 0;
texture.is_resolve_buffer = format.is_resolve_buffer;
+ texture.is_discardable = format.is_discardable;
texture.usage_flags = format.usage_bits & ~forced_usage_bits;
texture.samples = format.samples;
texture.allowed_shared_formats = format.shareable_formats;
@@ -949,6 +950,7 @@ RID RenderingDevice::texture_create_shared(const TextureView &p_view, RID p_with
tracker->texture_size = Size2i(texture.width, texture.height);
tracker->texture_subresources = texture.barrier_range();
tracker->texture_usage = alias_format.usage_bits;
+ tracker->is_discardable = texture.is_discardable;
tracker->reference_count = 1;
texture.shared_fallback->texture_tracker = tracker;
texture.shared_fallback->revision = 0;
@@ -1129,6 +1131,7 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view,
tracker->texture_size = Size2i(texture.width, texture.height);
tracker->texture_subresources = slice_range;
tracker->texture_usage = slice_format.usage_bits;
+ tracker->is_discardable = slice_format.is_discardable;
tracker->reference_count = 1;
texture.shared_fallback->texture_tracker = tracker;
texture.shared_fallback->revision = 0;
@@ -1889,6 +1892,7 @@ RD::TextureFormat RenderingDevice::texture_get_format(RID p_texture) {
tf.usage_bits = tex->usage_flags;
tf.shareable_formats = tex->allowed_shared_formats;
tf.is_resolve_buffer = tex->is_resolve_buffer;
+ tf.is_discardable = tex->is_discardable;
return tf;
}
@@ -2029,6 +2033,32 @@ Error RenderingDevice::texture_resolve_multisample(RID p_from_texture, RID p_to_
return OK;
}
+void RenderingDevice::texture_set_discardable(RID p_texture, bool p_discardable) {
+ ERR_RENDER_THREAD_GUARD();
+
+ Texture *texture = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_NULL(texture);
+
+ texture->is_discardable = p_discardable;
+
+ if (texture->draw_tracker != nullptr) {
+ texture->draw_tracker->is_discardable = p_discardable;
+ }
+
+ if (texture->shared_fallback != nullptr && texture->shared_fallback->texture_tracker != nullptr) {
+ texture->shared_fallback->texture_tracker->is_discardable = p_discardable;
+ }
+}
+
+bool RenderingDevice::texture_is_discardable(RID p_texture) {
+ ERR_RENDER_THREAD_GUARD_V(false);
+
+ Texture *texture = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_NULL_V(texture, false);
+
+ return texture->is_discardable;
+}
+
Error RenderingDevice::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers) {
ERR_RENDER_THREAD_GUARD_V(ERR_UNAVAILABLE);
@@ -2082,31 +2112,7 @@ bool RenderingDevice::texture_is_format_supported_for_usage(DataFormat p_format,
/**** FRAMEBUFFER ****/
/*********************/
-static RDD::AttachmentLoadOp initial_action_to_load_op(RenderingDevice::InitialAction p_action) {
- switch (p_action) {
- case RenderingDevice::INITIAL_ACTION_LOAD:
- return RDD::ATTACHMENT_LOAD_OP_LOAD;
- case RenderingDevice::INITIAL_ACTION_CLEAR:
- return RDD::ATTACHMENT_LOAD_OP_CLEAR;
- case RenderingDevice::INITIAL_ACTION_DISCARD:
- return RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
- default:
- ERR_FAIL_V_MSG(RDD::ATTACHMENT_LOAD_OP_DONT_CARE, "Invalid initial action value (" + itos(p_action) + ")");
- }
-}
-
-static RDD::AttachmentStoreOp final_action_to_store_op(RenderingDevice::FinalAction p_action) {
- switch (p_action) {
- case RenderingDevice::FINAL_ACTION_STORE:
- return RDD::ATTACHMENT_STORE_OP_STORE;
- case RenderingDevice::FINAL_ACTION_DISCARD:
- return RDD::ATTACHMENT_STORE_OP_DONT_CARE;
- default:
- ERR_FAIL_V_MSG(RDD::ATTACHMENT_STORE_OP_DONT_CARE, "Invalid final action value (" + itos(p_action) + ")");
- }
-}
-
-RDD::RenderPassID RenderingDevice::_render_pass_create(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, InitialAction p_initial_action, FinalAction p_final_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, uint32_t p_view_count, Vector<TextureSamples> *r_samples) {
+RDD::RenderPassID RenderingDevice::_render_pass_create(RenderingDeviceDriver *p_driver, const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, uint32_t p_view_count, Vector<TextureSamples> *r_samples) {
// NOTE:
// Before the refactor to RenderingDevice-RenderingDeviceDriver, there was commented out code to
// specify dependencies to external subpasses. Since it had been unused for a long timel it wasn't ported
@@ -2116,7 +2122,7 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(const Vector<AttachmentFo
attachment_last_pass.resize(p_attachments.size());
if (p_view_count > 1) {
- const RDD::MultiviewCapabilities &capabilities = driver->get_multiview_capabilities();
+ const RDD::MultiviewCapabilities &capabilities = p_driver->get_multiview_capabilities();
// This only works with multiview!
ERR_FAIL_COND_V_MSG(!capabilities.is_supported, RDD::RenderPassID(), "Multiview not supported");
@@ -2157,17 +2163,17 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(const Vector<AttachmentFo
description.final_layout = RDD::TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
} else {
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- description.load_op = initial_action_to_load_op(p_initial_action);
- description.store_op = final_action_to_store_op(p_final_action);
+ description.load_op = p_load_ops[i];
+ description.store_op = p_store_ops[i];
description.stencil_load_op = RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
description.stencil_store_op = RDD::ATTACHMENT_STORE_OP_DONT_CARE;
description.initial_layout = RDD::TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
description.final_layout = RDD::TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- description.load_op = initial_action_to_load_op(p_initial_depth_action);
- description.store_op = final_action_to_store_op(p_final_depth_action);
- description.stencil_load_op = initial_action_to_load_op(p_initial_depth_action);
- description.stencil_store_op = final_action_to_store_op(p_final_depth_action);
+ description.load_op = p_load_ops[i];
+ description.store_op = p_store_ops[i];
+ description.stencil_load_op = p_load_ops[i];
+ description.stencil_store_op = p_store_ops[i];
description.initial_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
description.final_layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
} else {
@@ -2329,12 +2335,23 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(const Vector<AttachmentFo
}
}
- RDD::RenderPassID render_pass = driver->render_pass_create(attachments, subpasses, subpass_dependencies, p_view_count);
+ RDD::RenderPassID render_pass = p_driver->render_pass_create(attachments, subpasses, subpass_dependencies, p_view_count);
ERR_FAIL_COND_V(!render_pass, RDD::RenderPassID());
return render_pass;
}
+RDD::RenderPassID RenderingDevice::_render_pass_create_from_graph(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data) {
+ DEV_ASSERT(p_driver != nullptr);
+ DEV_ASSERT(p_user_data != nullptr);
+
+ // The graph delegates the creation of the render pass to the user according to the load and store ops that were determined as necessary after
+ // resolving the dependencies between commands. This function creates a render pass for the framebuffer accordingly.
+ Framebuffer *framebuffer = (Framebuffer *)(p_user_data);
+ const FramebufferFormatKey &key = framebuffer->rendering_device->framebuffer_formats[framebuffer->format_id].E->key();
+ return _render_pass_create(p_driver, key.attachments, key.passes, p_load_ops, p_store_ops, framebuffer->view_count);
+}
+
RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_format_create(const Vector<AttachmentFormat> &p_format, uint32_t p_view_count) {
FramebufferPass pass;
for (int i = 0; i < p_format.size(); i++) {
@@ -2349,6 +2366,7 @@ RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_format_create(
passes.push_back(pass);
return framebuffer_format_create_multipass(p_format, passes, p_view_count);
}
+
RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_format_create_multipass(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, uint32_t p_view_count) {
_THREAD_SAFE_METHOD_
@@ -2364,14 +2382,21 @@ RenderingDevice::FramebufferFormatID RenderingDevice::framebuffer_format_create_
}
Vector<TextureSamples> samples;
- RDD::RenderPassID render_pass = _render_pass_create(p_attachments, p_passes, INITIAL_ACTION_CLEAR, FINAL_ACTION_STORE, INITIAL_ACTION_CLEAR, FINAL_ACTION_STORE, p_view_count, &samples); // Actions don't matter for this use case.
+ LocalVector<RDD::AttachmentLoadOp> load_ops;
+ LocalVector<RDD::AttachmentStoreOp> store_ops;
+ for (int64_t i = 0; i < p_attachments.size(); i++) {
+ load_ops.push_back(RDD::ATTACHMENT_LOAD_OP_CLEAR);
+ store_ops.push_back(RDD::ATTACHMENT_STORE_OP_STORE);
+ }
+ RDD::RenderPassID render_pass = _render_pass_create(driver, p_attachments, p_passes, load_ops, store_ops, p_view_count, &samples); // Actions don't matter for this use case.
if (!render_pass) { // Was likely invalid.
return INVALID_ID;
}
- FramebufferFormatID id = FramebufferFormatID(framebuffer_format_cache.size()) | (FramebufferFormatID(ID_TYPE_FRAMEBUFFER_FORMAT) << FramebufferFormatID(ID_BASE_SHIFT));
+ FramebufferFormatID id = FramebufferFormatID(framebuffer_format_cache.size()) | (FramebufferFormatID(ID_TYPE_FRAMEBUFFER_FORMAT) << FramebufferFormatID(ID_BASE_SHIFT));
E = framebuffer_format_cache.insert(key, id);
+
FramebufferFormat fb_format;
fb_format.E = E;
fb_format.render_pass = render_pass;
@@ -2438,15 +2463,24 @@ RID RenderingDevice::framebuffer_create_empty(const Size2i &p_size, TextureSampl
_THREAD_SAFE_METHOD_
Framebuffer framebuffer;
+ framebuffer.rendering_device = this;
framebuffer.format_id = framebuffer_format_create_empty(p_samples);
ERR_FAIL_COND_V(p_format_check != INVALID_FORMAT_ID && framebuffer.format_id != p_format_check, RID());
framebuffer.size = p_size;
framebuffer.view_count = 1;
+ RDG::FramebufferCache *framebuffer_cache = RDG::framebuffer_cache_create();
+ framebuffer_cache->width = p_size.width;
+ framebuffer_cache->height = p_size.height;
+ framebuffer.framebuffer_cache = framebuffer_cache;
+
RID id = framebuffer_owner.make_rid(framebuffer);
#ifdef DEV_ENABLED
set_resource_name(id, "RID:" + itos(id.get_id()));
#endif
+
+ framebuffer_cache->render_pass_creation_user_data = framebuffer_owner.get_or_null(id);
+
return id;
}
@@ -2487,6 +2521,8 @@ RID RenderingDevice::framebuffer_create_multipass(const Vector<RID> &p_texture_a
_THREAD_SAFE_METHOD_
Vector<AttachmentFormat> attachments;
+ LocalVector<RDD::TextureID> textures;
+ LocalVector<RDG::ResourceTracker *> trackers;
attachments.resize(p_texture_attachments.size());
Size2i size;
bool size_set = false;
@@ -2495,6 +2531,7 @@ RID RenderingDevice::framebuffer_create_multipass(const Vector<RID> &p_texture_a
Texture *texture = texture_owner.get_or_null(p_texture_attachments[i]);
if (!texture) {
af.usage_flags = AttachmentFormat::UNUSED_ATTACHMENT;
+ trackers.push_back(nullptr);
} else {
ERR_FAIL_COND_V_MSG(texture->layers != p_view_count, RID(), "Layers of our texture doesn't match view count for this framebuffer");
@@ -2516,6 +2553,11 @@ RID RenderingDevice::framebuffer_create_multipass(const Vector<RID> &p_texture_a
af.format = texture->format;
af.samples = texture->samples;
af.usage_flags = texture->usage_flags;
+
+ _texture_make_mutable(texture, p_texture_attachments[i]);
+
+ textures.push_back(texture->driver_id);
+ trackers.push_back(texture->draw_tracker);
}
attachments.write[i] = af;
}
@@ -2531,11 +2573,19 @@ RID RenderingDevice::framebuffer_create_multipass(const Vector<RID> &p_texture_a
"The format used to check this framebuffer differs from the intended framebuffer format.");
Framebuffer framebuffer;
+ framebuffer.rendering_device = this;
framebuffer.format_id = format_id;
framebuffer.texture_ids = p_texture_attachments;
framebuffer.size = size;
framebuffer.view_count = p_view_count;
+ RDG::FramebufferCache *framebuffer_cache = RDG::framebuffer_cache_create();
+ framebuffer_cache->width = size.width;
+ framebuffer_cache->height = size.height;
+ framebuffer_cache->textures = textures;
+ framebuffer_cache->trackers = trackers;
+ framebuffer.framebuffer_cache = framebuffer_cache;
+
RID id = framebuffer_owner.make_rid(framebuffer);
#ifdef DEV_ENABLED
set_resource_name(id, "RID:" + itos(id.get_id()));
@@ -2547,6 +2597,8 @@ RID RenderingDevice::framebuffer_create_multipass(const Vector<RID> &p_texture_a
}
}
+ framebuffer_cache->render_pass_creation_user_data = framebuffer_owner.get_or_null(id);
+
return id;
}
@@ -3833,7 +3885,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin_for_screen(DisplayS
clear_value.color = p_clear_color;
RDD::RenderPassID render_pass = driver->swap_chain_get_render_pass(sc_it->value);
- draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, clear_value, true, false, RDD::BreadcrumbMarker::BLIT_PASS);
+ draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, RDG::ATTACHMENT_OPERATION_CLEAR, clear_value, true, false, RDD::BreadcrumbMarker::BLIT_PASS);
draw_graph.add_draw_list_set_viewport(viewport);
draw_graph.add_draw_list_set_scissor(viewport);
@@ -3841,150 +3893,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin_for_screen(DisplayS
return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT;
}
-Error RenderingDevice::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, RDD::FramebufferID *r_framebuffer, RDD::RenderPassID *r_render_pass, uint32_t *r_subpass_count) {
- Framebuffer::VersionKey vk;
- vk.initial_color_action = p_initial_color_action;
- vk.final_color_action = p_final_color_action;
- vk.initial_depth_action = p_initial_depth_action;
- vk.final_depth_action = p_final_depth_action;
- vk.view_count = p_framebuffer->view_count;
-
- if (!p_framebuffer->framebuffers.has(vk)) {
- // Need to create this version.
- Framebuffer::Version version;
-
- version.render_pass = _render_pass_create(framebuffer_formats[p_framebuffer->format_id].E->key().attachments, framebuffer_formats[p_framebuffer->format_id].E->key().passes, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_framebuffer->view_count);
-
- LocalVector<RDD::TextureID> attachments;
- for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
- if (texture) {
- attachments.push_back(texture->driver_id);
- if (!(texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT)) { // VRS attachment will be a different size.
- ERR_FAIL_COND_V(texture->width != p_framebuffer->size.width, ERR_BUG);
- ERR_FAIL_COND_V(texture->height != p_framebuffer->size.height, ERR_BUG);
- }
- }
- }
-
- version.framebuffer = driver->framebuffer_create(version.render_pass, attachments, p_framebuffer->size.width, p_framebuffer->size.height);
- ERR_FAIL_COND_V(!version.framebuffer, ERR_CANT_CREATE);
-
- version.subpass_count = framebuffer_formats[p_framebuffer->format_id].E->key().passes.size();
-
- p_framebuffer->framebuffers.insert(vk, version);
- }
- const Framebuffer::Version &version = p_framebuffer->framebuffers[vk];
- *r_framebuffer = version.framebuffer;
- *r_render_pass = version.render_pass;
- *r_subpass_count = version.subpass_count;
-
- return OK;
-}
-
-Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass, uint32_t p_breadcrumb) {
- thread_local LocalVector<RDD::RenderPassClearValue> clear_values;
- thread_local LocalVector<RDG::ResourceTracker *> resource_trackers;
- thread_local LocalVector<RDG::ResourceUsage> resource_usages;
- bool uses_color = false;
- bool uses_depth = false;
- clear_values.clear();
- clear_values.resize(p_framebuffer->texture_ids.size());
- resource_trackers.clear();
- resource_usages.clear();
- int clear_values_count = 0;
- {
- int color_index = 0;
- for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
- RDD::RenderPassClearValue clear_value;
-
- RID texture_rid = p_framebuffer->texture_ids[i];
- Texture *texture = texture_owner.get_or_null(texture_rid);
- if (!texture) {
- color_index++;
- continue;
- }
-
- // Indicate the texture will get modified for the shared texture fallback.
- _texture_update_shared_fallback(texture_rid, texture, true);
-
- if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- if (color_index < p_clear_colors.size()) {
- ERR_FAIL_INDEX_V(color_index, p_clear_colors.size(), ERR_BUG); // A bug.
- clear_value.color = p_clear_colors[color_index];
- color_index++;
- }
-
- resource_trackers.push_back(texture->draw_tracker);
- resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE);
- uses_color = true;
- } else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- clear_value.depth = p_clear_depth;
- clear_value.stencil = p_clear_stencil;
- resource_trackers.push_back(texture->draw_tracker);
- resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE);
- uses_depth = true;
- }
-
- clear_values[clear_values_count++] = clear_value;
- }
- }
-
- draw_graph.add_draw_list_begin(p_render_pass, p_framebuffer_driver_id, Rect2i(p_viewport_offset, p_viewport_size), clear_values, uses_color, uses_depth, p_breadcrumb);
- draw_graph.add_draw_list_usages(resource_trackers, resource_usages);
-
- // Mark textures as bound.
- draw_list_bound_textures.clear();
-
- for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
- if (!texture) {
- continue;
- }
- texture->bound = true;
- draw_list_bound_textures.push_back(p_framebuffer->texture_ids[i]);
- }
-
- return OK;
-}
-
-void RenderingDevice::_draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil) {
- LocalVector<RDD::AttachmentClear> clear_attachments;
- int color_index = 0;
- int texture_index = 0;
- for (int i = 0; i < p_framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(p_framebuffer->texture_ids[i]);
-
- if (!texture) {
- texture_index++;
- continue;
- }
-
- RDD::AttachmentClear clear_at;
- if (p_clear_color && (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
- Color clear_color = p_clear_colors[texture_index++];
- clear_at.value.color = clear_color;
- clear_at.color_attachment = color_index++;
- clear_at.aspect = RDD::TEXTURE_ASPECT_COLOR_BIT;
- } else if (p_clear_depth && (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
- clear_at.value.depth = p_depth;
- clear_at.value.stencil = p_stencil;
- clear_at.color_attachment = 0;
- clear_at.aspect = RDD::TEXTURE_ASPECT_DEPTH_BIT;
- if (format_has_stencil(texture->format)) {
- clear_at.aspect.set_flag(RDD::TEXTURE_ASPECT_STENCIL_BIT);
- }
- } else {
- ERR_CONTINUE(true);
- }
- clear_attachments.push_back(clear_at);
- }
-
- Rect2i rect = Rect2i(p_viewport_offset, p_viewport_size);
- draw_graph.add_draw_list_clear_attachments(clear_attachments, rect);
-}
-
-RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, uint32_t p_breadcrumb) {
+RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer, BitField<DrawFlags> p_draw_flags, const Vector<Color> &p_clear_color_values, float p_clear_depth_value, uint32_t p_clear_stencil_value, const Rect2 &p_region, uint32_t p_breadcrumb) {
ERR_RENDER_THREAD_GUARD_V(INVALID_ID);
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
@@ -4008,43 +3917,88 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer,
viewport_size = regioni.size;
}
- if (p_initial_color_action == INITIAL_ACTION_CLEAR) { // Check clear values.
- int color_count = 0;
- for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
- Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
- // We only check for our VRS usage bit if this is not the first texture id.
- // If it is the first we're likely populating our VRS texture.
- // Bit dirty but...
- if (!texture || (!(texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && !(i != 0 && texture->usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT))) {
- if (!texture || !texture->is_resolve_buffer) {
- color_count++;
- }
+ thread_local LocalVector<RDG::AttachmentOperation> operations;
+ thread_local LocalVector<RDD::RenderPassClearValue> clear_values;
+ thread_local LocalVector<RDG::ResourceTracker *> resource_trackers;
+ thread_local LocalVector<RDG::ResourceUsage> resource_usages;
+ bool uses_color = false;
+ bool uses_depth = false;
+ operations.resize(framebuffer->texture_ids.size());
+ clear_values.resize(framebuffer->texture_ids.size());
+ resource_trackers.clear();
+ resource_usages.clear();
+
+ uint32_t color_index = 0;
+ for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
+ RID texture_rid = framebuffer->texture_ids[i];
+ Texture *texture = texture_owner.get_or_null(texture_rid);
+ if (texture == nullptr) {
+ operations[i] = RDG::ATTACHMENT_OPERATION_DEFAULT;
+ clear_values[i] = RDD::RenderPassClearValue();
+ continue;
+ }
+
+ // Indicate the texture will get modified for the shared texture fallback.
+ _texture_update_shared_fallback(texture_rid, texture, true);
+
+ RDG::AttachmentOperation operation = RDG::ATTACHMENT_OPERATION_DEFAULT;
+ RDD::RenderPassClearValue clear_value;
+ if (texture->usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (p_draw_flags.has_flag(DrawFlags(DRAW_CLEAR_COLOR_0 << color_index))) {
+ ERR_FAIL_COND_V_MSG(color_index >= p_clear_color_values.size(), INVALID_ID, vformat("Color texture (%d) was specified to be cleared but no color value was provided.", color_index));
+ operation = RDG::ATTACHMENT_OPERATION_CLEAR;
+ clear_value.color = p_clear_color_values[color_index];
+ } else if (p_draw_flags.has_flag(DrawFlags(DRAW_IGNORE_COLOR_0 << color_index))) {
+ operation = RDG::ATTACHMENT_OPERATION_IGNORE;
+ }
+
+ resource_trackers.push_back(texture->draw_tracker);
+ resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE);
+ uses_color = true;
+ color_index++;
+ } else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ if (p_draw_flags.has_flag(DRAW_CLEAR_DEPTH) || p_draw_flags.has_flag(DRAW_CLEAR_STENCIL)) {
+ operation = RDG::ATTACHMENT_OPERATION_CLEAR;
+ clear_value.depth = p_clear_depth_value;
+ clear_value.stencil = p_clear_stencil_value;
+ } else if (p_draw_flags.has_flag(DRAW_IGNORE_DEPTH) || p_draw_flags.has_flag(DRAW_IGNORE_STENCIL)) {
+ operation = RDG::ATTACHMENT_OPERATION_IGNORE;
}
+
+ resource_trackers.push_back(texture->draw_tracker);
+ resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE);
+ uses_depth = true;
}
- ERR_FAIL_COND_V_MSG(p_clear_color_values.size() != color_count, INVALID_ID, "Clear color values supplied (" + itos(p_clear_color_values.size()) + ") differ from the amount required for framebuffer color attachments (" + itos(color_count) + ").");
+
+ operations[i] = operation;
+ clear_values[i] = clear_value;
}
- RDD::FramebufferID fb_driver_id;
- RDD::RenderPassID render_pass;
+ draw_graph.add_draw_list_begin(framebuffer->framebuffer_cache, Rect2i(viewport_offset, viewport_size), operations, clear_values, uses_color, uses_depth, p_breadcrumb);
+ draw_graph.add_draw_list_usages(resource_trackers, resource_usages);
- Error err = _draw_list_setup_framebuffer(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, &fb_driver_id, &render_pass, &draw_list_subpass_count);
- ERR_FAIL_COND_V(err != OK, INVALID_ID);
+ // Mark textures as bound.
+ draw_list_bound_textures.clear();
- err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, fb_driver_id, render_pass, p_breadcrumb);
+ for (int i = 0; i < framebuffer->texture_ids.size(); i++) {
+ Texture *texture = texture_owner.get_or_null(framebuffer->texture_ids[i]);
+ if (texture == nullptr) {
+ continue;
+ }
- if (err != OK) {
- return INVALID_ID;
+ texture->bound = true;
+ draw_list_bound_textures.push_back(framebuffer->texture_ids[i]);
}
- draw_list_render_pass = render_pass;
- draw_list_vkframebuffer = fb_driver_id;
-
_draw_list_allocate(Rect2i(viewport_offset, viewport_size), 0);
#ifdef DEBUG_ENABLED
draw_list_framebuffer_format = framebuffer->format_id;
#endif
draw_list_current_subpass = 0;
+ const FramebufferFormatKey &key = framebuffer_formats[framebuffer->format_id].E->key();
+ draw_list_subpass_count = key.passes.size();
+
Rect2i viewport_rect(viewport_offset, viewport_size);
draw_graph.add_draw_list_set_viewport(viewport_rect);
draw_graph.add_draw_list_set_scissor(viewport_rect);
@@ -5443,6 +5397,7 @@ bool RenderingDevice::_texture_make_mutable(Texture *p_texture, RID p_texture_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->is_discardable = p_texture->is_discardable;
p_texture->draw_tracker->reference_count = 1;
if (p_texture_id.is_valid()) {
@@ -5853,13 +5808,7 @@ void RenderingDevice::_free_pending_resources(int p_frame) {
// Framebuffers.
while (frames[p_frame].framebuffers_to_dispose_of.front()) {
Framebuffer *framebuffer = &frames[p_frame].framebuffers_to_dispose_of.front()->get();
-
- for (const KeyValue<Framebuffer::VersionKey, Framebuffer::Version> &E : framebuffer->framebuffers) {
- // First framebuffer, then render pass because it depends on it.
- driver->framebuffer_free(E.value.framebuffer);
- driver->render_pass_free(E.value.render_pass);
- }
-
+ draw_graph.framebuffer_cache_free(driver, framebuffer->framebuffer_cache);
frames[p_frame].framebuffers_to_dispose_of.pop_front();
}
@@ -6211,7 +6160,7 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ
driver->command_buffer_begin(frames[0].command_buffer);
// Create draw graph and start it initialized as well.
- draw_graph.initialize(driver, device, frames.size(), main_queue_family, SECONDARY_COMMAND_BUFFERS_PER_FRAME);
+ draw_graph.initialize(driver, device, &_render_pass_create_from_graph, frames.size(), main_queue_family, SECONDARY_COMMAND_BUFFERS_PER_FRAME);
draw_graph.begin();
for (uint32_t i = 0; i < frames.size(); i++) {
@@ -6709,6 +6658,9 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared);
ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid);
+ ClassDB::bind_method(D_METHOD("texture_set_discardable", "texture", "discardable"), &RenderingDevice::texture_set_discardable);
+ ClassDB::bind_method(D_METHOD("texture_is_discardable", "texture"), &RenderingDevice::texture_is_discardable);
+
ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer"), &RenderingDevice::texture_copy);
ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count"), &RenderingDevice::texture_clear);
ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture"), &RenderingDevice::texture_resolve_multisample);
@@ -6770,7 +6722,7 @@ void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color()));
- ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "breadcrumb"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "draw_flags", "clear_color_values", "clear_depth_value", "clear_stencil_value", "region", "breadcrumb"), &RenderingDevice::draw_list_begin, DEFVAL(DRAW_DEFAULT_ALL), DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(0));
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
#endif
@@ -7294,22 +7246,20 @@ void RenderingDevice::_bind_methods() {
BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_WRITE_MASK);
BIND_BITFIELD_FLAG(DYNAMIC_STATE_STENCIL_REFERENCE);
+#ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(INITIAL_ACTION_LOAD);
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR);
BIND_ENUM_CONSTANT(INITIAL_ACTION_DISCARD);
BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX);
-#ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION);
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION_CONTINUE);
BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP);
BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP);
BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE);
-#endif
BIND_ENUM_CONSTANT(FINAL_ACTION_STORE);
BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD);
BIND_ENUM_CONSTANT(FINAL_ACTION_MAX);
-#ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(FINAL_ACTION_READ);
BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE);
#endif
@@ -7391,6 +7341,34 @@ void RenderingDevice::_bind_methods() {
BIND_ENUM_CONSTANT(BLIT_PASS);
BIND_ENUM_CONSTANT(UI_PASS);
BIND_ENUM_CONSTANT(DEBUG_PASS);
+
+ BIND_BITFIELD_FLAG(DRAW_DEFAULT_ALL);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_0);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_1);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_2);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_3);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_4);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_5);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_6);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_7);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_MASK);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_COLOR_ALL);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_0);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_1);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_2);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_3);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_4);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_5);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_6);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_7);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_MASK);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_COLOR_ALL);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_DEPTH);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_DEPTH);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_STENCIL);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_STENCIL);
+ BIND_BITFIELD_FLAG(DRAW_CLEAR_ALL);
+ BIND_BITFIELD_FLAG(DRAW_IGNORE_ALL);
}
void RenderingDevice::make_current() {
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index ccfe51043b..4e54e4ca1a 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -251,6 +251,7 @@ public:
Vector<DataFormat> allowed_shared_formats;
bool is_resolve_buffer = false;
+ bool is_discardable = false;
bool has_initial_data = false;
BitField<RDD::TextureAspectBits> read_aspect_flags;
@@ -287,6 +288,7 @@ public:
tf.usage_bits = usage_flags;
tf.shareable_formats = allowed_shared_formats;
tf.is_resolve_buffer = is_resolve_buffer;
+ tf.is_discardable = is_discardable;
return tf;
}
};
@@ -349,33 +351,8 @@ public:
Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers);
Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture);
- /************************/
- /**** DRAW LISTS (I) ****/
- /************************/
-
- enum InitialAction {
- INITIAL_ACTION_LOAD,
- INITIAL_ACTION_CLEAR,
- INITIAL_ACTION_DISCARD,
- INITIAL_ACTION_MAX,
-#ifndef DISABLE_DEPRECATED
- INITIAL_ACTION_CLEAR_REGION = INITIAL_ACTION_CLEAR,
- INITIAL_ACTION_CLEAR_REGION_CONTINUE = INITIAL_ACTION_CLEAR,
- INITIAL_ACTION_KEEP = INITIAL_ACTION_LOAD,
- INITIAL_ACTION_DROP = INITIAL_ACTION_DISCARD,
- INITIAL_ACTION_CONTINUE = INITIAL_ACTION_LOAD,
-#endif
- };
-
- enum FinalAction {
- FINAL_ACTION_STORE,
- FINAL_ACTION_DISCARD,
- FINAL_ACTION_MAX,
-#ifndef DISABLE_DEPRECATED
- FINAL_ACTION_READ = FINAL_ACTION_STORE,
- FINAL_ACTION_CONTINUE = FINAL_ACTION_STORE,
-#endif
- };
+ void texture_set_discardable(RID p_texture, bool p_discardable);
+ bool texture_is_discardable(RID p_texture);
/*********************/
/**** FRAMEBUFFER ****/
@@ -523,7 +500,8 @@ private:
}
};
- RDD::RenderPassID _render_pass_create(const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, InitialAction p_initial_action, FinalAction p_final_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, uint32_t p_view_count = 1, Vector<TextureSamples> *r_samples = nullptr);
+ static RDD::RenderPassID _render_pass_create(RenderingDeviceDriver *p_driver, const Vector<AttachmentFormat> &p_attachments, const Vector<FramebufferPass> &p_passes, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, uint32_t p_view_count = 1, Vector<TextureSamples> *r_samples = nullptr);
+ static RDD::RenderPassID _render_pass_create_from_graph(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data);
// This is a cache and it's never freed, it ensures
// IDs for a given format are always unique.
@@ -538,47 +516,13 @@ private:
HashMap<FramebufferFormatID, FramebufferFormat> framebuffer_formats;
struct Framebuffer {
+ RenderingDevice *rendering_device = nullptr;
FramebufferFormatID format_id;
- struct VersionKey {
- InitialAction initial_color_action;
- FinalAction final_color_action;
- InitialAction initial_depth_action;
- FinalAction final_depth_action;
- uint32_t view_count;
-
- bool operator<(const VersionKey &p_key) const {
- if (initial_color_action == p_key.initial_color_action) {
- if (final_color_action == p_key.final_color_action) {
- if (initial_depth_action == p_key.initial_depth_action) {
- if (final_depth_action == p_key.final_depth_action) {
- return view_count < p_key.view_count;
- } else {
- return final_depth_action < p_key.final_depth_action;
- }
- } else {
- return initial_depth_action < p_key.initial_depth_action;
- }
- } else {
- return final_color_action < p_key.final_color_action;
- }
- } else {
- return initial_color_action < p_key.initial_color_action;
- }
- }
- };
-
uint32_t storage_mask = 0;
Vector<RID> texture_ids;
InvalidationCallback invalidated_callback = nullptr;
void *invalidated_callback_userdata = nullptr;
-
- struct Version {
- RDD::FramebufferID framebuffer;
- RDD::RenderPassID render_pass; // This one is owned.
- uint32_t subpass_count = 1;
- };
-
- RBMap<VersionKey, Version> framebuffers;
+ RDG::FramebufferCache *framebuffer_cache = nullptr;
Size2 size;
uint32_t view_count;
};
@@ -826,6 +770,26 @@ public:
BARRIER_MASK_NO_BARRIER = 0x8000,
};
+ enum InitialAction {
+ INITIAL_ACTION_LOAD,
+ INITIAL_ACTION_CLEAR,
+ INITIAL_ACTION_DISCARD,
+ INITIAL_ACTION_MAX,
+ INITIAL_ACTION_CLEAR_REGION = INITIAL_ACTION_CLEAR,
+ INITIAL_ACTION_CLEAR_REGION_CONTINUE = INITIAL_ACTION_CLEAR,
+ INITIAL_ACTION_KEEP = INITIAL_ACTION_LOAD,
+ INITIAL_ACTION_DROP = INITIAL_ACTION_DISCARD,
+ INITIAL_ACTION_CONTINUE = INITIAL_ACTION_LOAD,
+ };
+
+ enum FinalAction {
+ FINAL_ACTION_STORE,
+ FINAL_ACTION_DISCARD,
+ FINAL_ACTION_MAX,
+ FINAL_ACTION_READ = FINAL_ACTION_STORE,
+ FINAL_ACTION_CONTINUE = FINAL_ACTION_STORE,
+ };
+
void barrier(BitField<BarrierMask> p_from = BARRIER_MASK_ALL_BARRIERS, BitField<BarrierMask> p_to = BARRIER_MASK_ALL_BARRIERS);
void full_barrier();
void draw_command_insert_label(String p_label_name, const Color &p_color = Color(1, 1, 1, 1));
@@ -854,7 +818,9 @@ private:
FramebufferFormatID _screen_get_framebuffer_format_bind_compat_87340() const;
- DrawListID _draw_list_begin_bind_compat_90993(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
+ DrawListID _draw_list_begin_bind_compat_90993(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region);
+
+ DrawListID _draw_list_begin_bind_compat_98670(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, uint32_t p_breadcrumb);
#endif
public:
@@ -1158,8 +1124,6 @@ private:
DrawList *draw_list = nullptr;
uint32_t draw_list_subpass_count = 0;
- RDD::RenderPassID draw_list_render_pass;
- RDD::FramebufferID draw_list_vkframebuffer;
#ifdef DEBUG_ENABLED
FramebufferFormatID draw_list_framebuffer_format = INVALID_ID;
#endif
@@ -1167,16 +1131,43 @@ private:
Vector<RID> draw_list_bound_textures;
- void _draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector<Color> &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil);
- Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, RDD::FramebufferID *r_framebuffer, RDD::RenderPassID *r_render_pass, uint32_t *r_subpass_count);
- Error _draw_list_render_pass_begin(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i p_viewport_offset, Point2i p_viewport_size, RDD::FramebufferID p_framebuffer_driver_id, RDD::RenderPassID p_render_pass, uint32_t p_breadcrumb);
_FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id);
Error _draw_list_allocate(const Rect2i &p_viewport, uint32_t p_subpass);
void _draw_list_free(Rect2i *r_last_viewport = nullptr);
public:
+ enum DrawFlags {
+ DRAW_DEFAULT_ALL = 0,
+ DRAW_CLEAR_COLOR_0 = (1 << 0),
+ DRAW_CLEAR_COLOR_1 = (1 << 1),
+ DRAW_CLEAR_COLOR_2 = (1 << 2),
+ DRAW_CLEAR_COLOR_3 = (1 << 3),
+ DRAW_CLEAR_COLOR_4 = (1 << 4),
+ DRAW_CLEAR_COLOR_5 = (1 << 5),
+ DRAW_CLEAR_COLOR_6 = (1 << 6),
+ DRAW_CLEAR_COLOR_7 = (1 << 7),
+ DRAW_CLEAR_COLOR_MASK = 0xFF,
+ DRAW_CLEAR_COLOR_ALL = DRAW_CLEAR_COLOR_MASK,
+ DRAW_IGNORE_COLOR_0 = (1 << 8),
+ DRAW_IGNORE_COLOR_1 = (1 << 9),
+ DRAW_IGNORE_COLOR_2 = (1 << 10),
+ DRAW_IGNORE_COLOR_3 = (1 << 11),
+ DRAW_IGNORE_COLOR_4 = (1 << 12),
+ DRAW_IGNORE_COLOR_5 = (1 << 13),
+ DRAW_IGNORE_COLOR_6 = (1 << 14),
+ DRAW_IGNORE_COLOR_7 = (1 << 15),
+ DRAW_IGNORE_COLOR_MASK = 0xFF00,
+ DRAW_IGNORE_COLOR_ALL = DRAW_IGNORE_COLOR_MASK,
+ DRAW_CLEAR_DEPTH = (1 << 16),
+ DRAW_IGNORE_DEPTH = (1 << 17),
+ DRAW_CLEAR_STENCIL = (1 << 18),
+ DRAW_IGNORE_STENCIL = (1 << 19),
+ DRAW_CLEAR_ALL = DRAW_CLEAR_COLOR_ALL | DRAW_CLEAR_DEPTH | DRAW_CLEAR_STENCIL,
+ DRAW_IGNORE_ALL = DRAW_IGNORE_COLOR_ALL | DRAW_IGNORE_DEPTH | DRAW_IGNORE_STENCIL
+ };
+
DrawListID draw_list_begin_for_screen(DisplayServer::WindowID p_screen = 0, const Color &p_clear_color = Color());
- DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), uint32_t p_breadcrumb = 0);
+ DrawListID draw_list_begin(RID p_framebuffer, BitField<DrawFlags> p_draw_flags = DRAW_DEFAULT_ALL, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth_value = 1.0f, uint32_t p_clear_stencil_value = 0, const Rect2 &p_region = Rect2(), uint32_t p_breadcrumb = 0);
void draw_list_set_blend_constants(DrawListID p_list, const Color &p_color);
void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline);
@@ -1569,15 +1560,16 @@ VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
VARIANT_BITFIELD_CAST(RenderingDevice::PipelineDynamicStateFlags)
VARIANT_ENUM_CAST(RenderingDevice::PipelineSpecializationConstantType)
-VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
-VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
VARIANT_ENUM_CAST(RenderingDevice::Limit)
VARIANT_ENUM_CAST(RenderingDevice::MemoryType)
VARIANT_ENUM_CAST(RenderingDevice::Features)
VARIANT_ENUM_CAST(RenderingDevice::BreadcrumbMarker)
+VARIANT_BITFIELD_CAST(RenderingDevice::DrawFlags);
#ifndef DISABLE_DEPRECATED
VARIANT_BITFIELD_CAST(RenderingDevice::BarrierMask);
+VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
+VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
#endif
typedef RenderingDevice RD;
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 4d9b565080..89fed7ffa6 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -69,6 +69,8 @@ public:
RD_SETGET(RD::TextureType, texture_type)
RD_SETGET(RD::TextureSamples, samples)
RD_SETGET(BitField<RenderingDevice::TextureUsageBits>, usage_bits)
+ RD_SETGET(bool, is_resolve_buffer)
+ RD_SETGET(bool, is_discardable)
void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
@@ -84,6 +86,9 @@ protected:
RD_BIND(Variant::INT, RDTextureFormat, texture_type);
RD_BIND(Variant::INT, RDTextureFormat, samples);
RD_BIND(Variant::INT, RDTextureFormat, usage_bits);
+ RD_BIND(Variant::BOOL, RDTextureFormat, is_resolve_buffer);
+ RD_BIND(Variant::BOOL, RDTextureFormat, is_discardable);
+
ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format);
ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format);
}
diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h
index d516d968af..9d01b69550 100644
--- a/servers/rendering/rendering_device_commons.h
+++ b/servers/rendering/rendering_device_commons.h
@@ -373,6 +373,7 @@ public:
uint32_t usage_bits = 0;
Vector<DataFormat> shareable_formats;
bool is_resolve_buffer = false;
+ bool is_discardable = false;
bool operator==(const TextureFormat &b) const {
if (format != b.format) {
@@ -395,6 +396,10 @@ public:
return false;
} else if (shareable_formats != b.shareable_formats) {
return false;
+ } else if (is_resolve_buffer != b.is_resolve_buffer) {
+ return false;
+ } else if (is_discardable != b.is_discardable) {
+ return false;
} else {
return true;
}
diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp
index ebfe328393..b2779af620 100644
--- a/servers/rendering/rendering_device_graph.cpp
+++ b/servers/rendering/rendering_device_graph.cpp
@@ -248,6 +248,40 @@ RenderingDeviceGraph::ComputeListInstruction *RenderingDeviceGraph::_allocate_co
return reinterpret_cast<ComputeListInstruction *>(&compute_instruction_list.data[compute_list_data_offset]);
}
+void RenderingDeviceGraph::_check_discardable_attachment_dependency(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) {
+ if (!p_resource_tracker->is_discardable) {
+ return;
+ }
+
+ // Check if the command is a a draw list that clears the attachment completely. If it is, we don't need to modify the previous draw list.
+ uint32_t command_offset = command_data_offsets[p_command_index];
+ RecordedDrawListCommand *draw_list_command = reinterpret_cast<RecordedDrawListCommand *>(&command_data[command_offset]);
+ if (draw_list_command->type == RecordedCommand::TYPE_DRAW_LIST) {
+ ResourceTracker **trackers = draw_list_command->trackers();
+ for (uint32_t i = 0; i < draw_list_command->trackers_count; i++) {
+ if (trackers[i] == p_resource_tracker && draw_list_command->load_ops()[i] == RDD::ATTACHMENT_LOAD_OP_CLEAR) {
+ return;
+ }
+ }
+ }
+
+ // Check if the previous command is a draw list.
+ uint32_t previous_command_offset = command_data_offsets[p_previous_command_index];
+ RecordedDrawListCommand *previous_draw_list_command = reinterpret_cast<RecordedDrawListCommand *>(&command_data[previous_command_offset]);
+ if (previous_draw_list_command->type != RecordedCommand::TYPE_DRAW_LIST) {
+ return;
+ }
+
+ // Search for the tracker inside the draw list command and modify the store operation accordingly.
+ ResourceTracker **trackers = previous_draw_list_command->trackers();
+ for (uint32_t i = 0; i < previous_draw_list_command->trackers_count; i++) {
+ if (trackers[i] == p_resource_tracker) {
+ previous_draw_list_command->store_ops()[i] = RDD::ATTACHMENT_STORE_OP_STORE;
+ return;
+ }
+ }
+}
+
void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_trackers, ResourceUsage *p_resource_usages, uint32_t p_resource_count, int32_t p_command_index, RecordedCommand *r_command) {
// Assign the next stages derived from the stages the command requires first.
r_command->next_stages = r_command->self_stages;
@@ -502,6 +536,8 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
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 (!write_list_node.partial_coverage || _check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index)) {
+ _check_discardable_attachment_dependency(search_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);
@@ -528,6 +564,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
if (search_tracker->write_command_or_list_index == p_command_index) {
ERR_FAIL_MSG("Command can't have itself as a dependency.");
} else {
+ _check_discardable_attachment_dependency(search_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);
}
}
@@ -698,6 +735,38 @@ void RenderingDeviceGraph::_run_compute_list_command(RDD::CommandBufferID p_comm
}
}
+void RenderingDeviceGraph::_get_draw_list_render_pass_and_framebuffer(const RecordedDrawListCommand *p_draw_list_command, RDD::RenderPassID &r_render_pass, RDD::FramebufferID &r_framebuffer) {
+ DEV_ASSERT(p_draw_list_command->trackers_count <= 21 && "Max number of attachments that can be encoded into the key.");
+
+ // Build a unique key from the load and store ops for each attachment.
+ const RDD::AttachmentLoadOp *load_ops = p_draw_list_command->load_ops();
+ const RDD::AttachmentStoreOp *store_ops = p_draw_list_command->store_ops();
+ uint64_t key = 0;
+ for (uint32_t i = 0; i < p_draw_list_command->trackers_count; i++) {
+ key |= uint64_t(load_ops[i]) << (i * 3);
+ key |= uint64_t(store_ops[i]) << (i * 3 + 2);
+ }
+
+ // Check the storage map if the render pass and the framebuffer needs to be created.
+ FramebufferCache *framebuffer_cache = p_draw_list_command->framebuffer_cache;
+ HashMap<uint64_t, FramebufferStorage>::Iterator it = framebuffer_cache->storage_map.find(key);
+ if (it == framebuffer_cache->storage_map.end()) {
+ FramebufferStorage storage;
+ VectorView<RDD::AttachmentLoadOp> load_ops_view(load_ops, p_draw_list_command->trackers_count);
+ VectorView<RDD::AttachmentStoreOp> store_ops_view(store_ops, p_draw_list_command->trackers_count);
+ storage.render_pass = render_pass_creation_function(driver, load_ops_view, store_ops_view, framebuffer_cache->render_pass_creation_user_data);
+ ERR_FAIL_COND(!storage.render_pass);
+
+ storage.framebuffer = driver->framebuffer_create(storage.render_pass, framebuffer_cache->textures, framebuffer_cache->width, framebuffer_cache->height);
+ ERR_FAIL_COND(!storage.framebuffer);
+
+ it = framebuffer_cache->storage_map.insert(key, storage);
+ }
+
+ r_render_pass = it->value.render_pass;
+ r_framebuffer = it->value.framebuffer;
+}
+
void RenderingDeviceGraph::_run_draw_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size) {
uint32_t instruction_data_cursor = 0;
while (instruction_data_cursor < p_instruction_data_size) {
@@ -805,6 +874,37 @@ void RenderingDeviceGraph::_run_draw_list_command(RDD::CommandBufferID p_command
}
}
+void RenderingDeviceGraph::_add_draw_list_begin(FramebufferCache *p_framebuffer_cache, RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) {
+ DEV_ASSERT(p_attachment_operations.size() == p_attachment_clear_values.size());
+
+ draw_instruction_list.clear();
+ draw_instruction_list.index++;
+ draw_instruction_list.framebuffer_cache = p_framebuffer_cache;
+ draw_instruction_list.render_pass = p_render_pass;
+ draw_instruction_list.framebuffer = p_framebuffer;
+ draw_instruction_list.region = p_region;
+ draw_instruction_list.attachment_operations.resize(p_attachment_operations.size());
+ draw_instruction_list.attachment_clear_values.resize(p_attachment_clear_values.size());
+
+ for (uint32_t i = 0; i < p_attachment_operations.size(); i++) {
+ draw_instruction_list.attachment_operations[i] = p_attachment_operations[i];
+ draw_instruction_list.attachment_clear_values[i] = p_attachment_clear_values[i];
+ }
+
+ if (p_uses_color) {
+ draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ }
+
+ if (p_uses_depth) {
+ draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+ draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
+ }
+
+#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
+ draw_instruction_list.breadcrumb = p_breadcrumb;
+#endif
+}
+
void RenderingDeviceGraph::_run_secondary_command_buffer_task(const SecondaryCommandBuffer *p_secondary) {
driver->command_buffer_begin_secondary(p_secondary->command_buffer, p_secondary->render_pass, 0, p_secondary->framebuffer);
_run_draw_list_command(p_secondary->command_buffer, p_secondary->instruction_data.ptr(), p_secondary->instruction_data.size());
@@ -825,7 +925,7 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
for (uint32_t i = 0; i < p_sorted_commands_count; i++) {
const uint32_t command_index = p_sorted_commands[i].index;
const uint32_t command_data_offset = command_data_offsets[command_index];
- const RecordedCommand *command = reinterpret_cast<RecordedCommand *>(&command_data[command_data_offset]);
+ const RecordedCommand *command = reinterpret_cast<const RecordedCommand *>(&command_data[command_data_offset]);
_run_label_command_change(r_command_buffer, command->label_index, p_level, false, true, &p_sorted_commands[i], p_sorted_commands_count - i, r_current_label_index, r_current_label_level);
switch (command->type) {
@@ -883,9 +983,20 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
driver->command_insert_breadcrumb(r_command_buffer, draw_list_command->breadcrumb);
#endif
- driver->command_begin_render_pass(r_command_buffer, draw_list_command->render_pass, draw_list_command->framebuffer, draw_list_command->command_buffer_type, draw_list_command->region, clear_values);
- _run_draw_list_command(r_command_buffer, draw_list_command->instruction_data(), draw_list_command->instruction_data_size);
- driver->command_end_render_pass(r_command_buffer);
+ RDD::RenderPassID render_pass;
+ RDD::FramebufferID framebuffer;
+ if (draw_list_command->framebuffer_cache != nullptr) {
+ _get_draw_list_render_pass_and_framebuffer(draw_list_command, render_pass, framebuffer);
+ } else {
+ render_pass = draw_list_command->render_pass;
+ framebuffer = draw_list_command->framebuffer;
+ }
+
+ if (framebuffer && render_pass) {
+ driver->command_begin_render_pass(r_command_buffer, render_pass, framebuffer, draw_list_command->command_buffer_type, draw_list_command->region, clear_values);
+ _run_draw_list_command(r_command_buffer, draw_list_command->instruction_data(), draw_list_command->instruction_data_size);
+ driver->command_end_render_pass(r_command_buffer);
+ }
} break;
case RecordedCommand::TYPE_TEXTURE_CLEAR: {
const RecordedTextureClearCommand *texture_clear_command = reinterpret_cast<const RecordedTextureClearCommand *>(command);
@@ -1338,9 +1449,14 @@ void RenderingDeviceGraph::_print_compute_list(const uint8_t *p_instruction_data
}
}
-void RenderingDeviceGraph::initialize(RDD *p_driver, RenderingContextDriver::Device p_device, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame) {
+void RenderingDeviceGraph::initialize(RDD *p_driver, RenderingContextDriver::Device p_device, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame) {
+ DEV_ASSERT(p_driver != nullptr);
+ DEV_ASSERT(p_render_pass_creation_function != nullptr);
+ DEV_ASSERT(p_frame_count > 0);
+
driver = p_driver;
device = p_device;
+ render_pass_creation_function = p_render_pass_creation_function;
frames.resize(p_frame_count);
for (uint32_t i = 0; i < p_frame_count; i++) {
@@ -1566,28 +1682,12 @@ void RenderingDeviceGraph::add_compute_list_end() {
_add_command_to_graph(compute_instruction_list.command_trackers.ptr(), compute_instruction_list.command_tracker_usages.ptr(), compute_instruction_list.command_trackers.size(), command_index, command);
}
-void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) {
- draw_instruction_list.clear();
- draw_instruction_list.index++;
- draw_instruction_list.render_pass = p_render_pass;
- draw_instruction_list.framebuffer = p_framebuffer;
- draw_instruction_list.region = p_region;
-#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
- draw_instruction_list.breadcrumb = p_breadcrumb;
-#endif
- draw_instruction_list.clear_values.resize(p_clear_values.size());
- for (uint32_t i = 0; i < p_clear_values.size(); i++) {
- draw_instruction_list.clear_values[i] = p_clear_values[i];
- }
-
- if (p_uses_color) {
- draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
- }
+void RenderingDeviceGraph::add_draw_list_begin(FramebufferCache *p_framebuffer_cache, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) {
+ _add_draw_list_begin(p_framebuffer_cache, RDD::RenderPassID(), RDD::FramebufferID(), p_region, p_attachment_operations, p_attachment_clear_values, p_uses_color, p_uses_depth, p_breadcrumb);
+}
- if (p_uses_depth) {
- draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
- draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
- }
+void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) {
+ _add_draw_list_begin(nullptr, p_render_pass, p_framebuffer, p_region, p_attachment_operations, p_attachment_clear_values, p_uses_color, p_uses_depth, p_breadcrumb);
}
void RenderingDeviceGraph::add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset) {
@@ -1768,51 +1868,62 @@ void RenderingDeviceGraph::add_draw_list_usages(VectorView<ResourceTracker *> p_
}
void RenderingDeviceGraph::add_draw_list_end() {
- // Arbitrary size threshold to evaluate if it'd be best to record the draw list on the background as a secondary buffer.
- const uint32_t instruction_data_threshold_for_secondary = 16384;
- RDD::CommandBufferType command_buffer_type;
- uint32_t &secondary_buffers_used = frames[frame].secondary_command_buffers_used;
- if (draw_instruction_list.data.size() > instruction_data_threshold_for_secondary && secondary_buffers_used < frames[frame].secondary_command_buffers.size()) {
- // Copy the current instruction list data into another array that will be used by the secondary command buffer worker.
- SecondaryCommandBuffer &secondary = frames[frame].secondary_command_buffers[secondary_buffers_used];
- secondary.render_pass = draw_instruction_list.render_pass;
- secondary.framebuffer = draw_instruction_list.framebuffer;
- secondary.instruction_data.resize(draw_instruction_list.data.size());
- memcpy(secondary.instruction_data.ptr(), draw_instruction_list.data.ptr(), draw_instruction_list.data.size());
-
- // Run a background task for recording the secondary command buffer.
- secondary.task = WorkerThreadPool::get_singleton()->add_template_task(this, &RenderingDeviceGraph::_run_secondary_command_buffer_task, &secondary, true);
-
- // Clear the instruction list and add a single command for executing the secondary command buffer instead.
- draw_instruction_list.data.clear();
- add_draw_list_execute_commands(secondary.command_buffer);
- secondary_buffers_used++;
-
- command_buffer_type = RDD::COMMAND_BUFFER_TYPE_SECONDARY;
- } else {
- command_buffer_type = RDD::COMMAND_BUFFER_TYPE_PRIMARY;
- }
-
+ FramebufferCache *framebuffer_cache = draw_instruction_list.framebuffer_cache;
int32_t command_index;
- uint32_t clear_values_size = sizeof(RDD::RenderPassClearValue) * draw_instruction_list.clear_values.size();
+ uint32_t clear_values_size = sizeof(RDD::RenderPassClearValue) * draw_instruction_list.attachment_clear_values.size();
+ uint32_t trackers_count = framebuffer_cache != nullptr ? framebuffer_cache->trackers.size() : 0;
+ uint32_t trackers_and_ops_size = (sizeof(ResourceTracker *) + sizeof(RDD::AttachmentLoadOp) + sizeof(RDD::AttachmentStoreOp)) * trackers_count;
uint32_t instruction_data_size = draw_instruction_list.data.size();
- uint32_t command_size = sizeof(RecordedDrawListCommand) + clear_values_size + instruction_data_size;
+ uint32_t command_size = sizeof(RecordedDrawListCommand) + clear_values_size + trackers_and_ops_size + instruction_data_size;
RecordedDrawListCommand *command = static_cast<RecordedDrawListCommand *>(_allocate_command(command_size, command_index));
command->type = RecordedCommand::TYPE_DRAW_LIST;
command->self_stages = draw_instruction_list.stages;
- command->instruction_data_size = instruction_data_size;
+ command->framebuffer_cache = framebuffer_cache;
command->render_pass = draw_instruction_list.render_pass;
command->framebuffer = draw_instruction_list.framebuffer;
- command->command_buffer_type = command_buffer_type;
+ command->instruction_data_size = instruction_data_size;
+ command->command_buffer_type = RDD::COMMAND_BUFFER_TYPE_PRIMARY;
command->region = draw_instruction_list.region;
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
command->breadcrumb = draw_instruction_list.breadcrumb;
#endif
- command->clear_values_count = draw_instruction_list.clear_values.size();
+ command->clear_values_count = draw_instruction_list.attachment_clear_values.size();
+ command->trackers_count = trackers_count;
+
+ // Initialize the load and store operations to their default behaviors. The store behavior will be modified if a command depends on the result of this render pass.
+ uint32_t attachment_op_count = draw_instruction_list.attachment_operations.size();
+ ResourceTracker **trackers = command->trackers();
+ RDD::AttachmentLoadOp *load_ops = command->load_ops();
+ RDD::AttachmentStoreOp *store_ops = command->store_ops();
+ for (uint32_t i = 0; i < command->trackers_count; i++) {
+ ResourceTracker *resource_tracker = framebuffer_cache->trackers[i];
+ if (resource_tracker != nullptr) {
+ if (i < command->clear_values_count && i < attachment_op_count && draw_instruction_list.attachment_operations[i] == ATTACHMENT_OPERATION_CLEAR) {
+ load_ops[i] = RDD::ATTACHMENT_LOAD_OP_CLEAR;
+ } else if (i < attachment_op_count && draw_instruction_list.attachment_operations[i] == ATTACHMENT_OPERATION_IGNORE) {
+ load_ops[i] = RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else if (resource_tracker->is_discardable) {
+ bool resource_has_parent = resource_tracker->parent != nullptr;
+ ResourceTracker *search_tracker = resource_has_parent ? resource_tracker->parent : resource_tracker;
+ search_tracker->reset_if_outdated(tracking_frame);
+ bool resource_was_modified_this_frame = search_tracker->write_command_or_list_index >= 0;
+ load_ops[i] = resource_was_modified_this_frame ? RDD::ATTACHMENT_LOAD_OP_LOAD : RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
+ } else {
+ load_ops[i] = RDD::ATTACHMENT_LOAD_OP_LOAD;
+ }
+
+ store_ops[i] = resource_tracker->is_discardable ? RDD::ATTACHMENT_STORE_OP_DONT_CARE : RDD::ATTACHMENT_STORE_OP_STORE;
+ } else {
+ load_ops[i] = RDD::ATTACHMENT_LOAD_OP_DONT_CARE;
+ store_ops[i] = RDD::ATTACHMENT_STORE_OP_DONT_CARE;
+ }
+
+ trackers[i] = resource_tracker;
+ }
RDD::RenderPassClearValue *clear_values = command->clear_values();
for (uint32_t i = 0; i < command->clear_values_count; i++) {
- clear_values[i] = draw_instruction_list.clear_values[i];
+ clear_values[i] = draw_instruction_list.attachment_clear_values[i];
}
memcpy(command->instruction_data(), draw_instruction_list.data.ptr(), instruction_data_size);
@@ -2182,20 +2293,20 @@ RenderingDeviceGraph::ResourceTracker *RenderingDeviceGraph::resource_tracker_cr
return memnew(ResourceTracker);
}
-void RenderingDeviceGraph::resource_tracker_free(ResourceTracker *tracker) {
- if (tracker == nullptr) {
+void RenderingDeviceGraph::resource_tracker_free(ResourceTracker *p_tracker) {
+ if (p_tracker == nullptr) {
return;
}
- if (tracker->in_parent_dirty_list) {
+ if (p_tracker->in_parent_dirty_list) {
// Delete the tracker from the parent's dirty linked list.
- if (tracker->parent->dirty_shared_list == tracker) {
- tracker->parent->dirty_shared_list = tracker->next_shared;
+ if (p_tracker->parent->dirty_shared_list == p_tracker) {
+ p_tracker->parent->dirty_shared_list = p_tracker->next_shared;
} else {
- ResourceTracker *node = tracker->parent->dirty_shared_list;
+ ResourceTracker *node = p_tracker->parent->dirty_shared_list;
while (node != nullptr) {
- if (node->next_shared == tracker) {
- node->next_shared = tracker->next_shared;
+ if (node->next_shared == p_tracker) {
+ node->next_shared = p_tracker->next_shared;
node = nullptr;
} else {
node = node->next_shared;
@@ -2204,9 +2315,28 @@ void RenderingDeviceGraph::resource_tracker_free(ResourceTracker *tracker) {
}
}
- memdelete(tracker);
+ memdelete(p_tracker);
#if PRINT_RESOURCE_TRACKER_TOTAL
print_line("Resource trackers:", --resource_tracker_total);
#endif
}
+
+RenderingDeviceGraph::FramebufferCache *RenderingDeviceGraph::framebuffer_cache_create() {
+ return memnew(FramebufferCache);
+}
+
+void RenderingDeviceGraph::framebuffer_cache_free(RDD *p_driver, FramebufferCache *p_cache) {
+ DEV_ASSERT(p_driver != nullptr);
+
+ if (p_cache == nullptr) {
+ return;
+ }
+
+ for (KeyValue<uint64_t, FramebufferStorage> &E : p_cache->storage_map) {
+ p_driver->framebuffer_free(E.value.framebuffer);
+ p_driver->render_pass_free(E.value.render_pass);
+ }
+
+ memdelete(p_cache);
+}
diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h
index f7d9027147..adfbb47e84 100644
--- a/servers/rendering/rendering_device_graph.h
+++ b/servers/rendering/rendering_device_graph.h
@@ -176,6 +176,7 @@ public:
Rect2i texture_slice_or_dirty_rect;
bool in_parent_dirty_list = false;
bool write_command_list_enabled = false;
+ bool is_discardable = false;
_FORCE_INLINE_ void reset_if_outdated(int64_t new_command_frame) {
if (new_command_frame != command_frame) {
@@ -193,6 +194,22 @@ public:
}
};
+ typedef RDD::RenderPassID (*RenderPassCreationFunction)(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data);
+
+ struct FramebufferStorage {
+ RDD::FramebufferID framebuffer;
+ RDD::RenderPassID render_pass;
+ };
+
+ struct FramebufferCache {
+ uint32_t width = 0;
+ uint32_t height = 0;
+ LocalVector<RDD::TextureID> textures;
+ LocalVector<ResourceTracker *> trackers;
+ HashMap<uint64_t, FramebufferStorage> storage_map;
+ void *render_pass_creation_user_data = nullptr;
+ };
+
struct CommandBufferPool {
// Provided by RenderingDevice.
RDD::CommandPoolID pool;
@@ -207,6 +224,15 @@ public:
bool draw_list_found = false;
};
+ enum AttachmentOperation {
+ // Loads or ignores if the attachment is discardable.
+ ATTACHMENT_OPERATION_DEFAULT,
+ // Clear the attachment to a value.
+ ATTACHMENT_OPERATION_CLEAR,
+ // Ignore any contents from the attachment.
+ ATTACHMENT_OPERATION_IGNORE,
+ };
+
private:
struct InstructionList {
LocalVector<uint8_t> data;
@@ -230,13 +256,16 @@ private:
};
struct DrawInstructionList : InstructionList {
+ FramebufferCache *framebuffer_cache = nullptr;
RDD::RenderPassID render_pass;
RDD::FramebufferID framebuffer;
Rect2i region;
+ LocalVector<AttachmentOperation> attachment_operations;
+ LocalVector<RDD::RenderPassClearValue> attachment_clear_values;
+
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
uint32_t breadcrumb;
#endif
- LocalVector<RDD::RenderPassClearValue> clear_values;
};
struct RecordedCommandSort {
@@ -320,15 +349,18 @@ private:
};
struct RecordedDrawListCommand : RecordedCommand {
- uint32_t instruction_data_size = 0;
- RDD::RenderPassID render_pass;
+ FramebufferCache *framebuffer_cache = nullptr;
RDD::FramebufferID framebuffer;
+ RDD::RenderPassID render_pass;
+ uint32_t instruction_data_size = 0;
RDD::CommandBufferType command_buffer_type;
Rect2i region;
+ uint32_t clear_values_count = 0;
+ uint32_t trackers_count = 0;
+
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
uint32_t breadcrumb = 0;
#endif
- uint32_t clear_values_count = 0;
_FORCE_INLINE_ RDD::RenderPassClearValue *clear_values() {
return reinterpret_cast<RDD::RenderPassClearValue *>(&this[1]);
@@ -338,12 +370,36 @@ private:
return reinterpret_cast<const RDD::RenderPassClearValue *>(&this[1]);
}
+ _FORCE_INLINE_ ResourceTracker **trackers() {
+ return reinterpret_cast<ResourceTracker **>(&clear_values()[clear_values_count]);
+ }
+
+ _FORCE_INLINE_ ResourceTracker *const *trackers() const {
+ return reinterpret_cast<ResourceTracker *const *>(&clear_values()[clear_values_count]);
+ }
+
+ _FORCE_INLINE_ RDD::AttachmentLoadOp *load_ops() {
+ return reinterpret_cast<RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);
+ }
+
+ _FORCE_INLINE_ const RDD::AttachmentLoadOp *load_ops() const {
+ return reinterpret_cast<const RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);
+ }
+
+ _FORCE_INLINE_ RDD::AttachmentStoreOp *store_ops() {
+ return reinterpret_cast<RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);
+ }
+
+ _FORCE_INLINE_ const RDD::AttachmentStoreOp *store_ops() const {
+ return reinterpret_cast<const RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);
+ }
+
_FORCE_INLINE_ uint8_t *instruction_data() {
- return reinterpret_cast<uint8_t *>(&clear_values()[clear_values_count]);
+ return reinterpret_cast<uint8_t *>(&store_ops()[trackers_count]);
}
_FORCE_INLINE_ const uint8_t *instruction_data() const {
- return reinterpret_cast<const uint8_t *>(&clear_values()[clear_values_count]);
+ return reinterpret_cast<const uint8_t *>(&store_ops()[trackers_count]);
}
};
@@ -616,6 +672,7 @@ private:
RDD *driver = nullptr;
RenderingContextDriver::Device device;
+ RenderPassCreationFunction render_pass_creation_function = nullptr;
int64_t tracking_frame = 0;
LocalVector<uint8_t> command_data;
LocalVector<uint32_t> command_data_offsets;
@@ -660,13 +717,16 @@ private:
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);
+ void _check_discardable_attachment_dependency(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index);
void _add_command_to_graph(ResourceTracker **p_resource_trackers, ResourceUsage *p_resource_usages, uint32_t p_resource_count, int32_t p_command_index, RecordedCommand *r_command);
void _add_texture_barrier_to_command(RDD::TextureID p_texture_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, ResourceUsage p_prev_usage, ResourceUsage p_next_usage, RDD::TextureSubresourceRange p_subresources, LocalVector<RDD::TextureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count);
#if USE_BUFFER_BARRIERS
void _add_buffer_barrier_to_command(RDD::BufferID p_buffer_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, int32_t &r_barrier_index, int32_t &r_barrier_count);
#endif
void _run_compute_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
+ void _get_draw_list_render_pass_and_framebuffer(const RecordedDrawListCommand *p_draw_list_command, RDD::RenderPassID &r_render_pass, RDD::FramebufferID &r_framebuffer);
void _run_draw_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
+ void _add_draw_list_begin(FramebufferCache *p_framebuffer_cache, RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb);
void _run_secondary_command_buffer_task(const SecondaryCommandBuffer *p_secondary);
void _wait_for_secondary_command_buffer_tasks();
void _run_render_commands(int32_t p_level, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool, int32_t &r_current_label_index, int32_t &r_current_label_level);
@@ -680,7 +740,7 @@ private:
public:
RenderingDeviceGraph();
~RenderingDeviceGraph();
- void initialize(RDD *p_driver, RenderingContextDriver::Device p_device, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame);
+ void initialize(RDD *p_driver, RenderingContextDriver::Device p_device, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame);
void finalize();
void begin();
void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size);
@@ -697,7 +757,8 @@ public:
void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
void add_compute_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
void add_compute_list_end();
- void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb = 0);
+ void add_draw_list_begin(FramebufferCache *p_framebuffer_cache, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb = 0);
+ void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb = 0);
void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset);
void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits);
void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
@@ -729,7 +790,9 @@ public:
void end_label();
void end(bool p_reorder_commands, bool p_full_barriers, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool);
static ResourceTracker *resource_tracker_create();
- static void resource_tracker_free(ResourceTracker *tracker);
+ static void resource_tracker_free(ResourceTracker *p_tracker);
+ static FramebufferCache *framebuffer_cache_create();
+ static void framebuffer_cache_free(RDD *p_driver, FramebufferCache *p_cache);
};
using RDG = RenderingDeviceGraph;