summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThaddeus Crews <repiteo@outlook.com>2024-11-27 10:47:29 -0600
committerThaddeus Crews <repiteo@outlook.com>2024-11-27 10:47:29 -0600
commited01f5f2aa8e5a4c7103417f78259c5c9d9471ff (patch)
treec07cc6c07b939c38742c67a318e3ec7db6dc6dfa
parentce4674a0a5085746e4f4014fd6b3250248c0b52d (diff)
parent6d5ac8f7ef4a3ddaf50720ab473b9dffece21674 (diff)
downloadredot-engine-ed01f5f2aa8e5a4c7103417f78259c5c9d9471ff.tar.gz
Merge pull request #98670 from DarioSamo/rd-transient-targets
Automatically resolve initial and final action for draw lists.
-rw-r--r--doc/classes/RDTextureFormat.xml7
-rw-r--r--doc/classes/RenderSceneBuffersRD.xml1
-rw-r--r--doc/classes/RenderingDevice.xml146
-rw-r--r--misc/extension_api_validation/4.3-stable.expected19
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp7
-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
32 files changed, 798 insertions, 472 deletions
diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml
index ac875ab7c1..617ed95434 100644
--- a/doc/classes/RDTextureFormat.xml
+++ b/doc/classes/RDTextureFormat.xml
@@ -37,6 +37,13 @@
<member name="height" type="int" setter="set_height" getter="get_height" default="1">
The texture's height (in pixels).
</member>
+ <member name="is_discardable" type="bool" setter="set_is_discardable" getter="get_is_discardable" default="false">
+ If a texture is discardable, its contents do not need to be preserved between frames. This flag is only relevant when the texture is used as target in a draw list.
+ This information is used by [RenderingDevice] to figure out if a texture's contents can be discarded, eliminating unnecessary writes to memory and boosting performance.
+ </member>
+ <member name="is_resolve_buffer" type="bool" setter="set_is_resolve_buffer" getter="get_is_resolve_buffer" default="false">
+ The texture will be used as the destination of a resolve operation.
+ </member>
<member name="mipmaps" type="int" setter="set_mipmaps" getter="get_mipmaps" default="1">
The number of mipmaps available in the texture.
</member>
diff --git a/doc/classes/RenderSceneBuffersRD.xml b/doc/classes/RenderSceneBuffersRD.xml
index 6a5aba1dbc..6a9445a25e 100644
--- a/doc/classes/RenderSceneBuffersRD.xml
+++ b/doc/classes/RenderSceneBuffersRD.xml
@@ -30,6 +30,7 @@
<param index="6" name="layers" type="int" />
<param index="7" name="mipmaps" type="int" />
<param index="8" name="unique" type="bool" />
+ <param index="9" name="discardable" type="bool" />
<description>
Create a new texture with the given definition and cache this under the given name. Will return the existing texture if it already exists.
</description>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index fe23f79119..59ca06085f 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -210,15 +210,12 @@
<method name="draw_list_begin">
<return type="int" />
<param index="0" name="framebuffer" type="RID" />
- <param index="1" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction" />
- <param index="2" name="final_color_action" type="int" enum="RenderingDevice.FinalAction" />
- <param index="3" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction" />
- <param index="4" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction" />
- <param index="5" name="clear_color_values" type="PackedColorArray" default="PackedColorArray()" />
- <param index="6" name="clear_depth" type="float" default="1.0" />
- <param index="7" name="clear_stencil" type="int" default="0" />
- <param index="8" name="region" type="Rect2" default="Rect2(0, 0, 0, 0)" />
- <param index="9" name="breadcrumb" type="int" default="0" />
+ <param index="1" name="draw_flags" type="int" enum="RenderingDevice.DrawFlags" is_bitfield="true" default="0" />
+ <param index="2" name="clear_color_values" type="PackedColorArray" default="PackedColorArray()" />
+ <param index="3" name="clear_depth_value" type="float" default="1.0" />
+ <param index="4" name="clear_stencil_value" type="int" default="0" />
+ <param index="5" name="region" type="Rect2" default="Rect2(0, 0, 0, 0)" />
+ <param index="6" name="breadcrumb" type="int" default="0" />
<description>
Starts a list of raster drawing commands created with the [code]draw_*[/code] methods. The returned value should be passed to other [code]draw_list_*[/code] functions.
Multiple draw lists cannot be created at the same time; you must finish the previous draw list first using [method draw_list_end].
@@ -226,7 +223,7 @@
[codeblock]
var rd = RenderingDevice.new()
var clear_colors = PackedColorArray([Color(0, 0, 0, 0), Color(0, 0, 0, 0), Color(0, 0, 0, 0)])
- var draw_list = rd.draw_list_begin(framebuffers[i], RenderingDevice.INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_READ, RenderingDevice.INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_DISCARD, clear_colors, RenderingDevice.OPAQUE_PASS)
+ var draw_list = rd.draw_list_begin(framebuffers[i], RenderingDevice.CLEAR_COLOR_ALL, clear_colors, true, 1.0f, true, 0, Rect2(), RenderingDevice.OPAQUE_PASS)
# Draw opaque.
rd.draw_list_bind_render_pipeline(draw_list, raster_pipeline)
@@ -241,10 +238,11 @@
rd.draw_list_end()
[/codeblock]
+ The [param draw_flags] indicates if the texture attachments of the framebuffer should be cleared or ignored. Only one of the two flags can be used for each individual attachment. Ignoring an attachment means that any contents that existed before the draw list will be completely discarded, reducing the memory bandwidth used by the render pass but producing garbage results if the pixels aren't replaced. The default behavior allows the engine to figure out the right operation to use if the texture is discardable, which can result in increased performance. See [RDTextureFormat] or [method texture_set_discardable].
The [param breadcrumb] parameter can be an arbitrary 32-bit integer that is useful to diagnose GPU crashes. If Godot is built in dev or debug mode; when the GPU crashes Godot will dump all shaders that were being executed at the time of the crash and the breadcrumb is useful to diagnose what passes did those shaders belong to.
It does not affect rendering behavior and can be set to 0. It is recommended to use [enum BreadcrumbMarker] enumerations for consistency but it's not required. It is also possible to use bitwise operations to add extra data. e.g.
[codeblock]
- rd.draw_list_begin(fb[i], RenderingDevice.INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_READ, RenderingDevice.INITIAL_ACTION_CLEAR, RenderingDevice.FINAL_ACTION_DISCARD, clear_colors, RenderingDevice.OPAQUE_PASS | 5)
+ rd.draw_list_begin(fb[i], RenderingDevice.CLEAR_COLOR_ALL, clear_colors, true, 1.0f, true, 0, Rect2(), RenderingDevice.OPAQUE_PASS | 5)
[/codeblock]
</description>
</method>
@@ -947,6 +945,13 @@
[b]Note:[/b] This function returns a [code]uint64_t[/code] which internally maps to a [code]GLuint[/code] (OpenGL) or [code]VkImage[/code] (Vulkan).
</description>
</method>
+ <method name="texture_is_discardable">
+ <return type="bool" />
+ <param index="0" name="texture" type="RID" />
+ <description>
+ Returns [code]true[/code] if the [param texture] is discardable, [code]false[/code] otherwise. See [RDTextureFormat] or [method texture_set_discardable].
+ </description>
+ </method>
<method name="texture_is_format_supported_for_usage" qualifiers="const">
<return type="bool" />
<param index="0" name="format" type="int" enum="RenderingDevice.DataFormat" />
@@ -984,6 +989,16 @@
[b]Note:[/b] [param to_texture] texture must [b]not[/b] be multisampled and must also be 2D (or a slice of a 3D/cubemap texture).
</description>
</method>
+ <method name="texture_set_discardable">
+ <return type="void" />
+ <param index="0" name="texture" type="RID" />
+ <param index="1" name="discardable" type="bool" />
+ <description>
+ Updates the discardable property of [param texture].
+ If a texture is discardable, its contents do not need to be preserved between frames. This flag is only relevant when the texture is used as target in a draw list.
+ This information is used by [RenderingDevice] to figure out if a texture's contents can be discarded, eliminating unnecessary writes to memory and boosting performance.
+ </description>
+ </method>
<method name="texture_update">
<return type="int" enum="Error" />
<param index="0" name="texture" type="RID" />
@@ -2279,40 +2294,40 @@
</constant>
<constant name="DYNAMIC_STATE_STENCIL_REFERENCE" value="64" enum="PipelineDynamicStateFlags" is_bitfield="true">
</constant>
- <constant name="INITIAL_ACTION_LOAD" value="0" enum="InitialAction">
+ <constant name="INITIAL_ACTION_LOAD" value="0" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
Load the previous contents of the framebuffer.
</constant>
- <constant name="INITIAL_ACTION_CLEAR" value="1" enum="InitialAction">
+ <constant name="INITIAL_ACTION_CLEAR" value="1" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
Clear the whole framebuffer or its specified region.
</constant>
- <constant name="INITIAL_ACTION_DISCARD" value="2" enum="InitialAction">
+ <constant name="INITIAL_ACTION_DISCARD" value="2" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
Ignore the previous contents of the framebuffer. This is the fastest option if you'll overwrite all of the pixels and don't need to read any of them.
</constant>
- <constant name="INITIAL_ACTION_MAX" value="3" enum="InitialAction">
+ <constant name="INITIAL_ACTION_MAX" value="3" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
Represents the size of the [enum InitialAction] enum.
</constant>
- <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction" deprecated="Use [constant INITIAL_ACTION_CLEAR] instead.">
+ <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="1" enum="InitialAction" deprecated="Use [constant INITIAL_ACTION_LOAD] instead.">
+ <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="1" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="INITIAL_ACTION_KEEP" value="0" enum="InitialAction" deprecated="Use [constant INITIAL_ACTION_LOAD] instead.">
+ <constant name="INITIAL_ACTION_KEEP" value="0" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction" deprecated="Use [constant INITIAL_ACTION_DISCARD] instead.">
+ <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="INITIAL_ACTION_CONTINUE" value="0" enum="InitialAction" deprecated="Use [constant INITIAL_ACTION_LOAD] instead.">
+ <constant name="INITIAL_ACTION_CONTINUE" value="0" enum="InitialAction" deprecated="Initial actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="FINAL_ACTION_STORE" value="0" enum="FinalAction">
+ <constant name="FINAL_ACTION_STORE" value="0" enum="FinalAction" deprecated="Final actions are solved automatically by RenderingDevice.">
Store the result of the draw list in the framebuffer. This is generally what you want to do.
</constant>
- <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction">
+ <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction" deprecated="Final actions are solved automatically by RenderingDevice.">
Discard the contents of the framebuffer. This is the fastest option if you don't need to use the results of the draw list.
</constant>
- <constant name="FINAL_ACTION_MAX" value="2" enum="FinalAction">
+ <constant name="FINAL_ACTION_MAX" value="2" enum="FinalAction" deprecated="Final actions are solved automatically by RenderingDevice.">
Represents the size of the [enum FinalAction] enum.
</constant>
- <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction" deprecated="Use [constant FINAL_ACTION_STORE] instead.">
+ <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction" deprecated="Final actions are solved automatically by RenderingDevice.">
</constant>
- <constant name="FINAL_ACTION_CONTINUE" value="0" enum="FinalAction" deprecated="Use [constant FINAL_ACTION_STORE] instead.">
+ <constant name="FINAL_ACTION_CONTINUE" value="0" enum="FinalAction" deprecated="Final actions are solved automatically by RenderingDevice.">
</constant>
<constant name="SHADER_STAGE_VERTEX" value="0" enum="ShaderStage">
Vertex shader stage. This can be used to manipulate vertices from a shader (but not create new vertices).
@@ -2514,5 +2529,86 @@
</constant>
<constant name="DEBUG_PASS" value="786432" enum="BreadcrumbMarker">
</constant>
+ <constant name="DRAW_DEFAULT_ALL" value="0" enum="DrawFlags" is_bitfield="true">
+ Do not clear or ignore any attachments.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_0" value="1" enum="DrawFlags" is_bitfield="true">
+ Clear the first color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_1" value="2" enum="DrawFlags" is_bitfield="true">
+ Clear the second color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_2" value="4" enum="DrawFlags" is_bitfield="true">
+ Clear the third color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_3" value="8" enum="DrawFlags" is_bitfield="true">
+ Clear the fourth color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_4" value="16" enum="DrawFlags" is_bitfield="true">
+ Clear the fifth color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_5" value="32" enum="DrawFlags" is_bitfield="true">
+ Clear the sixth color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_6" value="64" enum="DrawFlags" is_bitfield="true">
+ Clear the seventh color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_7" value="128" enum="DrawFlags" is_bitfield="true">
+ Clear the eighth color attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_MASK" value="255" enum="DrawFlags" is_bitfield="true">
+ Mask for clearing all color attachments.
+ </constant>
+ <constant name="DRAW_CLEAR_COLOR_ALL" value="255" enum="DrawFlags" is_bitfield="true">
+ Clear all color attachments.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_0" value="256" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the first color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_1" value="512" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the second color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_2" value="1024" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the third color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_3" value="2048" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the fourth color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_4" value="4096" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the fifth color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_5" value="8192" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the sixth color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_6" value="16384" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the seventh color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_7" value="32768" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the eighth color attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_MASK" value="65280" enum="DrawFlags" is_bitfield="true">
+ Mask for ignoring all the previous contents of the color attachments.
+ </constant>
+ <constant name="DRAW_IGNORE_COLOR_ALL" value="65280" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of all color attachments.
+ </constant>
+ <constant name="DRAW_CLEAR_DEPTH" value="65536" enum="DrawFlags" is_bitfield="true">
+ Clear the depth attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_DEPTH" value="131072" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the depth attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_STENCIL" value="262144" enum="DrawFlags" is_bitfield="true">
+ Clear the stencil attachment.
+ </constant>
+ <constant name="DRAW_IGNORE_STENCIL" value="524288" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of the stencil attachment.
+ </constant>
+ <constant name="DRAW_CLEAR_ALL" value="327935" enum="DrawFlags" is_bitfield="true">
+ Clear all attachments.
+ </constant>
+ <constant name="DRAW_IGNORE_ALL" value="720640" enum="DrawFlags" is_bitfield="true">
+ Ignore the previous contents of all attachments.
+ </constant>
</constants>
</class>
diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected
index 506844e6d6..0c988b8913 100644
--- a/misc/extension_api_validation/4.3-stable.expected
+++ b/misc/extension_api_validation/4.3-stable.expected
@@ -159,3 +159,22 @@ Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXI
Validate extension JSON: API was removed: builtin_classes/Vector4i/constants/AXIS_Z
These constants have been replaced with corresponding enum constants.
+
+
+GH-98670
+--------
+Validate extension JSON: Error: Field 'classes/RenderSceneBuffersRD/methods/create_texture/arguments': size changed value in new API, from 9 to 10.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments': size changed value in new API, from 10 to 7.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments': size changed value in new API, from 9 to 7.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/1': type changed value in new API, from "enum::RenderingDevice.InitialAction" to "bitfield::RenderingDevice.DrawFlags".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/2': type changed value in new API, from "enum::RenderingDevice.FinalAction" to "PackedColorArray".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/3': type changed value in new API, from "enum::RenderingDevice.InitialAction" to "float".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/4': type changed value in new API, from "enum::RenderingDevice.FinalAction" to "int".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/5': default_value changed value in new API, from "PackedColorArray()" to "Rect2(0, 0, 0, 0)".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/5': type changed value in new API, from "PackedColorArray" to "Rect2".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/6': default_value changed value in new API, from "1.0" to "0".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/6': meta changed value in new API, from "float" to "uint32".
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments/6': type changed value in new API, from "float" to "int".
+
+Draw lists no longer require the initial and final action for color and depth attachments to be specified.
+Draw lists can now specify if a particular color, depth, or stencil attachment should be cleared.
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index bd71e29d0a..9cfeff4f69 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -722,7 +722,7 @@ void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int
raster_push_constant.uv_offset[0] = -0.5f / float(atlas_size.x);
raster_push_constant.uv_offset[1] = -0.5f / float(atlas_size.y);
- RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, 1.0, 0, Rect2(), RDD::BreadcrumbMarker::LIGHTMAPPER_PASS);
+ RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::DRAW_CLEAR_ALL, clear_colors, 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::LIGHTMAPPER_PASS);
//draw opaque
rd->draw_list_bind_render_pipeline(draw_list, raster_pipeline);
rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
@@ -1419,6 +1419,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
tf.texture_type = RD::TEXTURE_TYPE_2D;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
tf.format = RD::DATA_FORMAT_D32_SFLOAT;
+ tf.is_discardable = true;
raster_depth_buffer = rd->texture_create(tf, RD::TextureView());
}
@@ -2049,8 +2050,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
uint32_t seam_offset = 0;
uint32_t triangle_offset = 0;
- Vector<Color> clear_colors;
- clear_colors.push_back(Color(0, 0, 0, 1));
for (int i = 0; i < atlas_slices; i++) {
int subslices = (p_bake_sh ? 4 : 1);
@@ -2064,7 +2063,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
seams_push_constant.debug = debug;
// Store the current subslice in the breadcrumb.
- RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i * subslices + k], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors, 1.0, 0, Rect2(), RDD::BreadcrumbMarker::LIGHTMAPPER_PASS | seams_push_constant.slice);
+ RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i * subslices + k], RD::DRAW_CLEAR_DEPTH, Vector<Color>(), 1.0f, 0, Rect2(), RDD::BreadcrumbMarker::LIGHTMAPPER_PASS | seams_push_constant.slice);
rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
rd->draw_list_bind_uniform_set(draw_list, blendseams_raster_uniform, 1);
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;