SVT example fixes

This commit is contained in:
Aleš Mlakar 2019-01-04 09:51:12 +01:00
parent 7732554b02
commit ec167c1d51
3 changed files with 58 additions and 38 deletions

View File

@ -6,11 +6,11 @@
/*
* Reference(s):
* - Sparse Virtual Textures by Sean Barrett
* http://silverspaceship.com/src/svt/
* http://web.archive.org/web/20190103162611/http://silverspaceship.com/src/svt/
* - Virtual Texture Demo by Brad Blanchard
* http://linedef.com/virtual-texture-demo.html
* http://web.archive.org/web/20190103162638/http://linedef.com/virtual-texture-demo.html
* - Mars texture
* http://www.celestiamotherlode.net/catalog/mars.php
* http://web.archive.org/web/20190103162730/http://www.celestiamotherlode.net/catalog/mars.php
*/
#include "common.h"

View File

@ -1,4 +1,9 @@
#include "vt.h"
/*
* Copyright 2018 Aleš Mlakar. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "vt.h"
#include <bx/file.h>
#include <algorithm>
@ -88,7 +93,7 @@ StagingPool::StagingPool(int _width, int _height, int _count, bool _readBack)
StagingPool::~StagingPool()
{
for (int i = 0; i < m_stagingTextures.size(); ++i)
for (int i = 0; i < (int)m_stagingTextures.size(); ++i)
{
bgfx::destroy(m_stagingTextures[i]);
}
@ -96,7 +101,7 @@ StagingPool::~StagingPool()
void StagingPool::grow(int count)
{
while (m_stagingTextures.size() < count)
while ((int)m_stagingTextures.size() < count)
{
auto stagingTexture = bgfx::createTexture2D((uint16_t)m_width, (uint16_t)m_height, false, 1, bgfx::TextureFormat::BGRA8, m_flags);
m_stagingTextures.push_back(stagingTexture);
@ -110,14 +115,14 @@ bgfx::TextureHandle StagingPool::getTexture()
void StagingPool::next()
{
m_stagingTextureIndex = (m_stagingTextureIndex + 1) % m_stagingTextures.size();
m_stagingTextureIndex = (m_stagingTextureIndex + 1) % (int)m_stagingTextures.size();
}
// PageIndexer
PageIndexer::PageIndexer(VirtualTextureInfo* _info)
: m_info(_info)
{
m_mipcount = (int)(log2(m_info->GetPageTableSize()) + 1);
m_mipcount = int(bx::log2((float)m_info->GetPageTableSize()) + 1);
m_sizes.resize(m_mipcount);
for (int i = 0; i < m_mipcount; ++i)
@ -200,6 +205,10 @@ int PageIndexer::getCount() const
return m_count;
}
int PageIndexer::getMipCount() const {
return m_mipcount;
}
// SimpleImage
SimpleImage::SimpleImage(int _width, int _height, int _channelCount, uint8_t _clearValue)
: m_width(_width)
@ -441,14 +450,14 @@ PageTable::PageTable(PageCache* _cache, VirtualTextureInfo* _info, PageIndexer*
, m_quadtree(nullptr)
, m_quadtreeDirty(true) // Force quadtree dirty on startup
{
int size = m_info->GetPageTableSize();
m_quadtree = new Quadtree({ 0, 0, size, size }, (int)log2(size));
auto size = m_info->GetPageTableSize();
m_quadtree = new 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); };
_cache->removed = [=](Page page, Point pt) { m_quadtreeDirty = true; m_quadtree->remove(page); pt; };
_cache->removed = [=](Page page, Point pt) { m_quadtreeDirty = true; m_quadtree->remove(page); BX_UNUSED(pt); };
int PageTableSizeLog2 = (int)log2(m_info->GetPageTableSize());
auto PageTableSizeLog2 = m_indexer->getMipCount();
for (int i = 0; i < PageTableSizeLog2 + 1; ++i)
{
@ -464,11 +473,11 @@ PageTable::~PageTable()
{
delete m_quadtree;
bgfx::destroy(m_texture);
for (int i = 0; i < m_images.size(); ++i)
for (int i = 0; i < (int)m_images.size(); ++i)
{
delete m_images[i];
}
for (int i = 0; i < m_stagingTextures.size(); ++i)
for (int i = 0; i < (int)m_stagingTextures.size(); ++i)
{
bgfx::destroy(m_stagingTextures[i]);
}
@ -481,7 +490,7 @@ void PageTable::update(bgfx::ViewId blitViewId)
return;
}
m_quadtreeDirty = false;
int PageTableSizeLog2 = (int)log2(m_info->GetPageTableSize());
auto PageTableSizeLog2 = m_indexer->getMipCount();
for (int i = 0; i < PageTableSizeLog2 + 1; ++i)
{
m_quadtree->write(*m_images[i], i);
@ -499,11 +508,11 @@ bgfx::TextureHandle PageTable::getTexture()
// PageLoader
PageLoader::PageLoader(TileDataFile* _tileDataFile, PageIndexer* _indexer, VirtualTextureInfo* _info)
: m_tileDataFile(_tileDataFile)
: m_colorMipLevels(false)
, m_showBorders(false)
, m_tileDataFile(_tileDataFile)
, m_indexer(_indexer)
, m_info(_info)
, m_colorMipLevels(false)
, m_showBorders(false)
{
}
@ -807,8 +816,8 @@ void FeedbackBuffer::download()
// We do this so that we can fall back to them if we run out of memory
void FeedbackBuffer::addRequestAndParents(Page request)
{
int PageTableSizeLog2 = (int)log2(m_info->GetPageTableSize());
int count = PageTableSizeLog2 - request.m_mip + 1;
auto PageTableSizeLog2 = m_indexer->getMipCount();
auto count = PageTableSizeLog2 - request.m_mip + 1;
for (int i = 0; i < count; ++i)
{
@ -817,6 +826,7 @@ void FeedbackBuffer::addRequestAndParents(Page request)
Page page = { xpos, ypos, request.m_mip + i };
// If it's not a valid page (position or mip out of range) just skip it
if (!m_indexer->isValid(page))
{
return;
@ -1001,7 +1011,7 @@ void VirtualTexture::update(const std::vector<int>& requests, bgfx::ViewId blitV
// If it is, update it's position in the LRU collection
// Otherwise add it to the list of pages to load
int touched = 0;
for (int i = 0; i < requests.size(); ++i)
for (int i = 0; i < (int)requests.size(); ++i)
{
if (requests[i] > 0)
{
@ -1039,10 +1049,10 @@ void VirtualTexture::update(const std::vector<int>& requests, bgfx::ViewId blitV
m_pageTable->update(blitViewId);
}
TileDataFile::TileDataFile(const std::string& filename, VirtualTextureInfo* _info, bool _readWrite) : m_info(_info)
TileDataFile::TileDataFile(const bx::FilePath& filename, VirtualTextureInfo* _info, bool _readWrite) : m_info(_info)
{
const char* access = _readWrite ? "w+b" : "rb";
m_file = fopen(filename.c_str(), access);
m_file = fopen(filename.get(), access);
m_size = m_info->GetPageSize() * m_info->GetPageSize() * ChannelCount;
}
@ -1108,28 +1118,32 @@ TileGenerator::~TileGenerator()
delete m_tileImage;
}
bool TileGenerator::generate(const std::string& filename)
bool TileGenerator::generate(const bx::FilePath& filename)
{
std::string cacheFilename = filename + ".cache";
// Generate cache filename
char tempFilename[256];
bx::snprintf(tempFilename, sizeof(tempFilename), "temp/%s.vt", filename.getBaseName().getPtr());
bx::FilePath cacheFilename = tempFilename;
// Check if tile file already exist
{
bx::Error error;
bx::FileReader fileReader;
fileReader.open(bx::FilePath(cacheFilename.c_str()), &error);
fileReader.open(cacheFilename, &error);
if (error.isOk())
{
bx::debugPrintf("Tile data file '%s' already exists. Skipping generation.\n", cacheFilename.c_str());
bx::debugPrintf("Tile data file '%s' already exists. Skipping generation.\n", cacheFilename.get());
return true;
}
}
// Read image
{
bx::debugPrintf("Reading image '%s'.\n", filename.c_str());
bx::debugPrintf("Reading image '%s'.\n", filename.get());
bx::Error error;
bx::FileReader fileReader;
fileReader.open(bx::FilePath(filename.c_str()), &error);
fileReader.open(bx::FilePath(filename.get()), &error);
if (!error.isOk())
{
bx::debugPrintf("Image open failed'%s'.\n", filename.get());
return false;
}
auto size = fileReader.seek(0, bx::Whence::End);
@ -1139,12 +1153,14 @@ bool TileGenerator::generate(const std::string& filename)
fileReader.close();
if (!error.isOk())
{
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);
if (!error.isOk())
{
bx::debugPrintf("Image parse failed'%s'.\n", filename.get());
return false;
}
}
@ -1164,8 +1180,8 @@ bool TileGenerator::generate(const std::string& filename)
// Generate tiles
bx::debugPrintf("Generating tiles\n");
int mipcount = (int)log2(m_info->GetPageTableSize());
for (int i = 0; i < mipcount + 1; ++i)
auto mipcount = m_indexer->getMipCount();
for (int i = 0; i < mipcount; ++i)
{
int count = (m_info->m_virtualTextureSize / m_tilesize) >> i;
bx::debugPrintf("Generating Mip:%d Count:%dx%d\n", i, count, count);
@ -1228,10 +1244,8 @@ void TileGenerator::CopyTile(SimpleImage& image, Page request)
Page page = { xpos + x - 1, ypos + y - 1, mip };
// Wrap so we get the border sections of other pages
#define Modulus(_a_, _b_) (int)(_a_ - _b_ * floorf( (float)_a_ / (float)_b_))
page.m_x = Modulus(page.m_x, size);
page.m_y = Modulus(page.m_y, size);
#undef Modulus
page.m_x = (int)bx::mod((float)page.m_x, (float)size);
page.m_y = (int)bx::mod((float)page.m_y, (float)size);
m_tileDataFile->readPage(m_indexer->getIndexFromPage(page), &m_page2Image->m_data[0]);

View File

@ -1,3 +1,8 @@
/*
* Copyright 2018 Aleš Mlakar. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#pragma once
#include "common.h"
#include "bgfx_utils.h"
@ -126,6 +131,7 @@ public:
bool isValid(Page page);
int getCount() const;
int getMipCount() const;
private:
VirtualTextureInfo* m_info;
@ -168,8 +174,8 @@ struct Quadtree
void write(Quadtree* node, SimpleImage& image, int miplevel);
static Quadtree* findPage(Quadtree* node, Page request, int* index);
int m_level;
Rect m_rectangle;
int m_level;
Point m_mapping;
Quadtree* m_children[4];
};
@ -374,7 +380,7 @@ private:
class TileDataFile
{
public:
TileDataFile(const std::string& filename, VirtualTextureInfo* _info, bool _readWrite = false);
TileDataFile(const bx::FilePath& filename, VirtualTextureInfo* _info, bool _readWrite = false);
~TileDataFile();
void readInfo();
@ -396,7 +402,7 @@ public:
TileGenerator(VirtualTextureInfo* _info);
~TileGenerator();
bool generate(const std::string& filename);
bool generate(const bx::FilePath& filename);
private:
void CopyTile(SimpleImage& image, Page request);