Prechádzať zdrojové kódy

SVT example allocator fixes

Aleš Mlakar 7 rokov pred
rodič
commit
2e327bff68

BIN
examples/40-svt/screenshot.png


+ 5 - 1
examples/40-svt/svt.cpp

@@ -7,7 +7,7 @@
   * Reference(s):
   * - Sparse Virtual Textures by Sean Barrett
   *   http://web.archive.org/web/20190103162611/http://silverspaceship.com/src/svt/
-  * - Virtual Texture Demo by Brad Blanchard
+  * - Based on Virtual Texture Demo by Brad Blanchard
   *	  http://web.archive.org/web/20190103162638/http://linedef.com/virtual-texture-demo.html
   * - Mars texture
   *   http://web.archive.org/web/20190103162730/http://www.celestiamotherlode.net/catalog/mars.php
@@ -134,6 +134,9 @@ public:
 		cameraSetPosition({ 0.0f, 5.0f, 0.0f });
 		cameraSetVerticalAngle(0.0f);
 
+		// Set VirtualTexture system allocator
+		vt::VirtualTexture::setAllocator(&m_vtAllocator);
+
 		// Create Virtual texture info
 		m_vti = new vt::VirtualTextureInfo();
 		m_vti->m_virtualTextureSize = 8192; // The actual size will be read from the tile data file
@@ -361,6 +364,7 @@ public:
 	const bgfx::Caps* m_caps;
 	int64_t m_timeOffset;
 
+	bx::DefaultAllocator m_vtAllocator;
 	vt::VirtualTextureInfo* m_vti;
 	vt::VirtualTexture* m_vt;
 	vt::FeedbackBuffer* m_feedbackBuffer;

+ 70 - 42
examples/40-svt/vt.cpp

@@ -3,6 +3,16 @@
  * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  */
 
+ /*
+  * Reference(s):
+  * - Sparse Virtual Textures by Sean Barrett
+  *   http://web.archive.org/web/20190103162611/http://silverspaceship.com/src/svt/
+  * - Based on Virtual Texture Demo by Brad Blanchard
+  *	  http://web.archive.org/web/20190103162638/http://linedef.com/virtual-texture-demo.html
+  * - Mars texture
+  *   http://web.archive.org/web/20190103162730/http://www.celestiamotherlode.net/catalog/mars.php
+  */
+
 #include "vt.h"
 #include <bx/file.h>
 #include <bx/sort.h>
@@ -283,7 +293,7 @@ Quadtree::~Quadtree()
 	{
 		if (m_children[i] != nullptr)
 		{
-			delete m_children[i];
+			BX_DELETE(VirtualTexture::getAllocator(), m_children[i]);
 		}
 	}
 }
@@ -306,7 +316,7 @@ void Quadtree::add(Page request, Point mapping)
 				// Create a new one if needed
 				if (node->m_children[i] == nullptr)
 				{
-					node->m_children[i] = new Quadtree(rect, node->m_level - 1);
+					node->m_children[i] = BX_NEW(VirtualTexture::getAllocator(), Quadtree)(rect, node->m_level - 1);
 					node = node->m_children[i];
 					break;
 				}
@@ -331,7 +341,7 @@ void Quadtree::remove(Page request)
 
 	if (node != nullptr)
 	{
-		delete node->m_children[index];
+		BX_DELETE(VirtualTexture::getAllocator(), node->m_children[index]);
 		node->m_children[index] = nullptr;
 	}
 }
@@ -429,7 +439,7 @@ PageTable::PageTable(PageCache* _cache, VirtualTextureInfo* _info, PageIndexer*
 	, m_quadtreeDirty(true) // Force quadtree dirty on startup
 {
 	auto size = m_info->GetPageTableSize();
-	m_quadtree = new Quadtree({ 0, 0, size, size }, (int)bx::log2((float)size));
+	m_quadtree = BX_NEW(VirtualTexture::getAllocator(), Quadtree)({ 0, 0, size, size }, (int)bx::log2((float)size));
 	m_texture = bgfx::createTexture2D((uint16_t)size, (uint16_t)size, true, 1, bgfx::TextureFormat::BGRA8, BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_POINT);
 
 	_cache->added = [=](Page page, Point pt) { m_quadtreeDirty = true; m_quadtree->add(page, pt); };
@@ -440,7 +450,7 @@ PageTable::PageTable(PageCache* _cache, VirtualTextureInfo* _info, PageIndexer*
 	for (int i = 0; i < PageTableSizeLog2; ++i)
 	{
 		int  mipSize = m_info->GetPageTableSize() >> i;
-		auto simpleImage = new SimpleImage(mipSize, mipSize, s_channelCount);
+		auto simpleImage = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(mipSize, mipSize, s_channelCount);
 		auto stagingTexture = bgfx::createTexture2D((uint16_t)mipSize, (uint16_t)mipSize, false, 1, bgfx::TextureFormat::BGRA8, BGFX_SAMPLER_UVW_CLAMP | BGFX_SAMPLER_POINT);
 		m_images.push_back(simpleImage);
 		m_stagingTextures.push_back(stagingTexture);
@@ -449,11 +459,11 @@ PageTable::PageTable(PageCache* _cache, VirtualTextureInfo* _info, PageIndexer*
 
 PageTable::~PageTable()
 {
-	delete m_quadtree;
+	BX_DELETE(VirtualTexture::getAllocator(), m_quadtree);
 	bgfx::destroy(m_texture);
 	for (int i = 0; i < (int)m_images.size(); ++i)
 	{
-		delete m_images[i];
+		BX_DELETE(VirtualTexture::getAllocator(), m_images[i]);
 	}
 	for (int i = 0; i < (int)m_stagingTextures.size(); ++i)
 	{
@@ -597,8 +607,10 @@ bool PageCache::touch(Page page)
 		if (m_lru_used.find(page) != m_lru_used.end())
 		{
 			// Find the page (slow!!) and add it to the back of the list
-			for (auto it = m_lru.begin(); it != m_lru.end(); ++it) {
-				if (it->m_page == page) {
+			for (auto it = m_lru.begin(); it != m_lru.end(); ++it)
+			{
+				if (it->m_page == page)
+				{
 					auto lruPage = *it;
 					m_lru.erase(it);
 					m_lru.push_back(lruPage);
@@ -731,7 +743,7 @@ FeedbackBuffer::FeedbackBuffer(VirtualTextureInfo* _info, int _width, int _heigh
 	, m_stagingPool(_width, _height, 1, true)
 {
 	// Setup classes
-	m_indexer = new PageIndexer(m_info);
+	m_indexer = BX_NEW(VirtualTexture::getAllocator(), PageIndexer)(m_info);
 	m_requests.resize(m_indexer->getCount());
 	// Initialize and clear buffers
 	m_downloadBuffer.resize(m_width * m_height * s_channelCount);
@@ -749,7 +761,7 @@ FeedbackBuffer::FeedbackBuffer(VirtualTextureInfo* _info, int _width, int _heigh
 
 FeedbackBuffer::~FeedbackBuffer()
 {
-	delete m_indexer;
+	BX_DELETE(VirtualTexture::getAllocator(), m_indexer);
 	bgfx::destroy(m_feedbackFrameBuffer);
 }
 
@@ -849,14 +861,14 @@ VirtualTexture::VirtualTexture(TileDataFile* _tileDataFile, VirtualTextureInfo*
 	m_atlasCount = _atlassize / m_info->GetPageSize();
 
 	// Setup indexer
-	m_indexer = new PageIndexer(m_info);
+	m_indexer = BX_NEW(VirtualTexture::getAllocator(), PageIndexer)(m_info);
 	m_pagesToLoad.reserve(m_indexer->getCount());
 
 	// Setup classes
-	m_atlas = new TextureAtlas(m_info, m_atlasCount, m_uploadsPerFrame);
-	m_loader = new PageLoader(m_tileDataFile, m_indexer, m_info);
-	m_cache = new PageCache(m_info, m_atlas, m_loader, m_indexer, m_atlasCount);
-	m_pageTable = new PageTable(m_cache, m_info, m_indexer);
+	m_atlas = BX_NEW(VirtualTexture::getAllocator(), TextureAtlas)(m_info, m_atlasCount, m_uploadsPerFrame);
+	m_loader = BX_NEW(VirtualTexture::getAllocator(), PageLoader)(m_tileDataFile, m_indexer, m_info);
+	m_cache = BX_NEW(VirtualTexture::getAllocator(), PageCache)(m_info, m_atlas, m_loader, m_indexer, m_atlasCount);
+	m_pageTable = BX_NEW(VirtualTexture::getAllocator(), PageTable)(m_cache, m_info, m_indexer);
 
 	// Create uniforms
 	u_vt_settings_1 = bgfx::createUniform("u_vt_settings_1", bgfx::UniformType::Vec4);
@@ -868,11 +880,11 @@ VirtualTexture::VirtualTexture(TileDataFile* _tileDataFile, VirtualTextureInfo*
 VirtualTexture::~VirtualTexture()
 {
 	// Destroy
-	delete m_indexer;
-	delete m_atlas;
-	delete m_loader;
-	delete m_cache;
-	delete m_pageTable;
+	BX_DELETE(VirtualTexture::getAllocator(), m_indexer);
+	BX_DELETE(VirtualTexture::getAllocator(), m_atlas);
+	BX_DELETE(VirtualTexture::getAllocator(), m_loader);
+	BX_DELETE(VirtualTexture::getAllocator(), m_cache);
+	BX_DELETE(VirtualTexture::getAllocator(), m_pageTable);
 	// Destroy all uniforms and textures
 	bgfx::destroy(u_vt_settings_1);
 	bgfx::destroy(u_vt_settings_2);
@@ -1038,6 +1050,18 @@ void VirtualTexture::update(const tinystl::vector<int>& requests, bgfx::ViewId b
 	m_pageTable->update(blitViewId);
 }
 
+bx::AllocatorI* VirtualTexture::s_allocator = nullptr;
+
+void VirtualTexture::setAllocator(bx::AllocatorI* allocator)
+{
+	s_allocator = allocator;
+}
+
+bx::AllocatorI* VirtualTexture::getAllocator()
+{
+	return s_allocator;
+}
+
 TileDataFile::TileDataFile(const bx::FilePath& filename, VirtualTextureInfo* _info, bool _readWrite) : m_info(_info)
 {
 	const char* access = _readWrite ? "w+b" : "rb";
@@ -1053,26 +1077,30 @@ TileDataFile::~TileDataFile()
 void TileDataFile::readInfo()
 {
 	fseek(m_file, 0, SEEK_SET);
-	fread(m_info, sizeof(*m_info), 1, m_file);
+	auto ret = fread(m_info, sizeof(*m_info), 1, m_file);
+	BX_UNUSED(ret);
 	m_size = m_info->GetPageSize() * m_info->GetPageSize() * s_channelCount;
 }
 
 void TileDataFile::writeInfo()
 {
 	fseek(m_file, 0, SEEK_SET);
-	fwrite(m_info, sizeof(*m_info), 1, m_file);
+	auto ret = fwrite(m_info, sizeof(*m_info), 1, m_file);
+	BX_UNUSED(ret);
 }
 
 void TileDataFile::readPage(int index, uint8_t* data)
 {
 	fseek(m_file, m_size * index + s_tileFileDataOffset, SEEK_SET);
-	fread(data, m_size, 1, m_file);
+	auto ret = fread(data, m_size, 1, m_file);
+	BX_UNUSED(ret);
 }
 
 void TileDataFile::writePage(int index, uint8_t* data)
 {
 	fseek(m_file, m_size * index + s_tileFileDataOffset, SEEK_SET);
-	fwrite(data, m_size, 1, m_file);
+	auto ret = fwrite(data, m_size, 1, m_file);
+	BX_UNUSED(ret);
 }
 
 // TileGenerator
@@ -1098,13 +1126,13 @@ TileGenerator::~TileGenerator()
 		bimg::imageFree(m_sourceImage);
 	}
 
-	delete m_indexer;
+	BX_DELETE(VirtualTexture::getAllocator(), m_indexer);
 
-	delete m_page1Image;
-	delete m_page2Image;
-	delete m_2xtileImage;
-	delete m_4xtileImage;
-	delete m_tileImage;
+	BX_DELETE(VirtualTexture::getAllocator(), m_page1Image);
+	BX_DELETE(VirtualTexture::getAllocator(), m_page2Image);
+	BX_DELETE(VirtualTexture::getAllocator(), m_2xtileImage);
+	BX_DELETE(VirtualTexture::getAllocator(), m_4xtileImage);
+	BX_DELETE(VirtualTexture::getAllocator(), m_tileImage);
 }
 
 bool TileGenerator::generate(const bx::FilePath& filename)
@@ -1137,7 +1165,7 @@ bool TileGenerator::generate(const bx::FilePath& filename)
 		}
 		auto size = fileReader.seek(0, bx::Whence::End);
 		fileReader.seek(0, bx::Whence::Begin);
-		auto rawImage = (uint8_t*)BX_ALLOC(&m_allocator, size);
+		auto rawImage = (uint8_t*)BX_ALLOC(VirtualTexture::getAllocator(), size);
 		fileReader.read(rawImage, int32_t(size), &error);
 		fileReader.close();
 		if (!error.isOk())
@@ -1145,8 +1173,8 @@ bool TileGenerator::generate(const bx::FilePath& filename)
 			bx::debugPrintf("Image read failed'%s'.\n", filename.get());
 			return false;
 		}
-		m_sourceImage = bimg::imageParse(&m_allocator, rawImage, uint32_t(size), bimg::TextureFormat::BGRA8, &error);
-		BX_FREE(&m_allocator, rawImage);
+		m_sourceImage = bimg::imageParse(VirtualTexture::getAllocator(), rawImage, uint32_t(size), bimg::TextureFormat::BGRA8, &error);
+		BX_FREE(VirtualTexture::getAllocator(), rawImage);
 		if (!error.isOk())
 		{
 			bx::debugPrintf("Image parse failed'%s'.\n", filename.get());
@@ -1156,16 +1184,16 @@ bool TileGenerator::generate(const bx::FilePath& filename)
 
 	// Setup
 	m_info->m_virtualTextureSize = int(m_sourceImage->m_width);
-	m_indexer = new PageIndexer(m_info);
+	m_indexer = BX_NEW(VirtualTexture::getAllocator(), PageIndexer)(m_info);
 
 	// Open tile data file
-	m_tileDataFile = new TileDataFile(cacheFilename, m_info, true);
+	m_tileDataFile = BX_NEW(VirtualTexture::getAllocator(), TileDataFile)(cacheFilename, m_info, true);
 
-	m_page1Image = new SimpleImage(m_pagesize, m_pagesize, s_channelCount, 0xff);
-	m_page2Image = new SimpleImage(m_pagesize, m_pagesize, s_channelCount, 0xff);
-	m_tileImage = new SimpleImage(m_tilesize, m_tilesize, s_channelCount, 0xff);
-	m_2xtileImage = new SimpleImage(m_tilesize * 2, m_tilesize * 2, s_channelCount, 0xff);
-	m_4xtileImage = new SimpleImage(m_tilesize * 4, m_tilesize * 4, s_channelCount, 0xff);
+	m_page1Image = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(m_pagesize, m_pagesize, s_channelCount, 0xff);
+	m_page2Image = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(m_pagesize, m_pagesize, s_channelCount, 0xff);
+	m_tileImage = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(m_tilesize, m_tilesize, s_channelCount, 0xff);
+	m_2xtileImage = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(m_tilesize * 2, m_tilesize * 2, s_channelCount, 0xff);
+	m_4xtileImage = BX_NEW(VirtualTexture::getAllocator(), SimpleImage)(m_tilesize * 4, m_tilesize * 4, s_channelCount, 0xff);
 
 	// Generate tiles
 	bx::debugPrintf("Generating tiles\n");
@@ -1189,7 +1217,7 @@ bool TileGenerator::generate(const bx::FilePath& filename)
 	// Write header
 	m_tileDataFile->writeInfo();
 	// Close tile file
-	delete m_tileDataFile;
+	BX_DELETE(VirtualTexture::getAllocator(), m_tileDataFile);
 	m_tileDataFile = nullptr;
 	bx::debugPrintf("Done!\n");
 	return true;

+ 15 - 1
examples/40-svt/vt.h

@@ -3,6 +3,16 @@
  * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  */
 
+ /*
+  * Reference(s):
+  * - Sparse Virtual Textures by Sean Barrett
+  *   http://web.archive.org/web/20190103162611/http://silverspaceship.com/src/svt/
+  * - Based on Virtual Texture Demo by Brad Blanchard
+  *	  http://web.archive.org/web/20190103162638/http://linedef.com/virtual-texture-demo.html
+  * - Mars texture
+  *   http://web.archive.org/web/20190103162730/http://www.celestiamotherlode.net/catalog/mars.php
+  */
+
 #pragma once
 #include "common.h"
 #include "bgfx_utils.h"
@@ -353,6 +363,9 @@ public:
 
 	void setUniforms();
 
+	static void setAllocator(bx::AllocatorI* allocator);
+	static bx::AllocatorI* getAllocator();
+
 private:
 	TileDataFile*		m_tileDataFile;
 	VirtualTextureInfo* m_info;
@@ -373,6 +386,8 @@ private:
 	bgfx::UniformHandle u_vt_settings_2;
 	bgfx::UniformHandle s_vt_page_table;
 	bgfx::UniformHandle s_vt_texture_atlas;
+
+	static bx::AllocatorI* s_allocator;
 };
 
 // TileDataFile
@@ -414,7 +429,6 @@ private:
 	int	m_tilesize;
 	int	m_pagesize;
 
-	bx::DefaultAllocator	m_allocator;
 	bimg::ImageContainer*	m_sourceImage;
 
 	SimpleImage* m_page1Image;