Fix for multimesh motion vector corruption by resetting motion vector state and filling both halves of buffer

This commit is contained in:
Sen 2024-08-08 08:14:43 +02:00 committed by Leroy Sikkes
parent 9221294653
commit 52cd5acdda
1 changed files with 7 additions and 3 deletions

View File

@ -1439,12 +1439,10 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
multimesh->motion_vectors_current_offset = 0; multimesh->motion_vectors_current_offset = 0;
multimesh->motion_vectors_previous_offset = 0; multimesh->motion_vectors_previous_offset = 0;
multimesh->motion_vectors_last_change = -1; multimesh->motion_vectors_last_change = -1;
multimesh->motion_vectors_enabled = false;
if (multimesh->instances) { if (multimesh->instances) {
uint32_t buffer_size = multimesh->instances * multimesh->stride_cache * sizeof(float); 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); multimesh->buffer = RD::get_singleton()->storage_buffer_create(buffer_size);
} }
@ -1934,6 +1932,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
ERR_FAIL_NULL(multimesh); ERR_FAIL_NULL(multimesh);
ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache)); 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); 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) { if (uses_motion_vectors) {
_multimesh_enable_motion_vectors(multimesh); _multimesh_enable_motion_vectors(multimesh);
@ -1952,6 +1951,11 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
{ {
const float *r = p_buffer.ptr(); 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); 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; multimesh->buffer_set = true;
} }