diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index b969e3bb8ea..8640879a4ec 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -2534,8 +2534,6 @@
Decreasing this value may improve GPU performance on certain setups, even if the maximum number of clustered elements is never reached in the project.
[b]Note:[/b] This setting is only effective when using the Forward+ rendering method, not Mobile and Compatibility.
-
-
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 5ca6d382679..495bec24dcc 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -14,12 +14,12 @@
$DOCS_URL/tutorials/shaders/compute_shaders.html
-
+
- Puts a memory barrier in place. This is used for synchronization to avoid data races. See also [method full_barrier], which may be useful for debugging.
+ [i]Deprecated.[/i] Barriers are automatically inserted by RenderingDevice.
@@ -27,9 +27,8 @@
-
- Clears the contents of the [param buffer], clearing [param size_bytes] bytes, starting at [param offset]. Always raises a memory barrier.
+ Clears the contents of the [param buffer], clearing [param size_bytes] bytes, starting at [param offset].
Prints an error if:
- the size isn't a multiple of four
- the region specified by [param offset] + [param size_bytes] exceeds the buffer
@@ -37,6 +36,21 @@
- a compute list is currently active (created by [method compute_list_begin])
+
+
+
+
+
+
+
+
+ Copies [param size] bytes from the [param src_buffer] at [param src_offset] into [param dst_buffer] at [param dst_offset].
+ Prints an error if:
+ - [param size] exceeds the size of either [param src_buffer] or [param dst_buffer] at their corresponding offsets
+ - a draw list is currently active (created by [method draw_list_begin])
+ - a compute list is currently active (created by [method compute_list_begin])
+
+
@@ -52,9 +66,8 @@
-
- Updates a region of [param size_bytes] bytes, starting at [param offset], in the buffer, with the specified [param data]. Raises a memory barrier except when [param post_barrier] is set to [constant BARRIER_MASK_NO_BARRIER].
+ Updates a region of [param size_bytes] bytes, starting at [param offset], in the buffer, with the specified [param data].
Prints an error if:
- the region specified by [param offset] + [param size_bytes] exceeds the buffer
- a draw list is currently active (created by [method draw_list_begin])
@@ -77,10 +90,9 @@
-
Starts a list of compute commands created with the [code]compute_*[/code] methods. The returned value should be passed to other [code]compute_list_*[/code] functions.
- If [param allow_draw_overlap] is [code]true[/code], you may have one draw list running at the same time as one compute list. Multiple compute lists cannot be created at the same time; you must finish the previous compute list first using [method compute_list_end].
+ Multiple compute lists cannot be created at the same time; you must finish the previous compute list first using [method compute_list_end].
A simple compute operation might look like this (code is not a complete example):
[codeblock]
var rd = RenderingDevice.new()
@@ -128,7 +140,6 @@
-
Finishes a list of compute commands created with the [code]compute_*[/code] methods.
@@ -170,7 +181,7 @@
Create a command buffer debug label region that can be displayed in third-party tools such as [url=https://renderdoc.org/]RenderDoc[/url]. All regions must be ended with a [method draw_command_end_label] call. When viewed from the linear series of submissions to a single queue, calls to [method draw_command_begin_label] and [method draw_command_end_label] must be matched and balanced.
- The [code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] Vulkan extension must be available and enabled for command buffer debug label region to work. See also [method draw_command_insert_label] and [method draw_command_end_label].
+ The [code]VK_EXT_DEBUG_UTILS_EXTENSION_NAME[/code] Vulkan extension must be available and enabled for command buffer debug label region to work. See also [method draw_command_end_label].
@@ -179,12 +190,12 @@
Ends the command buffer debug label region started by a [method draw_command_begin_label] call.
-
+
- Inserts a command buffer debug label region in the current command buffer. Unlike [method draw_command_begin_label], this region should not be ended with a [method draw_command_end_label] call.
+ [i]Deprecated.[/i] Inserting labels no longer applies due to command reordering.
@@ -198,7 +209,6 @@
-
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].
@@ -232,7 +242,7 @@
[b]Note:[/b] Cannot be used with local RenderingDevices, as these don't have a screen. If called on a local RenderingDevice, [method draw_list_begin_for_screen] returns [constant INVALID_ID].
-
+
@@ -246,7 +256,7 @@
- Variant of [method draw_list_begin] with support for multiple splits. The [param splits] parameter determines how many splits are created.
+ [i]Deprecated.[/i] Split draw lists are used automatically by RenderingDevice.
@@ -310,7 +320,6 @@
-
Finishes a list of raster drawing commands created with the [code]draw_*[/code] methods.
@@ -335,14 +344,14 @@
- Switches to the next draw pass and returns the split's ID. Equivalent to [method draw_list_switch_to_next_pass_split] with [code]splits[/code] set to [code]1[/code].
+ Switches to the next draw pass.
-
+
- Switches to the next draw pass, with the number of splits allocated specified in [param splits]. The return value is an array containing the ID of each split. For single-split usage, see [method draw_list_switch_to_next_pass].
+ [i]Deprecated.[/i] Split draw lists are used automatically by RenderingDevice.
@@ -430,10 +439,10 @@
Tries to free an object in the RenderingDevice. To avoid memory leaks, this should be called after using an object as memory management does not occur automatically when using RenderingDevice directly.
-
+
- Puts a [i]full[/i] memory barrier in place. This is a memory [method barrier] with all flags enabled. [method full_barrier] it should only be used for debugging as it can severely impact performance.
+ [i]Deprecated.[/i] Barriers are automatically inserted by RenderingDevice.
@@ -704,7 +713,6 @@
-
Clears the specified [param texture] by replacing all of its pixels with the specified [param color]. [param base_mipmap] and [param mipmap_count] determine which mipmaps of the texture are affected by this clear operation, while [param base_layer] and [param layer_count] determine which layers of a 3D texture (or texture array) are affected by this clear operation. For 2D textures (which only have one layer by design), [param base_layer] must be [code]0[/code] and [param layer_count] must be [code]1[/code].
[b]Note:[/b] [param texture] can't be cleared while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to [constant FINAL_ACTION_CONTINUE]) to clear this texture.
@@ -721,7 +729,6 @@
-
Copies the [param from_texture] to [param to_texture] with the specified [param from_pos], [param to_pos] and [param size] coordinates. The Z axis of the [param from_pos], [param to_pos] and [param size] must be [code]0[/code] for 2-dimensional textures. Source and destination mipmaps/layers must also be specified, with these parameters being [code]0[/code] for textures without mipmaps or single-layer textures. Returns [constant @GlobalScope.OK] if the texture copy was successful or [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] [param from_texture] texture can't be copied while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to [constant FINAL_ACTION_CONTINUE]) to copy this texture.
@@ -831,7 +838,6 @@
-
Resolves the [param from_texture] texture onto [param to_texture] with multisample antialiasing enabled. This must be used when rendering a framebuffer for MSAA to work. Returns [constant @GlobalScope.OK] if successful, [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] [param from_texture] and [param to_texture] textures must have the same dimension, format and type (color or depth).
@@ -848,7 +854,6 @@
-
Updates texture data with new data, replacing the previous data in place. The updated texture data must have the same dimensions and format. For 2D textures (which only have one layer), [param layer] must be [code]0[/code]. Returns [constant @GlobalScope.OK] if the update was successful, [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] Updating textures is forbidden during creation of a draw or compute list.
@@ -2150,39 +2155,48 @@
-
- Start rendering and clear the whole framebuffer.
+
+ Load the previous contents of the framebuffer.
-
- Start rendering and clear the framebuffer in the specified region.
+
+ Clear the whole framebuffer or its specified region.
-
- Continue rendering and clear the framebuffer in the specified region. Framebuffer must have been left in [constant FINAL_ACTION_CONTINUE] state as the final action previously.
+
+ 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.
-
- Start rendering, but keep attached color texture contents. If the framebuffer was previously used to read in a shader, this will automatically insert a layout transition.
-
-
- Start rendering, ignore what is there; write above it. In general, this is the fastest option when you will be writing every single pixel and you don't need a clear color.
-
-
- Continue rendering. Framebuffer must have been left in [constant FINAL_ACTION_CONTINUE] state as the final action previously.
-
-
+
Represents the size of the [enum InitialAction] enum.
-
- Store the texture for reading and make it read-only if it has the [constant TEXTURE_USAGE_SAMPLING_BIT] bit (only applies to color, depth and stencil attachments).
+
+ [i]Deprecated.[/i] Use [constant INITIAL_ACTION_CLEAR] instead.
+
+
+ [i]Deprecated.[/i] Use [constant INITIAL_ACTION_LOAD] instead.
+
+
+ [i]Deprecated.[/i] Use [constant INITIAL_ACTION_LOAD] instead.
+
+
+ [i]Deprecated.[/i] Use [constant INITIAL_ACTION_DISCARD] instead.
+
+
+ [i]Deprecated.[/i] Use [constant INITIAL_ACTION_LOAD] instead.
+
+
+ Store the result of the draw list in the framebuffer. This is generally what you want to do.
- Discard the texture data and make it read-only if it has the [constant TEXTURE_USAGE_SAMPLING_BIT] bit (only applies to color, depth and stencil attachments).
+ Discard the contents of the framebuffer. This is the fastest option if you don't need to use the results of the draw list.
-
- Store the texture and continue for further processing. Similar to [constant FINAL_ACTION_READ], but does not make the texture read-only if it has the [constant TEXTURE_USAGE_SAMPLING_BIT] bit.
-
-
+
Represents the size of the [enum FinalAction] enum.
+
+ [i]Deprecated.[/i] Use [constant FINAL_ACTION_STORE] instead.
+
+
+ [i]Deprecated.[/i] Use [constant FINAL_ACTION_STORE] instead.
+
Vertex shader stage. This can be used to manipulate vertices from a shader (but not create new vertices).
diff --git a/drivers/d3d12/d3d12_context.cpp b/drivers/d3d12/d3d12_context.cpp
index fa27b9bc559..37066a811d8 100644
--- a/drivers/d3d12/d3d12_context.cpp
+++ b/drivers/d3d12/d3d12_context.cpp
@@ -76,6 +76,8 @@ char godot_nir_arch_name[32];
#endif
#endif
+#define D3D12_DEBUG_LAYER_BREAK_ON_ERROR 0
+
void D3D12Context::_debug_message_func(
D3D12_MESSAGE_CATEGORY p_category,
D3D12_MESSAGE_SEVERITY p_severity,
@@ -563,6 +565,11 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) {
res = info_queue->PushStorageFilter(&filter);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
+
+#if D3D12_DEBUG_LAYER_BREAK_ON_ERROR
+ res = info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
+ ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
+#endif
}
return OK;
@@ -1056,27 +1063,6 @@ void D3D12Context::local_device_free(RID p_local_device) {
local_device_owner.free(p_local_device);
}
-void D3D12Context::command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
-#ifdef PIX_ENABLED
- const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
- PIXBeginEvent(cmd_buf_info->cmd_list.Get(), p_color.to_argb32(), p_label_name.utf8().get_data());
-#endif
-}
-
-void D3D12Context::command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
-#ifdef PIX_ENABLED
- const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
- PIXSetMarker(cmd_buf_info->cmd_list.Get(), p_color.to_argb32(), p_label_name.utf8().get_data());
-#endif
-}
-
-void D3D12Context::command_end_label(RDD::CommandBufferID p_command_buffer) {
-#ifdef PIX_ENABLED
- const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
- PIXEndEvent(cmd_buf_info->cmd_list.Get());
-#endif
-}
-
void D3D12Context::set_object_name(ID3D12Object *p_object, String p_object_name) {
ERR_FAIL_NULL(p_object);
int name_len = p_object_name.size();
@@ -1125,6 +1111,14 @@ RenderingDeviceDriver *D3D12Context::get_driver(RID p_local_device) {
}
}
+bool D3D12Context::is_debug_utils_enabled() const {
+#ifdef PIX_ENABLED
+ return true;
+#else
+ return false;
+#endif
+}
+
D3D12Context::D3D12Context() {
command_list_queue.resize(1); // First one is always the setup command.
command_list_queue[0] = nullptr;
diff --git a/drivers/d3d12/d3d12_context.h b/drivers/d3d12/d3d12_context.h
index a27c8f4320b..ac90d384674 100644
--- a/drivers/d3d12/d3d12_context.h
+++ b/drivers/d3d12/d3d12_context.h
@@ -240,9 +240,6 @@ public:
virtual Error swap_buffers() override final;
virtual Error initialize() override final;
- virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
- virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
- virtual void command_end_label(RDD::CommandBufferID p_command_buffer) override final;
void set_object_name(ID3D12Object *p_object, String p_object_name);
virtual String get_device_vendor_name() const override final;
@@ -255,6 +252,7 @@ public:
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const override final;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) override final;
+ virtual bool is_debug_utils_enabled() const override final;
D3D12Context();
virtual ~D3D12Context();
diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp
index 6a2a3c32b06..d3a7344c9d3 100644
--- a/drivers/d3d12/rendering_device_driver_d3d12.cpp
+++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp
@@ -5162,6 +5162,20 @@ void RenderingDeviceDriverD3D12::command_timestamp_write(CommandBufferID p_cmd_b
cmd_buf_info->cmd_list->ResolveQueryData(tqp_info->query_heap.Get(), D3D12_QUERY_TYPE_TIMESTAMP, p_index, tqp_info->query_count, results_buffer, p_index * sizeof(uint64_t));
}
+void RenderingDeviceDriverD3D12::command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) {
+#ifdef PIX_ENABLED
+ const CommandBufferInfo *cmd_buf_info = (const CommandBufferInfo *)p_cmd_buffer.id;
+ PIXBeginEvent(cmd_buf_info->cmd_list.Get(), p_color.to_argb32(), p_label_name);
+#endif
+}
+
+void RenderingDeviceDriverD3D12::command_end_label(CommandBufferID p_cmd_buffer) {
+#ifdef PIX_ENABLED
+ const CommandBufferInfo *cmd_buf_info = (const CommandBufferInfo *)p_cmd_buffer.id;
+ PIXEndEvent(cmd_buf_info->cmd_list.Get());
+#endif
+}
+
/****************/
/**** SCREEN ****/
/****************/
diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h
index bd195728783..0da339c6fdb 100644
--- a/drivers/d3d12/rendering_device_driver_d3d12.h
+++ b/drivers/d3d12/rendering_device_driver_d3d12.h
@@ -770,6 +770,13 @@ public:
virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) override final;
virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) override final;
+ /****************/
+ /**** LABELS ****/
+ /****************/
+
+ virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final;
+ virtual void command_end_label(CommandBufferID p_cmd_buffer) override final;
+
/****************/
/**** SCREEN ****/
/****************/
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp
index e18161c9748..34acc0cc15c 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp
@@ -733,6 +733,9 @@ RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(Tex
case TEXTURE_SLICE_2D_ARRAY: {
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
} break;
+ default: {
+ return TextureID(nullptr);
+ }
}
image_view_create_info.format = RD_TO_VK_FORMAT[p_view.format];
image_view_create_info.components.r = (VkComponentSwizzle)p_view.swizzle_r;
@@ -1172,7 +1175,7 @@ bool RenderingDeviceDriverVulkan::command_buffer_begin_secondary(CommandBufferID
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
+ cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
cmd_buf_begin_info.pInheritanceInfo = &inheritance_info;
VkResult err = vkBeginCommandBuffer((VkCommandBuffer)p_cmd_buffer.id, &cmd_buf_begin_info);
@@ -1557,11 +1560,9 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
read_offset += sizeof(ShaderBinary::SpecializationConstant);
}
- struct Stage {
- ShaderStage type = SHADER_STAGE_MAX;
- Vector spirv;
- };
- Vector stages;
+ Vector> stages_spirv;
+ stages_spirv.resize(binary_data.stage_count);
+ r_shader_desc.stages.resize(binary_data.stage_count);
for (uint32_t i = 0; i < binary_data.stage_count; i++) {
ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) * 3 >= binsize, ShaderID());
@@ -1587,17 +1588,14 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
src_smolv = binptr + read_offset;
}
- Vector spirv;
+ Vector &spirv = stages_spirv.ptrw()[i];
uint32_t spirv_size = smolv::GetDecodedBufferSize(src_smolv, smolv_size);
spirv.resize(spirv_size);
if (!smolv::Decode(src_smolv, smolv_size, spirv.ptrw(), spirv_size)) {
ERR_FAIL_V_MSG(ShaderID(), "Malformed smolv input uncompressing shader stage:" + String(SHADER_STAGE_NAMES[stage]));
}
- Stage stage_entry;
- stage_entry.type = ShaderStage(stage);
- stage_entry.spirv = spirv;
- stages.push_back(stage_entry);
+ r_shader_desc.stages.set(i, ShaderStage(stage));
if (buf_size % 4 != 0) {
buf_size += 4 - (buf_size % 4);
@@ -1614,22 +1612,22 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_bytecode(const Vec
String error_text;
- for (int i = 0; i < stages.size(); i++) {
+ for (int i = 0; i < r_shader_desc.stages.size(); i++) {
VkShaderModuleCreateInfo shader_module_create_info = {};
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
- shader_module_create_info.codeSize = stages[i].spirv.size();
- shader_module_create_info.pCode = (const uint32_t *)stages[i].spirv.ptr();
+ shader_module_create_info.codeSize = stages_spirv[i].size();
+ shader_module_create_info.pCode = (const uint32_t *)stages_spirv[i].ptr();
VkShaderModule vk_module = VK_NULL_HANDLE;
VkResult res = vkCreateShaderModule(vk_device, &shader_module_create_info, nullptr, &vk_module);
if (res) {
- error_text = "Error (" + itos(res) + ") creating shader module for stage: " + String(SHADER_STAGE_NAMES[stages[i].type]);
+ error_text = "Error (" + itos(res) + ") creating shader module for stage: " + String(SHADER_STAGE_NAMES[r_shader_desc.stages[i]]);
break;
}
VkPipelineShaderStageCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
- create_info.stage = RD_STAGE_TO_VK_SHADER_STAGE_BITS[stages[i].type];
+ create_info.stage = RD_STAGE_TO_VK_SHADER_STAGE_BITS[r_shader_desc.stages[i]];
create_info.module = vk_module;
create_info.pName = "main";
@@ -3053,6 +3051,26 @@ void RenderingDeviceDriverVulkan::command_timestamp_write(CommandBufferID p_cmd_
vkCmdWriteTimestamp((VkCommandBuffer)p_cmd_buffer.id, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkQueryPool)p_pool_id.id, p_index);
}
+/****************/
+/**** LABELS ****/
+/****************/
+
+void RenderingDeviceDriverVulkan::command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) {
+ VkDebugUtilsLabelEXT label;
+ label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+ label.pNext = nullptr;
+ label.pLabelName = p_label_name;
+ label.color[0] = p_color[0];
+ label.color[1] = p_color[1];
+ label.color[2] = p_color[2];
+ label.color[3] = p_color[3];
+ vkCmdBeginDebugUtilsLabelEXT((VkCommandBuffer)p_cmd_buffer.id, &label);
+}
+
+void RenderingDeviceDriverVulkan::command_end_label(CommandBufferID p_cmd_buffer) {
+ vkCmdEndDebugUtilsLabelEXT((VkCommandBuffer)p_cmd_buffer.id);
+}
+
/****************/
/**** SCREEN ****/
/****************/
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h
index 6d8f6fd0e03..1edee6b76e1 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.h
+++ b/drivers/vulkan/rendering_device_driver_vulkan.h
@@ -432,6 +432,13 @@ public:
virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) override final;
virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) override final;
+ /****************/
+ /**** LABELS ****/
+ /****************/
+
+ virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final;
+ virtual void command_end_label(CommandBufferID p_cmd_buffer) override final;
+
/****************/
/**** SCREEN ****/
/****************/
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index d536b4455ab..7db2a9cd661 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -2822,46 +2822,6 @@ void VulkanContext::local_device_free(RID p_local_device) {
local_device_owner.free(p_local_device);
}
-void VulkanContext::command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
- if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
- return;
- }
-
- CharString cs = p_label_name.utf8();
- VkDebugUtilsLabelEXT label;
- label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
- label.pNext = nullptr;
- label.pLabelName = cs.get_data();
- label.color[0] = p_color[0];
- label.color[1] = p_color[1];
- label.color[2] = p_color[2];
- label.color[3] = p_color[3];
- CmdBeginDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id, &label);
-}
-
-void VulkanContext::command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
- if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
- return;
- }
- CharString cs = p_label_name.utf8();
- VkDebugUtilsLabelEXT label;
- label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
- label.pNext = nullptr;
- label.pLabelName = cs.get_data();
- label.color[0] = p_color[0];
- label.color[1] = p_color[1];
- label.color[2] = p_color[2];
- label.color[3] = p_color[3];
- CmdInsertDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id, &label);
-}
-
-void VulkanContext::command_end_label(RDD::CommandBufferID p_command_buffer) {
- if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
- return;
- }
- CmdEndDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id);
-}
-
void VulkanContext::set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) {
if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
return;
@@ -2917,6 +2877,10 @@ RenderingDeviceDriver *VulkanContext::get_driver(RID p_local_device) {
}
}
+bool VulkanContext::is_debug_utils_enabled() const {
+ return is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
+}
+
VulkanContext::VulkanContext() {
command_buffer_queue.resize(1); // First one is always the setup command.
command_buffer_queue[0] = nullptr;
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index b914acf3a94..cbb6cf326fa 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -327,9 +327,6 @@ public:
virtual Error swap_buffers() override final;
virtual Error initialize() override final;
- virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
- virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
- virtual void command_end_label(RDD::CommandBufferID p_command_buffer) override final;
void set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name);
virtual String get_device_vendor_name() const override final;
@@ -342,6 +339,7 @@ public:
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const override final;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) override final;
+ virtual bool is_debug_utils_enabled() const override final;
VulkanContext();
virtual ~VulkanContext();
diff --git a/misc/extension_api_validation/4.2-stable.expected b/misc/extension_api_validation/4.2-stable.expected
index a8b3af78919..53303ebec42 100644
--- a/misc/extension_api_validation/4.2-stable.expected
+++ b/misc/extension_api_validation/4.2-stable.expected
@@ -28,3 +28,26 @@ GH-86687
Validate extension JSON: Error: Field 'classes/AnimationMixer/methods/_post_process_key_value/arguments/3': type changed value in new API, from "Object" to "int".
Exposing the pointer was dangerous and it must be changed to avoid crash. Compatibility methods registered.
+
+
+GH-84976
+--------
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/FinalAction/values/FINAL_ACTION_CONTINUE': value changed value in new API, from 2.0 to 0.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/FinalAction/values/FINAL_ACTION_MAX': value changed value in new API, from 3.0 to 2.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CLEAR': value changed value in new API, from 0.0 to 1.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CLEAR_REGION_CONTINUE': value changed value in new API, from 2.0 to 0.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CONTINUE': value changed value in new API, from 5.0 to 0.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_DROP': value changed value in new API, from 4.0 to 2.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_KEEP': value changed value in new API, from 3.0 to 0.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_MAX': value changed value in new API, from 6.0 to 3.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/buffer_clear/arguments': size changed value in new API, from 4 to 3.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/buffer_update/arguments': size changed value in new API, from 5 to 4.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/draw_list_begin/arguments': size changed value in new API, from 10 to 9.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/texture_clear/arguments': size changed value in new API, from 7 to 6.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/texture_copy/arguments': size changed value in new API, from 10 to 9.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/texture_resolve_multisample/arguments': size changed value in new API, from 3 to 2.
+Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/texture_update/arguments': size changed value in new API, from 4 to 3.
+
+Barrier arguments have been removed from all relevant functions as they're no longer required.
+Draw and compute list overlap no longer needs to be specified.
+Initial and final actions have been simplified into fewer options.
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 5c2c3f96ded..4746ffb79b9 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -703,7 +703,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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ 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);
//draw opaque
rd->draw_list_bind_render_pipeline(draw_list, raster_pipeline);
rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
@@ -1863,7 +1863,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
seams_push_constant.slice = uint32_t(i * subslices + k);
seams_push_constant.debug = debug;
- RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_LOAD, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
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/api_context_rd.h b/servers/rendering/renderer_rd/api_context_rd.h
index 16e877032cb..fd3be806052 100644
--- a/servers/rendering/renderer_rd/api_context_rd.h
+++ b/servers/rendering/renderer_rd/api_context_rd.h
@@ -64,10 +64,6 @@ public:
virtual Error swap_buffers() = 0;
virtual Error initialize() = 0;
- virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) = 0;
- virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) = 0;
- virtual void command_end_label(RDD::CommandBufferID p_command_buffer) = 0;
-
virtual String get_device_vendor_name() const = 0;
virtual String get_device_name() const = 0;
virtual RDD::DeviceType get_device_type() const = 0;
@@ -78,6 +74,7 @@ public:
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const = 0;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) = 0;
+ virtual bool is_debug_utils_enabled() const = 0;
virtual ~ApiContextRD();
};
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 0d1721039cb..e661fd92178 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -420,11 +420,11 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->draw_command_begin_label("Bake Light Cluster");
// Clear cluster buffer.
- RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_clear(cluster_buffer, 0, cluster_buffer_size);
if (render_element_count > 0) {
// Clear render buffer.
- RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_clear(cluster_render_buffer, 0, cluster_render_buffer_size);
{ // Fill state uniform.
@@ -439,18 +439,18 @@ void ClusterBuilderRD::bake_cluster() {
state.cluster_depth_offset = (render_element_max / 32);
state.cluster_data_size = state.cluster_depth_offset + render_element_max;
- RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(state_uniform, 0, sizeof(StateUniform), &state);
}
// Update instances.
- RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements);
RENDER_TIMESTAMP("Render 3D Cluster Elements");
// Render elements.
{
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
+ 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);
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]);
@@ -488,7 +488,7 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->draw_list_draw(draw_list, true, instances);
i += instances;
}
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->draw_list_end();
}
// Store elements.
RENDER_TIMESTAMP("Pack 3D Cluster Elements");
@@ -513,10 +513,8 @@ void ClusterBuilderRD::bake_cluster() {
RD::get_singleton()->compute_list_dispatch_threads(compute_list, cluster_screen_size.x, cluster_screen_size.y, 1);
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->compute_list_end();
}
- } else {
- RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
}
RENDER_TIMESTAMP("< Bake 3D Cluster");
RD::get_singleton()->draw_command_end_label();
diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp
index cc5031823ea..e6262c83e2b 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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 bb584beb52c..fd6409d6bf1 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -583,7 +583,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, p_rect);
+ 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(), 1.0, 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()) {
@@ -650,7 +650,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_bind_index_array(draw_list, material_storage->get_quad_index_array());
@@ -724,7 +724,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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);
@@ -826,7 +826,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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) {
@@ -846,7 +846,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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);
@@ -916,7 +916,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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_bind_index_array(draw_list, material_storage->get_quad_index_array());
@@ -982,7 +982,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, p_region);
+ 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(), 1.0, 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, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant));
@@ -990,7 +990,7 @@ void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, con
RD::get_singleton()->draw_list_end();
}
-void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip, BitField p_post_barrier) {
+void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -1015,14 +1015,14 @@ 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_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+ 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);
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());
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end(p_post_barrier);
+ RD::get_singleton()->draw_list_end();
}
void CopyEffects::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
@@ -1080,7 +1080,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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);
@@ -1159,7 +1159,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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);
@@ -1237,7 +1237,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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);
@@ -1257,7 +1257,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector());
+ 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());
int mode;
if (p_reflection.is_valid()) {
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h
index 60272a2eab9..d18971a6767 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.h
+++ b/servers/rendering/renderer_rd/effects/copy_effects.h
@@ -345,7 +345,7 @@ public:
void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false);
void set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region);
- void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip, BitField p_post_barrier = RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER);
+ void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip);
void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
void cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size);
void cubemap_filter(RID p_source_cubemap, Vector p_dest_cubemap, bool p_use_array);
diff --git a/servers/rendering/renderer_rd/effects/debug_effects.cpp b/servers/rendering/renderer_rd/effects/debug_effects.cpp
index 3033d423758..a57a65fd5a6 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, rect);
+ 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(), 1.0, 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, rect);
+ 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(), 1.0, 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({ default_sampler, p_velocity }));
RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector({ default_sampler, p_depth }));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_fb, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
+ 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::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 reprojection = p_previous_projection.flipped_y() * p_previous_transform.affine_inverse() * p_current_transform * p_current_projection.flipped_y().inverse();
diff --git a/servers/rendering/renderer_rd/effects/fsr.cpp b/servers/rendering/renderer_rd/effects/fsr.cpp
index 0c51adf9ee3..5599a5a162d 100644
--- a/servers/rendering/renderer_rd/effects/fsr.cpp
+++ b/servers/rendering/renderer_rd/effects/fsr.cpp
@@ -124,5 +124,5 @@ void FSR::fsr_upscale(Ref p_render_buffers, RID p_source_r
RD::get_singleton()->compute_list_dispatch(compute_list, dispatch_x, dispatch_y, 1);
- RD::get_singleton()->compute_list_end(compute_list);
+ RD::get_singleton()->compute_list_end();
}
diff --git a/servers/rendering/renderer_rd/effects/fsr2.cpp b/servers/rendering/renderer_rd/effects/fsr2.cpp
index 0c389893049..bebbf51d51e 100644
--- a/servers/rendering/renderer_rd/effects/fsr2.cpp
+++ b/servers/rendering/renderer_rd/effects/fsr2.cpp
@@ -377,10 +377,7 @@ static FfxErrorCode execute_gpu_job_copy_rd(FSR2Context::Scratch &p_scratch, con
ERR_FAIL_COND_V(dst_desc.type == FFX_RESOURCE_TYPE_BUFFER, FFX_ERROR_INVALID_ARGUMENT);
for (uint32_t mip_level = 0; mip_level < src_desc.mipCount; mip_level++) {
- // Only push the barriers on the last copy.
- // FIXME: This could be optimized if RenderingDevice was able to copy multiple mip levels in a single command.
- BitField post_barrier = (mip_level == (src_desc.mipCount - 1)) ? RD::BARRIER_MASK_ALL_BARRIERS : RD::BARRIER_MASK_NO_BARRIER;
- RD::get_singleton()->texture_copy(src, dst, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(src_desc.width, src_desc.height, src_desc.depth), mip_level, mip_level, 0, 0, post_barrier);
+ RD::get_singleton()->texture_copy(src, dst, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(src_desc.width, src_desc.height, src_desc.depth), mip_level, mip_level, 0, 0);
}
return FFX_OK;
@@ -435,8 +432,7 @@ static FfxErrorCode execute_gpu_job_compute_rd(FSR2Context::Scratch &p_scratch,
RID buffer_rid = p_scratch.ubo_ring_buffer[p_scratch.ubo_ring_buffer_index];
p_scratch.ubo_ring_buffer_index = (p_scratch.ubo_ring_buffer_index + 1) % FSR2_UBO_RING_BUFFER_SIZE;
- BitField post_barrier = (i == (p_job.pipeline.constCount - 1)) ? RD::BARRIER_MASK_ALL_BARRIERS : RD::BARRIER_MASK_NO_BARRIER;
- RD::get_singleton()->buffer_update(buffer_rid, 0, p_job.cbs[i].uint32Size * sizeof(uint32_t), p_job.cbs[i].data, post_barrier);
+ RD::get_singleton()->buffer_update(buffer_rid, 0, p_job.cbs[i].uint32Size * sizeof(uint32_t), p_job.cbs[i].data);
RD::Uniform buffer_uniform(RD::UNIFORM_TYPE_UNIFORM_BUFFER, p_job.pipeline.cbResourceBindings[i].slotIndex, buffer_rid);
compute_uniforms.push_back(buffer_uniform);
@@ -566,7 +562,6 @@ FSR2Effect::FSR2Effect() {
FfxResourceBinding{ 2, 0, L"r_dilatedDepth" },
FfxResourceBinding{ 3, 0, L"r_reactive_mask" },
FfxResourceBinding{ 4, 0, L"r_transparency_and_composition_mask" },
- FfxResourceBinding{ 5, 0, L"r_prepared_input_color" },
FfxResourceBinding{ 6, 0, L"r_previous_dilated_motion_vectors" },
FfxResourceBinding{ 7, 0, L"r_input_motion_vectors" },
FfxResourceBinding{ 8, 0, L"r_input_color_jittered" },
diff --git a/servers/rendering/renderer_rd/effects/luminance.cpp b/servers/rendering/renderer_rd/effects/luminance.cpp
index 3aa5f5706e2..61b2248b5cd 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({ 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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::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/resolve.cpp b/servers/rendering/renderer_rd/effects/resolve.cpp
index 18671d06e14..feb0e6ed1e2 100644
--- a/servers/rendering/renderer_rd/effects/resolve.cpp
+++ b/servers/rendering/renderer_rd/effects/resolve.cpp
@@ -54,7 +54,7 @@ Resolve::~Resolve() {
resolve.shader.version_free(resolve.shader_version);
}
-void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -93,10 +93,10 @@ void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
- RD::get_singleton()->compute_list_end(p_barrier);
+ RD::get_singleton()->compute_list_end();
}
-void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -126,5 +126,5 @@ void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_scr
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
- RD::get_singleton()->compute_list_end(p_barrier);
+ RD::get_singleton()->compute_list_end();
}
diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h
index fcc1021904e..14477f90e4a 100644
--- a/servers/rendering/renderer_rd/effects/resolve.h
+++ b/servers/rendering/renderer_rd/effects/resolve.h
@@ -65,8 +65,8 @@ public:
Resolve();
~Resolve();
- void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
- void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
+ void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples);
+ void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples);
};
} // namespace RendererRD
diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp
index 628edc0127d..46fb0a75d68 100644
--- a/servers/rendering/renderer_rd/effects/ss_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp
@@ -525,7 +525,7 @@ void SSEffects::downsample_depth(Ref p_render_buffers, uin
RD::get_singleton()->compute_list_add_barrier(compute_list);
RD::get_singleton()->draw_command_end_label();
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->compute_list_end();
ss_effects.used_full_mips_last_frame = use_full_mips;
ss_effects.used_half_size_last_frame = use_half_size;
@@ -950,10 +950,10 @@ void SSEffects::screen_space_indirect_lighting(Ref p_rende
RD::get_singleton()->draw_command_end_label(); // SSIL
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); // Zeroing importance_map_load_counter depends on us.
+ RD::get_singleton()->compute_list_end();
int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
+ RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
}
/* SSAO */
@@ -1332,10 +1332,10 @@ void SSEffects::generate_ssao(Ref p_render_buffers, SSAORe
RD::get_singleton()->draw_command_end_label(); // Interleave
}
RD::get_singleton()->draw_command_end_label(); //SSAO
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); // Zeroing importance_map_load_counter depends on us.
+ RD::get_singleton()->compute_list_end();
int zero[1] = { 0 };
- RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
+ RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
}
/* Screen Space Reflection */
@@ -1394,7 +1394,7 @@ void SSEffects::screen_space_reflection(Ref p_render_buffe
scene_data.eye_offset[v][3] = 0.0;
}
- RD::get_singleton()->buffer_update(ssr.ubo, 0, sizeof(ScreenSpaceReflectionSceneData), &scene_data, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(ssr.ubo, 0, sizeof(ScreenSpaceReflectionSceneData), &scene_data);
}
uint32_t pipeline_specialization = 0;
diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp
index 48c65114089..ee0b6adb4d6 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_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
+ 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::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 63c99facdd7..41a6b2d6221 100644
--- a/servers/rendering/renderer_rd/effects/vrs.cpp
+++ b/servers/rendering/renderer_rd/effects/vrs.cpp
@@ -82,7 +82,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector());
+ 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());
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, &vrs_shader.push_constant, sizeof(VRSPushConstant));
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp
index 2befb194f7b..78ab6f3650f 100644
--- a/servers/rendering/renderer_rd/environment/fog.cpp
+++ b/servers/rendering/renderer_rd/environment/fog.cpp
@@ -570,7 +570,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);
- RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms);
if (fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->fog_uniform_set)) {
Vector uniforms;
@@ -1086,7 +1086,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");
RENDER_TIMESTAMP("Render Fog");
- RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms);
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -1140,7 +1140,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);
RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1);
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->compute_list_end();
RENDER_TIMESTAMP("< Volumetric Fog");
RD::get_singleton()->draw_command_end_label();
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index d968736037e..6da828df45e 100644
--- a/servers/rendering/renderer_rd/environment/gi.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -583,7 +583,8 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re
/* Buffers */
cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * solid_cell_count);
- cascade.solid_cell_dispatch_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
+ cascade.solid_cell_dispatch_buffer_storage = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector());
+ cascade.solid_cell_dispatch_buffer_call = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);
cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS));
{
Vector uniforms;
@@ -650,7 +651,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 10;
- u.append_id(cascade.solid_cell_dispatch_buffer);
+ u.append_id(cascade.solid_cell_dispatch_buffer_storage);
uniforms.push_back(u);
}
{
@@ -698,7 +699,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 5;
- u.append_id(cascade.solid_cell_dispatch_buffer);
+ u.append_id(cascade.solid_cell_dispatch_buffer_storage);
uniforms.push_back(u);
}
{
@@ -761,7 +762,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.append_id(cascade.solid_cell_dispatch_buffer);
+ u.append_id(cascade.solid_cell_dispatch_buffer_storage);
uniforms.push_back(u);
}
{
@@ -1129,7 +1130,8 @@ GI::SDFGI::~SDFGI() {
RD::get_singleton()->free(c.light_aniso_0_tex);
RD::get_singleton()->free(c.light_aniso_1_tex);
RD::get_singleton()->free(c.sdf_tex);
- RD::get_singleton()->free(c.solid_cell_dispatch_buffer);
+ RD::get_singleton()->free(c.solid_cell_dispatch_buffer_storage);
+ RD::get_singleton()->free(c.solid_cell_dispatch_buffer_call);
RD::get_singleton()->free(c.solid_cell_buffer);
RD::get_singleton()->free(c.lightprobe_history_tex);
RD::get_singleton()->free(c.lightprobe_average_tex);
@@ -1238,6 +1240,10 @@ void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) {
void GI::SDFGI::update_light() {
RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light");
+ for (uint32_t i = 0; i < cascades.size(); i++) {
+ RD::get_singleton()->buffer_copy(cascades[i].solid_cell_dispatch_buffer_storage, cascades[i].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);
+ }
+
/* Update dynamic light */
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -1276,9 +1282,9 @@ void GI::SDFGI::update_light() {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_dynamic_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer_call, 0);
}
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->compute_list_end();
RD::get_singleton()->draw_command_end_label();
}
@@ -1351,7 +1357,7 @@ void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {
render_pass++;
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_PROCESS]);
int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
@@ -1368,14 +1374,11 @@ void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {
RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);
}
- //end later after raster to avoid barriering on layout changes
- //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
-
+ RD::get_singleton()->compute_list_end();
RD::get_singleton()->draw_command_end_label();
}
void GI::SDFGI::store_probes() {
- RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE);
RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes");
SDFGIShader::IntegratePushConstant push_constant;
@@ -1414,7 +1417,7 @@ void GI::SDFGI::store_probes() {
RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1);
}
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->compute_list_end();
RD::get_singleton()->draw_command_end_label();
}
@@ -1493,7 +1496,7 @@ void GI::SDFGI::update_cascades() {
cascade_data[i].pad = 0;
}
- RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data);
}
void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector &p_texture_views) {
@@ -1636,7 +1639,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projection
copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2i(Point2i(), rtsize), true, false, false, false, RID(), p_view_count > 1);
}
-void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) {
+void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
// setup scene data
@@ -1651,7 +1654,7 @@ void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, con
RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);
}
- RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data);
}
// setup push constant
@@ -1718,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_CONTINUE, p_will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ 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::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)));
@@ -1861,7 +1864,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
}
}
- RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data);
/* Update dynamic lights in SDFGI cascades */
@@ -1983,7 +1986,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
}
if (idx > 0) {
- RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);
}
cascade_dynamic_light_count[i] = idx;
@@ -2046,6 +2049,8 @@ void GI::SDFGI::render_region(Ref p_render_buffers, int p_
push_constant.cascade = cascade;
if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {
+ RD::get_singleton()->buffer_copy(cascades[cascade].solid_cell_dispatch_buffer_storage, cascades[cascade].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);
+
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
//must pre scroll existing data because not all is dirty
@@ -2053,7 +2058,7 @@ void GI::SDFGI::render_region(Ref p_render_buffers, int p_
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer, 0);
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer_call, 0);
// no barrier do all together
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION]);
@@ -2142,7 +2147,7 @@ void GI::SDFGI::render_region(Ref p_render_buffers, int p_
//clear dispatch indirect data
uint32_t dispatch_indirct_data[4] = { 0, 0, 0, 0 };
- RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer, 0, sizeof(uint32_t) * 4, dispatch_indirct_data);
+ RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer_storage, 0, sizeof(uint32_t) * 4, dispatch_indirct_data);
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -2451,6 +2456,15 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref= cascades.size());
+
+ SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];
+ if (light_count[i] > 0) {
+ RD::get_singleton()->buffer_copy(cc.solid_cell_dispatch_buffer_storage, cc.solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);
+ }
+ }
+
/* Static Lights */
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -2482,7 +2496,7 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref 0) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_static_uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant));
- RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer, 0);
+ RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer_call, 0);
}
}
@@ -3716,7 +3730,7 @@ void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref 0) {
RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup");
- RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data);
RD::get_singleton()->draw_command_end_label();
}
@@ -3804,11 +3818,11 @@ void GI::process_gi(Ref p_render_buffers, const RID *p_nor
scene_data.screen_size[0] = internal_size.x;
scene_data.screen_size[1] = internal_size.y;
- RD::get_singleton()->buffer_update(rbgi->scene_data_ubo, 0, sizeof(SceneData), &scene_data, RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(rbgi->scene_data_ubo, 0, sizeof(SceneData), &scene_data);
}
// Now compute the contents of our buffers.
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
// Render each eye separately.
// We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..
@@ -4038,8 +4052,7 @@ void GI::process_gi(Ref p_render_buffers, const RID *p_nor
}
}
- //do barrier later to allow oeverlap
- //RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time
+ RD::get_singleton()->compute_list_end();
RD::get_singleton()->draw_command_end_label();
}
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index c46d4cbd25b..011493f1f6e 100644
--- a/servers/rendering/renderer_rd/environment/gi.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -584,7 +584,9 @@ public:
uint32_t static_light_aniso;
};
- RID solid_cell_dispatch_buffer; //buffer for indirect compute dispatch
+ // Buffers for indirect compute dispatch.
+ RID solid_cell_dispatch_buffer_storage;
+ RID solid_cell_dispatch_buffer_call;
RID solid_cell_buffer;
RID lightprobe_history_tex;
@@ -686,7 +688,7 @@ public:
void update_cascades();
void debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector &p_texture_views);
- void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
+ void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms);
void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data);
void render_region(Ref p_render_buffers, int p_region, const PagedArray &p_instances, float p_exposure_normalization);
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index ba72ab3b08b..41609dc74d3 100644
--- a/servers/rendering/renderer_rd/environment/sky.cpp
+++ b/servers/rendering/renderer_rd/environment/sky.cpp
@@ -1307,7 +1307,7 @@ void SkyRD::update_radiance_buffers(Ref 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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);
_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();
}
@@ -1328,7 +1328,7 @@ void SkyRD::update_radiance_buffers(Ref 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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);
_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();
}
@@ -1345,7 +1345,7 @@ void SkyRD::update_radiance_buffers(Ref 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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);
_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();
}
@@ -1469,7 +1469,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p
Vector 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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ 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);
_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();
}
@@ -1488,7 +1488,7 @@ void SkyRD::update_res_buffers(Ref p_render_buffers, RID p
Vector 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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ 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);
_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 76e814e1ee6..0c0062662ac 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -576,31 +576,13 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis
}
}
-void RenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
- uint32_t render_total = p_params->element_count;
- uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count();
- uint32_t render_from = p_thread * render_total / total_threads;
- uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads);
- _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to);
-}
-
-void RenderForwardClustered::_render_list_with_threads(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 &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector &p_storage_textures) {
+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 &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
p_params->framebuffer_format = fb_format;
- if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time
- //multi threaded
- thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count());
- RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), 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, p_storage_textures);
- WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardClustered::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardClusteredRenderList"));
- WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
- RD::get_singleton()->draw_list_end(p_params->barrier);
- } else {
- //single threaded
- 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, p_storage_textures);
- _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
- RD::get_singleton()->draw_list_end(p_params->barrier);
- }
+ 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);
+ _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
+ RD::get_singleton()->draw_list_end();
}
void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_apply_alpha_multiplier, bool p_pancake_shadows, int p_index) {
@@ -683,7 +665,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
}
}
- RD::get_singleton()->buffer_update(scene_state.implementation_uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.implementation_uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo);
}
void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) {
@@ -696,7 +678,7 @@ void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_rende
scene_state.instance_buffer[p_render_list] = RD::get_singleton()->storage_buffer_create(new_size * sizeof(SceneState::InstanceData));
scene_state.instance_buffer_size[p_render_list] = new_size;
}
- RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr());
}
}
void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, int *p_render_info, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
@@ -1097,7 +1079,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
}
if (p_render_list == RENDER_LIST_OPAQUE && lightmap_captures_used) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures);
}
}
@@ -1135,7 +1117,7 @@ void RenderForwardClustered::_setup_lightmaps(const RenderDataRD *p_render_data,
scene_state.lightmaps_used++;
}
if (scene_state.lightmaps_used > 0) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps);
}
}
@@ -1427,7 +1409,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_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE);
+ 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);
RD::get_singleton()->draw_list_end();
}
}
@@ -1461,18 +1443,12 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
_render_shadow_process();
}
- //start GI
if (render_gi) {
gi.process_gi(rb, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances);
}
- //Do shadow rendering (in parallel with GI)
if (render_shadows) {
- _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER);
- }
-
- if (render_gi) {
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier
+ _render_shadow_end();
}
if (rb_data.is_valid() && ss_effects) {
@@ -1496,9 +1472,6 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
}
}
- //full barrier here, we need raster, transfer and compute and it depends from the previous work
- RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
-
if (current_cluster_builder) {
// Note: when rendering stereoscopic (multiview) we are using our combined frustum projection to create
// our cluster data. We use reprojection in the shader to adjust for our left/right eye.
@@ -1814,7 +1787,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
float sky_energy_multiplier = 1.0 / _render_buffers_get_luminance_multiplier();
Color clear_color;
- bool keep_color = false;
+ bool load_color = false;
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
@@ -1857,10 +1830,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool convert_to_linear = !RendererRD::TextureStorage::get_singleton()->render_target_is_using_hdr(rb->get_render_target());
copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, convert_to_linear);
}
- keep_color = true;
+ load_color = true;
} break;
case RS::ENV_BG_KEEP: {
- keep_color = true;
+ load_color = true;
} break;
case RS::ENV_BG_CAMERA_FEED: {
} break;
@@ -1912,7 +1885,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
- bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
@@ -1923,7 +1895,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_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
+ 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);
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);
@@ -1935,21 +1907,14 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi;
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);
- _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector() : depth_pass_clear);
+ _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() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label();
- if (needs_pre_resolve) {
- _pre_resolve_render(p_render_data, using_sdfgi || using_voxelgi);
- }
-
if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
- if (needs_pre_resolve) {
- RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
- }
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
}
@@ -1960,8 +1925,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
RD::get_singleton()->draw_command_end_label();
}
-
- continue_depth = !finish_depth;
}
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
@@ -1990,10 +1953,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
{
bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty();
- bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
- bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
- RD::FinalAction final_color_action = will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ;
- RD::FinalAction final_depth_action = will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ;
{
Vector c;
@@ -2014,7 +1973,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);
- _render_list_with_threads(&render_list_params, opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, render_motion_pass ? RD::FINAL_ACTION_CONTINUE : final_color_action, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, render_motion_pass ? RD::FINAL_ACTION_CONTINUE : final_depth_action, c, 1.0, 0);
+ _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, 1.0, 0);
}
RD::get_singleton()->draw_command_end_label();
@@ -2022,7 +1981,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (using_motion_pass) {
Vector 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, render_motion_pass ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE, motion_vector_clear_colors);
+ 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_end();
}
@@ -2034,33 +1993,17 @@ 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);
- _render_list_with_threads(&render_list_params, color_framebuffer, RD::INITIAL_ACTION_CONTINUE, final_color_action, RD::INITIAL_ACTION_CONTINUE, final_depth_action);
+ _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);
RD::get_singleton()->draw_command_end_label();
-
- if (will_continue_color) {
- // Close the motion vectors framebuffer as it'll no longer be used.
- RD::get_singleton()->draw_list_begin(rb_data->get_velocity_only_fb(), RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
- RD::get_singleton()->draw_list_end();
- }
- }
-
- if (will_continue_color && using_separate_specular) {
- // Close the specular framebuffer as it'll no longer be used.
- RD::get_singleton()->draw_list_begin(rb_data->get_specular_only_fb(), RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, RD::FINAL_ACTION_CONTINUE);
- RD::get_singleton()->draw_list_end();
}
}
if (debug_voxelgis) {
- //debug voxelgis
- bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
- bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only);
-
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_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ 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::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);
@@ -2070,24 +2013,20 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
if (debug_sdfgi_probes) {
- //debug sdfgi
- bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
- bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only);
-
Projection dc;
dc.set_depth_correction(true);
Projection cms[RendererSceneRender::MAX_RENDER_VIEWS];
for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
cms[v] = (dc * p_render_data->scene_data->view_projection[v]) * Projection(p_render_data->scene_data->cam_transform.affine_inverse());
}
- _debug_sdfgi_probes(rb, color_only_framebuffer, p_render_data->scene_data->view_count, cms, will_continue_color, will_continue_depth);
+ _debug_sdfgi_probes(rb, color_only_framebuffer, p_render_data->scene_data->view_count, cms);
}
if (draw_sky || draw_sky_fog_only) {
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_CONTINUE, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ 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);
sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_energy_multiplier);
@@ -2146,7 +2085,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Clear Separate Specular (Canvas Background Mode)");
Vector 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_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, blank_clear_color);
+ 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_end();
}
@@ -2187,7 +2126,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(), false, 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);
- _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+ _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);
}
RD::get_singleton()->draw_command_end_label();
@@ -2226,7 +2165,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
exposure = luminance->get_current_luminance_buffer(rb);
}
+ RD::get_singleton()->draw_command_begin_label("FSR2");
RENDER_TIMESTAMP("FSR2");
+
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
real_t fov = p_render_data->scene_data->cam_projection.get_fov();
real_t aspect = p_render_data->scene_data->cam_projection.get_aspect();
@@ -2257,9 +2198,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
fsr2_effect->upscale(params);
}
+
+ RD::get_singleton()->draw_command_end_label();
} else if (using_taa) {
+ RD::get_singleton()->draw_command_begin_label("TAA");
RENDER_TIMESTAMP("TAA");
taa->process(rb, _render_buffers_get_color_format(), p_render_data->scene_data->z_near, p_render_data->scene_data->z_far);
+ RD::get_singleton()->draw_command_end_label();
}
}
@@ -2571,8 +2516,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 ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
- shadow_pass.final_depth_action = p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE;
+ shadow_pass.initial_depth_action = p_begin ? RD::INITIAL_ACTION_CLEAR : (p_clear_region ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD);
shadow_pass.rect = p_rect;
scene_state.shadow_passes.push_back(shadow_pass);
@@ -2591,17 +2535,14 @@ void RenderForwardClustered::_render_shadow_process() {
RD::get_singleton()->draw_command_end_label();
}
-void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
+void RenderForwardClustered::_render_shadow_end() {
RD::get_singleton()->draw_command_begin_label("Shadow Render");
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, RD::BARRIER_MASK_NO_BARRIER);
- _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector(), 1.0, 0, shadow_pass.rect);
+ 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(), 1.0, 0, shadow_pass.rect);
}
- if (p_barrier != RD::BARRIER_MASK_NO_BARRIER) {
- RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, p_barrier);
- }
RD::get_singleton()->draw_command_end_label();
}
@@ -2644,7 +2585,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_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
+ _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);
}
RD::get_singleton()->draw_command_end_label();
}
@@ -2697,7 +2638,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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
+ 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, 1.0, 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();
}
@@ -2747,7 +2688,7 @@ void RenderForwardClustered::_render_uv2(const PagedArraydraw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
+ 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, 1.0, 0, p_region);
const int uv_offset_count = 9;
static const Vector2 uv_offsets[uv_offset_count] = {
@@ -2803,13 +2744,6 @@ void RenderForwardClustered::_render_sdfgi(Ref p_render_bu
Vector3 half_size = p_bounds.size * 0.5;
Vector3 center = p_bounds.position + half_size;
- Vector sbs = {
- p_albedo_texture,
- p_emission_texture,
- p_emission_aniso_texture,
- p_geom_facing_texture
- };
-
//print_line("re-render " + p_from + " - " + p_size + " bounds " + p_bounds);
for (int i = 0; i < 3; i++) {
scene_state.ubo.sdf_offset[i] = p_from[i];
@@ -2860,7 +2794,7 @@ void RenderForwardClustered::_render_sdfgi(Ref 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_threads(&render_list_params, E->value, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, Rect2(), sbs);
+ _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(), 1.0, 0, Rect2());
}
RD::get_singleton()->draw_command_end_label();
@@ -4280,8 +4214,6 @@ RenderForwardClustered::RenderForwardClustered() {
best_fit_normal.shader.version_free(best_fit_normal.shader_version);
}
- render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
-
_update_shader_quality_settings();
resolve_effects = memnew(RendererRD::Resolve());
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 5ff3d9f52a6..5af213bc02f 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -209,10 +209,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float screen_mesh_lod_threshold = 0.0;
RD::FramebufferFormatID framebuffer_format = 0;
uint32_t element_offset = 0;
- uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
bool use_directional_soft_shadow = false;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, uint32_t p_color_pass_flags, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
@@ -227,7 +226,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
lod_distance_multiplier = p_lod_distance_multiplier;
screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
element_offset = p_element_offset;
- barrier = p_barrier;
use_directional_soft_shadow = p_use_directional_soft_shadows;
}
};
@@ -352,7 +350,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID framebuffer;
RD::InitialAction initial_depth_action;
- RD::FinalAction final_depth_action;
Rect2i rect;
};
@@ -378,14 +375,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
template
_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);
-
- LocalVector thread_draw_lists;
- void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
- void _render_list_with_threads(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 &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector &p_storage_textures = Vector());
-
- uint32_t render_list_thread_threshold = 500;
+ 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 &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 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);
@@ -604,7 +595,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
void _render_shadow_begin();
void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr, const Size2i &p_viewport_size = Size2i(1, 1));
void _render_shadow_process();
- void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
+ void _render_shadow_end();
/* Render Scene */
void _process_ssao(Ref p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections);
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index bba1f620239..86852ce020f 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -446,7 +446,7 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
bool SceneShaderForwardClustered::MaterialData::update_parameters(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
- return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, true, true, RD::BARRIER_MASK_RASTER);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, true, true);
}
SceneShaderForwardClustered::MaterialData::~MaterialData() {
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 b7d7105daa0..da04e6f9389 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -596,7 +596,7 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co
scene_state.lightmaps_used++;
}
if (scene_state.lightmaps_used > 0) {
- RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps);
}
}
@@ -631,7 +631,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_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE);
+ 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);
RD::get_singleton()->draw_list_end();
}
}
@@ -655,11 +655,8 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
_render_shadow_process();
- _render_shadow_end(RD::BARRIER_MASK_NO_BARRIER);
+ _render_shadow_end();
}
-
- //full barrier here, we need raster, transfer and compute and it depends from the previous work
- RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);
}
void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
@@ -811,7 +808,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
float sky_energy_multiplier = inverse_luminance_multiplier;
Color clear_color = p_default_bg_color;
- bool keep_color = false;
+ bool load_color = false;
bool copy_canvas = false;
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
@@ -855,7 +852,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
}
} break;
case RS::ENV_BG_KEEP: {
- keep_color = true;
+ load_color = true;
} break;
case RS::ENV_BG_CAMERA_FEED: {
} break;
@@ -955,6 +952,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (rb_data.is_valid()) {
cc.a = 0; // For transparent viewport backgrounds.
}
+
c.push_back(cc); // Our render buffer.
if (rb_data.is_valid()) {
if (p_render_data->render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
@@ -966,7 +964,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
}
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, merge_transparent_pass ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, merge_transparent_pass ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, c, 1.0, 0);
+ 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, 1.0, 0);
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
if (copy_canvas) {
@@ -1026,12 +1024,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
+ RD::get_singleton()->draw_list_end();
} else {
// We're done with our subpasses so end our container pass
// note, if MSAA is used we should get an automatic resolve here
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
+ RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label(); // Render 3D Pass / Render Reflection Probe Pass
@@ -1062,9 +1060,9 @@ 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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+ 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);
_render_list(draw_list, fb_format, &render_list_params, 0, render_list_params.element_count);
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL_BARRIERS);
+ RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label(); // Render Transparent Pass
}
@@ -1248,15 +1246,15 @@ void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, i
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info);
if (finalize_cubemap) {
_render_shadow_process();
- _render_shadow_end(RD::BARRIER_MASK_FRAGMENT);
+ _render_shadow_end();
// reblit
Rect2 atlas_rect_norm = atlas_rect;
atlas_rect_norm.position /= float(atlas_size);
atlas_rect_norm.size /= float(atlas_size);
- copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false, RD::BARRIER_MASK_NO_BARRIER);
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false);
atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size;
- copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true, RD::BARRIER_MASK_NO_BARRIER);
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true);
//restore transform so it can be properly used
light_storage->light_instance_set_shadow_transform(p_light, Projection(), light_storage->light_instance_get_base_transform(p_light), zfar, 0, 0, 0);
@@ -1337,8 +1335,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 ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
- shadow_pass.final_depth_action = p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE;
+ shadow_pass.initial_depth_action = p_begin ? RD::INITIAL_ACTION_CLEAR : (p_clear_region ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD);
shadow_pass.rect = p_rect;
scene_state.shadow_passes.push_back(shadow_pass);
@@ -1357,17 +1354,14 @@ void RenderForwardMobile::_render_shadow_process() {
RD::get_singleton()->draw_command_end_label();
}
-void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
+void RenderForwardMobile::_render_shadow_end() {
RD::get_singleton()->draw_command_begin_label("Shadow Render");
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, 0, false, Vector2(), shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
- _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector(), 1.0, 0, shadow_pass.rect);
+ 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, 0, 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(), 1.0, 0, shadow_pass.rect);
}
- if (p_barrier != RD::BARRIER_MASK_NO_BARRIER) {
- RD::get_singleton()->barrier(RD::BARRIER_MASK_FRAGMENT, p_barrier);
- }
RD::get_singleton()->draw_command_end_label();
}
@@ -1416,7 +1410,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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
+ 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, 1.0, 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();
}
@@ -1462,7 +1456,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray
Color(0, 0, 0, 0)
};
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
+ 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, 1.0, 0, p_region);
const int uv_offset_count = 9;
static const Vector2 uv_offsets[uv_offset_count] = {
@@ -1535,7 +1529,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, 0);
- _render_list_with_threads(&render_list_params, p_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
+ _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);
}
RD::get_singleton()->draw_command_end_label();
}
@@ -1672,7 +1666,7 @@ void RenderForwardMobile::_update_instance_data_buffer(RenderListType p_render_l
scene_state.instance_buffer[p_render_list] = RD::get_singleton()->storage_buffer_create(new_size * sizeof(SceneState::InstanceData));
scene_state.instance_buffer_size[p_render_list] = new_size;
}
- RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr());
}
}
@@ -1991,32 +1985,13 @@ void RenderForwardMobile::_render_list(RenderingDevice::DrawListID p_draw_list,
}
}
-void RenderForwardMobile::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
- uint32_t render_total = p_params->element_count;
- uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count();
- uint32_t render_from = p_thread * render_total / total_threads;
- uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads);
- _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to);
-}
-
-void RenderForwardMobile::_render_list_with_threads(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 &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector &p_storage_textures) {
+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 &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
p_params->framebuffer_format = fb_format;
- if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time
- //multi threaded
- thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count());
- RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), 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, p_storage_textures);
- WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass"));
- WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
-
- RD::get_singleton()->draw_list_end(p_params->barrier);
- } else {
- //single threaded
- 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, p_storage_textures);
- _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
- RD::get_singleton()->draw_list_end(p_params->barrier);
- }
+ 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);
+ _render_list(draw_list, fb_format, p_params, 0, p_params->element_count);
+ RD::get_singleton()->draw_list_end();
}
template
@@ -2813,9 +2788,6 @@ RenderForwardMobile::RenderForwardMobile() {
scene_shader.init(defines);
- // !BAS! maybe we need a mobile version of this setting?
- render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
-
_update_shader_quality_settings();
}
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 da96ca2124e..f1f6bb3db4f 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -155,10 +155,9 @@ private:
float screen_mesh_lod_threshold = 0.0;
RD::FramebufferFormatID framebuffer_format = 0;
uint32_t element_offset = 0;
- uint32_t barrier = RD::BARRIER_MASK_ALL_BARRIERS;
uint32_t subpass = 0;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, uint32_t p_spec_constant_base_flags = 0, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
@@ -172,7 +171,6 @@ private:
lod_distance_multiplier = p_lod_distance_multiplier;
screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
element_offset = p_element_offset;
- barrier = p_barrier;
spec_constant_base_flags = p_spec_constant_base_flags;
}
};
@@ -183,7 +181,7 @@ private:
void _render_shadow_begin();
void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
void _render_shadow_process();
- void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
+ void _render_shadow_end();
/* Render Scene */
@@ -277,7 +275,6 @@ private:
RID framebuffer;
RD::InitialAction initial_depth_action;
- RD::FinalAction final_depth_action;
Rect2i rect;
};
@@ -351,14 +348,8 @@ private:
template
_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);
-
- LocalVector thread_draw_lists;
- void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
- void _render_list_with_threads(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 &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector &p_storage_textures = Vector());
-
- uint32_t render_list_thread_threshold = 500;
+ 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 &p_clear_color_values = Vector(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
RenderList render_list[RENDER_LIST_MAX];
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index f1cec0e07cf..043cdbc8e5c 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -398,7 +398,7 @@ void SceneShaderForwardMobile::MaterialData::set_next_pass(RID p_pass) {
bool SceneShaderForwardMobile::MaterialData::update_parameters(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardMobile *shader_singleton = (SceneShaderForwardMobile *)SceneShaderForwardMobile::singleton;
- return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, true, true, RD::BARRIER_MASK_RASTER);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, true, true);
}
SceneShaderForwardMobile::MaterialData::~MaterialData() {
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 657628111ae..28fccbaf882 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1177,7 +1177,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
+ 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);
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);
@@ -1721,8 +1721,8 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
//light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
- RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, i != 3 ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD;
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, RD::FINAL_ACTION_STORE, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
Projection projection;
{
@@ -1811,7 +1811,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_REGION, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
+ 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);
Projection projection;
projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance);
@@ -1881,7 +1881,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan
Vector 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_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc);
+ 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);
Projection projection;
@@ -2371,8 +2371,8 @@ RendererRD::MaterialStorage::ShaderData *RendererCanvasRenderRD::_create_shader_
bool RendererCanvasRenderRD::CanvasMaterialData::update_parameters(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererCanvasRenderRD *canvas_singleton = static_cast(RendererCanvasRender::singleton);
- bool uniform_set_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, true, false, RD::BARRIER_MASK_ALL_BARRIERS);
- bool uniform_set_srgb_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set_srgb, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, false, false, RD::BARRIER_MASK_ALL_BARRIERS);
+ bool uniform_set_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, true, false);
+ bool uniform_set_srgb_changed = update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set_srgb, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET, false, false);
return uniform_set_changed || uniform_set_srgb_changed;
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 30c9b97aa42..3b05431f4a3 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -220,7 +220,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins
gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects);
}
-void RendererSceneRenderRD::_debug_sdfgi_probes(Ref p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) {
+void RendererSceneRenderRD::_debug_sdfgi_probes(Ref p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms) {
ERR_FAIL_COND(p_render_buffers.is_null());
if (!p_render_buffers->has_custom_data(RB_SCOPE_SDFGI)) {
@@ -229,7 +229,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(Ref p_rend
Ref sdfgi = p_render_buffers->get_custom_data(RB_SCOPE_SDFGI);
- sdfgi->debug_probes(p_framebuffer, p_view_count, p_camera_with_transforms, p_will_continue_color, p_will_continue_depth);
+ sdfgi->debug_probes(p_framebuffer, p_view_count, p_camera_with_transforms);
}
////////////////////////////////
@@ -987,14 +987,6 @@ void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bo
}
}
-void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi) {
- if (p_render_data->render_buffers.is_valid()) {
- if (p_use_gi) {
- RD::get_singleton()->compute_list_end();
- }
- }
-}
-
void RendererSceneRenderRD::render_scene(const Ref &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray &p_instances, const PagedArray &p_lights, const PagedArray &p_reflection_probes, const PagedArray &p_voxel_gi_instances, const PagedArray &p_decals, const PagedArray &p_lightmaps, const PagedArray &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 211d191039d..4811ae3b44e 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -137,14 +137,13 @@ protected:
virtual void _render_sdfgi(Ref p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) = 0;
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray &p_instances) = 0;
- void _debug_sdfgi_probes(Ref p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
+ void _debug_sdfgi_probes(Ref p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms);
virtual RID _render_buffers_get_normal_texture(Ref p_render_buffers) = 0;
virtual RID _render_buffers_get_velocity_texture(Ref p_render_buffers) = 0;
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
diff --git a/servers/rendering/renderer_rd/shaders/effects/fsr2/SCsub b/servers/rendering/renderer_rd/shaders/effects/fsr2/SCsub
index f06a2d86e24..5b8bbc343b7 100644
--- a/servers/rendering/renderer_rd/shaders/effects/fsr2/SCsub
+++ b/servers/rendering/renderer_rd/shaders/effects/fsr2/SCsub
@@ -6,6 +6,11 @@ if "RD_GLSL" in env["BUILDERS"]:
# find all include files
gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
+ # Add all FSR2 shader and header files.
+ fsr2_dir = "#thirdparty/amd-fsr2/shaders"
+ gl_include_files += [str(f) for f in Glob(fsr2_dir + "/*.h")]
+ gl_include_files += [str(f) for f in Glob(fsr2_dir + "/*.glsl")]
+
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index 5f4bf6c8ed4..21c6425a878 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -996,15 +996,15 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
//update without barriers
if (omni_light_count) {
- RD::get_singleton()->buffer_update(omni_light_buffer, 0, sizeof(LightData) * omni_light_count, omni_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(omni_light_buffer, 0, sizeof(LightData) * omni_light_count, omni_lights);
}
if (spot_light_count) {
- RD::get_singleton()->buffer_update(spot_light_buffer, 0, sizeof(LightData) * spot_light_count, spot_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(spot_light_buffer, 0, sizeof(LightData) * spot_light_count, spot_lights);
}
if (r_directional_light_count) {
- RD::get_singleton()->buffer_update(directional_light_buffer, 0, sizeof(DirectionalLightData) * r_directional_light_count, directional_lights, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(directional_light_buffer, 0, sizeof(DirectionalLightData) * r_directional_light_count, directional_lights);
}
}
@@ -1722,7 +1722,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
}
if (reflection_count) {
- RD::get_singleton()->buffer_update(reflection_buffer, 0, reflection_count * sizeof(ReflectionData), reflections, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(reflection_buffer, 0, reflection_count * sizeof(ReflectionData), reflections);
}
}
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 2e8c9d7f8ef..1c3076b128f 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -986,7 +986,7 @@ void MaterialStorage::MaterialData::free_parameters_uniform_set(RID p_uniform_se
}
}
-bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap &p_uniforms, const uint32_t *p_uniform_offsets, const Vector &p_texture_uniforms, const HashMap> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material, uint32_t p_barrier) {
+bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap &p_uniforms, const uint32_t *p_uniform_offsets, const Vector &p_texture_uniforms, const HashMap> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material) {
if ((uint32_t)ubo_data.size() != p_ubo_size) {
p_uniform_dirty = true;
if (uniform_buffer.is_valid()) {
@@ -1011,7 +1011,7 @@ bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
update_uniform_buffer(p_uniforms, p_uniform_offsets, p_parameters, ubo_data.ptrw(), ubo_data.size(), p_use_linear_color);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), p_barrier);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
}
uint32_t tex_uniform_count = 0U;
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index 403fd286b46..fe769a778d5 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -87,7 +87,7 @@ public:
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
- bool update_parameters_uniform_set(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap &p_uniforms, const uint32_t *p_uniform_offsets, const Vector &p_texture_uniforms, const HashMap> &p_default_texture_params, uint32_t p_ubo_size, RID &r_uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material, uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
+ bool update_parameters_uniform_set(const HashMap &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap &p_uniforms, const uint32_t *p_uniform_offsets, const Vector &p_texture_uniforms, const HashMap> &p_default_texture_params, uint32_t p_ubo_size, RID &r_uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material);
void free_parameters_uniform_set(RID p_uniform_set);
private:
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 01ee4f3c013..b97ce2d0066 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -1458,8 +1458,7 @@ void MeshStorage::_multimesh_enable_motion_vectors(MultiMesh *multimesh) {
if (multimesh->buffer_set && multimesh->data_cache.is_empty()) {
// If the buffer was set but there's no data cached in the CPU, we copy the buffer directly on the GPU.
- RD::get_singleton()->barrier();
- RD::get_singleton()->buffer_copy(multimesh->buffer, new_buffer, 0, 0, buffer_size, RD::BARRIER_MASK_NO_BARRIER);
+ RD::get_singleton()->buffer_copy(multimesh->buffer, new_buffer, 0, 0, buffer_size);
RD::get_singleton()->buffer_copy(multimesh->buffer, new_buffer, 0, buffer_size, buffer_size);
} else if (!multimesh->data_cache.is_empty()) {
// Simply upload the data cached in the CPU, which should already be doubled in size.
@@ -2037,10 +2036,9 @@ void MeshStorage::_update_dirty_multimeshes() {
uint32_t offset = i * region_size;
uint32_t size = multimesh->stride_cache * (uint32_t)multimesh->instances * (uint32_t)sizeof(float);
uint32_t region_start_index = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * i;
- RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index], RD::BARRIER_MASK_NO_BARRIER);
+ RD::get_singleton()->buffer_update(multimesh->buffer, buffer_offset * sizeof(float) + offset, MIN(region_size, size - offset), &data[region_start_index]);
}
}
- RD::get_singleton()->barrier(RD::BARRIER_MASK_NO_BARRIER, RD::BARRIER_MASK_ALL_BARRIERS);
}
memcpy(multimesh->previous_data_cache_dirty_regions, multimesh->data_cache_dirty_regions, data_cache_dirty_region_count * sizeof(bool));
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 3d3cb585ac1..a854e78f536 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -307,6 +307,11 @@ void ParticlesStorage::_particles_free_data(Particles *particles) {
particles->emission_storage_buffer = RID();
}
+ if (particles->unused_storage_buffer.is_valid()) {
+ RD::get_singleton()->free(particles->unused_storage_buffer);
+ particles->unused_storage_buffer = RID();
+ }
+
if (RD::get_singleton()->uniform_set_is_valid(particles->particles_material_uniform_set)) {
//will need to be re-created
RD::get_singleton()->free(particles->particles_material_uniform_set);
@@ -530,6 +535,12 @@ void ParticlesStorage::_particles_allocate_emission_buffer(Particles *particles)
}
}
+void ParticlesStorage::_particles_ensure_unused_buffer(Particles *particles) {
+ if (particles->unused_storage_buffer.is_null()) {
+ particles->unused_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4);
+ }
+}
+
void ParticlesStorage::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_NULL(particles);
@@ -757,7 +768,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
if (p_particles->emission_storage_buffer.is_valid()) {
u.append_id(p_particles->emission_storage_buffer);
} else {
- u.append_id(MeshStorage::get_singleton()->get_default_rd_storage_buffer());
+ _particles_ensure_unused_buffer(p_particles);
+ u.append_id(p_particles->unused_storage_buffer);
}
uniforms.push_back(u);
}
@@ -772,7 +784,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
}
u.append_id(sub_emitter->emission_storage_buffer);
} else {
- u.append_id(MeshStorage::get_singleton()->get_default_rd_storage_buffer());
+ _particles_ensure_unused_buffer(p_particles);
+ u.append_id(p_particles->unused_storage_buffer);
}
uniforms.push_back(u);
}
@@ -1463,7 +1476,8 @@ void ParticlesStorage::update_particles() {
if (particles->trail_bind_pose_buffer.is_valid()) {
u.append_id(particles->trail_bind_pose_buffer);
} else {
- u.append_id(MeshStorage::get_singleton()->get_default_rd_storage_buffer());
+ _particles_ensure_unused_buffer(particles);
+ u.append_id(particles->unused_storage_buffer);
}
uniforms.push_back(u);
}
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index a28d7b41540..33f44f3045a 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -247,6 +247,8 @@ private:
ParticleEmissionBuffer *emission_buffer = nullptr;
RID emission_storage_buffer;
+ RID unused_storage_buffer;
+
HashSet collisions;
Dependency dependency;
@@ -263,6 +265,7 @@ private:
void _particles_process(Particles *p_particles, double p_delta);
void _particles_allocate_emission_buffer(Particles *particles);
+ void _particles_ensure_unused_buffer(Particles *particles);
void _particles_free_data(Particles *particles);
void _particles_update_buffers(Particles *particles);
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
index 40891f9a631..f2231664fa9 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
@@ -252,7 +252,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
}
uniform_buffer = p_uniform_buffer;
- RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo);
}
RID RenderSceneDataRD::get_uniform_buffer() {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 380e325ffa2..d8baf260f97 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -2703,7 +2703,7 @@ void TextureStorage::update_decal_atlas() {
Vector 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_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
+ 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);
for (const KeyValue &E : decal_atlas.textures) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
@@ -2981,7 +2981,7 @@ void TextureStorage::update_decal_buffer(const PagedArray &p_decals, const
}
if (decal_count > 0) {
- RD::get_singleton()->buffer_update(decal_buffer, 0, sizeof(DecalData) * decal_count, decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
+ RD::get_singleton()->buffer_update(decal_buffer, 0, sizeof(DecalData) * decal_count, decals);
}
}
@@ -3384,7 +3384,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_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ 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_end();
rt->msaa_needs_resolve = false;
}
@@ -3501,7 +3501,7 @@ void TextureStorage::render_target_do_clear_request(RID p_render_target) {
}
Vector 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_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
+ 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_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 8e7beda6f31..f79c9c9f7c3 100644
--- a/servers/rendering/rendering_device.compat.inc
+++ b/servers/rendering/rendering_device.compat.inc
@@ -34,39 +34,87 @@ RID RenderingDevice::_shader_create_from_bytecode_bind_compat_79606(const Vector
return shader_create_from_bytecode(p_shader_binary, RID());
}
-BitField RenderingDevice::_convert_barrier_mask_81356(BitField p_old_barrier) {
- if (p_old_barrier == 7) {
- return BARRIER_MASK_ALL_BARRIERS;
- } else if (p_old_barrier == 16) {
- return BARRIER_MASK_NO_BARRIER;
- }
-
- BitField new_barrier;
- if (p_old_barrier & 1) {
- new_barrier.set_flag(BARRIER_MASK_VERTEX);
- }
- if (p_old_barrier & 2) {
- new_barrier.set_flag(BARRIER_MASK_FRAGMENT);
- }
- if (p_old_barrier & 4) {
- new_barrier.set_flag(BARRIER_MASK_COMPUTE);
- }
- if (p_old_barrier & 8) {
- new_barrier.set_flag(BARRIER_MASK_TRANSFER);
- }
- return new_barrier;
-}
-
void RenderingDevice::_draw_list_end_bind_compat_81356(BitField p_post_barrier) {
- draw_list_end(_convert_barrier_mask_81356(p_post_barrier));
+ draw_list_end();
}
void RenderingDevice::_compute_list_end_bind_compat_81356(BitField p_post_barrier) {
- compute_list_end(_convert_barrier_mask_81356(p_post_barrier));
+ compute_list_end();
}
void RenderingDevice::_barrier_bind_compat_81356(BitField p_from, BitField p_to) {
- barrier(_convert_barrier_mask_81356(p_from), _convert_barrier_mask_81356(p_to));
+ // Does nothing.
+}
+
+void RenderingDevice::_draw_list_end_bind_compat_84976(BitField p_post_barrier) {
+ draw_list_end();
+}
+
+void RenderingDevice::_compute_list_end_bind_compat_84976(BitField p_post_barrier) {
+ compute_list_end();
+}
+
+RenderingDevice::InitialAction RenderingDevice::_convert_initial_action_84976(InitialAction p_old_initial_action) {
+ switch (uint32_t(p_old_initial_action)) {
+ case 0: // INITIAL_ACTION_CLEAR
+ return INITIAL_ACTION_CLEAR;
+ case 1: // INITIAL_ACTION_CLEAR_REGION
+ return INITIAL_ACTION_CLEAR;
+ case 2: // INITIAL_ACTION_CLEAR_REGION_CONTINUE
+ case 3: // INITIAL_ACTION_KEEP
+ return INITIAL_ACTION_LOAD;
+ case 4: // INITIAL_ACTION_DROP
+ return INITIAL_ACTION_DISCARD;
+ case 5: // INITIAL_ACTION_CONTINUE
+ return INITIAL_ACTION_LOAD;
+ default:
+ return INITIAL_ACTION_LOAD;
+ }
+}
+
+RenderingDevice::FinalAction RenderingDevice::_convert_final_action_84976(FinalAction p_old_final_action) {
+ switch (uint32_t(p_old_final_action)) {
+ case 0: // FINAL_ACTION_READ
+ return FINAL_ACTION_STORE;
+ case 1: // FINAL_ACTION_DISCARD
+ return FINAL_ACTION_DISCARD;
+ case 2: // FINAL_ACTION_CONTINUE
+ return FINAL_ACTION_STORE;
+ default:
+ return FINAL_ACTION_STORE;
+ }
+}
+
+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 &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const TypedArray &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);
+}
+
+RenderingDevice::ComputeListID RenderingDevice::_compute_list_begin_bind_compat_84976(bool p_allow_draw_overlap) {
+ return compute_list_begin();
+}
+
+Error RenderingDevice::_buffer_update_bind_compat_84976(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector &p_data, BitField p_post_barrier) {
+ return _buffer_update_bind(p_buffer, p_offset, p_size, p_data);
+}
+
+Error RenderingDevice::_buffer_clear_bind_compat_84976(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField p_post_barrier) {
+ return buffer_clear(p_buffer, p_offset, p_size);
+}
+
+Error RenderingDevice::_texture_update_bind_compat_84976(RID p_texture, uint32_t p_layer, const Vector &p_data, BitField p_post_barrier) {
+ return texture_update(p_texture, p_layer, p_data);
+}
+
+Error RenderingDevice::_texture_copy_bind_compat_84976(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField p_post_barrier) {
+ return texture_copy(p_from_texture, p_to_texture, p_from, p_to, p_size, p_src_mipmap, p_dst_mipmap, p_src_layer, p_dst_layer);
+}
+
+Error RenderingDevice::_texture_clear_bind_compat_84976(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, BitField p_post_barrier) {
+ return texture_clear(p_texture, p_color, p_base_mipmap, p_mipmaps, p_base_layer, p_layers);
+}
+
+Error RenderingDevice::_texture_resolve_multisample_bind_compat_84976(RID p_from_texture, RID p_to_texture, BitField p_post_barrier) {
+ return texture_resolve_multisample(p_from_texture, p_to_texture);
}
void RenderingDevice::_bind_compatibility_methods() {
@@ -74,6 +122,16 @@ void RenderingDevice::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::_draw_list_end_bind_compat_81356, DEFVAL(7));
ClassDB::bind_compatibility_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::_compute_list_end_bind_compat_81356, DEFVAL(7));
ClassDB::bind_compatibility_method(D_METHOD("barrier", "from", "to"), &RenderingDevice::_barrier_bind_compat_81356, DEFVAL(7), DEFVAL(7));
+ ClassDB::bind_compatibility_method(D_METHOD("draw_list_end", "post_barrier"), &RenderingDevice::_draw_list_end_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("compute_list_end", "post_barrier"), &RenderingDevice::_compute_list_end_bind_compat_84976, DEFVAL(0x7FFF));
+ 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", "storage_textures"), &RenderingDevice::_draw_list_begin_bind_compat_84976, DEFVAL(Vector()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray()));
+ ClassDB::bind_compatibility_method(D_METHOD("compute_list_begin", "allow_draw_overlap"), &RenderingDevice::_compute_list_begin_bind_compat_84976, DEFVAL(false));
+ ClassDB::bind_compatibility_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "post_barrier"), &RenderingDevice::_buffer_update_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("buffer_clear", "buffer", "offset", "size_bytes", "post_barrier"), &RenderingDevice::_buffer_clear_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::_texture_update_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "post_barrier"), &RenderingDevice::_texture_copy_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "post_barrier"), &RenderingDevice::_texture_clear_bind_compat_84976, DEFVAL(0x7FFF));
+ ClassDB::bind_compatibility_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "post_barrier"), &RenderingDevice::_texture_resolve_multisample_bind_compat_84976, DEFVAL(0x7FFF));
}
#endif
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 9e7c32094bf..03ffe967e26 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -37,7 +37,26 @@
#include "core/io/dir_access.h"
#include "servers/rendering/renderer_rd/api_context_rd.h"
-//#define FORCE_FULL_BARRIER
+// When true, the command graph will attempt to reorder the rendering commands submitted by the user based on the dependencies detected from
+// the commands automatically. This should improve rendering performance in most scenarios at the cost of some extra CPU overhead.
+//
+// This behavior can be disabled if it's suspected that the graph is not detecting dependencies correctly and more control over the order of
+// the commands is desired (e.g. debugging).
+
+#define RENDER_GRAPH_REORDER 1
+
+// Synchronization barriers are issued between the graph's levels only with the necessary amount of detail to achieve the correct result. If
+// it's suspected that the graph is not doing this correctly, full barriers can be issued instead that will block all types of operations
+// between the synchronization levels. This setting will have a very negative impact on performance when enabled, so it's only intended for
+// debugging purposes.
+
+#define RENDER_GRAPH_FULL_BARRIERS 0
+
+// The command graph can automatically issue secondary command buffers and record them on background threads when they reach an arbitrary
+// size threshold. This can be very beneficial towards reducing the time the main thread takes to record all the rendering commands. However,
+// this setting is not enabled by default as it's been shown to cause some strange issues with certain IHVs that have yet to be understood.
+
+#define SECONDARY_COMMAND_BUFFERS_PER_FRAME 0
RenderingDevice *RenderingDevice::singleton = nullptr;
@@ -131,127 +150,23 @@ RID RenderingDevice::shader_create_from_spirv(const Vector
return shader_create_from_bytecode(bytecode);
}
-/******************/
-/**** BARRIERS ****/
-/******************/
-
-void RenderingDevice::_full_barrier(bool p_sync_with_draw) {
- // Used for debug.
-
- RDD::MemoryBarrier mb;
- mb.src_access = (RDD::BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT |
- RDD::BARRIER_ACCESS_INDEX_READ_BIT |
- RDD::BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
- RDD::BARRIER_ACCESS_UNIFORM_READ_BIT |
- RDD::BARRIER_ACCESS_INPUT_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_SHADER_READ_BIT |
- RDD::BARRIER_ACCESS_SHADER_WRITE_BIT |
- RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
- RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
- RDD::BARRIER_ACCESS_TRANSFER_READ_BIT |
- RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT |
- RDD::BARRIER_ACCESS_HOST_READ_BIT |
- RDD::BARRIER_ACCESS_HOST_WRITE_BIT);
- mb.dst_access = (RDD::BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT |
- RDD::BARRIER_ACCESS_INDEX_READ_BIT |
- RDD::BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
- RDD::BARRIER_ACCESS_UNIFORM_READ_BIT |
- RDD::BARRIER_ACCESS_INPUT_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_SHADER_READ_BIT |
- RDD::BARRIER_ACCESS_SHADER_WRITE_BIT |
- RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
- RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
- RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
- RDD::BARRIER_ACCESS_TRANSFER_READ_BIT |
- RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT |
- RDD::BARRIER_ACCESS_HOST_READ_BIT |
- RDD::BARRIER_ACCESS_HOST_WRITE_BIT);
-
- RDD::CommandBufferID cmd_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
- driver->command_pipeline_barrier(cmd_buffer, RDD::PIPELINE_STAGE_ALL_COMMANDS_BIT, RDD::PIPELINE_STAGE_ALL_COMMANDS_BIT, mb, {}, {});
-}
-
/***************************/
/**** BUFFER MANAGEMENT ****/
/***************************/
-RenderingDevice::Buffer *RenderingDevice::_get_buffer_from_owner(RID p_buffer, BitField &r_stages, BitField &r_access, BitField p_post_barrier) {
+RenderingDevice::Buffer *RenderingDevice::_get_buffer_from_owner(RID p_buffer) {
Buffer *buffer = nullptr;
- r_stages.clear();
- r_access.clear();
if (vertex_buffer_owner.owns(p_buffer)) {
buffer = vertex_buffer_owner.get_or_null(p_buffer);
-
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
- if (buffer->usage & RDD::BUFFER_USAGE_STORAGE_BIT) {
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- r_stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- r_stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- }
- }
} else if (index_buffer_owner.owns(p_buffer)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_INDEX_READ_BIT);
buffer = index_buffer_owner.get_or_null(p_buffer);
} else if (uniform_buffer_owner.owns(p_buffer)) {
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- }
- r_access.set_flag(RDD::BARRIER_ACCESS_UNIFORM_READ_BIT);
buffer = uniform_buffer_owner.get_or_null(p_buffer);
} else if (texture_buffer_owner.owns(p_buffer)) {
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT);
- }
-
- // FIXME: Broken.
+ DEV_ASSERT(false && "FIXME: Broken.");
//buffer = texture_buffer_owner.get_or_null(p_buffer)->buffer;
} else if (storage_buffer_owner.owns(p_buffer)) {
buffer = storage_buffer_owner.get_or_null(p_buffer);
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
-
- if (buffer->usage.has_flag(RDD::BUFFER_USAGE_INDIRECT_BIT)) {
- r_stages.set_flag(RDD::PIPELINE_STAGE_DRAW_INDIRECT_BIT);
- r_access.set_flag(RDD::BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT);
- }
}
return buffer;
}
@@ -269,10 +184,11 @@ Error RenderingDevice::_insert_staging_block() {
return OK;
}
-Error RenderingDevice::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, bool p_can_segment) {
+Error RenderingDevice::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_required_align, uint32_t &r_alloc_offset, uint32_t &r_alloc_size, StagingRequiredAction &r_required_action, bool p_can_segment) {
// Determine a block to use.
r_alloc_size = p_amount;
+ r_required_action = STAGING_REQUIRED_ACTION_NONE;
while (true) {
r_alloc_offset = 0;
@@ -324,23 +240,7 @@ Error RenderingDevice::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_re
// and this frame is not even done.
// If this is the main thread, it means the user is likely loading a lot of resources at once,.
// Otherwise, the thread should just be blocked until the next frame (currently unimplemented).
-
- if (false) { // Separate thread from render.
-
- //block_until_next_frame()
- continue;
- } else {
- // Flush EVERYTHING including setup commands. IF not immediate, also need to flush the draw commands.
- _flush(true);
-
- // Clear the whole staging buffer.
- for (int i = 0; i < staging_buffer_blocks.size(); i++) {
- staging_buffer_blocks.write[i].frame_used = 0;
- staging_buffer_blocks.write[i].fill_amount = 0;
- }
- // Claim current.
- staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn;
- }
+ r_required_action = STAGING_REQUIRED_ACTION_FLUSH_CURRENT;
}
} else {
@@ -368,28 +268,7 @@ Error RenderingDevice::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_re
// Let's flush older frames.
// The logic here is that if a game is loading a lot of data from the main thread, it will need to be stalled anyway.
// If loading from a separate thread, we can block that thread until next frame when more room is made (not currently implemented, though).
-
- if (false) {
- // Separate thread from render.
- //block_until_next_frame()
- continue; // And try again.
- } else {
- _flush(false);
-
- for (int i = 0; i < staging_buffer_blocks.size(); i++) {
- // Clear all blocks but the ones from this frame.
- int block_idx = (i + staging_buffer_current) % staging_buffer_blocks.size();
- if (staging_buffer_blocks[block_idx].frame_used == frames_drawn) {
- break; // Ok, we reached something from this frame, abort.
- }
-
- staging_buffer_blocks.write[block_idx].frame_used = 0;
- staging_buffer_blocks.write[block_idx].fill_amount = 0;
- }
-
- // Claim for current frame.
- staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn;
- }
+ r_required_action = STAGING_REQUIRED_ACTION_FLUSH_OLDER;
}
}
@@ -402,20 +281,78 @@ Error RenderingDevice::_staging_buffer_allocate(uint32_t p_amount, uint32_t p_re
return OK;
}
-Error RenderingDevice::_buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer, uint32_t p_required_align) {
+void RenderingDevice::_staging_buffer_execute_required_action(StagingRequiredAction p_required_action) {
+ switch (p_required_action) {
+ case STAGING_REQUIRED_ACTION_NONE: {
+ // Do nothing.
+ } break;
+ case STAGING_REQUIRED_ACTION_FLUSH_CURRENT: {
+ // Flush EVERYTHING including setup commands. IF not immediate, also need to flush the draw commands.
+ _flush(true);
+
+ // Clear the whole staging buffer.
+ for (int i = 0; i < staging_buffer_blocks.size(); i++) {
+ staging_buffer_blocks.write[i].frame_used = 0;
+ staging_buffer_blocks.write[i].fill_amount = 0;
+ }
+
+ // Claim for current frame.
+ staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn;
+ } break;
+ case STAGING_REQUIRED_ACTION_FLUSH_OLDER: {
+ _flush(false);
+
+ for (int i = 0; i < staging_buffer_blocks.size(); i++) {
+ // Clear all blocks but the ones from this frame.
+ int block_idx = (i + staging_buffer_current) % staging_buffer_blocks.size();
+ if (staging_buffer_blocks[block_idx].frame_used == frames_drawn) {
+ break; // Ok, we reached something from this frame, abort.
+ }
+
+ staging_buffer_blocks.write[block_idx].frame_used = 0;
+ staging_buffer_blocks.write[block_idx].fill_amount = 0;
+ }
+
+ // Claim for current frame.
+ staging_buffer_blocks.write[staging_buffer_current].frame_used = frames_drawn;
+ } break;
+ default: {
+ DEV_ASSERT(false && "Unknown required action.");
+ } break;
+ }
+}
+
+Error RenderingDevice::_buffer_update(Buffer *p_buffer, RID p_buffer_id, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_queue, uint32_t p_required_align) {
// Submitting may get chunked for various reasons, so convert this to a task.
size_t to_submit = p_data_size;
size_t submit_from = 0;
+ thread_local LocalVector command_buffer_copies_vector;
+ command_buffer_copies_vector.clear();
+
while (to_submit > 0) {
uint32_t block_write_offset;
uint32_t block_write_amount;
+ StagingRequiredAction required_action;
- Error err = _staging_buffer_allocate(MIN(to_submit, staging_buffer_block_size), p_required_align, block_write_offset, block_write_amount);
+ Error err = _staging_buffer_allocate(MIN(to_submit, staging_buffer_block_size), p_required_align, block_write_offset, block_write_amount, required_action);
if (err) {
return err;
}
+ if (p_use_draw_queue && !command_buffer_copies_vector.is_empty() && required_action == STAGING_REQUIRED_ACTION_FLUSH_CURRENT) {
+ if (_buffer_make_mutable(p_buffer, p_buffer_id)) {
+ // The buffer must be mutable to be used as a copy destination.
+ draw_graph.add_synchronization();
+ }
+
+ // If we're using the draw queue and the staging buffer requires flushing everything, we submit the command early and clear the current vector.
+ draw_graph.add_buffer_update(p_buffer->driver_id, p_buffer->draw_tracker, command_buffer_copies_vector);
+ command_buffer_copies_vector.clear();
+ }
+
+ _staging_buffer_execute_required_action(required_action);
+
// Map staging buffer (It's CPU and coherent).
uint8_t *data_ptr = driver->buffer_map(staging_buffer_blocks[staging_buffer_current].driver_id);
ERR_FAIL_NULL_V(data_ptr, ERR_CANT_CREATE);
@@ -427,12 +364,19 @@ Error RenderingDevice::_buffer_update(Buffer *p_buffer, size_t p_offset, const u
driver->buffer_unmap(staging_buffer_blocks[staging_buffer_current].driver_id);
// Insert a command to copy this.
-
RDD::BufferCopyRegion region;
region.src_offset = block_write_offset;
region.dst_offset = submit_from + p_offset;
region.size = block_write_amount;
- driver->command_copy_buffer(p_use_draw_command_buffer ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer, staging_buffer_blocks[staging_buffer_current].driver_id, p_buffer->driver_id, region);
+
+ if (p_use_draw_queue) {
+ RDG::RecordedBufferCopy buffer_copy;
+ buffer_copy.source = staging_buffer_blocks[staging_buffer_current].driver_id;
+ buffer_copy.region = region;
+ command_buffer_copies_vector.push_back(buffer_copy);
+ } else {
+ driver->command_copy_buffer(frames[frame].setup_command_buffer, staging_buffer_blocks[staging_buffer_current].driver_id, p_buffer->driver_id, region);
+ }
staging_buffer_blocks.write[staging_buffer_current].fill_amount = block_write_offset + block_write_amount;
@@ -440,10 +384,19 @@ Error RenderingDevice::_buffer_update(Buffer *p_buffer, size_t p_offset, const u
submit_from += block_write_amount;
}
+ if (p_use_draw_queue && !command_buffer_copies_vector.is_empty()) {
+ if (_buffer_make_mutable(p_buffer, p_buffer_id)) {
+ // The buffer must be mutable to be used as a copy destination.
+ draw_graph.add_synchronization();
+ }
+
+ draw_graph.add_buffer_update(p_buffer->driver_id, p_buffer->draw_tracker, command_buffer_copies_vector);
+ }
+
return OK;
}
-Error RenderingDevice::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t p_src_offset, uint32_t p_dst_offset, uint32_t p_size, BitField p_post_barrier) {
+Error RenderingDevice::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t p_src_offset, uint32_t p_dst_offset, uint32_t p_size) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER,
@@ -451,25 +404,12 @@ Error RenderingDevice::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t
ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER,
"Copying buffers is forbidden during creation of a compute list");
- // This method assumes the barriers have been pushed prior to being called, therefore no barriers are pushed
- // for the source or destination buffers before performing the copy. These masks are effectively ignored.
- BitField src_stages;
- BitField src_access;
- Buffer *src_buffer = _get_buffer_from_owner(p_src_buffer, src_stages, src_access, BARRIER_MASK_NO_BARRIER);
+ Buffer *src_buffer = _get_buffer_from_owner(p_src_buffer);
if (!src_buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Source buffer argument is not a valid buffer of any type.");
}
- BitField dst_stages;
- BitField dst_access;
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- // If the post barrier mask defines it, we indicate the destination buffer will require a barrier with these flags set
- // after the copy command is queued.
- dst_stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- dst_access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- Buffer *dst_buffer = _get_buffer_from_owner(p_dst_buffer, dst_stages, dst_access, p_post_barrier);
+ Buffer *dst_buffer = _get_buffer_from_owner(p_dst_buffer);
if (!dst_buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Destination buffer argument is not a valid buffer of any type.");
}
@@ -483,31 +423,18 @@ Error RenderingDevice::buffer_copy(RID p_src_buffer, RID p_dst_buffer, uint32_t
region.src_offset = p_src_offset;
region.dst_offset = p_dst_offset;
region.size = p_size;
- driver->command_copy_buffer(frames[frame].draw_command_buffer, src_buffer->driver_id, dst_buffer->driver_id, region);
-#ifdef FORCE_FULL_BARRIER
- _full_barrier(true);
-#else
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS) && p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) {
- if (dst_stages.is_empty()) {
- dst_stages = RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
- }
-
- // As indicated by the post barrier mask, push a new barrier.
- RDD::BufferBarrier bb;
- bb.buffer = dst_buffer->driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = dst_access;
- bb.offset = p_dst_offset;
- bb.size = p_size;
- driver->command_pipeline_barrier(frames[frame].draw_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, dst_stages, {}, bb, {});
+ if (_buffer_make_mutable(dst_buffer, p_dst_buffer)) {
+ // The destination buffer must be mutable to be used as a copy destination.
+ draw_graph.add_synchronization();
}
-#endif
+
+ draw_graph.add_buffer_copy(src_buffer->driver_id, src_buffer->draw_tracker, dst_buffer->driver_id, dst_buffer->draw_tracker, region);
return OK;
}
-Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField p_post_barrier) {
+Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list, ERR_INVALID_PARAMETER,
@@ -515,14 +442,7 @@ Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p
ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER,
"Updating buffers is forbidden during creation of a compute list");
- BitField dst_stages;
- BitField dst_access;
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- // Protect subsequent updates.
- dst_stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- dst_access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
- Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stages, dst_access, p_post_barrier);
+ Buffer *buffer = _get_buffer_from_owner(p_buffer);
if (!buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type.");
}
@@ -530,33 +450,10 @@ Error RenderingDevice::buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p
ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER,
"Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end.");
- Error err = _buffer_update(buffer, p_offset, (uint8_t *)p_data, p_size, true);
- if (err) {
- return err;
- }
-
-#ifdef FORCE_FULL_BARRIER
- _full_barrier(true);
-#else
- if (dst_stages.is_empty()) {
- dst_stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
- }
-
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS) && p_post_barrier != RD::BARRIER_MASK_NO_BARRIER) {
- RDD::BufferBarrier bb;
- bb.buffer = buffer->driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = dst_access;
- bb.offset = p_offset;
- bb.size = p_size;
- driver->command_pipeline_barrier(frames[frame].draw_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, dst_stages, {}, bb, {});
- }
-
-#endif
- return err;
+ return _buffer_update(buffer, p_buffer, p_offset, (uint8_t *)p_data, p_size, true);
}
-Error RenderingDevice::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField p_post_barrier) {
+Error RenderingDevice::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG((p_size % 4) != 0, ERR_INVALID_PARAMETER,
@@ -566,15 +463,7 @@ Error RenderingDevice::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_
ERR_FAIL_COND_V_MSG(compute_list, ERR_INVALID_PARAMETER,
"Updating buffers is forbidden during creation of a compute list");
- BitField dst_stages;
- BitField dst_access;
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- // Protect subsequent updates.
- dst_stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- dst_access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- Buffer *buffer = _get_buffer_from_owner(p_buffer, dst_stages, dst_access, p_post_barrier);
+ Buffer *buffer = _get_buffer_from_owner(p_buffer);
if (!buffer) {
ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Buffer argument is not a valid buffer of any type.");
}
@@ -582,51 +471,24 @@ Error RenderingDevice::buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_
ERR_FAIL_COND_V_MSG(p_offset + p_size > buffer->size, ERR_INVALID_PARAMETER,
"Attempted to write buffer (" + itos((p_offset + p_size) - buffer->size) + " bytes) past the end.");
- driver->command_clear_buffer(frames[frame].draw_command_buffer, buffer->driver_id, p_offset, p_size);
-
-#ifdef FORCE_FULL_BARRIER
- _full_barrier(true);
-#else
- if (dst_stages.is_empty()) {
- dst_stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
+ if (_buffer_make_mutable(buffer, p_buffer)) {
+ // The destination buffer must be mutable to be used as a clear destination.
+ draw_graph.add_synchronization();
}
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = buffer->driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = dst_access;
- bb.offset = p_offset;
- bb.size = p_size;
- driver->command_pipeline_barrier(frames[frame].draw_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, dst_stages, {}, bb, {});
- }
+ draw_graph.add_buffer_clear(buffer->driver_id, buffer->draw_tracker, p_offset, p_size);
-#endif
return OK;
}
Vector RenderingDevice::buffer_get_data(RID p_buffer, uint32_t p_offset, uint32_t p_size) {
_THREAD_SAFE_METHOD_
- // It could be this buffer was just created.
- BitField src_stages = RDD::PIPELINE_STAGE_TRANSFER_BIT;
- BitField src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- // Get the vulkan buffer and the potential stage/access possible.
- Buffer *buffer = _get_buffer_from_owner(p_buffer, src_stages, src_access, BARRIER_MASK_ALL_BARRIERS);
+ Buffer *buffer = _get_buffer_from_owner(p_buffer);
if (!buffer) {
ERR_FAIL_V_MSG(Vector(), "Buffer is either invalid or this type of buffer can't be retrieved. Only Index and Vertex buffers allow retrieving.");
}
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- // Make sure no one is using the buffer -- the "true" gets us to the same command buffer as below.
- RDD::BufferBarrier bb;
- bb.buffer = buffer->driver_id;
- bb.src_access = src_access;
- bb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- bb.size = buffer->size;
- driver->command_pipeline_barrier(frames[frame].draw_command_buffer, src_stages, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, bb, {});
- }
-
// Size of buffer to retrieve.
if (!p_size) {
p_size = buffer->size;
@@ -641,7 +503,9 @@ Vector RenderingDevice::buffer_get_data(RID p_buffer, uint32_t p_offset
RDD::BufferCopyRegion region;
region.src_offset = p_offset;
region.size = p_size;
- driver->command_copy_buffer(frames[frame].draw_command_buffer, buffer->driver_id, tmp_buffer, region);
+
+ draw_graph.add_buffer_get_data(buffer->driver_id, buffer->draw_tracker, tmp_buffer, region);
+
// Flush everything so memory can be safely mapped.
_flush(true);
@@ -676,23 +540,21 @@ RID RenderingDevice::storage_buffer_create(uint32_t p_size_bytes, const Vectorbuffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU);
ERR_FAIL_COND_V(!buffer.driver_id, RID());
+ // Storage buffers are assumed to be mutable.
+ buffer.draw_tracker = RDG::resource_tracker_create();
+ buffer.draw_tracker->buffer_driver_id = buffer.driver_id;
+
if (p_data.size()) {
- uint64_t data_size = p_data.size();
- const uint8_t *r = p_data.ptr();
- _buffer_update(&buffer, 0, r, data_size);
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = buffer.driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = (RDD::BARRIER_ACCESS_SHADER_READ_BIT | RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- bb.size = data_size;
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT, {}, bb, {});
- }
+ _buffer_update(&buffer, RID(), 0, p_data.ptr(), p_data.size());
}
buffer_memory += buffer.size;
- return storage_buffer_owner.make_rid(buffer);
+ RID id = storage_buffer_owner.make_rid(buffer);
+#ifdef DEV_ENABLED
+ set_resource_name(id, "RID:" + itos(id.get_id()));
+#endif
+ return id;
}
RID RenderingDevice::texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector &p_data) {
@@ -710,6 +572,12 @@ RID RenderingDevice::texture_buffer_create(uint32_t p_size_elements, DataFormat
texture_buffer.driver_id = driver->buffer_create(size_bytes, usage, RDD::MEMORY_ALLOCATION_TYPE_GPU);
ERR_FAIL_COND_V(!texture_buffer.driver_id, RID());
+ // Texture buffers are assumed to be immutable unless they don't have initial data.
+ if (p_data.is_empty()) {
+ texture_buffer.draw_tracker = RDG::resource_tracker_create();
+ texture_buffer.draw_tracker->buffer_driver_id = texture_buffer.driver_id;
+ }
+
bool ok = driver->buffer_set_texel_format(texture_buffer.driver_id, p_format);
if (!ok) {
driver->buffer_free(texture_buffer.driver_id);
@@ -717,15 +585,7 @@ RID RenderingDevice::texture_buffer_create(uint32_t p_size_elements, DataFormat
}
if (p_data.size()) {
- _buffer_update(&texture_buffer, 0, p_data.ptr(), p_data.size());
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = texture_buffer.driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT;
- bb.size = size_bytes;
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, (RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT), {}, bb, {});
- }
+ _buffer_update(&texture_buffer, RID(), 0, p_data.ptr(), p_data.size());
}
buffer_memory += size_bytes;
@@ -787,10 +647,8 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
ERR_FAIL_COND_V_MSG(required_mipmaps < format.mipmaps, RID(),
"Too many mipmaps requested for texture format and dimensions (" + itos(format.mipmaps) + "), maximum allowed: (" + itos(required_mipmaps) + ").");
+ uint32_t forced_usage_bits = 0;
if (p_data.size()) {
- ERR_FAIL_COND_V_MSG(!(format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT), RID(),
- "Texture needs the TEXTURE_USAGE_CAN_UPDATE_BIT usage flag in order to be updated at initialization or later");
-
ERR_FAIL_COND_V_MSG(p_data.size() != (int)format.array_layers, RID(),
"Default supplied data for image format is of invalid length (" + itos(p_data.size()) + "), should be (" + itos(format.array_layers) + ").");
@@ -799,6 +657,10 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
ERR_FAIL_COND_V_MSG((uint32_t)p_data[i].size() != required_size, RID(),
"Data for slice index " + itos(i) + " (mapped to layer " + itos(i) + ") differs in size (supplied: " + itos(p_data[i].size()) + ") than what is required by the format (" + itos(required_size) + ").");
}
+
+ if (!(format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT)) {
+ forced_usage_bits = TEXTURE_USAGE_CAN_UPDATE_BIT;
+ }
}
{
@@ -849,7 +711,7 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
// Create.
Texture texture;
-
+ format.usage_bits |= forced_usage_bits;
texture.driver_id = driver->texture_create(format, tv);
ERR_FAIL_COND_V(!texture.driver_id, RID());
texture.type = format.texture_type;
@@ -862,26 +724,10 @@ 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.usage_flags = format.usage_bits;
+ texture.usage_flags = format.usage_bits & ~forced_usage_bits;
texture.samples = format.samples;
texture.allowed_shared_formats = format.shareable_formats;
-
- // Set base layout based on usage priority.
-
- if ((format.usage_bits & TEXTURE_USAGE_SAMPLING_BIT)) {
- // First priority, readable.
- texture.layout = RDD::TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- } else if ((format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) {
- // Second priority, storage.
- texture.layout = RDD::TEXTURE_LAYOUT_GENERAL;
- } else if ((format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
- // Third priority, color or depth.
- texture.layout = RDD::TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- } else if ((format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
- texture.layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- } else {
- texture.layout = RDD::TEXTURE_LAYOUT_GENERAL;
- }
+ texture.has_initial_data = !p_data.is_empty();
if ((format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
@@ -896,18 +742,10 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
texture.bound = false;
- // Barrier to set layout.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::TextureBarrier tb;
- tb.texture = texture.driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_UNDEFINED;
- tb.next_layout = texture.layout;
- tb.subresources.aspect = texture.barrier_aspect_flags;
- tb.subresources.mipmap_count = format.mipmaps;
- tb.subresources.layer_count = format.array_layers;
-
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT, {}, {}, tb);
+ // Textures are only assumed to be immutable if they have initial data and none of the other bits that indicate write usage are enabled.
+ bool texture_mutable_by_default = texture.usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_STORAGE_BIT | TEXTURE_USAGE_STORAGE_ATOMIC_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT);
+ if (p_data.is_empty() || texture_mutable_by_default) {
+ _texture_make_mutable(&texture, RID());
}
texture_memory += driver->texture_get_allocation_size(texture.driver_id);
@@ -919,9 +757,15 @@ RID RenderingDevice::texture_create(const TextureFormat &p_format, const Texture
if (p_data.size()) {
for (uint32_t i = 0; i < p_format.array_layers; i++) {
- _texture_update(id, i, p_data[i], BARRIER_MASK_ALL_BARRIERS, true);
+ _texture_update(id, i, p_data[i], true, false);
+ }
+
+ if (texture.draw_tracker != nullptr) {
+ // Draw tracker can assume the texture will be in transfer destination.
+ texture.draw_tracker->usage = RDG::RESOURCE_USAGE_TRANSFER_TO;
}
}
+
return id;
}
@@ -959,6 +803,12 @@ RID RenderingDevice::texture_create_shared(const TextureView &p_view, RID p_with
texture.driver_id = driver->texture_create_shared(texture.driver_id, tv);
ERR_FAIL_COND_V(!texture.driver_id, RID());
+ texture.slice_trackers.clear();
+
+ if (texture.draw_tracker != nullptr) {
+ texture.draw_tracker->reference_count++;
+ }
+
texture.owner = p_with_texture;
RID id = texture_owner.make_rid(texture);
#ifdef DEV_ENABLED
@@ -988,23 +838,6 @@ RID RenderingDevice::texture_create_from_extension(TextureType p_type, DataForma
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
- // Set base layout based on usage priority.
-
- if (p_usage.has_flag(TEXTURE_USAGE_SAMPLING_BIT)) {
- // First priority, readable.
- texture.layout = RDD::TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- } else if (p_usage.has_flag(TEXTURE_USAGE_STORAGE_BIT)) {
- // Second priority, storage.
- texture.layout = RDD::TEXTURE_LAYOUT_GENERAL;
- } else if (p_usage.has_flag(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
- // Third priority, color or depth.
- texture.layout = RDD::TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- } else if (p_usage.has_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
- texture.layout = RDD::TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
- } else {
- texture.layout = RDD::TEXTURE_LAYOUT_GENERAL;
- }
-
if (p_usage.has_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
texture.read_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
texture.barrier_aspect_flags.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
@@ -1019,19 +852,7 @@ RID RenderingDevice::texture_create_from_extension(TextureType p_type, DataForma
texture.driver_id = driver->texture_create_from_extension(p_image, p_type, p_format, p_layers, (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
ERR_FAIL_COND_V(!texture.driver_id, RID());
- // Barrier to set layout.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::TextureBarrier tb;
- tb.texture = texture.driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_UNDEFINED;
- tb.next_layout = texture.layout;
- tb.subresources.aspect = texture.barrier_aspect_flags;
- tb.subresources.mipmap_count = texture.mipmaps;
- tb.subresources.layer_count = texture.layers;
-
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT, {}, {}, tb);
- }
+ _texture_make_mutable(&texture, RID());
RID id = texture_owner.make_rid(texture);
#ifdef DEV_ENABLED
@@ -1081,6 +902,7 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view,
}
Texture texture = *src_texture;
+
get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
texture.mipmaps = p_mipmaps;
texture.layers = slice_layers;
@@ -1118,7 +940,17 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view,
texture.driver_id = driver->texture_create_shared_from_slice(src_texture->driver_id, tv, p_slice_type, p_layer, slice_layers, p_mipmap, p_mipmaps);
ERR_FAIL_COND_V(!texture.driver_id, RID());
+ const Rect2i slice_rect(p_mipmap, p_layer, p_mipmaps, slice_layers);
texture.owner = p_with_texture;
+ texture.slice_type = p_slice_type;
+ texture.slice_rect = slice_rect;
+
+ // If parent is mutable, make slice mutable by default.
+ if (src_texture->draw_tracker != nullptr) {
+ texture.draw_tracker = nullptr;
+ _texture_make_mutable(&texture, RID());
+ }
+
RID id = texture_owner.make_rid(texture);
#ifdef DEV_ENABLED
set_resource_name(id, "RID:" + itos(id.get_id()));
@@ -1128,8 +960,8 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view,
return id;
}
-Error RenderingDevice::texture_update(RID p_texture, uint32_t p_layer, const Vector &p_data, BitField p_post_barrier) {
- return _texture_update(p_texture, p_layer, p_data, p_post_barrier, false);
+Error RenderingDevice::texture_update(RID p_texture, uint32_t p_layer, const Vector &p_data) {
+ return _texture_update(p_texture, p_layer, p_data, false, true);
}
static _ALWAYS_INLINE_ void _copy_region(uint8_t const *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_x, uint32_t p_src_y, uint32_t p_src_w, uint32_t p_src_h, uint32_t p_src_full_w, uint32_t p_dst_pitch, uint32_t p_unit_size) {
@@ -1148,7 +980,7 @@ static _ALWAYS_INLINE_ void _copy_region(uint8_t const *__restrict p_src, uint8_
}
}
-Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Vector &p_data, BitField p_post_barrier, bool p_use_setup_queue) {
+Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Vector &p_data, bool p_use_setup_queue, bool p_validate_can_update) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG((draw_list || compute_list) && !p_use_setup_queue, ERR_INVALID_PARAMETER,
@@ -1166,7 +998,7 @@ Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Ve
ERR_FAIL_COND_V_MSG(texture->bound, ERR_CANT_ACQUIRE_RESOURCE,
"Texture can't be updated while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to `RenderingDevice.FINAL_ACTION_CONTINUE`) to update this texture.");
- ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT), ERR_INVALID_PARAMETER,
+ ERR_FAIL_COND_V_MSG(p_validate_can_update && !(texture->usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT), ERR_INVALID_PARAMETER,
"Texture requires the `RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT` to be set to be updatable.");
uint32_t layer_count = texture->layers;
@@ -1191,21 +1023,22 @@ Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Ve
const uint8_t *r = p_data.ptr();
- RDD::CommandBufferID command_buffer = p_use_setup_queue ? frames[frame].setup_command_buffer : frames[frame].draw_command_buffer;
+ thread_local LocalVector command_buffer_to_texture_copies_vector;
+ command_buffer_to_texture_copies_vector.clear();
- // Barrier to transfer.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
+ if (p_use_setup_queue && driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
+ // When using the setup queue directly, we transition the texture to the optimal layout.
RDD::TextureBarrier tb;
tb.texture = texture->driver_id;
tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.prev_layout = texture->layout;
+ tb.prev_layout = RDD::TEXTURE_LAYOUT_UNDEFINED;
tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
tb.subresources.aspect = texture->barrier_aspect_flags;
tb.subresources.mipmap_count = texture->mipmaps;
tb.subresources.base_layer = p_layer;
tb.subresources.layer_count = 1;
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
+ driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
}
uint32_t mipmap_offset = 0;
@@ -1240,12 +1073,26 @@ Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Ve
uint32_t pitch_step = driver->api_trait_get(RDD::API_TRAIT_TEXTURE_DATA_ROW_PITCH_STEP);
region_pitch = STEPIFY(region_pitch, pitch_step);
uint32_t to_allocate = region_pitch * region_h;
-
uint32_t alloc_offset = 0, alloc_size = 0;
- Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, false);
+ StagingRequiredAction required_action;
+ Error err = _staging_buffer_allocate(to_allocate, required_align, alloc_offset, alloc_size, required_action, false);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- uint8_t *write_ptr = nullptr;
+ if (!p_use_setup_queue && !command_buffer_to_texture_copies_vector.is_empty() && required_action == STAGING_REQUIRED_ACTION_FLUSH_CURRENT) {
+ if (_texture_make_mutable(texture, p_texture)) {
+ // The texture must be mutable to be used as a copy destination.
+ draw_graph.add_synchronization();
+ }
+
+ // If we're using the draw queue and the staging buffer requires flushing everything, we submit the command early and clear the current vector.
+ draw_graph.add_texture_update(texture->driver_id, texture->draw_tracker, command_buffer_to_texture_copies_vector);
+ command_buffer_to_texture_copies_vector.clear();
+ }
+
+ _staging_buffer_execute_required_action(required_action);
+
+ uint8_t *write_ptr;
+
{ // Map.
uint8_t *data_ptr = driver->buffer_map(staging_buffer_blocks[staging_buffer_current].driver_id);
ERR_FAIL_NULL_V(data_ptr, ERR_CANT_CREATE);
@@ -1288,7 +1135,14 @@ Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Ve
copy_region.texture_offset = Vector3i(x, y, z);
copy_region.texture_region_size = Vector3i(region_logic_w, region_logic_h, 1);
- driver->command_copy_buffer_to_texture(command_buffer, staging_buffer_blocks[staging_buffer_current].driver_id, texture->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL, copy_region);
+ if (p_use_setup_queue) {
+ driver->command_copy_buffer_to_texture(frames[frame].setup_command_buffer, staging_buffer_blocks[staging_buffer_current].driver_id, texture->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL, copy_region);
+ } else {
+ RDG::RecordedBufferToTextureCopy buffer_to_texture_copy;
+ buffer_to_texture_copy.from_buffer = staging_buffer_blocks[staging_buffer_current].driver_id;
+ buffer_to_texture_copy.region = copy_region;
+ command_buffer_to_texture_copies_vector.push_back(buffer_to_texture_copy);
+ }
staging_buffer_blocks.write[staging_buffer_current].fill_amount = alloc_offset + alloc_size;
}
@@ -1300,50 +1154,25 @@ Error RenderingDevice::_texture_update(RID p_texture, uint32_t p_layer, const Ve
logic_height = MAX(1u, logic_height >> 1);
}
- // Barrier to restore layout.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- BitField stages;
- BitField access;
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- if (stages.is_empty()) {
- stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
- }
-
+ if (p_use_setup_queue && (texture->draw_tracker == nullptr) && driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
+ // If the texture does not have a tracker, it means it must be transitioned to the sampling state.
RDD::TextureBarrier tb;
tb.texture = texture->driver_id;
tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.dst_access = access;
tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
- tb.next_layout = texture->layout;
+ tb.next_layout = RDD::TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
tb.subresources.aspect = texture->barrier_aspect_flags;
tb.subresources.mipmap_count = texture->mipmaps;
tb.subresources.base_layer = p_layer;
tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, stages, {}, {}, tb);
-
- if (texture->used_in_frame != frames_drawn) {
- texture->used_in_raster = false;
- texture->used_in_compute = false;
- texture->used_in_frame = frames_drawn;
+ driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, {}, {}, tb);
+ } else if (!p_use_setup_queue && !command_buffer_to_texture_copies_vector.is_empty()) {
+ if (_texture_make_mutable(texture, p_texture)) {
+ // The texture must be mutable to be used as a copy destination.
+ draw_graph.add_synchronization();
}
- texture->used_in_transfer = true;
+
+ draw_graph.add_texture_update(texture->driver_id, texture->draw_tracker, command_buffer_to_texture_copies_vector);
}
return OK;
@@ -1455,63 +1284,35 @@ Vector RenderingDevice::texture_get_data(RID p_texture, uint32_t p_laye
RDD::BufferID tmp_buffer = driver->buffer_create(work_buffer_size, RDD::BUFFER_USAGE_TRANSFER_TO_BIT, RDD::MEMORY_ALLOCATION_TYPE_CPU);
ERR_FAIL_COND_V(!tmp_buffer, Vector());
- RDD::CommandBufferID command_buffer = frames[frame].draw_command_buffer; // Makes more sense to retrieve.
+ thread_local LocalVector command_buffer_texture_copy_regions_vector;
+ command_buffer_texture_copy_regions_vector.clear();
- // Pre-copy barrier.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::TextureBarrier tb;
- tb.texture = tex->driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.prev_layout = tex->layout;
- tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.subresources.aspect = tex->barrier_aspect_flags;
- tb.subresources.mipmap_count = tex->mipmaps;
- tb.subresources.base_layer = p_layer;
- tb.subresources.layer_count = 1;
+ uint32_t w = tex->width;
+ uint32_t h = tex->height;
+ uint32_t d = tex->depth;
+ for (uint32_t i = 0; i < tex->mipmaps; i++) {
+ RDD::BufferTextureCopyRegion copy_region;
+ copy_region.buffer_offset = mip_layouts[i].offset;
+ copy_region.texture_subresources.aspect = tex->read_aspect_flags;
+ copy_region.texture_subresources.mipmap = i;
+ copy_region.texture_subresources.base_layer = p_layer;
+ copy_region.texture_subresources.layer_count = 1;
+ copy_region.texture_region_size.x = w;
+ copy_region.texture_region_size.y = h;
+ copy_region.texture_region_size.z = d;
+ command_buffer_texture_copy_regions_vector.push_back(copy_region);
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
+ w = MAX(1u, w >> 1);
+ h = MAX(1u, h >> 1);
+ d = MAX(1u, d >> 1);
}
- {
- uint32_t w = tex->width;
- uint32_t h = tex->height;
- uint32_t d = tex->depth;
- for (uint32_t i = 0; i < tex->mipmaps; i++) {
- RDD::BufferTextureCopyRegion copy_region;
- copy_region.buffer_offset = mip_layouts[i].offset;
- copy_region.texture_subresources.aspect = tex->read_aspect_flags;
- copy_region.texture_subresources.mipmap = i;
- copy_region.texture_subresources.base_layer = p_layer;
- copy_region.texture_subresources.layer_count = 1;
- copy_region.texture_region_size.x = w;
- copy_region.texture_region_size.y = h;
- copy_region.texture_region_size.z = d;
- driver->command_copy_texture_to_buffer(command_buffer, tex->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL, tmp_buffer, copy_region);
-
- w = MAX(1u, w >> 1);
- h = MAX(1u, h >> 1);
- d = MAX(1u, d >> 1);
- }
+ if (_texture_make_mutable(tex, p_texture)) {
+ // The texture must be mutable to be used as a copy source due to layout transitions.
+ draw_graph.add_synchronization();
}
- // Post-copy barrier.
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::TextureBarrier tb;
- tb.texture = tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.dst_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT;
- if ((tex->usage_flags & TEXTURE_USAGE_STORAGE_BIT)) {
- tb.dst_access.set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.next_layout = tex->layout;
- tb.subresources.aspect = tex->barrier_aspect_flags;
- tb.subresources.mipmap_count = tex->mipmaps;
- tb.subresources.base_layer = p_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT, {}, {}, tb);
- }
+ draw_graph.add_texture_get_data(tex->driver_id, tex->draw_tracker, tmp_buffer, command_buffer_texture_copy_regions_vector);
_flush(true);
@@ -1519,39 +1320,35 @@ Vector RenderingDevice::texture_get_data(RID p_texture, uint32_t p_laye
ERR_FAIL_NULL_V(read_ptr, Vector());
Vector buffer_data;
- {
- uint32_t tight_buffer_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps);
- buffer_data.resize(tight_buffer_size);
+ uint32_t tight_buffer_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps);
+ buffer_data.resize(tight_buffer_size);
- uint8_t *write_ptr = buffer_data.ptrw();
+ uint8_t *write_ptr = buffer_data.ptrw();
- uint32_t w = tex->width;
- uint32_t h = tex->height;
- uint32_t d = tex->depth;
- for (uint32_t i = 0; i < tex->mipmaps; i++) {
- uint32_t width = 0, height = 0, depth = 0;
- uint32_t tight_mip_size = get_image_format_required_size(tex->format, w, h, d, 1, &width, &height, &depth);
- uint32_t block_w = 0, block_h = 0;
- get_compressed_image_format_block_dimensions(tex->format, block_w, block_h);
- uint32_t tight_row_pitch = tight_mip_size / ((height / block_h) * depth);
+ w = tex->width;
+ h = tex->height;
+ d = tex->depth;
+ for (uint32_t i = 0; i < tex->mipmaps; i++) {
+ uint32_t width = 0, height = 0, depth = 0;
+ uint32_t tight_mip_size = get_image_format_required_size(tex->format, w, h, d, 1, &width, &height, &depth);
+ uint32_t block_w = 0, block_h = 0;
+ get_compressed_image_format_block_dimensions(tex->format, block_w, block_h);
+ uint32_t tight_row_pitch = tight_mip_size / ((height / block_h) * depth);
- {
- // Copy row-by-row to erase padding due to alignments.
- const uint8_t *rp = read_ptr;
- uint8_t *wp = write_ptr;
- for (uint32_t row = h * d / block_h; row != 0; row--) {
- memcpy(wp, rp, tight_row_pitch);
- rp += mip_layouts[i].row_pitch;
- wp += tight_row_pitch;
- }
- }
-
- w = MAX(1u, w >> 1);
- h = MAX(1u, h >> 1);
- d = MAX(1u, d >> 1);
- read_ptr += mip_layouts[i].size;
- write_ptr += tight_mip_size;
+ // Copy row-by-row to erase padding due to alignments.
+ const uint8_t *rp = read_ptr;
+ uint8_t *wp = write_ptr;
+ for (uint32_t row = h * d / block_h; row != 0; row--) {
+ memcpy(wp, rp, tight_row_pitch);
+ rp += mip_layouts[i].row_pitch;
+ wp += tight_row_pitch;
}
+
+ w = MAX(1u, w >> 1);
+ h = MAX(1u, h >> 1);
+ d = MAX(1u, d >> 1);
+ read_ptr += mip_layouts[i].size;
+ write_ptr += tight_mip_size;
}
driver->buffer_unmap(tmp_buffer);
@@ -1610,7 +1407,7 @@ uint64_t RenderingDevice::texture_get_native_handle(RID p_texture) {
}
#endif
-Error RenderingDevice::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, BitField p_post_barrier) {
+Error RenderingDevice::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.get_or_null(p_from_texture);
@@ -1658,133 +1455,34 @@ Error RenderingDevice::texture_copy(RID p_from_texture, RID p_to_texture, const
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_flags != dst_tex->read_aspect_flags, ERR_INVALID_PARAMETER,
"Source and destination texture must be of the same type (color or depth).");
- RDD::CommandBufferID command_buffer = frames[frame].draw_command_buffer;
+ RDD::TextureCopyRegion copy_region;
+ copy_region.src_subresources.aspect = src_tex->read_aspect_flags;
+ copy_region.src_subresources.mipmap = p_src_mipmap;
+ copy_region.src_subresources.base_layer = p_src_layer;
+ copy_region.src_subresources.layer_count = 1;
+ copy_region.src_offset = p_from;
- // PRE Copy the image.
+ copy_region.dst_subresources.aspect = dst_tex->read_aspect_flags;
+ copy_region.dst_subresources.mipmap = p_dst_mipmap;
+ copy_region.dst_subresources.base_layer = p_dst_layer;
+ copy_region.dst_subresources.layer_count = 1;
+ copy_region.dst_offset = p_to;
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- { // Source.
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.prev_layout = src_tex->layout;
- tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.subresources.aspect = src_tex->barrier_aspect_flags;
- tb.subresources.base_mipmap = p_src_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = p_src_layer;
- tb.subresources.layer_count = 1;
+ copy_region.size = p_size;
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
- }
- { // Dest.
- RDD::TextureBarrier tb;
- tb.texture = dst_tex->driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.prev_layout = dst_tex->layout;
- tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
- tb.subresources.aspect = dst_tex->read_aspect_flags;
- tb.subresources.base_mipmap = p_dst_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = p_dst_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
- }
+ // The textures must be mutable to be used in the copy operation.
+ bool src_made_mutable = _texture_make_mutable(src_tex, p_from_texture);
+ bool dst_made_mutable = _texture_make_mutable(dst_tex, p_to_texture);
+ if (src_made_mutable || dst_made_mutable) {
+ draw_graph.add_synchronization();
}
- // COPY.
-
- {
- RDD::TextureCopyRegion copy_region;
- copy_region.src_subresources.aspect = src_tex->read_aspect_flags;
- copy_region.src_subresources.mipmap = p_src_mipmap;
- copy_region.src_subresources.base_layer = p_src_layer;
- copy_region.src_subresources.layer_count = 1;
- copy_region.src_offset = p_from;
-
- copy_region.dst_subresources.aspect = dst_tex->read_aspect_flags;
- copy_region.dst_subresources.mipmap = p_dst_mipmap;
- copy_region.dst_subresources.base_layer = p_dst_layer;
- copy_region.dst_subresources.layer_count = 1;
- copy_region.dst_offset = p_to;
-
- copy_region.size = p_size;
-
- driver->command_copy_texture(command_buffer, src_tex->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_tex->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL, copy_region);
- }
-
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- // RESTORE LAYOUT for SRC and DST.
-
- BitField stages;
- BitField access;
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- if (stages.is_empty()) {
- stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
- }
-
- { // Restore src.
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.dst_access = access;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.next_layout = src_tex->layout;
- tb.subresources.aspect = src_tex->barrier_aspect_flags;
- tb.subresources.base_mipmap = p_src_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = p_src_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, stages, {}, {}, tb);
- }
-
- { // Make dst readable.
-
- RDD::TextureBarrier tb;
- tb.texture = dst_tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.dst_access = access;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
- tb.next_layout = dst_tex->layout;
- tb.subresources.aspect = dst_tex->read_aspect_flags;
- tb.subresources.base_mipmap = p_dst_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = p_dst_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, stages, {}, {}, tb);
- }
-
- if (dst_tex->used_in_frame != frames_drawn) {
- dst_tex->used_in_raster = false;
- dst_tex->used_in_compute = false;
- dst_tex->used_in_frame = frames_drawn;
- }
- dst_tex->used_in_transfer = true;
- }
+ draw_graph.add_texture_copy(src_tex->driver_id, src_tex->draw_tracker, dst_tex->driver_id, dst_tex->draw_tracker, copy_region);
return OK;
}
-Error RenderingDevice::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, BitField p_post_barrier) {
+Error RenderingDevice::texture_resolve_multisample(RID p_from_texture, RID p_to_texture) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.get_or_null(p_from_texture);
@@ -1815,108 +1513,19 @@ Error RenderingDevice::texture_resolve_multisample(RID p_from_texture, RID p_to_
ERR_FAIL_COND_V_MSG(src_tex->read_aspect_flags != dst_tex->read_aspect_flags, ERR_INVALID_PARAMETER,
"Source and destination texture must be of the same type (color or depth).");
- RDD::CommandBufferID command_buffer = frames[frame].draw_command_buffer;
-
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- // PRE Copy the image.
-
- { // Source.
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.prev_layout = src_tex->layout;
- tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.subresources.aspect = src_tex->barrier_aspect_flags;
- tb.subresources.base_mipmap = src_tex->base_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = src_tex->base_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
- }
- { // Dest.
- RDD::TextureBarrier tb;
- tb.texture = dst_tex->driver_id;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.prev_layout = dst_tex->layout;
- tb.next_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
- tb.subresources.aspect = dst_tex->barrier_aspect_flags;
- tb.subresources.base_mipmap = dst_tex->base_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = dst_tex->base_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
- }
+ // The textures must be mutable to be used in the resolve operation.
+ bool src_made_mutable = _texture_make_mutable(src_tex, p_from_texture);
+ bool dst_made_mutable = _texture_make_mutable(dst_tex, p_to_texture);
+ if (src_made_mutable || dst_made_mutable) {
+ draw_graph.add_synchronization();
}
- // RESOLVE.
- driver->command_resolve_texture(command_buffer, src_tex->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_tex->base_layer, src_tex->base_mipmap, dst_tex->driver_id, RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_tex->base_layer, dst_tex->base_mipmap);
-
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- // RESTORE LAYOUT for SRC and DST.
-
- BitField stages;
- BitField access;
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- if (stages.is_empty()) {
- stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
- }
-
- { // Restore src.
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_READ_BIT;
- tb.dst_access = access;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- tb.next_layout = src_tex->layout;
- tb.subresources.aspect = src_tex->barrier_aspect_flags;
- tb.subresources.base_mipmap = src_tex->base_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = src_tex->base_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT, stages, {}, {}, tb);
- }
-
- { // Make dst readable.
-
- RDD::TextureBarrier tb;
- tb.texture = dst_tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.dst_access = access;
- tb.prev_layout = RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
- tb.next_layout = dst_tex->layout;
- tb.subresources.aspect = RDD::TEXTURE_ASPECT_COLOR_BIT;
- tb.subresources.base_mipmap = dst_tex->base_mipmap;
- tb.subresources.mipmap_count = 1;
- tb.subresources.base_layer = dst_tex->base_layer;
- tb.subresources.layer_count = 1;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, stages, {}, {}, tb);
- }
- }
+ draw_graph.add_texture_resolve(src_tex->driver_id, src_tex->draw_tracker, dst_tex->driver_id, dst_tex->draw_tracker, src_tex->base_layer, src_tex->base_mipmap, dst_tex->base_layer, dst_tex->base_mipmap);
return OK;
}
-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, BitField p_post_barrier) {
+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) {
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.get_or_null(p_texture);
@@ -1939,33 +1548,6 @@ Error RenderingDevice::texture_clear(RID p_texture, const Color &p_color, uint32
ERR_FAIL_COND_V(p_base_mipmap + p_mipmaps > src_tex->mipmaps, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_base_layer + p_layers > src_layer_count, ERR_INVALID_PARAMETER);
- RDD::CommandBufferID command_buffer = frames[frame].draw_command_buffer;
-
- RDD::TextureLayout clear_layout = (src_tex->layout == RDD::TEXTURE_LAYOUT_GENERAL) ? RDD::TEXTURE_LAYOUT_GENERAL : RDD::TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL;
-
- // NOTE: Perhaps the valid stages/accesses for a given owner should be a property of the owner. (Here and places like _get_buffer_from_owner.)
- const BitField valid_texture_stages = RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT;
- constexpr BitField read_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT;
- constexpr BitField read_write_access = RDD::BARRIER_ACCESS_SHADER_READ_BIT | RDD::BARRIER_ACCESS_SHADER_WRITE_BIT;
- const BitField valid_texture_access = (src_tex->usage_flags & TEXTURE_USAGE_STORAGE_BIT) ? read_write_access : read_access;
-
- // Barrier from previous access with optional layout change (see clear_layout logic above).
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.src_access = valid_texture_access;
- tb.dst_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.prev_layout = src_tex->layout;
- tb.next_layout = clear_layout;
- tb.subresources.aspect = src_tex->read_aspect_flags;
- tb.subresources.base_mipmap = src_tex->base_mipmap + p_base_mipmap;
- tb.subresources.mipmap_count = p_mipmaps;
- tb.subresources.base_layer = src_tex->base_layer + p_base_layer;
- tb.subresources.layer_count = p_layers;
-
- driver->command_pipeline_barrier(command_buffer, valid_texture_stages, RDD::PIPELINE_STAGE_TRANSFER_BIT, {}, {}, tb);
- }
-
RDD::TextureSubresourceRange range;
range.aspect = src_tex->read_aspect_flags;
range.base_mipmap = src_tex->base_mipmap + p_base_mipmap;
@@ -1973,55 +1555,13 @@ Error RenderingDevice::texture_clear(RID p_texture, const Color &p_color, uint32
range.base_layer = src_tex->base_layer + p_base_layer;
range.layer_count = p_layers;
- driver->command_clear_color_texture(command_buffer, src_tex->driver_id, clear_layout, p_color, range);
-
- // Barrier to post clear accesses (changing back the layout if needed).
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- BitField stages;
- BitField access;
- if (p_post_barrier.has_flag(BARRIER_MASK_COMPUTE)) {
- stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_VERTEX)) {
- stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_FRAGMENT)) {
- stages.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_SHADER_READ_BIT).set_flag(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT);
- }
- if (p_post_barrier.has_flag(BARRIER_MASK_TRANSFER)) {
- stages.set_flag(RDD::PIPELINE_STAGE_TRANSFER_BIT);
- access.set_flag(RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT);
- }
-
- if (stages.is_empty()) {
- stages.set_flag(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
- }
-
- RDD::TextureBarrier tb;
- tb.texture = src_tex->driver_id;
- tb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- tb.dst_access = access;
- tb.prev_layout = clear_layout;
- tb.next_layout = src_tex->layout;
- tb.subresources.aspect = src_tex->read_aspect_flags;
- tb.subresources.base_mipmap = src_tex->base_mipmap + p_base_mipmap;
- tb.subresources.mipmap_count = p_mipmaps;
- tb.subresources.base_layer = src_tex->base_layer + p_base_layer;
- tb.subresources.layer_count = p_layers;
-
- driver->command_pipeline_barrier(command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, stages, {}, {}, tb);
-
- if (src_tex->used_in_frame != frames_drawn) {
- src_tex->used_in_raster = false;
- src_tex->used_in_compute = false;
- src_tex->used_in_frame = frames_drawn;
- }
- src_tex->used_in_transfer = true;
+ if (_texture_make_mutable(src_tex, p_texture)) {
+ // The texture must be mutable to be used as a clear destination.
+ draw_graph.add_synchronization();
}
+ draw_graph.add_texture_clear(src_tex->driver_id, src_tex->draw_tracker, p_color, range);
+
return OK;
}
@@ -2040,6 +1580,30 @@ 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 &p_attachments, const Vector &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 *r_samples) {
// NOTE:
// Before the refactor to RenderingDevice-RenderingDeviceDriver, there was commented out code to
@@ -2077,209 +1641,40 @@ RDD::RenderPassID RenderingDevice::_render_pass_create(const Vector samples;
- RDD::RenderPassID render_pass = _render_pass_create(p_attachments, p_passes, INITIAL_ACTION_CLEAR, FINAL_ACTION_READ, INITIAL_ACTION_CLEAR, FINAL_ACTION_READ, p_view_count, &samples); // Actions don't matter for this use case.
+ 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.
if (!render_pass) { // Was likely invalid.
return INVALID_ID;
@@ -2701,18 +2096,14 @@ RID RenderingDevice::vertex_buffer_create(uint32_t p_size_bytes, const Vectorbuffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU);
ERR_FAIL_COND_V(!buffer.driver_id, RID());
+ // Vertex buffers are assumed to be immutable unless they don't have initial data or they've been marked for storage explicitly.
+ if (p_data.is_empty() || p_use_as_storage) {
+ buffer.draw_tracker = RDG::resource_tracker_create();
+ buffer.draw_tracker->buffer_driver_id = buffer.driver_id;
+ }
+
if (p_data.size()) {
- uint64_t data_size = p_data.size();
- const uint8_t *r = p_data.ptr();
- _buffer_update(&buffer, 0, r, data_size);
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = buffer.driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = RDD::BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
- bb.size = data_size;
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT, {}, bb, {});
- }
+ _buffer_update(&buffer, RID(), 0, p_data.ptr(), p_data.size());
}
buffer_memory += buffer.size;
@@ -2809,6 +2200,12 @@ RID RenderingDevice::vertex_array_create(uint32_t p_vertex_count, VertexFormatID
}
vertex_array.buffers.push_back(buffer->driver_id);
+
+ if (buffer->draw_tracker != nullptr) {
+ vertex_array.draw_trackers.push_back(buffer->draw_tracker);
+ } else {
+ vertex_array.untracked_buffers.insert(p_src_buffers[i]);
+ }
}
RID id = vertex_array_owner.make_rid(vertex_array);
@@ -2863,18 +2260,14 @@ RID RenderingDevice::index_buffer_create(uint32_t p_index_count, IndexBufferForm
index_buffer.driver_id = driver->buffer_create(index_buffer.size, index_buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU);
ERR_FAIL_COND_V(!index_buffer.driver_id, RID());
+ // Index buffers are assumed to be immutable unless they don't have initial data.
+ if (p_data.is_empty()) {
+ index_buffer.draw_tracker = RDG::resource_tracker_create();
+ index_buffer.draw_tracker->buffer_driver_id = index_buffer.driver_id;
+ }
+
if (p_data.size()) {
- uint64_t data_size = p_data.size();
- const uint8_t *r = p_data.ptr();
- _buffer_update(&index_buffer, 0, r, data_size);
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = index_buffer.driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = RDD::BARRIER_ACCESS_INDEX_READ_BIT;
- bb.size = data_size;
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT, {}, bb, {});
- }
+ _buffer_update(&index_buffer, RID(), 0, p_data.ptr(), p_data.size());
}
buffer_memory += index_buffer.size;
@@ -2899,6 +2292,7 @@ RID RenderingDevice::index_array_create(RID p_index_buffer, uint32_t p_index_off
IndexArray index_array;
index_array.max_index = index_buffer->max_index;
index_array.driver_id = index_buffer->driver_id;
+ index_array.draw_tracker = index_buffer->draw_tracker;
index_array.offset = p_index_offset;
index_array.indices = p_index_count;
index_array.format = index_buffer->format;
@@ -2991,6 +2385,29 @@ RID RenderingDevice::shader_create_from_bytecode(const Vector &p_shader
shader->set_formats.push_back(format);
}
+ for (ShaderStage stage : shader_desc.stages) {
+ switch (stage) {
+ case SHADER_STAGE_VERTEX:
+ shader->stage_bits.set_flag(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT);
+ break;
+ case SHADER_STAGE_FRAGMENT:
+ shader->stage_bits.set_flag(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
+ break;
+ case SHADER_STAGE_TESSELATION_CONTROL:
+ shader->stage_bits.set_flag(RDD::PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
+ break;
+ case SHADER_STAGE_TESSELATION_EVALUATION:
+ shader->stage_bits.set_flag(RDD::PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT);
+ break;
+ case SHADER_STAGE_COMPUTE:
+ shader->stage_bits.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
+ break;
+ default:
+ DEV_ASSERT(false && "Unknown shader stage.");
+ break;
+ }
+ }
+
#ifdef DEV_ENABLED
set_resource_name(id, "RID:" + itos(id.get_id()));
#endif
@@ -3025,18 +2442,14 @@ RID RenderingDevice::uniform_buffer_create(uint32_t p_size_bytes, const Vectorbuffer_create(buffer.size, buffer.usage, RDD::MEMORY_ALLOCATION_TYPE_GPU);
ERR_FAIL_COND_V(!buffer.driver_id, RID());
+ // Uniform buffers are assumed to be immutable unless they don't have initial data.
+ if (p_data.is_empty()) {
+ buffer.draw_tracker = RDG::resource_tracker_create();
+ buffer.draw_tracker->buffer_driver_id = buffer.driver_id;
+ }
+
if (p_data.size()) {
- uint64_t data_size = p_data.size();
- const uint8_t *r = p_data.ptr();
- _buffer_update(&buffer, 0, r, data_size);
- if (driver->api_trait_get(RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS)) {
- RDD::BufferBarrier bb;
- bb.buffer = buffer.driver_id;
- bb.src_access = RDD::BARRIER_ACCESS_TRANSFER_WRITE_BIT;
- bb.dst_access = RDD::BARRIER_ACCESS_UNIFORM_READ_BIT;
- bb.size = data_size;
- driver->command_pipeline_barrier(frames[frame].setup_command_buffer, RDD::PIPELINE_STAGE_TRANSFER_BIT, RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT | RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT | RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT, {}, bb, {});
- }
+ _buffer_update(&buffer, RID(), 0, p_data.ptr(), p_data.size());
}
buffer_memory += buffer.size;
@@ -3073,8 +2486,9 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
// Used for verification to make sure a uniform set does not use a framebuffer bound texture.
LocalVector attachable_textures;
- Vector mutable_sampled_textures;
- Vector mutable_storage_textures;
+ Vector draw_trackers;
+ Vector draw_trackers_usage;
+ HashMap untracked_usage;
for (uint32_t i = 0; i < set_uniform_count; i++) {
const ShaderUniform &set_uniform = set_uniforms[i];
@@ -3126,7 +2540,8 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
RDD::SamplerID *sampler_driver_id = sampler_owner.get_or_null(uniform.get_id(j + 0));
ERR_FAIL_COND_V_MSG(!sampler_driver_id, RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ", index " + itos(j + 1) + ") is not a valid sampler.");
- Texture *texture = texture_owner.get_or_null(uniform.get_id(j + 1));
+ RID texture_id = uniform.get_id(j + 1);
+ Texture *texture = texture_owner.get_or_null(texture_id);
ERR_FAIL_NULL_V_MSG(texture, RID(), "Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture.");
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
@@ -3139,8 +2554,11 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
attachable_textures.push_back(attachable_texture);
}
- if ((texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT)) {
- mutable_sampled_textures.push_back(texture);
+ if (texture->draw_tracker != nullptr) {
+ draw_trackers.push_back(texture->draw_tracker);
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_TEXTURE_SAMPLE);
+ } else {
+ untracked_usage[texture_id] = RDG::RESOURCE_USAGE_TEXTURE_SAMPLE;
}
DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner));
@@ -3159,7 +2577,8 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
}
for (uint32_t j = 0; j < uniform.get_id_count(); j++) {
- Texture *texture = texture_owner.get_or_null(uniform.get_id(j));
+ RID texture_id = uniform.get_id(j);
+ Texture *texture = texture_owner.get_or_null(texture_id);
ERR_FAIL_NULL_V_MSG(texture, RID(), "Texture (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture.");
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT), RID(),
@@ -3172,8 +2591,11 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
attachable_textures.push_back(attachable_texture);
}
- if ((texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT)) {
- mutable_sampled_textures.push_back(texture);
+ if (texture->draw_tracker != nullptr) {
+ draw_trackers.push_back(texture->draw_tracker);
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_TEXTURE_SAMPLE);
+ } else {
+ untracked_usage[texture_id] = RDG::RESOURCE_USAGE_TEXTURE_SAMPLE;
}
DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner));
@@ -3191,7 +2613,8 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
}
for (uint32_t j = 0; j < uniform.get_id_count(); j++) {
- Texture *texture = texture_owner.get_or_null(uniform.get_id(j));
+ RID texture_id = uniform.get_id(j);
+ Texture *texture = texture_owner.get_or_null(texture_id);
ERR_FAIL_NULL_V_MSG(texture, RID(),
"Image (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture.");
@@ -3199,8 +2622,19 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
ERR_FAIL_COND_V_MSG(!(texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT), RID(),
"Image (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") needs the TEXTURE_USAGE_STORAGE_BIT usage flag set in order to be used as uniform.");
- if ((texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT)) {
- mutable_storage_textures.push_back(texture);
+ if (_texture_make_mutable(texture, texture_id)) {
+ // The texture must be mutable as a layout transition will be required.
+ draw_graph.add_synchronization();
+ }
+
+ if (texture->draw_tracker != nullptr) {
+ draw_trackers.push_back(texture->draw_tracker);
+
+ if (set_uniform.writable) {
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_STORAGE_IMAGE_READ_WRITE);
+ } else {
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_STORAGE_IMAGE_READ);
+ }
}
DEV_ASSERT(!texture->owner.is_valid() || texture_owner.get_or_null(texture->owner));
@@ -3218,9 +2652,27 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
}
for (uint32_t j = 0; j < uniform.get_id_count(); j++) {
- Buffer *buffer = texture_buffer_owner.get_or_null(uniform.get_id(j));
+ RID buffer_id = uniform.get_id(j);
+ Buffer *buffer = texture_buffer_owner.get_or_null(buffer_id);
ERR_FAIL_NULL_V_MSG(buffer, RID(), "Texture Buffer (binding: " + itos(uniform.binding) + ", index " + itos(j) + ") is not a valid texture buffer.");
+ if (set_uniform.writable && _buffer_make_mutable(buffer, buffer_id)) {
+ // The buffer must be mutable if it's used for writing.
+ draw_graph.add_synchronization();
+ }
+
+ if (buffer->draw_tracker != nullptr) {
+ draw_trackers.push_back(buffer->draw_tracker);
+
+ if (set_uniform.writable) {
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_TEXTURE_BUFFER_READ_WRITE);
+ } else {
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_TEXTURE_BUFFER_READ);
+ }
+ } else {
+ untracked_usage[buffer_id] = RDG::RESOURCE_USAGE_TEXTURE_BUFFER_READ;
+ }
+
driver_uniform.ids.push_back(buffer->driver_id);
}
} break;
@@ -3237,9 +2689,17 @@ RID RenderingDevice::uniform_set_create(const Vector &p_uniforms, RID p
RDD::SamplerID *sampler_driver_id = sampler_owner.get_or_null(uniform.get_id(j + 0));
ERR_FAIL_COND_V_MSG(!sampler_driver_id, RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ", index " + itos(j + 1) + ") is not a valid sampler.");
- Buffer *buffer = texture_buffer_owner.get_or_null(uniform.get_id(j + 1));
+ RID buffer_id = uniform.get_id(j + 1);
+ Buffer *buffer = texture_buffer_owner.get_or_null(buffer_id);
ERR_FAIL_NULL_V_MSG(buffer, RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ", index " + itos(j + 1) + ") is not a valid texture buffer.");
+ if (buffer->draw_tracker != nullptr) {
+ draw_trackers.push_back(buffer->draw_tracker);
+ draw_trackers_usage.push_back(RDG::RESOURCE_USAGE_TEXTURE_BUFFER_READ);
+ } else {
+ untracked_usage[buffer_id] = RDG::RESOURCE_USAGE_TEXTURE_BUFFER_READ;
+ }
+
driver_uniform.ids.push_back(*sampler_driver_id);
driver_uniform.ids.push_back(buffer->driver_id);
}
@@ -3251,12 +2711,20 @@ RID RenderingDevice::uniform_set_create(const Vector