diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index 4083f09251..188fff9979 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -85,16 +85,14 @@ TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t s auto transferDimensions = _parent._gpuObject.evalMipDimensions(sourceMip); GLenum format; GLenum type; + auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat()); format = texelFormat.format; type = texelFormat.type; - auto mipSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face); - if (0 == lines) { - _transferSize = mipSize; + _transferSize = mipData->getSize(); _bufferingLambda = [=] { - auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face); _buffer.resize(_transferSize); memcpy(&_buffer[0], mipData->readData(), _transferSize); _bufferingCompleted = true; @@ -103,11 +101,11 @@ TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t s } else { transferDimensions.y = lines; auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip); + auto mipSize = mipData->getSize(); auto bytesPerLine = (uint32_t)mipSize / dimensions.y; - auto sourceOffset = bytesPerLine * lineOffset; _transferSize = bytesPerLine * lines; + auto sourceOffset = bytesPerLine * lineOffset; _bufferingLambda = [=] { - auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face); _buffer.resize(_transferSize); memcpy(&_buffer[0], mipData->readData() + sourceOffset, _transferSize); _bufferingCompleted = true; @@ -587,10 +585,10 @@ void GL45ResourceTexture::populateTransferQueue() { // break down the transfers into chunks so that no single transfer is // consuming more than X bandwidth - auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face); + auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); const auto lines = mipDimensions.y; - auto bytesPerLine = mipSize / lines; - Q_ASSERT(0 == (mipSize % lines)); + auto bytesPerLine = (uint32_t)mipData->getSize() / lines; + Q_ASSERT(0 == (mipData->getSize() % lines)); uint32_t linesPerTransfer = (uint32_t)(MAX_TRANSFER_SIZE / bytesPerLine); uint32_t lineOffset = 0; while (lineOffset < lines) { diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 38019c5a03..1f66b2900e 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -149,10 +149,6 @@ PixelsPointer MemoryStorage::getMipFace(uint16 level, uint8 face) const { return PixelsPointer(); } -Size MemoryStorage::getMipFaceSize(uint16 level, uint8 face) const { - return getMipFace(level, face)->getSize(); -} - bool MemoryStorage::isMipAvailable(uint16 level, uint8 face) const { PixelsPointer mipFace = getMipFace(level, face); return (mipFace && mipFace->getSize()); @@ -482,39 +478,43 @@ uint16 Texture::autoGenerateMips(uint16 maxMip) { } uint16 Texture::getStoredMipWidth(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level); } - return evalMipWidth(level); + return 0; } uint16 Texture::getStoredMipHeight(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mip = accessStoredMipFace(level); + if (mip && mip->getSize()) { + return evalMipHeight(level); } - return evalMipHeight(level); + return 0; } uint16 Texture::getStoredMipDepth(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipDepth(level); } - return evalMipDepth(level); + return 0; } uint32 Texture::getStoredMipNumTexels(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); + return 0; } uint32 Texture::getStoredMipSize(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); } - - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); + return 0; } gpu::Resource::Size Texture::getStoredSize() const { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index d6185df0d4..ce71b41b77 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -25,8 +25,6 @@ namespace ktx { class KTX; using KTXUniquePointer = std::unique_ptr; - struct KTXDescriptor; - using KTXDescriptorPointer = std::unique_ptr; struct Header; } @@ -263,7 +261,6 @@ public: virtual void reset() = 0; virtual PixelsPointer getMipFace(uint16 level, uint8 face = 0) const = 0; - virtual Size getMipFaceSize(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; @@ -289,7 +286,6 @@ public: public: void reset() override; PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override; - Size getMipFaceSize(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; @@ -301,9 +297,8 @@ public: class KtxStorage : public Storage { public: - KtxStorage(const std::string& filename); + KtxStorage(ktx::KTXUniquePointer& ktxData); PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override; - Size getMipFaceSize(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; } @@ -317,8 +312,7 @@ public: void reset() override { } protected: - std::string _filename; - ktx::KTXDescriptorPointer _ktxDescriptor; + ktx::KTXUniquePointer _ktxData; friend class Texture; }; @@ -481,10 +475,9 @@ public: // Access the the sub mips 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); } - Size getStoredMipFaceSize(uint16 level, uint8 face = 0) const { return _storage->getMipFaceSize(level, face); } void setStorage(std::unique_ptr& newStorage); - void setKtxBacking(const std::string& filename); + void setKtxBacking(ktx::KTXUniquePointer& newBacking); // access sizes for the stored mips uint16 getStoredMipWidth(uint16 level) const; @@ -522,7 +515,7 @@ public: // Textures can be serialized directly to ktx data file, here is how static ktx::KTXUniquePointer serialize(const Texture& texture); - static Texture* unserialize(const std::string& ktxFile, TextureUsageType usageType = TextureUsageType::RESOURCE, Usage usage = Usage(), const Sampler::Desc& sampler = Sampler::Desc()); + static Texture* unserialize(const ktx::KTXUniquePointer& srcData, TextureUsageType usageType = TextureUsageType::RESOURCE, Usage usage = Usage(), const Sampler::Desc& sampler = Sampler::Desc()); static bool evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header); static bool evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat); diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 913ced8141..ab5be7475a 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -42,37 +42,30 @@ struct GPUKTXPayload { std::string GPUKTXPayload::KEY { "hifi.gpu" }; -KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { - { - ktx::StoragePointer storage { new storage::FileStorage(_filename.c_str()) }; - auto ktxPointer = ktx::KTX::create(storage); - _ktxDescriptor.reset(new ktx::KTXDescriptor(ktxPointer->toDescriptor())); +KtxStorage::KtxStorage(ktx::KTXUniquePointer& ktxData) { + + // if the source ktx is valid let's config this KtxStorage correctly + if (ktxData && ktxData->getHeader()) { + + // now that we know the ktx, let's get the header info to configure this Texture::Storage: + Format mipFormat = Format::COLOR_BGRA_32; + Format texelFormat = Format::COLOR_SRGBA_32; + if (Texture::evalTextureFormat(*ktxData->getHeader(), mipFormat, texelFormat)) { + _format = mipFormat; + } + + } - // now that we know the ktx, let's get the header info to configure this Texture::Storage: - Format mipFormat = Format::COLOR_BGRA_32; - Format texelFormat = Format::COLOR_SRGBA_32; - if (Texture::evalTextureFormat(_ktxDescriptor->header, mipFormat, texelFormat)) { - _format = mipFormat; - } + _ktxData.reset(ktxData.release()); } PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const { - storage::StoragePointer result; - auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face); - auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face); - if (faceSize != 0 && faceOffset != 0) { - result = std::make_shared(_filename.c_str())->createView(faceSize, faceOffset)->toMemoryStorage(); - } - return result; + return _ktxData->getMipFaceTexelsData(level, face); } -Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const { - return _ktxDescriptor->getMipFaceTexelsSize(level, face); -} - -void Texture::setKtxBacking(const std::string& filename) { - auto newBacking = std::unique_ptr(new KtxStorage(filename)); +void Texture::setKtxBacking(ktx::KTXUniquePointer& ktxBacking) { + auto newBacking = std::unique_ptr(new KtxStorage(ktxBacking)); setStorage(newBacking); } @@ -184,9 +177,11 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { return ktxBuffer; } -Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) { - ktx::KTXDescriptor descriptor { ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) })->toDescriptor() }; - const auto& header = descriptor.header; +Texture* Texture::unserialize(const ktx::KTXUniquePointer& srcData, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) { + if (!srcData) { + return nullptr; + } + const auto& header = *srcData->getHeader(); Format mipFormat = Format::COLOR_BGRA_32; Format texelFormat = Format::COLOR_SRGBA_32; @@ -214,7 +209,7 @@ Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usage // If found, use the GPUKTXPayload gpuktxKeyValue; - bool isGPUKTXPayload = GPUKTXPayload::findInKeyValues(descriptor.keyValues, gpuktxKeyValue); + bool isGPUKTXPayload = GPUKTXPayload::findInKeyValues(srcData->_keyValues, gpuktxKeyValue); auto tex = Texture::create( (isGPUKTXPayload ? gpuktxKeyValue._usageType : usageType), type, @@ -230,7 +225,14 @@ Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usage // Assing the mips availables tex->setStoredMipFormat(mipFormat); - tex->setKtxBacking(ktxfile); + uint16_t level = 0; + for (auto& image : srcData->_images) { + for (uint32_t face = 0; face < image._numFaces; face++) { + tex->assignStoredMipFace(level, face, image._faceSize, image._faceBytes[face]); + } + level++; + } + return tex; } diff --git a/libraries/ktx/src/ktx/KTX.cpp b/libraries/ktx/src/ktx/KTX.cpp index 6fca39788b..bbd4e1bc86 100644 --- a/libraries/ktx/src/ktx/KTX.cpp +++ b/libraries/ktx/src/ktx/KTX.cpp @@ -108,39 +108,47 @@ KTX::~KTX() { void KTX::resetStorage(const StoragePointer& storage) { _storage = storage; - if (_storage->size() >= sizeof(Header)) { - memcpy(&_header, _storage->data(), sizeof(Header)); - } } -const Header& KTX::getHeader() const { - return _header; +const Header* KTX::getHeader() const { + if (!_storage) { + return nullptr; + } + return reinterpret_cast(_storage->data()); } size_t KTX::getKeyValueDataSize() const { - return _header.bytesOfKeyValueData; + if (_storage) { + return getHeader()->bytesOfKeyValueData; + } else { + return 0; + } } size_t KTX::getTexelsDataSize() const { - if (!_storage) { + if (_storage) { + //return _storage->size() - (sizeof(Header) + getKeyValueDataSize()); + return (_storage->data() + _storage->size()) - getTexelsData(); + } else { return 0; } - return (_storage->data() + _storage->size()) - getTexelsData(); } const Byte* KTX::getKeyValueData() const { - if (!_storage) { + if (_storage) { + return (_storage->data() + sizeof(Header)); + } else { return nullptr; } - return (_storage->data() + sizeof(Header)); } const Byte* KTX::getTexelsData() const { - if (!_storage) { + if (_storage) { + return (_storage->data() + sizeof(Header) + getKeyValueDataSize()); + } else { return nullptr; } - return (_storage->data() + sizeof(Header) + getKeyValueDataSize()); } storage::StoragePointer KTX::getMipFaceTexelsData(uint16_t mip, uint8_t face) const { @@ -155,58 +163,3 @@ storage::StoragePointer KTX::getMipFaceTexelsData(uint16_t mip, uint8_t face) co } return result; } - -size_t KTXDescriptor::getMipFaceTexelsSize(uint16_t mip, uint8_t face) const { - size_t result { 0 }; - if (mip < images.size()) { - const auto& faces = images[mip]; - if (face < faces._numFaces) { - result = faces._faceSize; - } - } - return result; -} - -size_t KTXDescriptor::getMipFaceTexelsOffset(uint16_t mip, uint8_t face) const { - size_t result { 0 }; - if (mip < images.size()) { - const auto& faces = images[mip]; - if (face < faces._numFaces) { - result = faces._faceOffsets[face]; - } - } - return result; -} - -ImageDescriptor Image::toImageDescriptor(const Byte* baseAddress) const { - FaceOffsets offsets; - offsets.resize(_faceBytes.size()); - for (size_t face = 0; face < _numFaces; ++face) { - offsets[face] = _faceBytes[face] - baseAddress; - } - // Note, implicit cast of *this to const ImageHeader& - return ImageDescriptor(*this, offsets); -} - -Image ImageDescriptor::toImage(const ktx::StoragePointer& storage) const { - FaceBytes faces; - faces.resize(_faceOffsets.size()); - for (size_t face = 0; face < _numFaces; ++face) { - faces[face] = storage->data() + _faceOffsets[face]; - } - // Note, implicit cast of *this to const ImageHeader& - return Image(*this, faces); -} - -KTXDescriptor KTX::toDescriptor() const { - ImageDescriptors newDescriptors; - auto storageStart = _storage ? _storage->data() : nullptr; - for (size_t i = 0; i < _images.size(); ++i) { - newDescriptors.emplace_back(_images[i].toImageDescriptor(storageStart)); - } - return { this->_header, this->_keyValues, newDescriptors }; -} - -KTX::KTX(const StoragePointer& storage, const Header& header, const KeyValues& keyValues, const Images& images) - : _header(header), _storage(storage), _keyValues(keyValues), _images(images) { -} \ No newline at end of file diff --git a/libraries/ktx/src/ktx/KTX.h b/libraries/ktx/src/ktx/KTX.h index f09986991a..8e901b1105 100644 --- a/libraries/ktx/src/ktx/KTX.h +++ b/libraries/ktx/src/ktx/KTX.h @@ -407,69 +407,43 @@ namespace ktx { }; using KeyValues = KeyValue::KeyValues; - struct ImageHeader { - using FaceOffsets = std::vector; + + struct Image { using FaceBytes = std::vector; - const uint32_t _numFaces; - const uint32_t _imageSize; - const uint32_t _faceSize; - const uint32_t _padding; - ImageHeader(bool cube, uint32_t imageSize, uint32_t padding) : - _numFaces(cube ? NUM_CUBEMAPFACES : 1), - _imageSize(imageSize * _numFaces), - _faceSize(imageSize), - _padding(padding) { - } - }; - struct Image; - - struct ImageDescriptor : public ImageHeader { - const FaceOffsets _faceOffsets; - ImageDescriptor(const ImageHeader& header, const FaceOffsets& offsets) : ImageHeader(header), _faceOffsets(offsets) {} - Image toImage(const ktx::StoragePointer& storage) const; - }; - - using ImageDescriptors = std::vector; - - struct Image : public ImageHeader { + uint32_t _numFaces{ 1 }; + uint32_t _imageSize; + uint32_t _faceSize; + uint32_t _padding; FaceBytes _faceBytes; - Image(const ImageHeader& header, const FaceBytes& faces) : ImageHeader(header), _faceBytes(faces) {} + + Image(uint32_t imageSize, uint32_t padding, const Byte* bytes) : - ImageHeader(false, imageSize, padding), + _numFaces(1), + _imageSize(imageSize), + _faceSize(imageSize), + _padding(padding), _faceBytes(1, bytes) {} + Image(uint32_t pageSize, uint32_t padding, const FaceBytes& cubeFaceBytes) : - ImageHeader(true, pageSize, padding) + _numFaces(NUM_CUBEMAPFACES), + _imageSize(pageSize * NUM_CUBEMAPFACES), + _faceSize(pageSize), + _padding(padding) { if (cubeFaceBytes.size() == NUM_CUBEMAPFACES) { _faceBytes = cubeFaceBytes; } } - - ImageDescriptor toImageDescriptor(const Byte* baseAddress) const; }; - using Images = std::vector; - class KTX; - - // A KTX descriptor is a lightweight container for all the information about a serialized KTX file, but without the - // actual image / face data available. - struct KTXDescriptor { - KTXDescriptor(const Header& header, const KeyValues& keyValues, const ImageDescriptors& imageDescriptors) : header(header), keyValues(keyValues), images(imageDescriptors) {} - const Header header; - const KeyValues keyValues; - const ImageDescriptors images; - size_t getMipFaceTexelsSize(uint16_t mip = 0, uint8_t face = 0) const; - size_t getMipFaceTexelsOffset(uint16_t mip = 0, uint8_t face = 0) const; - }; - class KTX { void resetStorage(const StoragePointer& src); KTX(); - KTX(const StoragePointer& storage, const Header& header, const KeyValues& keyValues, const Images& images); public: + ~KTX(); // Define a KTX object manually to write it somewhere (in a file on disk?) @@ -501,23 +475,18 @@ namespace ktx { static Images parseImages(const Header& header, size_t srcSize, const Byte* srcBytes); // Access raw pointers to the main sections of the KTX - const Header& getHeader() const; - + 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; } - KTXDescriptor toDescriptor() const; size_t getKeyValueDataSize() const; size_t getTexelsDataSize() const; - Header _header; StoragePointer _storage; KeyValues _keyValues; Images _images; - - friend struct KTXDescriptor; }; } diff --git a/libraries/ktx/src/ktx/Reader.cpp b/libraries/ktx/src/ktx/Reader.cpp index bf72faeba5..277ce42e69 100644 --- a/libraries/ktx/src/ktx/Reader.cpp +++ b/libraries/ktx/src/ktx/Reader.cpp @@ -185,10 +185,10 @@ namespace ktx { result->resetStorage(src); // read metadata - result->_keyValues = parseKeyValues(result->getHeader().bytesOfKeyValueData, result->getKeyValueData()); + result->_keyValues = parseKeyValues(result->getHeader()->bytesOfKeyValueData, result->getKeyValueData()); // populate image table - result->_images = parseImages(result->getHeader(), result->getTexelsDataSize(), result->getTexelsData()); + result->_images = parseImages(*result->getHeader(), result->getTexelsDataSize(), result->getTexelsData()); return result; } diff --git a/libraries/model-networking/src/model-networking/KTXCache.cpp b/libraries/model-networking/src/model-networking/KTXCache.cpp index 8ec1c4e41c..63d35fe4a4 100644 --- a/libraries/model-networking/src/model-networking/KTXCache.cpp +++ b/libraries/model-networking/src/model-networking/KTXCache.cpp @@ -38,3 +38,10 @@ std::unique_ptr KTXCache::createFile(Metadata&& metadata, const std::strin KTXFile::KTXFile(Metadata&& metadata, const std::string& filepath) : cache::File(std::move(metadata), filepath) {} +std::unique_ptr KTXFile::getKTX() const { + ktx::StoragePointer storage = std::make_shared(getFilepath().c_str()); + if (*storage) { + return ktx::KTX::create(storage); + } + return {}; +} diff --git a/libraries/model-networking/src/model-networking/KTXCache.h b/libraries/model-networking/src/model-networking/KTXCache.h index bbf7ceadea..4ef5e52721 100644 --- a/libraries/model-networking/src/model-networking/KTXCache.h +++ b/libraries/model-networking/src/model-networking/KTXCache.h @@ -39,6 +39,9 @@ protected: class KTXFile : public cache::File { Q_OBJECT +public: + std::unique_ptr getKTX() const; + protected: friend class KTXCache; diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 98b03eba1e..5dfaddd471 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -438,9 +438,15 @@ void NetworkTexture::loadContent(const QByteArray& content) { if (!texture) { KTXFilePointer ktxFile = textureCache->_ktxCache.getFile(hash); if (ktxFile) { - texture.reset(gpu::Texture::unserialize(ktxFile->getFilepath())); - if (texture) { - texture = textureCache->cacheTextureByHash(hash, texture); + // Ensure that the KTX deserialization worked + auto ktx = ktxFile->getKTX(); + if (ktx) { + texture.reset(gpu::Texture::unserialize(ktx)); + // Ensure that the texture population worked + if (texture) { + texture->setKtxBacking(ktx); + texture = textureCache->cacheTextureByHash(hash, texture); + } } } } @@ -580,7 +586,10 @@ void ImageReader::read() { qCWarning(modelnetworking) << _url << "file cache failed"; } else { resource.staticCast()->_file = file; - texture->setKtxBacking(file->getFilepath()); + auto fileKtx = file->getKTX(); + if (fileKtx) { + texture->setKtxBacking(fileKtx); + } } } diff --git a/tests/ktx/src/main.cpp b/tests/ktx/src/main.cpp index 3a6fcabf43..aa6795e17b 100644 --- a/tests/ktx/src/main.cpp +++ b/tests/ktx/src/main.cpp @@ -111,40 +111,38 @@ int main(int argc, char** argv) { outFile.close(); } + auto ktxFile = ktx::KTX::create(std::shared_ptr(new storage::FileStorage(TEST_IMAGE_KTX))); { - auto ktxFile = ktx::KTX::create(std::shared_ptr(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); - } + 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(TEST_IMAGE_KTX.toStdString()); + testTexture->setKtxBacking(ktxFile); return 0; }