diff --git a/examples/Paging/main.cpp b/examples/Paging/main.cpp index a01779fb..1fd22aab 100644 --- a/examples/Paging/main.cpp +++ b/examples/Paging/main.cpp @@ -158,10 +158,8 @@ int main(int argc, char *argv[]) PerlinNoisePager* pager = new PerlinNoisePager(); LargeVolume volData(PolyVox::Region::MaxRegion, pager, 256); - //volData.setMaxNumberOfBlocksInMemory(4096); - volData.setMaxNumberOfUncompressedBlocks(64); + volData.setTargetMemoryUsage(2 * 1024 * 1024); // 2Mb - //volData.setMaxNumberOfUncompressedBlocks(4096); //createSphereInVolume(volData, 30); //createPerlinTerrain(volData); //createPerlinVolumeSlow(volData); diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h index 2bd177ea..01008dcd 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.h @@ -256,7 +256,7 @@ namespace PolyVox POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const; /// Sets the number of blocks for which uncompressed data is stored - void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks); + void setTargetMemoryUsage(uint32_t uTargetMemoryUsageInBytes); /// Sets the voxel at the position given by x,y,z coordinates void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate); /// Sets the voxel at the position given by a 3D vector diff --git a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl index fcf13e20..86461937 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/LargeVolume.inl @@ -225,22 +225,26 @@ namespace PolyVox /// \param uMaxNumberOfUncompressedBlocks The number of blocks for which uncompressed data can be cached. //////////////////////////////////////////////////////////////////////////////// template - void LargeVolume::setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks) + void LargeVolume::setTargetMemoryUsage(uint32_t uTargetMemoryUsageInBytes) { POLYVOX_THROW_IF(!m_pPager, invalid_operation, "You cannot limit the memory usage of the volume because it was created without a pager attached."); - //clearBlockCache(); + uint32_t uUncompressedBlockSizeInBytes = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); - /*if (m_pRecentlyUsedBlocks.size() > uMaxNumberOfBlocksInMemory) + m_uMaxNumberOfUncompressedBlocks = uTargetMemoryUsageInBytes / uUncompressedBlockSizeInBytes; + + const uint32_t uMinPracticalNoOfBlocks = 4; + POLYVOX_LOG_WARNING_IF(m_uMaxNumberOfUncompressedBlocks < uMinPracticalNoOfBlocks, "The target memory usage is set too low and cannot be adhered to."); + m_uMaxNumberOfUncompressedBlocks = (std::max)(m_uMaxNumberOfUncompressedBlocks, uMinPracticalNoOfBlocks); + + + if (m_pRecentlyUsedBlocks.size() > m_uMaxNumberOfUncompressedBlocks) { flushAll(); - }*/ + } - m_uMaxNumberOfUncompressedBlocks = uMaxNumberOfUncompressedBlocks; - - uint32_t uUncompressedBlockSizeInBytes = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType); - POLYVOX_LOG_DEBUG("The maximum number of uncompresed blocks has been set to " << m_uMaxNumberOfUncompressedBlocks - << ", which is " << m_uMaxNumberOfUncompressedBlocks * uUncompressedBlockSizeInBytes << " bytes"); + POLYVOX_LOG_DEBUG("Target memory usage for volume set to " << uTargetMemoryUsageInBytes << "bytes (" + << m_uMaxNumberOfUncompressedBlocks << " blocks of " << uUncompressedBlockSizeInBytes << "bytes each)."); } //////////////////////////////////////////////////////////////////////////////// @@ -353,11 +357,13 @@ namespace PolyVox v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower); } + // Ensure we don't page in more blocks than the volume can hold. Region region(v3dStart, v3dEnd); uint32_t uNoOfBlocks = static_cast(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels()); POLYVOX_LOG_WARNING_IF(uNoOfBlocks > m_uMaxNumberOfUncompressedBlocks, "Attempting to prefetch more than the maximum number of blocks."); uNoOfBlocks = (std::min)(uNoOfBlocks, m_uMaxNumberOfUncompressedBlocks); + // Loops over the specified positions and touch the corresponding blocks. for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) { for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) @@ -598,12 +604,16 @@ namespace PolyVox template void LargeVolume::purgeNullPtrsFromAllBlocks(void) const { - for (auto blockIter = m_pAllBlocks.begin(); blockIter != m_pAllBlocks.end(); blockIter++) + for (auto blockIter = m_pAllBlocks.begin(); blockIter != m_pAllBlocks.end();) { if (blockIter->second.expired()) { blockIter = m_pAllBlocks.erase(blockIter); } + else + { + blockIter++; + } } } diff --git a/tests/testvolume.cpp b/tests/testvolume.cpp index 3d737c0d..ae4df9e8 100644 --- a/tests/testvolume.cpp +++ b/tests/testvolume.cpp @@ -277,8 +277,7 @@ TestVolume::TestVolume() m_pSimpleVolume = new SimpleVolume(region); m_pLargeVolume = new LargeVolume(region, m_pFilePager, 32); - //m_pLargeVolume->setMaxNumberOfBlocksInMemory(32); - m_pLargeVolume->setMaxNumberOfUncompressedBlocks(64); + m_pLargeVolume->setTargetMemoryUsage(1 * 1024 * 1024); //Fill the volume with some data for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++)