Explorar o código

fix crash during unloading of distant chunks

Kolja Strohm hai 9 horas
pai
achega
5479434f9f
Modificáronse 2 ficheiros con 15 adicións e 6 borrados
  1. 2 0
      FactoryCraft/CustomDX12API.cpp
  2. 13 6
      FactoryCraft/Dimension.cpp

+ 2 - 0
FactoryCraft/CustomDX12API.cpp

@@ -331,6 +331,7 @@ void CustomDX12API::renderWorld(Framework::World3D* zWorld,
         const Dimension* dim = dynamic_cast<const Dimension*>(collection);
         if (dim)
         {
+            dim->getReadLock().lock();
             for (const Chunk* chunk : dim->getChunks())
             {
                 DX12ChunkData* chunkData = chunk->zDX12Data();
@@ -450,6 +451,7 @@ void CustomDX12API::renderWorld(Framework::World3D* zWorld,
                 chunkData->setBufferChanged(0);
                 ++objectIndex;
             }
+            dim->getReadLock().unlock();
         }
     }
     DirectX12::renderWorld(zWorld, zTLAS, zSBT, objectIndex);

+ 13 - 6
FactoryCraft/Dimension.cpp

@@ -253,13 +253,20 @@ void Dimension::removeDistantChunks(Point wPos)
         index++;
     }
     lock.unlockRead();
-    for (int i : removed)
+    if (removed.getEntryCount())
     {
-        lock.lockWrite();
-        Chunk* chunk = chunkList.get(i);
-        chunk->destroy();
-        setChunk(0, chunk->getCenter());
-        lock.unlockWrite();
+        window->zScreen()->postAction([this, removed]() {
+            // chunk removal must be done in main thread because otherwise gpu
+            // memory will be freend during rendering which will cause a crash
+            for (int i : removed)
+            {
+                lock.lockWrite();
+                Chunk* chunk = chunkList.get(i);
+                chunk->destroy();
+                setChunk(0, chunk->getCenter());
+                lock.unlockWrite();
+            }
+        });
     }
 }