mirror of
https://github.com/overte-org/overte.git
synced 2025-07-24 09:23:49 +02:00
Improve gl backend handling of unavailable mips
This commit is contained in:
parent
70b816827e
commit
5594e81fe4
11 changed files with 58 additions and 11 deletions
|
@ -520,6 +520,7 @@ void GLVariableAllocationSupport::processWorkQueues() {
|
||||||
_memoryPressureStateStale = true;
|
_memoryPressureStateStale = true;
|
||||||
} else if (MemoryPressureState::Undersubscribed == _memoryPressureState) {
|
} else if (MemoryPressureState::Undersubscribed == _memoryPressureState) {
|
||||||
if (!vartexture->canPromote()) {
|
if (!vartexture->canPromote()) {
|
||||||
|
vartexture->populateTransferQueue();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
vartexture->promote();
|
vartexture->promote();
|
||||||
|
|
|
@ -116,6 +116,7 @@ protected:
|
||||||
bool canDemote() const { return _allocatedMip < _maxAllocatedMip; }
|
bool canDemote() const { return _allocatedMip < _maxAllocatedMip; }
|
||||||
bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; }
|
bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; }
|
||||||
void executeNextTransfer(const TexturePointer& currentTexture);
|
void executeNextTransfer(const TexturePointer& currentTexture);
|
||||||
|
virtual bool canPopulate() const = 0;
|
||||||
virtual void populateTransferQueue() = 0;
|
virtual void populateTransferQueue() = 0;
|
||||||
virtual void promote() = 0;
|
virtual void promote() = 0;
|
||||||
virtual void demote() = 0;
|
virtual void demote() = 0;
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
GL41VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
GL41VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||||
~GL41VariableAllocationTexture();
|
~GL41VariableAllocationTexture();
|
||||||
|
|
||||||
|
bool canPopulate() const override { return _gpuObject.isStoredMipFaceAvailable(_populatedMip - 1, 0); }
|
||||||
void allocateStorage(uint16 allocatedMip);
|
void allocateStorage(uint16 allocatedMip);
|
||||||
void syncSampler() const override;
|
void syncSampler() const override;
|
||||||
void promote() override;
|
void promote() override;
|
||||||
|
|
|
@ -392,8 +392,10 @@ void GL41VariableAllocationTexture::populateTransferQueue() {
|
||||||
--sourceMip;
|
--sourceMip;
|
||||||
auto targetMip = sourceMip - _allocatedMip;
|
auto targetMip = sourceMip - _allocatedMip;
|
||||||
auto mipDimensions = _gpuObject.evalMipDimensions(sourceMip);
|
auto mipDimensions = _gpuObject.evalMipDimensions(sourceMip);
|
||||||
|
bool didQueueTransfer = false;
|
||||||
for (uint8_t face = 0; face < maxFace; ++face) {
|
for (uint8_t face = 0; face < maxFace; ++face) {
|
||||||
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip, face)) {
|
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip, face)) {
|
||||||
|
const_cast<gpu::Texture&>(_gpuObject).requestInterestInMip(sourceMip);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,6 +403,7 @@ void GL41VariableAllocationTexture::populateTransferQueue() {
|
||||||
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
|
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
|
||||||
// Can the mip be transferred in one go
|
// Can the mip be transferred in one go
|
||||||
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
|
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
|
||||||
|
didQueueTransfer = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,14 +419,17 @@ void GL41VariableAllocationTexture::populateTransferQueue() {
|
||||||
uint32_t linesToCopy = std::min<uint32_t>(lines - lineOffset, linesPerTransfer);
|
uint32_t linesToCopy = std::min<uint32_t>(lines - lineOffset, linesPerTransfer);
|
||||||
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
|
_pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
|
||||||
lineOffset += linesToCopy;
|
lineOffset += linesToCopy;
|
||||||
|
didQueueTransfer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue up the sampler and populated mip change for after the transfer has completed
|
// queue up the sampler and populated mip change for after the transfer has completed
|
||||||
_pendingTransfers.emplace(new TransferJob(*this, [=] {
|
if (didQueueTransfer) {
|
||||||
_populatedMip = sourceMip;
|
_pendingTransfers.emplace(new TransferJob(*this, [=] {
|
||||||
syncSampler();
|
_populatedMip = sourceMip;
|
||||||
}));
|
syncSampler();
|
||||||
|
}));
|
||||||
|
}
|
||||||
} while (sourceMip != _allocatedMip);
|
} while (sourceMip != _allocatedMip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
GL45VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
GL45VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||||
~GL45VariableAllocationTexture();
|
~GL45VariableAllocationTexture();
|
||||||
Size size() const override { return _size; }
|
Size size() const override { return _size; }
|
||||||
|
bool canPopulate() const override { return _gpuObject.isStoredMipFaceAvailable(_populatedMip - 1, 0); }
|
||||||
Size _size { 0 };
|
Size _size { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,16 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (texture.getUsageType() == TextureUsageType::RESOURCE) {
|
||||||
|
auto varTex = static_cast<GL45VariableAllocationTexture*> (object);
|
||||||
|
|
||||||
|
if (varTex->canPromoteAndPopulate()) {
|
||||||
|
GL45VariableAllocationTexture::_memoryPressureStateStale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -62,6 +62,7 @@ GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend
|
||||||
//glObjectLabel(GL_TEXTURE, _id, _source.length(), _source.data());
|
//glObjectLabel(GL_TEXTURE, _id, _source.length(), _source.data());
|
||||||
uint16_t allocatedMip = _populatedMip - std::min<uint16_t>(_populatedMip, 2);
|
uint16_t allocatedMip = _populatedMip - std::min<uint16_t>(_populatedMip, 2);
|
||||||
allocateStorage(allocatedMip);
|
allocateStorage(allocatedMip);
|
||||||
|
_memoryPressureStateStale = true;
|
||||||
copyMipsFromTexture();
|
copyMipsFromTexture();
|
||||||
syncSampler();
|
syncSampler();
|
||||||
|
|
||||||
|
@ -105,7 +106,12 @@ void GL45ResourceTexture::syncSampler() const {
|
||||||
|
|
||||||
void GL45ResourceTexture::promote() {
|
void GL45ResourceTexture::promote() {
|
||||||
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
|
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
|
||||||
Q_ASSERT(_allocatedMip > 0);
|
//Q_ASSERT(_allocatedMip > 0);
|
||||||
|
uint16_t sourceMip = _populatedMip;
|
||||||
|
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip, 0)) {
|
||||||
|
const_cast<gpu::Texture&>(_gpuObject).requestInterestInMip(sourceMip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
GLuint oldId = _id;
|
GLuint oldId = _id;
|
||||||
auto oldSize = _size;
|
auto oldSize = _size;
|
||||||
// create new texture
|
// create new texture
|
||||||
|
@ -191,6 +197,7 @@ void GL45ResourceTexture::populateTransferQueue() {
|
||||||
for (uint8_t face = 0; face < maxFace; ++face) {
|
for (uint8_t face = 0; face < maxFace; ++face) {
|
||||||
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip, face)) {
|
if (!_gpuObject.isStoredMipFaceAvailable(sourceMip, face)) {
|
||||||
const_cast<gpu::Texture&>(_gpuObject).requestInterestInMip(sourceMip);
|
const_cast<gpu::Texture&>(_gpuObject).requestInterestInMip(sourceMip);
|
||||||
|
_minRequestedMip = sourceMip;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +225,7 @@ void GL45ResourceTexture::populateTransferQueue() {
|
||||||
lineOffset += linesToCopy;
|
lineOffset += linesToCopy;
|
||||||
transferQueued = true;
|
transferQueued = true;
|
||||||
}
|
}
|
||||||
|
_minRequestedMip = std::min(_minRequestedMip, sourceMip);
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue up the sampler and populated mip change for after the transfer has completed
|
// queue up the sampler and populated mip change for after the transfer has completed
|
||||||
|
|
|
@ -275,6 +275,7 @@ public:
|
||||||
virtual void assignMipData(uint16 level, const storage::StoragePointer& storage) = 0;
|
virtual void assignMipData(uint16 level, const storage::StoragePointer& storage) = 0;
|
||||||
virtual void assignMipFaceData(uint16 level, uint8 face, 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;
|
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const = 0;
|
||||||
|
virtual uint16 minAvailableMipLevel() const { return 0; }
|
||||||
Texture::Type getType() const { return _type; }
|
Texture::Type getType() const { return _type; }
|
||||||
|
|
||||||
Stamp getStamp() const { return _stamp; }
|
Stamp getStamp() const { return _stamp; }
|
||||||
|
@ -315,6 +316,7 @@ public:
|
||||||
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
|
bool isMipAvailable(uint16 level, uint8 face = 0) const override;
|
||||||
void assignMipData(uint16 level, const storage::StoragePointer& storage) override;
|
void assignMipData(uint16 level, const storage::StoragePointer& storage) override;
|
||||||
void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override;
|
void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override;
|
||||||
|
uint16 minAvailableMipLevel() const override;
|
||||||
|
|
||||||
void reset() override { }
|
void reset() override { }
|
||||||
|
|
||||||
|
@ -332,6 +334,8 @@ public:
|
||||||
friend class Texture;
|
friend class Texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint16 minAvailableMipLevel() const { return _storage->minAvailableMipLevel(); };
|
||||||
|
|
||||||
static const uint16 MAX_NUM_MIPS = 0;
|
static const uint16 MAX_NUM_MIPS = 0;
|
||||||
static const uint16 SINGLE_MIP = 1;
|
static const uint16 SINGLE_MIP = 1;
|
||||||
static TexturePointer create1D(const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer create1D(const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
|
|
|
@ -115,9 +115,14 @@ bool KtxStorage::isMipAvailable(uint16 level, uint8 face) const {
|
||||||
return avail;
|
return avail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 KtxStorage::minAvailableMipLevel() const {
|
||||||
|
return _minMipLevelAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& storage) {
|
void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& storage) {
|
||||||
if (level != _minMipLevelAvailable - 1) {
|
if (level != _minMipLevelAvailable - 1) {
|
||||||
qWarning() << "Invalid level to be stored, expected: " << (_minMipLevelAvailable - 1) << ", got: " << level;
|
qWarning() << "Invalid level to be stored, expected: " << (_minMipLevelAvailable - 1) << ", got: " << level;
|
||||||
|
//throw std::runtime_error("Invalid image size for level");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +133,7 @@ void KtxStorage::assignMipData(uint16 level, const storage::StoragePointer& stor
|
||||||
if (storage->size() != _ktxDescriptor->images[level]._imageSize) {
|
if (storage->size() != _ktxDescriptor->images[level]._imageSize) {
|
||||||
qDebug() << "Invalid image size: " << storage->size() << ", expected: " << _ktxDescriptor->images[level]._imageSize
|
qDebug() << "Invalid image size: " << storage->size() << ", expected: " << _ktxDescriptor->images[level]._imageSize
|
||||||
<< ", filename: " << QString::fromStdString(_filename);
|
<< ", filename: " << QString::fromStdString(_filename);
|
||||||
//throw std::runtime_error("Invalid image size for level");
|
throw std::runtime_error("Invalid image size for level");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,8 @@ size_t Header::evalPixelOrBlockSize() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qWarning() << "Unknown ktx format: " << glFormat << " " << glBaseInternalFormat << " " << glInternalFormat;
|
qWarning() << "Unknown ktx format: " << glFormat << " " << glBaseInternalFormat << " " << glInternalFormat;
|
||||||
throw std::runtime_error("Unknown format");
|
return 1;
|
||||||
|
//throw std::runtime_error("Unknown format");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Header::evalRowSize(uint32_t level) const {
|
size_t Header::evalRowSize(uint32_t level) const {
|
||||||
|
@ -130,9 +131,10 @@ ImageDescriptors Header::generateImageDescriptors() const {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
imageOffset += imageSize + 4;
|
imageOffset += (imageSize * numberOfFaces) + 4;
|
||||||
|
|
||||||
ImageHeader::FaceOffsets offsets;
|
ImageHeader::FaceOffsets offsets;
|
||||||
|
// TODO Add correct face offsets
|
||||||
for (uint32_t i = 0; i < numberOfFaces; ++i) {
|
for (uint32_t i = 0; i < numberOfFaces; ++i) {
|
||||||
offsets.push_back(0);
|
offsets.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,6 +388,7 @@ void NetworkTexture::makeRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkTexture::handleMipInterestCallback(uint16_t level) {
|
void NetworkTexture::handleMipInterestCallback(uint16_t level) {
|
||||||
|
//qDebug(networking) << "++++ Got request for mip level: " << _url << " " << level;
|
||||||
QMetaObject::invokeMethod(this, "handleMipInterestLevel", Qt::QueuedConnection, Q_ARG(int, level));
|
QMetaObject::invokeMethod(this, "handleMipInterestLevel", Qt::QueuedConnection, Q_ARG(int, level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +467,7 @@ void NetworkTexture::ktxMipRequestFinished() {
|
||||||
auto texture = _textureSource->getGPUTexture();
|
auto texture = _textureSource->getGPUTexture();
|
||||||
if (texture) {
|
if (texture) {
|
||||||
_lowestKnownPopulatedMip = _ktxMipLevelRangeInFlight.first;
|
_lowestKnownPopulatedMip = _ktxMipLevelRangeInFlight.first;
|
||||||
|
qDebug() << "Writing mip for " << _url;
|
||||||
texture->assignStoredMip(_ktxMipLevelRangeInFlight.first,
|
texture->assignStoredMip(_ktxMipLevelRangeInFlight.first,
|
||||||
_ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data()));
|
_ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data()));
|
||||||
} else {
|
} else {
|
||||||
|
@ -542,9 +544,10 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() {
|
||||||
});
|
});
|
||||||
std::string filename;
|
std::string filename;
|
||||||
if (found == keyValues.end()) {
|
if (found == keyValues.end()) {
|
||||||
qWarning("Source hash key not found, bailing");
|
//qWarning("Source hash key not found, bailing");
|
||||||
finishedLoading(false);
|
//finishedLoading(false);
|
||||||
return;
|
//return;
|
||||||
|
filename = _url.fileName().toStdString();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (found->_value.size() < 32) {
|
if (found->_value.size() < 32) {
|
||||||
|
@ -558,6 +561,11 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto memKtx = ktx::KTX::createBare(*header, keyValues);
|
auto memKtx = ktx::KTX::createBare(*header, keyValues);
|
||||||
|
if (!memKtx) {
|
||||||
|
qWarning() << " Ktx could not be created, bailing";
|
||||||
|
finishedLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//auto d = const_cast<uint8_t*>(memKtx->getStorage()->data());
|
//auto d = const_cast<uint8_t*>(memKtx->getStorage()->data());
|
||||||
//memcpy(d + memKtx->_storage->size() - _ktxHighMipData.size(), _ktxHighMipData.data(), _ktxHighMipData.size());
|
//memcpy(d + memKtx->_storage->size() - _ktxHighMipData.size(), _ktxHighMipData.data(), _ktxHighMipData.size());
|
||||||
|
|
Loading…
Reference in a new issue