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:
Chris Collins 2017-04-26 21:31:19 -07:00 committed by GitHub
commit b2870be25c
3 changed files with 25 additions and 35 deletions

View file

@ -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);
}; };
} }

View file

@ -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

View file

@ -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;
} }