More KTX testing, functionality

This commit is contained in:
Brad Davis 2017-02-22 15:44:06 -08:00
parent 05efac9ddf
commit 62422690d0
5 changed files with 98 additions and 25 deletions

View file

@ -19,6 +19,7 @@
#include <QtCore/QThread>
#include <Trace.h>
#include <ktx/KTX.h>
#include <NumericalConstants.h>
#include "GPULogging.h"
@ -120,19 +121,24 @@ void Texture::setAllowedGPUMemoryUsage(Size size) {
uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = { 1, 1, 1, 6 };
void Texture::Storage::assignTexture(Texture* texture) {
using Storage = Texture::Storage;
using PixelsPointer = Texture::PixelsPointer;
using MemoryStorage = Texture::MemoryStorage;
using KtxStorage = Texture::KtxStorage;
void Storage::assignTexture(Texture* texture) {
_texture = texture;
if (_texture) {
_type = _texture->getType();
}
}
void Texture::MemoryStorage::reset() {
void MemoryStorage::reset() {
_mips.clear();
bumpStamp();
}
const Texture::PixelsPointer Texture::MemoryStorage::getMipFace(uint16 level, uint8 face) const {
PixelsPointer MemoryStorage::getMipFace(uint16 level, uint8 face) const {
if (level < _mips.size()) {
assert(face < _mips[level].size());
return _mips[level][face];
@ -140,12 +146,12 @@ const Texture::PixelsPointer Texture::MemoryStorage::getMipFace(uint16 level, ui
return PixelsPointer();
}
bool Texture::MemoryStorage::isMipAvailable(uint16 level, uint8 face) const {
bool MemoryStorage::isMipAvailable(uint16 level, uint8 face) const {
PixelsPointer mipFace = getMipFace(level, face);
return (mipFace && mipFace->getSize());
}
bool Texture::MemoryStorage::allocateMip(uint16 level) {
bool MemoryStorage::allocateMip(uint16 level) {
bool changed = false;
if (level >= _mips.size()) {
_mips.resize(level+1, std::vector<PixelsPointer>(Texture::NUM_FACES_PER_TYPE[getType()]));
@ -164,7 +170,7 @@ bool Texture::MemoryStorage::allocateMip(uint16 level) {
return changed;
}
void Texture::MemoryStorage::assignMipData(uint16 level, const storage::StoragePointer& storagePointer) {
void MemoryStorage::assignMipData(uint16 level, const storage::StoragePointer& storagePointer) {
allocateMip(level);
auto& mip = _mips[level];
@ -193,6 +199,13 @@ void Texture::MemoryStorage::assignMipFaceData(uint16 level, uint8 face, const s
}
}
KtxStorage::KtxStorage(ktx::KTXUniquePointer& ktxData) : _ktxData(ktxData.release()) {
}
PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const {
return _ktxData->getMipFaceTexelsData(level, face);
}
Texture* Texture::createExternal(const ExternalRecycler& recycler, const Sampler& sampler) {
Texture* tex = new Texture(TextureUsageType::EXTERNAL);
tex->_type = TEX_2D;
@ -963,3 +976,11 @@ Texture::ExternalUpdates Texture::getUpdates() const {
return result;
}
void Texture::setStorage(std::unique_ptr<Storage>& newStorage) {
_storage.swap(newStorage);
}
void Texture::setKtxBacking(ktx::KTXUniquePointer& ktxBacking) {
auto newBacking = std::unique_ptr<Storage>(new KtxStorage(ktxBacking));
setStorage(newBacking);
}

View file

@ -256,7 +256,7 @@ public:
virtual ~Storage() {}
virtual void reset() = 0;
virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const = 0;
virtual PixelsPointer getMipFace(uint16 level, uint8 face = 0) const = 0;
virtual void assignMipData(uint16 level, const storage::StoragePointer& storage) = 0;
virtual void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) = 0;
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const = 0;
@ -281,7 +281,7 @@ public:
class MemoryStorage : public Storage {
public:
void reset() override;
const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
void assignMipData(uint16 level, const storage::StoragePointer& storage) override;
void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override;
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
@ -294,8 +294,9 @@ public:
class KtxStorage : public Storage {
public:
KtxStorage(ktx::KTXUniquePointer& ktxData);
const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override;
// By convention, all mip levels and faces MUST be populated when using KTX backing
bool isMipAvailable(uint16 level, uint8 face = 0) const override { return true; }
void assignMipData(uint16 level, const storage::StoragePointer& storage) override {
throw std::runtime_error("Invalid call");
@ -474,6 +475,9 @@ public:
bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); }
const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0) const { return _storage->getMipFace(level, face); }
void setStorage(std::unique_ptr<Storage>& newStorage);
void setKtxBacking(ktx::KTXUniquePointer& newBacking);
// access sizes for the stored mips
uint16 getStoredMipWidth(uint16 level) const;
uint16 getStoredMipHeight(uint16 level) const;

View file

@ -126,3 +126,15 @@ const Byte* KTX::getTexelsData() const {
}
}
storage::StoragePointer KTX::getMipFaceTexelsData(uint16_t mip, uint8_t face) const {
storage::StoragePointer result;
if (mip < _images.size()) {
const auto& faces = _images[mip];
if (face < faces._numFaces) {
auto faceOffset = faces._faceBytes[face] - _storage->data();
auto faceSize = faces._faceSize;
result = _storage->createView(faceSize, faceOffset);
}
}
return result;
}

View file

@ -459,6 +459,7 @@ namespace ktx {
const Header* getHeader() const;
const Byte* getKeyValueData() const;
const Byte* getTexelsData() const;
storage::StoragePointer getMipFaceTexelsData(uint16_t mip = 0, uint8_t face = 0) const;
const StoragePointer& getStorage() const { return _storage; }
size_t getKeyValueDataSize() const;

View file

@ -87,6 +87,8 @@ int main(int argc, char** argv) {
QCoreApplication::setOrganizationDomain("highfidelity.com");
logger.reset(new FileLogger());
Q_ASSERT(sizeof(ktx::Header) == 12 + (sizeof(uint32_t) * 13));
DependencyManager::set<tracing::Tracer>();
qInstallMessageHandler(messageHandler);
QLoggingCategory::setFilterRules(LOG_FILTER_RULES);
@ -94,22 +96,55 @@ int main(int argc, char** argv) {
QImage image(TEST_IMAGE);
gpu::Texture* testTexture = model::TextureUsage::process2DTextureColorFromImage(image, TEST_IMAGE.toStdString(), true, false, true);
auto ktxPtr = gpu::Texture::serialize(*testTexture);
const auto& ktxStorage = ktxPtr->getStorage();
auto header = ktxPtr->getHeader();
assert(sizeof(ktx::Header) == 12 + (sizeof(uint32_t) * 13));
QFile outFile(TEST_IMAGE_KTX);
if (!outFile.open(QFile::Truncate | QFile::ReadWrite)) {
throw std::runtime_error("Unable to open file");
auto ktxMemory = gpu::Texture::serialize(*testTexture);
{
const auto& ktxStorage = ktxMemory->getStorage();
auto header = ktxMemory->getHeader();
QFile outFile(TEST_IMAGE_KTX);
if (!outFile.open(QFile::Truncate | QFile::ReadWrite)) {
throw std::runtime_error("Unable to open file");
}
//auto ktxSize = sizeof(ktx::Header); // ktxStorage->size()
auto ktxSize = ktxStorage->size();
outFile.resize(ktxSize);
auto dest = outFile.map(0, ktxSize);
memcpy(dest, ktxStorage->data(), ktxSize);
outFile.unmap(dest);
outFile.close();
}
//auto ktxSize = sizeof(ktx::Header); // ktxStorage->size()
auto ktxSize = ktxStorage->size();
outFile.resize(ktxSize);
auto dest = outFile.map(0, ktxSize);
memcpy(dest, ktxStorage->data(), ktxSize);
outFile.unmap(dest);
outFile.close();
// gpu::Texture* ktxTexture = cacheTexture(TEST_IMAGE.toStdString(), testTexture, true, true);
auto ktxFile = ktx::KTX::create(std::unique_ptr<storage::Storage>(new storage::FileStorage(TEST_IMAGE_KTX)));
{
const auto& memStorage = ktxMemory->getStorage();
const auto& fileStorage = ktxFile->getStorage();
Q_ASSERT(memStorage->size() == fileStorage->size());
Q_ASSERT(memStorage->data() != fileStorage->data());
Q_ASSERT(0 == memcmp(memStorage->data(), fileStorage->data(), memStorage->size()));
Q_ASSERT(ktxFile->_images.size() == ktxMemory->_images.size());
auto imageCount = ktxFile->_images.size();
auto startMemory = ktxMemory->_storage->data();
auto startFile = ktxFile->_storage->data();
for (size_t i = 0; i < imageCount; ++i) {
auto memImages = ktxMemory->_images[i];
auto fileImages = ktxFile->_images[i];
Q_ASSERT(memImages._padding == fileImages._padding);
Q_ASSERT(memImages._numFaces == fileImages._numFaces);
Q_ASSERT(memImages._imageSize == fileImages._imageSize);
Q_ASSERT(memImages._faceSize == fileImages._faceSize);
Q_ASSERT(memImages._faceBytes.size() == memImages._numFaces);
Q_ASSERT(fileImages._faceBytes.size() == fileImages._numFaces);
auto faceCount = fileImages._numFaces;
for (uint32_t face = 0; face < faceCount; ++face) {
auto memFace = memImages._faceBytes[face];
auto memOffset = memFace - startMemory;
auto fileFace = fileImages._faceBytes[face];
auto fileOffset = fileFace - startFile;
Q_ASSERT(memOffset % 4 == 0);
Q_ASSERT(memOffset == fileOffset);
}
}
}
testTexture->setKtxBacking(ktxFile);
return 0;
}