mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 11:22:24 +02:00
Merge pull request #10256 from jherico/fix_stored_size
Fix excessive copying when querying the size of a KTX backed texture
This commit is contained in:
commit
b2870be25c
3 changed files with 25 additions and 35 deletions
|
@ -140,7 +140,7 @@ GLExternalTexture::~GLExternalTexture() {
|
||||||
if (recycler) {
|
if (recycler) {
|
||||||
backend->releaseExternalTexture(_id, recycler);
|
backend->releaseExternalTexture(_id, recycler);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "No recycler available for texture " << _id << " possible leak";
|
qCWarning(gpugllogging) << "No recycler available for texture " << _id << " possible leak";
|
||||||
}
|
}
|
||||||
const_cast<GLuint&>(_id) = 0;
|
const_cast<GLuint&>(_id) = 0;
|
||||||
}
|
}
|
||||||
|
@ -210,42 +210,32 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t
|
||||||
format = texelFormat.format;
|
format = texelFormat.format;
|
||||||
internalFormat = texelFormat.internalFormat;
|
internalFormat = texelFormat.internalFormat;
|
||||||
type = texelFormat.type;
|
type = texelFormat.type;
|
||||||
auto mipSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face);
|
_transferSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face);
|
||||||
|
|
||||||
|
// If we're copying a subsection of the mip, do additional calculations to find the size and offset of the segment
|
||||||
if (0 == lines) {
|
if (0 != lines) {
|
||||||
_transferSize = mipSize;
|
|
||||||
_bufferingLambda = [=] {
|
|
||||||
auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face);
|
|
||||||
if (!mipData) {
|
|
||||||
qWarning() << "Mip not available: " << sourceMip;
|
|
||||||
} else {
|
|
||||||
_buffer.resize(_transferSize);
|
|
||||||
memcpy(&_buffer[0], mipData->readData(), _transferSize);
|
|
||||||
}
|
|
||||||
_bufferingCompleted = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
transferDimensions.y = lines;
|
transferDimensions.y = lines;
|
||||||
auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
|
auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
|
||||||
auto bytesPerLine = (uint32_t)mipSize / dimensions.y;
|
auto bytesPerLine = (uint32_t)_transferSize / dimensions.y;
|
||||||
auto sourceOffset = bytesPerLine * lineOffset;
|
_transferOffset = bytesPerLine * lineOffset;
|
||||||
_transferSize = bytesPerLine * lines;
|
_transferSize = bytesPerLine * lines;
|
||||||
_bufferingLambda = [=] {
|
|
||||||
auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face);
|
|
||||||
_buffer.resize(_transferSize);
|
|
||||||
memcpy(&_buffer[0], mipData->readData() + sourceOffset, _transferSize);
|
|
||||||
_bufferingCompleted = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Backend::updateTextureTransferPendingSize(0, _transferSize);
|
Backend::updateTextureTransferPendingSize(0, _transferSize);
|
||||||
|
|
||||||
|
if (_transferSize > GLVariableAllocationSupport::MAX_TRANSFER_SIZE) {
|
||||||
|
qCWarning(gpugllogging) << "Transfer size of " << _transferSize << " exceeds theoretical maximum transfer size";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffering can invoke disk IO, so it should be off of the main and render threads
|
||||||
|
_bufferingLambda = [=] {
|
||||||
|
_mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face)->createView(_transferSize, _transferOffset);
|
||||||
|
_bufferingCompleted = true;
|
||||||
|
};
|
||||||
|
|
||||||
_transferLambda = [=] {
|
_transferLambda = [=] {
|
||||||
_parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _buffer.size(), _buffer.data());
|
_parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData());
|
||||||
std::vector<uint8_t> emptyVector;
|
_mipData.reset();
|
||||||
_buffer.swap(emptyVector);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,10 @@ public:
|
||||||
using VoidLambdaQueue = std::queue<VoidLambda>;
|
using VoidLambdaQueue = std::queue<VoidLambda>;
|
||||||
using ThreadPointer = std::shared_ptr<std::thread>;
|
using ThreadPointer = std::shared_ptr<std::thread>;
|
||||||
const GLTexture& _parent;
|
const GLTexture& _parent;
|
||||||
// Holds the contents to transfer to the GPU in CPU memory
|
Texture::PixelsPointer _mipData;
|
||||||
std::vector<uint8_t> _buffer;
|
size_t _transferOffset { 0 };
|
||||||
|
size_t _transferSize { 0 };
|
||||||
|
|
||||||
// Indicates if a transfer from backing storage to interal storage has started
|
// Indicates if a transfer from backing storage to interal storage has started
|
||||||
bool _bufferingStarted { false };
|
bool _bufferingStarted { false };
|
||||||
bool _bufferingCompleted { false };
|
bool _bufferingCompleted { false };
|
||||||
|
@ -78,7 +80,6 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t _transferSize { 0 };
|
|
||||||
#if THREADED_TEXTURE_BUFFERING
|
#if THREADED_TEXTURE_BUFFERING
|
||||||
void startBuffering();
|
void startBuffering();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -493,12 +493,11 @@ void Texture::setAutoGenerateMips(bool enable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Size Texture::getStoredMipSize(uint16 level) const {
|
Size Texture::getStoredMipSize(uint16 level) const {
|
||||||
PixelsPointer mipFace = accessStoredMipFace(level);
|
|
||||||
Size size = 0;
|
Size size = 0;
|
||||||
if (mipFace && mipFace->getSize()) {
|
for (int face = 0; face < getNumFaces(); face++) {
|
||||||
for (int face = 0; face < getNumFaces(); face++) {
|
if (isStoredMipFaceAvailable(level, face)) {
|
||||||
size += getStoredMipFaceSize(level, face);
|
size += getStoredMipFaceSize(level, face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue