@@ -344,7 +344,7 @@ class AcceleratorBuffer
344344 ~AcceleratorBuffer ()
345345 {
346346 FreeCpuBuffer ();
347- FreeGpuBuffer ();
347+ FreeGpuBuffer (true );
348348 }
349349
350350 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1073,15 +1073,25 @@ class AcceleratorBuffer
10731073 }
10741074 }
10751075
1076+ public:
10761077 /* *
10771078 @brief Free the GPU-side buffer and underlying physical memory
1079+
1080+ @param dataLossOK True if we do not intend to use the contents of this buffer again
1081+ (and thus it's OK to remove the only copy of the data)
10781082 */
1079- void FreeGpuBuffer ()
1083+ void FreeGpuBuffer (bool dataLossOK = false )
10801084 {
10811085 // Early out if buffer is already null
10821086 if (m_gpuPhysMem == nullptr )
10831087 return ;
10841088
1089+ // If we do NOT have a CPU-side buffer, we're deleting all of our data! Warn for now
1090+ if ( (m_cpuMemoryType == MEM_TYPE_NULL) && m_gpuPhysMemIsStale && !empty () && !dataLossOK)
1091+ {
1092+ LogWarning (" Freeing a GPU buffer without any CPU backing, may cause data loss\n " );
1093+ }
1094+
10851095 // If we have a CPU-side buffer, and it's stale, move our about-to-be-deleted content over before we free it
10861096 if ( (m_cpuMemoryType != MEM_TYPE_NULL) && m_cpuPhysMemIsStale && !empty () )
10871097 CopyToCpu ();
@@ -1325,12 +1335,34 @@ class AcceleratorBuffer
13251335 }
13261336 }
13271337
1338+ // Retry one more time.
1339+ // If we OOM simultaneously in two threads, it's possible to have the second OnMemoryPressure call
1340+ // return false because the first one already freed all it could. But we might have enough free to continue.
1341+ if (!ok)
1342+ {
1343+ LogDebug (" Final retry\n " );
1344+ try
1345+ {
1346+ m_gpuPhysMem = std::make_unique<vk::raii::DeviceMemory>(*g_vkComputeDevice, info);
1347+ ok = true ;
1348+ }
1349+ catch (vk::OutOfDeviceMemoryError& ex2)
1350+ {
1351+ LogDebug (" Allocation failed again\n " );
1352+ }
1353+ }
1354+
13281355 // If we get here, we couldn't allocate no matter what
1329- LogError (
1330- " Failed to allocate %s of GPU memory despite our best efforts to reclaim space\n "
1331- " This is unrecoverable (for now).\n " ,
1332- Unit (Unit::UNIT_BYTES).PrettyPrint (req.size , 4 ).c_str ());
1333- exit (1 );
1356+ // TODO: Fall back to a CPU-side allocation
1357+ if (!ok)
1358+ {
1359+ LogError (
1360+ " Failed to allocate %s of GPU memory despite our best efforts to reclaim space\n "
1361+ " This is unrecoverable (for now).\n " ,
1362+ Unit (Unit::UNIT_BYTES).PrettyPrint (req.size , 4 ).c_str ());
1363+
1364+ std::abort ();
1365+ }
13341366 }
13351367 m_gpuMemoryType = MEM_TYPE_GPU_ONLY;
13361368
0 commit comments