mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 04:53:10 +02:00
Implement KTXStorage::assignMipData and add writing of mips to
TextureCache
This commit is contained in:
parent
cf3dc12542
commit
e9bb895bff
4 changed files with 50 additions and 5 deletions
|
@ -118,6 +118,7 @@ Texture::Size Texture::getAllowedGPUMemoryUsage() {
|
||||||
return _allowedCPUMemoryUsage;
|
return _allowedCPUMemoryUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Texture::setAllowedGPUMemoryUsage(Size size) {
|
void Texture::setAllowedGPUMemoryUsage(Size size) {
|
||||||
qCDebug(gpulogging) << "New MAX texture memory " << BYTES_TO_MB(size) << " MB";
|
qCDebug(gpulogging) << "New MAX texture memory " << BYTES_TO_MB(size) << " MB";
|
||||||
_allowedCPUMemoryUsage = size;
|
_allowedCPUMemoryUsage = size;
|
||||||
|
|
|
@ -56,7 +56,8 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) {
|
||||||
if (found != keyValues.end()) {
|
if (found != keyValues.end()) {
|
||||||
_minMipLevelAvailable = found->_value[0];
|
_minMipLevelAvailable = found->_value[0];
|
||||||
} else {
|
} else {
|
||||||
_minMipLevelAvailable = 4;// _ktxDescriptor->header.numberOfMipmapLevels;
|
// Assume all mip levels are available
|
||||||
|
_minMipLevelAvailable = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +94,32 @@ bool KtxStorage::isMipAvailable(uint16 level, uint8 face) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& storage) {
|
void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& storage) {
|
||||||
throw std::runtime_error("Invalid call");
|
if (level != _minMipLevelAvailable - 1) {
|
||||||
|
qWarning() << "Invalid level to be stored";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level >= _ktxDescriptor->images.size()) {
|
||||||
|
throw std::runtime_error("Invalid level");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storage->size() != _ktxDescriptor->images[level]._imageSize) {
|
||||||
|
throw std::runtime_error("Invalid image size for level");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ktx::StoragePointer file { new storage::FileStorage(_filename.c_str()) };
|
||||||
|
auto data = file->mutableData();
|
||||||
|
data += file->size();
|
||||||
|
|
||||||
|
// TODO Cache this data inside Image or ImageDescriptor?
|
||||||
|
for (auto i = _ktxDescriptor->header.numberOfMipmapLevels - 1; i >= level; --i) {
|
||||||
|
data -= _ktxDescriptor->images[i]._imageSize;
|
||||||
|
data -= 4;
|
||||||
|
}
|
||||||
|
data += 4;
|
||||||
|
memcpy(data, storage->data(), _ktxDescriptor->images[level]._imageSize);
|
||||||
|
_minMipLevelAvailable = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KtxStorage::assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) {
|
void KtxStorage::assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) {
|
||||||
|
|
|
@ -45,10 +45,10 @@ namespace ktx {
|
||||||
|
|
||||||
auto newHeader = header;
|
auto newHeader = header;
|
||||||
|
|
||||||
Byte minMip = header.numberOfMipmapLevels - 6;
|
Byte minMip = header.numberOfMipmapLevels;
|
||||||
auto newKeyValues = keyValues;
|
auto newKeyValues = keyValues;
|
||||||
//newKeyValues.emplace_back(KeyValue(HIFI_MIN_POPULATED_MIP_KEY, sizeof(Byte), &minMip));
|
newKeyValues.emplace_back(KeyValue(HIFI_MIN_POPULATED_MIP_KEY, sizeof(Byte), &minMip));
|
||||||
//newHeader.bytesOfKeyValueData = KeyValue::serializedKeyValuesByteSize(newKeyValues);
|
newHeader.bytesOfKeyValueData = KeyValue::serializedKeyValuesByteSize(newKeyValues);
|
||||||
|
|
||||||
StoragePointer storagePointer;
|
StoragePointer storagePointer;
|
||||||
{
|
{
|
||||||
|
|
|
@ -387,6 +387,7 @@ void NetworkTexture::startMipRangeRequest(uint16_t low, uint16_t high) {
|
||||||
_ktxMipRequest = ResourceManager::createResourceRequest(this, _activeUrl);
|
_ktxMipRequest = ResourceManager::createResourceRequest(this, _activeUrl);
|
||||||
qDebug() << ">>> Making request to " << _url << " for " << low << " to " << high;
|
qDebug() << ">>> Making request to " << _url << " for " << low << " to " << high;
|
||||||
|
|
||||||
|
_ktxMipLevelRangeInFlight = { low, high };
|
||||||
if (isHighMipRequest) {
|
if (isHighMipRequest) {
|
||||||
// This is a special case where we load the high 7 mips
|
// This is a special case where we load the high 7 mips
|
||||||
ByteRange range;
|
ByteRange range;
|
||||||
|
@ -479,6 +480,23 @@ void NetworkTexture::maybeCreateKTX() {
|
||||||
texture->setKtxBacking(file->getFilepath());
|
texture->setKtxBacking(file->getFilepath());
|
||||||
texture->setSource(filename);
|
texture->setSource(filename);
|
||||||
|
|
||||||
|
auto& images = _ktxDescriptor->images;
|
||||||
|
size_t imageSizeRemaining = _ktxHighMipData.size();
|
||||||
|
uint8_t* ktxData = reinterpret_cast<uint8_t*>(_ktxHighMipData.data());
|
||||||
|
ktxData += _ktxHighMipData.size();
|
||||||
|
// TODO Move image offset calculation to ktx ImageDescriptor
|
||||||
|
for (uint16_t i = images.size() - 1; i >= 0; --i) {
|
||||||
|
auto& image = images[i];
|
||||||
|
if (image._imageSize > imageSizeRemaining) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qDebug() << "Transferring " << i;
|
||||||
|
ktxData -= image._imageSize;
|
||||||
|
texture->assignStoredMip(i, image._imageSize, ktxData);
|
||||||
|
ktxData -= 4;
|
||||||
|
imageSizeRemaining - image._imageSize - 4;
|
||||||
|
}
|
||||||
|
|
||||||
// We replace the texture with the one stored in the cache. This deals with the possible race condition of two different
|
// We replace the texture with the one stored in the cache. This deals with the possible race condition of two different
|
||||||
// images with the same hash being loaded concurrently. Only one of them will make it into the cache by hash first and will
|
// images with the same hash being loaded concurrently. Only one of them will make it into the cache by hash first and will
|
||||||
// be the winner
|
// be the winner
|
||||||
|
|
Loading…
Reference in a new issue