A PagedVolume must now always be provided with a Pager when it is constructed.
This commit is contained in:
		@@ -249,7 +249,7 @@ namespace PolyVox
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		/// Constructor for creating a fixed size volume.
 | 
							/// Constructor for creating a fixed size volume.
 | 
				
			||||||
		PagedVolume(Pager* pPager = nullptr, uint32_t uTargetMemoryUsageInBytes = 256 * 1024 * 1024, uint16_t uChunkSideLength = 32);
 | 
							PagedVolume(Pager* pPager, uint32_t uTargetMemoryUsageInBytes = 256 * 1024 * 1024, uint16_t uChunkSideLength = 32);
 | 
				
			||||||
		/// Destructor
 | 
							/// Destructor
 | 
				
			||||||
		~PagedVolume();
 | 
							~PagedVolume();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -319,7 +319,7 @@ namespace PolyVox
 | 
				
			|||||||
		uint8_t m_uChunkSideLengthPower;
 | 
							uint8_t m_uChunkSideLengthPower;
 | 
				
			||||||
		int32_t m_iChunkMask;
 | 
							int32_t m_iChunkMask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Pager* m_pPager;
 | 
							Pager* m_pPager = nullptr;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ namespace PolyVox
 | 
				
			|||||||
		, m_uChunkSideLength(uChunkSideLength)
 | 
							, m_uChunkSideLength(uChunkSideLength)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Validation of parameters
 | 
							// Validation of parameters
 | 
				
			||||||
 | 
							POLYVOX_THROW_IF(!pPager, std::invalid_argument, "You must provide a valid pager when constructing a PagedVolume");
 | 
				
			||||||
		POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical");
 | 
							POLYVOX_THROW_IF(uTargetMemoryUsageInBytes < 1 * 1024 * 1024, std::invalid_argument, "Target memory usage is too small to be practical");
 | 
				
			||||||
		POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero.");
 | 
							POLYVOX_THROW_IF(m_uChunkSideLength == 0, std::invalid_argument, "Chunk side length cannot be zero.");
 | 
				
			||||||
		POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical.");
 | 
							POLYVOX_THROW_IF(m_uChunkSideLength > 256, std::invalid_argument, "Chunk size is too large to be practical.");
 | 
				
			||||||
@@ -191,7 +192,7 @@ namespace PolyVox
 | 
				
			|||||||
		// Ensure we don't page in more chunks than the volume can hold.
 | 
							// Ensure we don't page in more chunks than the volume can hold.
 | 
				
			||||||
		Region region(v3dStart, v3dEnd);
 | 
							Region region(v3dStart, v3dEnd);
 | 
				
			||||||
		uint32_t uNoOfChunks = static_cast<uint32_t>(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels());
 | 
							uint32_t uNoOfChunks = static_cast<uint32_t>(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels());
 | 
				
			||||||
		POLYVOX_LOG_WARNING_IF(uNoOfChunks > m_uChunkCountLimit, "Attempting to prefetch more than the maximum number of chunks.");
 | 
							POLYVOX_LOG_WARNING_IF(uNoOfChunks > m_uChunkCountLimit, "Attempting to prefetch more than the maximum number of chunks (this will cause thrashing).");
 | 
				
			||||||
		uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit);
 | 
							uNoOfChunks = (std::min)(uNoOfChunks, m_uChunkCountLimit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Loops over the specified positions and touch the corresponding chunks.
 | 
							// Loops over the specified positions and touch the corresponding chunks.
 | 
				
			||||||
@@ -213,8 +214,6 @@ namespace PolyVox
 | 
				
			|||||||
	template <typename VoxelType>
 | 
						template <typename VoxelType>
 | 
				
			||||||
	void PagedVolume<VoxelType>::flushAll()
 | 
						void PagedVolume<VoxelType>::flushAll()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		POLYVOX_LOG_WARNING_IF(!m_pPager, "Data discarded by flush operation as no pager is attached.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Clear this pointer so it doesn't hang on to any chunks.
 | 
							// Clear this pointer so it doesn't hang on to any chunks.
 | 
				
			||||||
		m_pLastAccessedChunk = nullptr;
 | 
							m_pLastAccessedChunk = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -234,8 +233,6 @@ namespace PolyVox
 | 
				
			|||||||
	template <typename VoxelType>
 | 
						template <typename VoxelType>
 | 
				
			||||||
	void PagedVolume<VoxelType>::flush(Region regFlush)
 | 
						void PagedVolume<VoxelType>::flush(Region regFlush)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		POLYVOX_LOG_WARNING_IF(!m_pPager, "Data discarded by flush operation as no pager is attached.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Clear this pointer so it doesn't hang on to any chunks.
 | 
							// Clear this pointer so it doesn't hang on to any chunks.
 | 
				
			||||||
		m_pLastAccessedChunk = nullptr;
 | 
							m_pLastAccessedChunk = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -329,10 +326,6 @@ namespace PolyVox
 | 
				
			|||||||
			bool erasedChunk = false;
 | 
								bool erasedChunk = false;
 | 
				
			||||||
			while (m_pRecentlyUsedChunks.size() + 1 > m_uChunkCountLimit) // +1 ready for new chunk we will add next.
 | 
								while (m_pRecentlyUsedChunks.size() + 1 > m_uChunkCountLimit) // +1 ready for new chunk we will add next.
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// This should never hit, because it should not have been possible for
 | 
					 | 
				
			||||||
				// the user to limit the number of chunks if they did not provide a pager.
 | 
					 | 
				
			||||||
				POLYVOX_ASSERT(m_pPager, "A valid pager is required to limit number of chunks");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// Find the least recently used chunk. Hopefully this isn't too slow.
 | 
									// Find the least recently used chunk. Hopefully this isn't too slow.
 | 
				
			||||||
				typename SharedPtrChunkMap::iterator itUnloadChunk = m_pRecentlyUsedChunks.begin();
 | 
									typename SharedPtrChunkMap::iterator itUnloadChunk = m_pRecentlyUsedChunks.begin();
 | 
				
			||||||
				for (typename SharedPtrChunkMap::iterator i = m_pRecentlyUsedChunks.begin(); i != m_pRecentlyUsedChunks.end(); i++)
 | 
									for (typename SharedPtrChunkMap::iterator i = m_pRecentlyUsedChunks.begin(); i != m_pRecentlyUsedChunks.end(); i++)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,8 @@ namespace PolyVox
 | 
				
			|||||||
		,m_pPager(pPager)
 | 
							,m_pPager(pPager)
 | 
				
			||||||
		,m_v3dChunkSpacePosition(v3dPosition)
 | 
							,m_v3dChunkSpacePosition(v3dPosition)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							POLYVOX_ASSERT(m_pPager, "No valid pager supplied to chunk constructor.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Compute the side length               
 | 
							// Compute the side length               
 | 
				
			||||||
		m_uSideLength = uSideLength;
 | 
							m_uSideLength = uSideLength;
 | 
				
			||||||
		m_uSideLengthPower = logBase2(uSideLength);
 | 
							m_uSideLengthPower = logBase2(uSideLength);
 | 
				
			||||||
@@ -44,8 +46,6 @@ namespace PolyVox
 | 
				
			|||||||
		m_tData = new VoxelType[uNoOfVoxels];  
 | 
							m_tData = new VoxelType[uNoOfVoxels];  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Pass the chunk to the Pager to give it a chance to initialise it with any data
 | 
							// Pass the chunk to the Pager to give it a chance to initialise it with any data
 | 
				
			||||||
		if (m_pPager)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
 | 
							// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
 | 
				
			||||||
		Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
 | 
							Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
 | 
				
			||||||
		Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uSideLength - 1, m_uSideLength - 1, m_uSideLength - 1);
 | 
							Vector3DInt32 v3dUpper = v3dLower + Vector3DInt32(m_uSideLength - 1, m_uSideLength - 1, m_uSideLength - 1);
 | 
				
			||||||
@@ -53,12 +53,6 @@ namespace PolyVox
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Page the data in
 | 
							// Page the data in
 | 
				
			||||||
		m_pPager->pageIn(reg, this);
 | 
							m_pPager->pageIn(reg, this);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			// Just fill with zeros
 | 
					 | 
				
			||||||
			std::fill(m_tData, m_tData + uNoOfVoxels, VoxelType());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// We'll use this later to decide if data needs to be paged out again.
 | 
							// We'll use this later to decide if data needs to be paged out again.
 | 
				
			||||||
		m_bDataModified = false;
 | 
							m_bDataModified = false;
 | 
				
			||||||
@@ -67,7 +61,7 @@ namespace PolyVox
 | 
				
			|||||||
	template <typename VoxelType>
 | 
						template <typename VoxelType>
 | 
				
			||||||
	PagedVolume<VoxelType>::Chunk::~Chunk()
 | 
						PagedVolume<VoxelType>::Chunk::~Chunk()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (m_pPager && m_bDataModified)
 | 
							if (m_bDataModified)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
 | 
								// From the coordinates of the chunk we deduce the coordinates of the contained voxels.
 | 
				
			||||||
			Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
 | 
								Vector3DInt32 v3dLower = m_v3dChunkSpacePosition * static_cast<int32_t>(m_uSideLength);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ freely, subject to the following restrictions:
 | 
				
			|||||||
#include "TestCubicSurfaceExtractor.h"
 | 
					#include "TestCubicSurfaceExtractor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "PolyVox/Density.h"
 | 
					#include "PolyVox/Density.h"
 | 
				
			||||||
 | 
					#include "PolyVox/FilePager.h"
 | 
				
			||||||
#include "PolyVox/Material.h"
 | 
					#include "PolyVox/Material.h"
 | 
				
			||||||
#include "PolyVox/MaterialDensityPair.h"
 | 
					#include "PolyVox/MaterialDensityPair.h"
 | 
				
			||||||
#include "PolyVox/RawVolume.h"
 | 
					#include "PolyVox/RawVolume.h"
 | 
				
			||||||
@@ -95,7 +96,8 @@ template <typename VolumeType>
 | 
				
			|||||||
VolumeType* createAndFillVolumeRealistic(int32_t iVolumeSideLength)
 | 
					VolumeType* createAndFillVolumeRealistic(int32_t iVolumeSideLength)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	//Create empty volume
 | 
						//Create empty volume
 | 
				
			||||||
	VolumeType* volData = new VolumeType;
 | 
						FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
 | 
				
			||||||
 | 
						VolumeType* volData = new VolumeType(filePager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Fill the volume with data
 | 
						//Fill the volume with data
 | 
				
			||||||
	for (int32_t z = 0; z < iVolumeSideLength; z++)
 | 
						for (int32_t z = 0; z < iVolumeSideLength; z++)
 | 
				
			||||||
@@ -158,7 +160,8 @@ void TestCubicSurfaceExtractor::testBehaviour()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void TestCubicSurfaceExtractor::testEmptyVolumePerformance()
 | 
					void TestCubicSurfaceExtractor::testEmptyVolumePerformance()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PagedVolume<uint32_t> emptyVol;
 | 
						FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
 | 
				
			||||||
 | 
						PagedVolume<uint32_t> emptyVol(filePager);
 | 
				
			||||||
	createAndFillVolumeWithNoise(emptyVol, 128, 0, 0);
 | 
						createAndFillVolumeWithNoise(emptyVol, 128, 0, 0);
 | 
				
			||||||
	Mesh< CubicVertex< uint32_t >, uint16_t > emptyMesh;
 | 
						Mesh< CubicVertex< uint32_t >, uint16_t > emptyMesh;
 | 
				
			||||||
	QBENCHMARK{ extractCubicMeshCustom(&emptyVol, Region(32, 32, 32, 63, 63, 63), &emptyMesh); }
 | 
						QBENCHMARK{ extractCubicMeshCustom(&emptyVol, Region(32, 32, 32, 63, 63, 63), &emptyMesh); }
 | 
				
			||||||
@@ -175,7 +178,8 @@ void TestCubicSurfaceExtractor::testRealisticVolumePerformance()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void TestCubicSurfaceExtractor::testNoiseVolumePerformance()
 | 
					void TestCubicSurfaceExtractor::testNoiseVolumePerformance()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PagedVolume<uint32_t> noiseVol;
 | 
						FilePager<uint32_t>* filePager = new FilePager<uint32_t>();
 | 
				
			||||||
 | 
						PagedVolume<uint32_t> noiseVol(filePager);
 | 
				
			||||||
	createAndFillVolumeWithNoise(noiseVol, 128, 0, 2);
 | 
						createAndFillVolumeWithNoise(noiseVol, 128, 0, 2);
 | 
				
			||||||
	Mesh< CubicVertex< uint32_t >, uint16_t > noiseMesh;
 | 
						Mesh< CubicVertex< uint32_t >, uint16_t > noiseMesh;
 | 
				
			||||||
	QBENCHMARK{ extractCubicMeshCustom(&noiseVol, Region(32, 32, 32, 63, 63, 63), &noiseMesh); }
 | 
						QBENCHMARK{ extractCubicMeshCustom(&noiseVol, Region(32, 32, 32, 63, 63, 63), &noiseMesh); }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user