1
0
Fork 0

Merge pull request #102454 from DarioSamo/rd-async-fixes

Fix erroneous logic when flushes are involved on RD async methods.
This commit is contained in:
Thaddeus Crews 2025-02-05 10:27:27 -06:00
commit 2687833dec
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
24 changed files with 134 additions and 75 deletions

View File

@ -74,7 +74,7 @@ jobs:
artifact: false
cache-limit: 5
- name: Template w/ Mono (target=template_release, tests=yes)
- name: Template w/ Mono, release (target=template_release, tests=yes)
cache-name: linux-template-mono
target: template_release
sconsflags: module_mono_enabled=yes
@ -84,6 +84,16 @@ jobs:
artifact: true
cache-limit: 1
- name: Template w/ Mono, debug (target=template_debug, tests=yes)
cache-name: linux-template-mono-debug
target: template_debug
sconsflags: module_mono_enabled=yes
bin: ./bin/godot.linuxbsd.template_debug.x86_64.mono
build-mono: false
tests: true
artifact: true
cache-limit: 1
- name: Minimal template (target=template_release, tests=yes, everything disabled)
cache-name: linux-template-minimal
target: template_release

View File

@ -535,7 +535,7 @@
<description>
Returns [code]true[/code] if the node is present in the [SceneTree], its [member visible] property is [code]true[/code] and all its ancestors are also visible. If any ancestor is hidden, this node will not be visible in the scene tree, and is therefore not drawn (see [method _draw]).
Visibility is checked only in parent nodes that inherit from [CanvasItem], [CanvasLayer], and [Window]. If the parent is of any other type (such as [Node], [AnimationPlayer], or [Node3D]), it is assumed to be visible.
[b]Note:[/b] This method does not take [member visibility_layer] into account, so even if this method returns [code]true[/code] the node might end up not being rendered.
[b]Note:[/b] This method does not take [member visibility_layer] into account, so even if this method returns [code]true[/code], the node might end up not being rendered.
</description>
</method>
<method name="make_canvas_position_local" qualifiers="const">

View File

@ -117,6 +117,8 @@
<return type="bool" />
<description>
Returns [code]true[/code] if the node is present in the [SceneTree], its [member visible] property is [code]true[/code] and all its ancestors are also visible. If any ancestor is hidden, this node will not be visible in the scene tree.
Visibility is checked only in parent nodes that inherit from [Node3D]. If the parent is of any other type (such as [Node], [AnimationPlayer], or [Node2D]), it is assumed to be visible.
[b]Note:[/b] This method does not take [member VisualInstance3D.layers] into account, so even if this method returns [code]true[/code], the node might end up not being rendered.
</description>
</method>
<method name="look_at">

View File

@ -93,6 +93,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MetalFeatures {
bool needs_arg_encoders = true;
bool metal_fx_spatial = false; /**< If true, Metal FX spatial functions are supported. */
bool metal_fx_temporal = false; /**< If true, Metal FX temporal functions are supported. */
bool supports_gpu_address = false; /**< If true, referencing a GPU address in a shader is supported. */
};
struct MetalLimits {

View File

@ -99,6 +99,10 @@ void MetalDeviceProperties::init_features(id<MTLDevice> p_device) {
features.supports32BitMSAA = p_device.supports32BitMSAA;
}
if (@available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) {
features.supports_gpu_address = true;
}
features.hostMemoryPageSize = sysconf(_SC_PAGESIZE);
for (SampleCount sc = SampleCount1; sc <= SampleCount64; sc <<= 1) {

View File

@ -65,7 +65,6 @@
#import <zlib.h>
#import <initializer_list>
#import <optional>
#import <spirv.hpp>
// These types can be used in Vector and other containers that use
// pointer operations not supported by ARC.
@ -563,7 +562,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) BindingInfo {
MTLBindingAccess access = MTLBindingAccessReadOnly;
MTLResourceUsage usage = 0;
MTLTextureType textureType = MTLTextureType2D;
spv::ImageFormat imageFormat = spv::ImageFormatUnknown;
int imageFormat = 0;
uint32_t arrayLength = 0;
bool isMultisampled = false;

View File

@ -164,6 +164,9 @@ uint64_t RenderingDeviceDriverMetal::buffer_get_device_address(BufferID p_buffer
id<MTLBuffer> obj = rid::get(p_buffer);
return obj.gpuAddress;
} else {
#if DEV_ENABLED
WARN_PRINT_ONCE("buffer_get_device_address is not supported on this OS version.");
#endif
return 0;
}
}
@ -355,7 +358,7 @@ RDD::TextureID RenderingDeviceDriverMetal::texture_create(const TextureFormat &p
// Check if it is a linear format for atomic operations and therefore needs a buffer,
// as generally Metal does not support atomic operations on textures.
bool needs_buffer = is_linear || (p_format.array_layers == 1 && p_format.mipmaps == 1 && p_format.texture_type == TEXTURE_TYPE_2D && flags::any(p_format.usage_bits, TEXTURE_USAGE_STORAGE_BIT) && (p_format.format == DATA_FORMAT_R32_UINT || p_format.format == DATA_FORMAT_R32_SINT));
bool needs_buffer = is_linear || (p_format.array_layers == 1 && p_format.mipmaps == 1 && p_format.texture_type == TEXTURE_TYPE_2D && flags::any(p_format.usage_bits, TEXTURE_USAGE_STORAGE_BIT) && (p_format.format == DATA_FORMAT_R32_UINT || p_format.format == DATA_FORMAT_R32_SINT || p_format.format == DATA_FORMAT_R32G32_UINT || p_format.format == DATA_FORMAT_R32G32_SINT));
id<MTLTexture> obj = nil;
if (needs_buffer) {
@ -2033,10 +2036,6 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec
CompilerMSL::Options msl_options{};
msl_options.set_msl_version(version_major, version_minor);
if (version_major == 3 && version_minor >= 1) {
// TODO(sgc): Restrict to Metal 3.0 for now, until bugs in SPIRV-cross image atomics are resolved.
msl_options.set_msl_version(3, 0);
}
bin_data.msl_version = msl_options.msl_version;
#if TARGET_OS_OSX
msl_options.platform = CompilerMSL::Options::macOS;
@ -2063,9 +2062,9 @@ Vector<uint8_t> RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec
msl_options.argument_buffers = false;
bin_data.set_uses_argument_buffers(false);
}
msl_options.force_active_argument_buffer_resources = true; // Same as MoltenVK when using argument buffers.
// msl_options.pad_argument_buffer_resources = true; // Same as MoltenVK when using argument buffers.
msl_options.force_active_argument_buffer_resources = true;
// We can't use this, as we have to add the descriptor sets via compiler.add_msl_resource_binding.
// msl_options.pad_argument_buffer_resources = true;
msl_options.texture_buffer_native = true; // Enable texture buffer support.
msl_options.use_framebuffer_fetch_subpasses = false;
msl_options.pad_fragment_output_components = true;
@ -4036,7 +4035,7 @@ bool RenderingDeviceDriverMetal::has_feature(Features p_feature) {
case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS:
return true;
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
return false;
return device_properties->features.supports_gpu_address;
case SUPPORTS_METALFX_SPATIAL:
return device_properties->features.metal_fx_spatial;
case SUPPORTS_METALFX_TEMPORAL:

View File

@ -605,7 +605,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
file_popup->add_separator();
file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_LIBRARY);
Rect2 pos = tree->get_item_rect(p_item, 1, 0);
Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll();
Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height));
file_popup->popup(Rect2(popup_pos, Size2()));
file_dialog_animation = StringName();
@ -645,7 +645,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int
file_popup->add_separator();
file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_ANIMATION);
Rect2 pos = tree->get_item_rect(p_item, 1, 0);
Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll();
Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height));
file_popup->popup(Rect2(popup_pos, Size2()));
file_dialog_animation = anim_name;

View File

@ -623,7 +623,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
return;
}
xform = vp->get_popup_base_transform();
if (!vp->get_visible_rect().has_point(xform.xform_inv(p_pos))) {
if (!vp->get_visible_rect().has_point(xform.affine_inverse().xform(p_pos))) {
return;
}
}
@ -726,7 +726,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
return;
}
xform = vp->get_popup_base_transform();
if (!vp->get_visible_rect().intersects(xform.xform_inv(p_rect))) {
if (!vp->get_visible_rect().intersects(xform.affine_inverse().xform(p_rect))) {
return;
}
}

View File

@ -261,6 +261,11 @@ void WindowWrapper::restore_window_from_saved_position(const Rect2 p_window_rect
window_rect = Rect2i(window_rect.position * screen_ratio, window_rect.size * screen_ratio);
window_rect.position += real_screen_rect.position;
// Make sure to restore the window if the user minimized it the last time it was displayed.
if (window->get_mode() == Window::MODE_MINIMIZED) {
window->set_mode(Window::MODE_WINDOWED);
}
// All good, restore the window.
window->set_current_screen(p_screen);
if (window->is_visible()) {

View File

@ -1075,26 +1075,6 @@ void GDScript::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new"));
}
void GDScript::set_path_cache(const String &p_path) {
if (ResourceCache::has(p_path)) {
set_path(p_path, true);
return;
}
if (is_root_script()) {
Script::set_path_cache(p_path);
}
String old_path = path;
path = p_path;
path_valid = true;
GDScriptCache::move_script(old_path, p_path);
for (KeyValue<StringName, Ref<GDScript>> &kv : subclasses) {
kv.value->set_path_cache(p_path);
}
}
void GDScript::set_path(const String &p_path, bool p_take_over) {
if (is_root_script()) {
Script::set_path(p_path, p_take_over);

View File

@ -309,7 +309,6 @@ public:
virtual Error reload(bool p_keep_state = false) override;
virtual void set_path_cache(const String &p_path) override;
virtual void set_path(const String &p_path, bool p_take_over = false) override;
String get_script_path() const;
Error load_source_code(const String &p_path);

View File

@ -312,7 +312,7 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, Error &r_e
Ref<GDScript> script;
script.instantiate();
script->set_path_cache(p_path);
script->set_path(p_path, true);
if (remapped_path.get_extension().to_lower() == "gdc") {
Vector<uint8_t> buffer = get_binary_tokens(remapped_path);
if (buffer.is_empty()) {
@ -360,7 +360,6 @@ Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_erro
return script;
}
}
script->set_path(p_path, true);
const String remapped_path = ResourceLoader::path_remap(p_path);

View File

@ -648,7 +648,7 @@ void trace_direct_light(vec3 p_position, vec3 p_normal, uint p_light_index, bool
}
r_shadow = penumbra;
r_light = light_data.color * light_data.energy * attenuation * penumbra * penumbra_color;
r_light = light_data.energy * attenuation * penumbra * penumbra_color;
}
#endif

View File

@ -1377,8 +1377,6 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
}
if (desktop_valid) {
use_simple_method = false;
// Handle bad window errors silently because there's no other way to check
// that one of the windows has been destroyed in the meantime.
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler);
@ -1406,6 +1404,8 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
}
}
if (!g_bad_window && strut_found && (format == 32) && (strut_len >= 4) && strut_data) {
use_simple_method = false;
long *struts = (long *)strut_data;
long left = struts[0];
@ -4767,6 +4767,13 @@ void DisplayServerX11::process_events() {
// Have we failed to set fullscreen while the window was unmapped?
_validate_mode_on_map(window_id);
// On KDE Plasma, when the parent window of an embedded process is restored after being minimized,
// only the embedded window receives the Map notification, causing it to
// appear without its parent.
if (wd.embed_parent) {
XMapWindow(x11_display, wd.embed_parent);
}
} break;
case Expose: {

View File

@ -597,7 +597,7 @@ void CPUParticles2D::_validate_property(PropertyInfo &p_property) const {
}
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
p_property.usage = PROPERTY_USAGE_NONE;
}
}
@ -1392,6 +1392,8 @@ void CPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
ADD_PROPERTY_DEFAULT("seed", 0);
////////////////////////////////
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles2D::set_direction);
@ -1561,6 +1563,7 @@ CPUParticles2D::CPUParticles2D() {
set_emitting(true);
set_amount(8);
set_use_local_coordinates(false);
set_seed(Math::rand());
rng.instantiate();

View File

@ -408,7 +408,7 @@ Ref<Texture2D> GPUParticles2D::get_texture() const {
void GPUParticles2D::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
p_property.usage = PROPERTY_USAGE_NONE;
}
if (p_property.name == "emitting") {
p_property.hint = one_shot ? PROPERTY_HINT_ONESHOT : PROPERTY_HINT_NONE;
@ -899,6 +899,8 @@ void GPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY);
BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR);
BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM);
ADD_PROPERTY_DEFAULT("seed", 0);
}
GPUParticles2D::GPUParticles2D() {
@ -912,8 +914,8 @@ GPUParticles2D::GPUParticles2D() {
one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
set_emitting(true);
set_one_shot(false);
set_seed(Math::rand());
set_use_fixed_seed(false);
set_seed(0);
set_amount(8);
set_amount_ratio(1.0);
set_lifetime(1);

View File

@ -612,7 +612,7 @@ void CPUParticles3D::_validate_property(PropertyInfo &p_property) const {
}
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
p_property.usage = PROPERTY_USAGE_NONE;
}
}
@ -1564,6 +1564,8 @@ void CPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH);
ADD_PROPERTY_DEFAULT("seed", 0);
////////////////////////////////
ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles3D::set_direction);
@ -1764,6 +1766,7 @@ CPUParticles3D::CPUParticles3D() {
set_emitting(true);
set_amount(8);
set_seed(Math::rand());
rng.instantiate();

View File

@ -464,7 +464,7 @@ void GPUParticles3D::_validate_property(PropertyInfo &p_property) const {
}
}
if (p_property.name == "seed" && !use_fixed_seed) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
p_property.usage = PROPERTY_USAGE_NONE;
}
}
@ -868,6 +868,8 @@ void GPUParticles3D::_bind_methods() {
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD);
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Y_TO_VELOCITY);
BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY);
ADD_PROPERTY_DEFAULT("seed", 0);
}
GPUParticles3D::GPUParticles3D() {
@ -877,6 +879,7 @@ GPUParticles3D::GPUParticles3D() {
one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
set_emitting(true);
set_one_shot(false);
set_seed(Math::rand());
set_amount_ratio(1.0);
set_amount(8);
set_lifetime(1);
@ -895,7 +898,6 @@ GPUParticles3D::GPUParticles3D() {
set_collision_base_size(collision_base_size);
set_transform_align(TRANSFORM_ALIGN_DISABLED);
set_use_fixed_seed(false);
set_seed(0);
}
GPUParticles3D::~GPUParticles3D() {

View File

@ -410,7 +410,7 @@ class AnimationNodeBlendTree : public AnimationRootNode {
Vector<StringName> connections;
};
AHashMap<StringName, Node> nodes;
RBMap<StringName, Node, StringName::AlphCompare> nodes;
Vector2 graph_offset;

View File

@ -306,8 +306,8 @@ private:
uint64_t last_pass = 0;
real_t activity = 0.0;
};
mutable AHashMap<StringName, LocalVector<Activity>> input_activity_map;
mutable AHashMap<StringName, LocalVector<Activity> *> input_activity_map_get;
mutable HashMap<StringName, LocalVector<Activity>> input_activity_map;
mutable HashMap<StringName, LocalVector<Activity> *> input_activity_map_get;
NodePath animation_player;

View File

@ -5208,10 +5208,12 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const {
}
int ofs = get_item_offset(p_item);
int height = compute_item_height(p_item);
int height = compute_item_height(p_item) + theme_cache.v_separation;
Rect2 r;
r.position.y = ofs;
r.position.y = ofs - theme_cache.offset.y + theme_cache.panel_style->get_offset().y;
r.size.height = height;
bool rtl = is_layout_rtl();
const Rect2 content_rect = _get_content_rect();
if (p_column == -1) {
r.position.x = 0;
@ -5221,18 +5223,45 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const {
for (int i = 0; i < p_column; i++) {
accum += get_column_width(i);
}
r.position.x = accum;
r.position.x = (rtl) ? get_size().x - (accum - theme_cache.offset.x) - get_column_width(p_column) - theme_cache.panel_style->get_margin(SIDE_LEFT) : accum - theme_cache.offset.x + theme_cache.panel_style->get_margin(SIDE_LEFT);
r.size.x = get_column_width(p_column);
if (p_button != -1) {
// RTL direction support for button rect is different due to buttons not
// having same behavior as they do in LTR when tree is scrolled.
const TreeItem::Cell &c = p_item->cells[p_column];
Vector2 ofst = Vector2(r.position.x + r.size.x, r.position.y);
Vector2 ofst = Vector2(r.position.x + r.size.x + theme_cache.button_margin, r.position.y);
// Compute total width of buttons block including spacings.
int buttons_width = 0;
for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = c.buttons[j].texture;
Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size();
ofst.x -= size.x;
buttons_width += size.width + theme_cache.button_margin;
}
for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = c.buttons[j].texture;
Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size();
ofst.x -= size.x + theme_cache.button_margin;
if (rtl) {
if (j == p_button) {
return Rect2(r.position, Size2(size.x, r.size.y));
}
r.position.x += size.x + theme_cache.button_margin;
continue;
}
if (j == p_button) {
return Rect2(ofst, size);
float content_rect_end_x = content_rect.position.x + content_rect.size.width;
if (r.position.x + r.size.x < content_rect_end_x) {
return Rect2(ofst, Size2(size.x, r.size.y));
}
// Button block can be outside of content_rect
if (content_rect_end_x - (r.position.x + theme_cache.h_separation) < buttons_width) {
return Rect2(r.position + Point2(theme_cache.h_separation + (buttons_width - ((r.position.x + r.size.x) - ofst.x)), 0), Size2(size.x, r.size.y));
}
return Rect2(ofst - Vector2((r.position.x + r.size.x) - content_rect_end_x, 0), Size2(size.x, r.size.y));
}
}
}

View File

@ -344,7 +344,7 @@ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_
}
}
_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::Scalar> &value, uint8_t *data) {
_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::Scalar> &value, uint8_t *data, bool p_use_linear_color) {
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
uint32_t *gui = (uint32_t *)data;
@ -441,18 +441,28 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_VEC3: {
Color c = Color(value[0].real, value[1].real, value[2].real);
if (p_use_linear_color) {
c = c.srgb_to_linear();
}
float *gui = reinterpret_cast<float *>(data);
for (int i = 0; i < 3; i++) {
gui[i] = value[i].real;
gui[i] = c.components[i];
}
} break;
case ShaderLanguage::TYPE_VEC4: {
Color c = Color(value[0].real, value[1].real, value[2].real, value[3].real);
if (p_use_linear_color) {
c = c.srgb_to_linear();
}
float *gui = reinterpret_cast<float *>(data);
for (int i = 0; i < 4; i++) {
gui[i] = value[i].real;
gui[i] = c.components[i];
}
} break;
case ShaderLanguage::TYPE_MAT2: {
@ -789,7 +799,7 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa
} else if (E.value.default_value.size()) {
//default value
_fill_std140_ubo_value(E.value.type, E.value.default_value, data);
_fill_std140_ubo_value(E.value.type, E.value.default_value, data, p_use_linear_color);
//value=E.value.default_value;
} else {
//zero because it was not provided

View File

@ -721,7 +721,6 @@ Error RenderingDevice::buffer_get_data_async(RID p_buffer, const Callable &p_cal
_check_transfer_worker_buffer(buffer);
BufferGetDataRequest get_data_request;
uint32_t flushed_copies = 0;
get_data_request.callback = p_callback;
get_data_request.frame_local_index = frames[frame].download_buffer_copy_regions.size();
get_data_request.size = p_size;
@ -738,22 +737,26 @@ Error RenderingDevice::buffer_get_data_async(RID p_buffer, const Callable &p_cal
return err;
}
if ((get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL) {
const bool flush_frames = (get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL;
if (flush_frames) {
if (_buffer_make_mutable(buffer, p_buffer)) {
// The buffer must be mutable to be used as a copy source.
draw_graph.add_synchronization();
}
for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) {
for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) {
uint32_t local_index = get_data_request.frame_local_index + i;
draw_graph.add_buffer_get_data(buffer->driver_id, buffer->draw_tracker, frames[frame].download_buffer_staging_buffers[local_index], frames[frame].download_buffer_copy_regions[local_index]);
}
flushed_copies = get_data_request.frame_local_count;
}
_staging_buffer_execute_required_action(download_staging_buffers, required_action);
if (flush_frames) {
get_data_request.frame_local_count = 0;
get_data_request.frame_local_index = frames[frame].download_buffer_copy_regions.size();
}
RDD::BufferCopyRegion region;
region.src_offset = submit_from + p_offset;
region.dst_offset = block_write_offset;
@ -775,7 +778,7 @@ Error RenderingDevice::buffer_get_data_async(RID p_buffer, const Callable &p_cal
draw_graph.add_synchronization();
}
for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) {
for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) {
uint32_t local_index = get_data_request.frame_local_index + i;
draw_graph.add_buffer_get_data(buffer->driver_id, buffer->draw_tracker, frames[frame].download_buffer_staging_buffers[local_index], frames[frame].download_buffer_copy_regions[local_index]);
}
@ -2098,7 +2101,6 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c
uint32_t block_write_offset;
uint32_t block_write_amount;
StagingRequiredAction required_action;
uint32_t flushed_copies = 0;
for (uint32_t i = 0; i < tex->mipmaps; i++) {
uint32_t image_total = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, i + 1, &w, &h, &d);
uint32_t tight_mip_size = image_total - mipmap_offset;
@ -2119,17 +2121,21 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c
Error err = _staging_buffer_allocate(download_staging_buffers, to_allocate, required_align, block_write_offset, block_write_amount, required_action, false);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
if ((get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL) {
for (uint32_t j = flushed_copies; j < get_data_request.frame_local_count; j++) {
const bool flush_frames = (get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL;
if (flush_frames) {
for (uint32_t j = 0; j < get_data_request.frame_local_count; j++) {
uint32_t local_index = get_data_request.frame_local_index + j;
draw_graph.add_texture_get_data(tex->driver_id, tex->draw_tracker, frames[frame].download_texture_staging_buffers[local_index], frames[frame].download_buffer_texture_copy_regions[local_index]);
}
flushed_copies = get_data_request.frame_local_count;
}
_staging_buffer_execute_required_action(download_staging_buffers, required_action);
if (flush_frames) {
get_data_request.frame_local_count = 0;
get_data_request.frame_local_index = frames[frame].download_buffer_texture_copy_regions.size();
}
RDD::BufferTextureCopyRegion copy_region;
copy_region.buffer_offset = block_write_offset;
copy_region.texture_subresources.aspect = tex->read_aspect_flags;
@ -2154,12 +2160,11 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c
}
if (get_data_request.frame_local_count > 0) {
for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) {
for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) {
uint32_t local_index = get_data_request.frame_local_index + i;
draw_graph.add_texture_get_data(tex->driver_id, tex->draw_tracker, frames[frame].download_texture_staging_buffers[local_index], frames[frame].download_buffer_texture_copy_regions[local_index]);
}
flushed_copies = get_data_request.frame_local_count;
frames[frame].download_texture_get_data_requests.push_back(get_data_request);
}