From 9af4c09d1bff53aca380d8e39d93490b3cc33f1a Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Fri, 1 May 2020 09:55:47 +0100 Subject: [PATCH] Fix uninitialized memory in CPUParticles2D Calls to set_amount can increase the size of the particle array, but do not zero the memory, they only set the active flag to false. This uninitialized memory can be sent to the GPU, possibly as NaNs. --- scene/2d/cpu_particles_2d.cpp | 34 ++++++++++++++++++---------------- scene/2d/cpu_particles_2d.h | 2 ++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index acb1b0b5a02..10d186c0adb 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -53,9 +53,11 @@ void CPUParticles2D::set_amount(int p_amount) { { PoolVector::Write w = particles.write(); - for (int i = 0; i < p_amount; i++) { - w[i].active = false; - } + // each particle must be set to false + // zeroing the data also prevents uninitialized memory being sent to GPU + zeromem(static_cast(&w[0]), p_amount * sizeof(Particle)); + // cast to prevent compiler warning .. note this relies on Particle not containing any complex types. + // an alternative is to use some zero method per item but the generated code will be far less efficient. } particle_data.resize((8 + 4 + 1) * p_amount); @@ -1020,22 +1022,22 @@ void CPUParticles2D::_update_particle_data_buffer() { ptr[6] = 0; ptr[7] = t.elements[2][1]; + Color c = r[idx].color; + uint8_t *data8 = (uint8_t *)&ptr[8]; + data8[0] = CLAMP(c.r * 255.0, 0, 255); + data8[1] = CLAMP(c.g * 255.0, 0, 255); + data8[2] = CLAMP(c.b * 255.0, 0, 255); + data8[3] = CLAMP(c.a * 255.0, 0, 255); + + ptr[9] = r[idx].custom[0]; + ptr[10] = r[idx].custom[1]; + ptr[11] = r[idx].custom[2]; + ptr[12] = r[idx].custom[3]; + } else { - zeromem(ptr, sizeof(float) * 8); + zeromem(ptr, sizeof(float) * 13); } - Color c = r[idx].color; - uint8_t *data8 = (uint8_t *)&ptr[8]; - data8[0] = CLAMP(c.r * 255.0, 0, 255); - data8[1] = CLAMP(c.g * 255.0, 0, 255); - data8[2] = CLAMP(c.b * 255.0, 0, 255); - data8[3] = CLAMP(c.a * 255.0, 0, 255); - - ptr[9] = r[idx].custom[0]; - ptr[10] = r[idx].custom[1]; - ptr[11] = r[idx].custom[2]; - ptr[12] = r[idx].custom[3]; - ptr += 13; } } diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index d59b94bcbba..8f8f4cfcca6 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -81,6 +81,8 @@ public: private: bool emitting; + // warning - beware of adding non-trivial types + // to this structure as it is zeroed to initialize in set_amount() struct Particle { Transform2D transform; Color color;