Fix errors when freeing GPUParticles

This commit is contained in:
bitsawer 2023-09-27 11:46:06 +03:00
parent 545d1c0adb
commit 898d1a2d5f
4 changed files with 30 additions and 23 deletions

View File

@ -94,13 +94,15 @@ RID ParticlesStorage::particles_allocate() {
} }
void ParticlesStorage::particles_initialize(RID p_rid) { void ParticlesStorage::particles_initialize(RID p_rid) {
particles_owner.initialize_rid(p_rid, Particles()); particles_owner.initialize_rid(p_rid);
} }
void ParticlesStorage::particles_free(RID p_rid) { void ParticlesStorage::particles_free(RID p_rid) {
update_particles();
Particles *particles = particles_owner.get_or_null(p_rid); Particles *particles = particles_owner.get_or_null(p_rid);
particles->dependency.deleted_notify(p_rid); particles->dependency.deleted_notify(p_rid);
particles->update_list.remove_from_list();
_particles_free_data(particles); _particles_free_data(particles);
particles_owner.free(p_rid); particles_owner.free(p_rid);
} }
@ -355,8 +357,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) {
if (!particles->dirty) { if (!particles->dirty) {
particles->dirty = true; particles->dirty = true;
particles->update_list = particle_update_list;
particle_update_list = particles; if (!particles->update_list.in_list()) {
particle_update_list.add(&particles->update_list);
}
} }
} }
@ -978,13 +982,12 @@ void ParticlesStorage::update_particles() {
glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer); glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0);
while (particle_update_list) { while (particle_update_list.first()) {
// Use transform feedback to process particles. // Use transform feedback to process particles.
Particles *particles = particle_update_list; Particles *particles = particle_update_list.first()->self();
particle_update_list = particles->update_list; particles->update_list.remove_from_list();
particles->update_list = nullptr;
particles->dirty = false; particles->dirty = false;
_particles_update_buffers(particles); _particles_update_buffers(particles);

View File

@ -209,7 +209,7 @@ private:
uint32_t userdata_count = 0; uint32_t userdata_count = 0;
bool dirty = false; bool dirty = false;
Particles *update_list = nullptr; SelfList<Particles> update_list;
double phase = 0.0; double phase = 0.0;
double prev_phase = 0.0; double prev_phase = 0.0;
@ -237,7 +237,8 @@ private:
double trail_length = 1.0; double trail_length = 1.0;
bool trails_enabled = false; bool trails_enabled = false;
Particles() { Particles() :
update_list(this) {
} }
}; };
@ -259,7 +260,7 @@ private:
RID copy_shader_version; RID copy_shader_version;
} particles_shader; } particles_shader;
Particles *particle_update_list = nullptr; SelfList<Particles>::List particle_update_list;
mutable RID_Owner<Particles, true> particles_owner; mutable RID_Owner<Particles, true> particles_owner;

View File

@ -221,13 +221,15 @@ RID ParticlesStorage::particles_allocate() {
} }
void ParticlesStorage::particles_initialize(RID p_rid) { void ParticlesStorage::particles_initialize(RID p_rid) {
particles_owner.initialize_rid(p_rid, Particles()); particles_owner.initialize_rid(p_rid);
} }
void ParticlesStorage::particles_free(RID p_rid) { void ParticlesStorage::particles_free(RID p_rid) {
update_particles();
Particles *particles = particles_owner.get_or_null(p_rid); Particles *particles = particles_owner.get_or_null(p_rid);
particles->dependency.deleted_notify(p_rid); particles->dependency.deleted_notify(p_rid);
particles->update_list.remove_from_list();
_particles_free_data(particles); _particles_free_data(particles);
particles_owner.free(p_rid); particles_owner.free(p_rid);
} }
@ -577,8 +579,10 @@ void ParticlesStorage::particles_request_process(RID p_particles) {
if (!particles->dirty) { if (!particles->dirty) {
particles->dirty = true; particles->dirty = true;
particles->update_list = particle_update_list;
particle_update_list = particles; if (!particles->update_list.in_list()) {
particle_update_list.add(&particles->update_list);
}
} }
} }
@ -1345,14 +1349,12 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
void ParticlesStorage::update_particles() { void ParticlesStorage::update_particles() {
uint32_t frame = RSG::rasterizer->get_frame_number(); uint32_t frame = RSG::rasterizer->get_frame_number();
bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0; bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;
while (particle_update_list) { while (particle_update_list.first()) {
//use transform feedback to process particles //use transform feedback to process particles
Particles *particles = particle_update_list; Particles *particles = particle_update_list.first()->self();
//take and remove particles->update_list.remove_from_list();
particle_update_list = particles->update_list;
particles->update_list = nullptr;
particles->dirty = false; particles->dirty = false;
_particles_update_buffers(particles); _particles_update_buffers(particles);

View File

@ -206,7 +206,7 @@ private:
RID particles_sort_uniform_set; RID particles_sort_uniform_set;
bool dirty = false; bool dirty = false;
Particles *update_list = nullptr; SelfList<Particles> update_list;
RID sub_emitter; RID sub_emitter;
@ -250,7 +250,8 @@ private:
LocalVector<ParticlesFrameParams> frame_history; LocalVector<ParticlesFrameParams> frame_history;
LocalVector<ParticlesFrameParams> trail_params; LocalVector<ParticlesFrameParams> trail_params;
Particles() { Particles() :
update_list(this) {
} }
}; };
@ -322,7 +323,7 @@ private:
} particles_shader; } particles_shader;
Particles *particle_update_list = nullptr; SelfList<Particles>::List particle_update_list;
mutable RID_Owner<Particles, true> particles_owner; mutable RID_Owner<Particles, true> particles_owner;