summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorSen <seniltai@gmail.com>2024-08-08 08:14:43 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-09-16 17:19:58 +0200
commite5be133032cba65d78ac26d7bb8b623f8663010c (patch)
tree77fe1b794ed1699fc91b52203da19d1fc36b21fd /servers
parent0f33a4b97ede3821495b24df70375cb61a779cb4 (diff)
downloadredot-engine-e5be133032cba65d78ac26d7bb8b623f8663010c.tar.gz
Fix for multimesh motion vector corruption by resetting motion vector state and filling both halves of buffer
(cherry picked from commit 52cd5acdda120776775e73babf3fbb65ef0a5c2e)
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 057c045081..a95c4ec83a 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -1440,12 +1440,10 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
multimesh->motion_vectors_current_offset = 0;
multimesh->motion_vectors_previous_offset = 0;
multimesh->motion_vectors_last_change = -1;
+ multimesh->motion_vectors_enabled = false;
if (multimesh->instances) {
uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float);
- if (multimesh->motion_vectors_enabled) {
- buffer_size *= 2;
- }
multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size);
}
@@ -1935,6 +1933,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
ERR_FAIL_NULL(multimesh);
ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
+ bool used_motion_vectors = multimesh->motion_vectors_enabled;
bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0) || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
if (uses_motion_vectors) {
_multimesh_enable_motion_vectors(multimesh);
@@ -1953,6 +1952,11 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
{
const float *r = p_buffer.ptr();
RD::get_singleton()->buffer_update(multimesh->buffer, multimesh->motion_vectors_current_offset * multimesh->stride_cache * sizeof(float), p_buffer.size() * sizeof(float), r);
+ if (multimesh->motion_vectors_enabled && !used_motion_vectors) {
+ // Motion vectors were just enabled, and the other half of the buffer will be empty.
+ // Need to ensure that both halves are filled for correct operation.
+ RD::get_singleton()->buffer_update(multimesh->buffer, multimesh->motion_vectors_previous_offset * multimesh->stride_cache * sizeof(float), p_buffer.size() * sizeof(float), r);
+ }
multimesh->buffer_set = true;
}