Applied ker's patch for prefetch and flush.

This commit is contained in:
David Williams 2011-03-22 21:44:12 +00:00
parent c7e452f537
commit 78c5884303
5 changed files with 99 additions and 4 deletions

View File

@ -78,7 +78,7 @@ int main(int argc, char *argv[])
openGLWidget.show();
//Create an empty volume and then place a sphere in it
Volume<MaterialDensityPair44> volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63)));
Volume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63)));
createSphereInVolume(volData, 30);
//Extract the surface

View File

@ -72,7 +72,7 @@ void exampleLog(string message, int severity)
int main(int argc, char *argv[])
{
logHandler = &exampleLog;
Volume<MaterialDensityPair44> volData(Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)));
Volume<MaterialDensityPair44> volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1)));
//Make our volume contain a sphere in the center.
int32_t minPos = 0;

View File

@ -250,7 +250,7 @@ int main(int argc, char *argv[])
openGLWidget.show();
//Create an empty volume and then place a sphere in it
Volume<MaterialDensityPair44> volData(&load, &unload, 128);
Volume<MaterialDensityPair44> volData(&load, &unload, 256);
volData.setMaxNumberOfBlocksInMemory(4096);
volData.setMaxNumberOfUncompressedBlocks(64);
@ -267,7 +267,19 @@ int main(int argc, char *argv[])
//createPerlinTerrain(volData);
//createPerlinVolumeSlow(volData);
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
//volData.setBlockCacheSize(64);
PolyVox::Region reg(Vector3DInt32(-255,0,0), Vector3DInt32(255,1024,255));
std::cout << "Prefetching region: " << reg.getLowerCorner() << " -> " << reg.getUpperCorner() << std::endl;
volData.prefetchRegion(reg);
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
PolyVox::Region reg2(Vector3DInt32(0,0,0), Vector3DInt32(500,500,500));
std::cout << "Flushing region: " << reg2.getLowerCorner() << " -> " << reg2.getUpperCorner() << std::endl;
uint32_t voxelsFlushed = volData.flushRegion(reg2);
Vector3DInt32 size = reg2.getUpperCorner() - reg2.getLowerCorner() + Vector3DInt32(1,1,1);
uint32_t voxelsFlushed2 = size.getX()*size.getY()*size.getZ();
std::cout << voxelsFlushed << " Voxels were unloaded, while " << voxelsFlushed2 << " should have been unloaded" << std::endl;
std::cout << "Memory usage: " << (volData.calculateSizeInBytes()/1024.0/1024.0) << "MB" << std::endl;
std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl;
@ -287,7 +299,6 @@ int main(int argc, char *argv[])
//Extract the surface
SurfaceMesh<PositionMaterialNormal> mesh;
//CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
PolyVox::Region reg(Vector3DInt32(-255,0,0), Vector3DInt32(255,1024,255));
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(&volData, reg, &mesh);
//CubicSurfaceExtractorWithNormals<MaterialDensityPair44> surfaceExtractor(&volData, reg, &mesh);
surfaceExtractor.execute();

View File

@ -186,6 +186,17 @@ namespace PolyVox
bool setVoxelAt(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue);
/// Sets the voxel at a 3D vector position
bool setVoxelAt(const Vector3DInt32& v3dPos, VoxelType tValue);
/// makes sure all the voxels in the given region are loaded
/// if MaxNumberOfBlocksInMemory is not large enough to support the region
/// this function will return false and the volume is unchanged
/// if all the voxels in the given region are already loaded, this function will not do anything but still return true.
/// other blocks might be unloaded to make space for the new blocks
bool prefetchRegion(Region regPrefetch);
/// attempts to unload all the voxels in the given region.
/// there is no guarantee that any voxels are unloaded
/// try unloading a region whose sidelengths are multiples of BlockSideLength
/// returns the number of voxels that were actually unloaded
uint32_t flushRegion(Region regFlush);
void clearBlockCache(void);
float calculateCompressionRatio(void);

View File

@ -375,6 +375,63 @@ namespace PolyVox
return setVoxelAt(v3dPos.getX(), v3dPos.getY(), v3dPos.getZ(), tValue);
}
template <typename VoxelType>
bool Volume<VoxelType>::prefetchRegion(Region regPrefetch)
{
Vector3DInt32 start;
for(int i = 0; i < 3; i++) start.setElement(i, regPrefetch.getLowerCorner().getElement(i) >> m_uBlockSideLengthPower);
Vector3DInt32 end;
for(int i = 0; i < 3; i++) end.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower);
Vector3DInt32 size = end-start + Vector3DInt32(1,1,1);
int32_t numblocks = size.getX() * size.getY() * size.getZ();
if(numblocks > m_uMaxNumberOfBlocksInMemory) {
return false;
}
if(numblocks > (m_uMaxNumberOfBlocksInMemory - m_pBlocks.size())) {
// TODO: unload enough blocks to support the blocks that will be loaded.
}
for(int32_t x = start.getX(); x <= end.getX(); x++) {
for(int32_t y = start.getY(); y <= end.getY(); y++) {
for(int32_t z = start.getZ(); z <= end.getZ(); z++) {
Block<VoxelType>* block = getUncompressedBlock(x,y,z);
}
}
}
return true;
}
template <typename VoxelType>
uint32_t Volume<VoxelType>::flushRegion(Region regFlush)
{
Vector3DInt32 start;
for(int i = 0; i < 3; i++) start.setElement(i, regFlush.getLowerCorner().getElement(i) >> m_uBlockSideLengthPower);
Vector3DInt32 end;
for(int i = 0; i < 3; i++) end.setElement(i, regFlush.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower);
uint32_t count = 0;
for(int32_t x = start.getX(); x <= end.getX(); x++) {
for(int32_t y = start.getY(); y <= end.getY(); y++) {
for(int32_t z = start.getZ(); z <= end.getZ(); z++) {
Vector3DInt32 pos(x,y,z);
if(m_v3dLastAccessedBlockPos == pos) {
m_pLastAccessedBlock = NULL;
}
typename std::map<Vector3DInt32, LoadedBlock>::iterator itBlock = m_pBlocks.find(pos);
if(itBlock == m_pBlocks.end()) {
// not loaded, not unloading
continue;
}
eraseBlock(itBlock);
count++;
}
}
}
if(count > ((std::numeric_limits<uint32_t>::max)() >> (m_uBlockSideLengthPower*3))) {
// eh, this will overflow... I have no idea what to do here
return (std::numeric_limits<uint32_t>::max)();
}
return count << (m_uBlockSideLengthPower*3);
}
template <typename VoxelType>
void Volume<VoxelType>::clearBlockCache(void)
{
@ -463,6 +520,22 @@ namespace PolyVox
m_funcDataOverflowHandler(ConstVolumeProxy, reg);
}
if(m_bCompressionEnabled) {
for(uint32_t ct = 0; ct < m_vecUncompressedBlockCache.size(); ct++)
{
// find the block in the uncompressed cache
if(m_vecUncompressedBlockCache[ct] == &(itBlock->second))
{
// TODO: compression is unneccessary? or will not compressing this cause a memleak?
itBlock->second.block.compress();
// put last object in cache here
m_vecUncompressedBlockCache[ct] = m_vecUncompressedBlockCache.back();
// decrease cache size by one since last element is now in here twice
m_vecUncompressedBlockCache.resize(m_vecUncompressedBlockCache.size()-1);
break;
}
}
}
m_pBlocks.erase(itBlock);
}