From fa0fb113293d9847da10089727504f9186c99e10 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 25 Apr 2017 11:55:48 -0700 Subject: [PATCH] Remove uneeded memory to memory copy for mip transfers --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 42 ++++++++++------------- libraries/gpu-gl/src/gpu/gl/GLTexture.h | 7 ++-- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index a6e6bf4fa3..27a31ca678 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -140,7 +140,7 @@ GLExternalTexture::~GLExternalTexture() { if (recycler) { backend->releaseExternalTexture(_id, recycler); } else { - qWarning() << "No recycler available for texture " << _id << " possible leak"; + qCWarning(gpugllogging) << "No recycler available for texture " << _id << " possible leak"; } const_cast(_id) = 0; } @@ -210,38 +210,32 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t format = texelFormat.format; internalFormat = texelFormat.internalFormat; type = texelFormat.type; - auto mipSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face); + _transferSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face); - - if (0 == lines) { - _transferSize = mipSize; - _bufferingLambda = [=] { - auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face); - _buffer.resize(_transferSize); - memcpy(&_buffer[0], mipData->readData(), _transferSize); - _bufferingCompleted = true; - }; - - } else { + // If we're copying a subsection of the mip, do additional calculations to find the size and offset of the segment + if (0 != lines) { transferDimensions.y = lines; auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip); - auto bytesPerLine = (uint32_t)mipSize / dimensions.y; - auto sourceOffset = bytesPerLine * lineOffset; + auto bytesPerLine = (uint32_t)_transferSize / dimensions.y; + _transferOffset = bytesPerLine * lineOffset; _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); + 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 = [=] { - _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _buffer.size(), _buffer.data()); - std::vector emptyVector; - _buffer.swap(emptyVector); + _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData()); + _mipData.reset(); }; } diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.h b/libraries/gpu-gl/src/gpu/gl/GLTexture.h index 8b4b545b7d..b21ff53dd8 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.h +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.h @@ -49,8 +49,10 @@ public: using VoidLambdaQueue = std::queue; using ThreadPointer = std::shared_ptr; const GLTexture& _parent; - // Holds the contents to transfer to the GPU in CPU memory - std::vector _buffer; + Texture::PixelsPointer _mipData; + size_t _transferOffset { 0 }; + size_t _transferSize { 0 }; + // Indicates if a transfer from backing storage to interal storage has started bool _bufferingStarted { false }; bool _bufferingCompleted { false }; @@ -78,7 +80,6 @@ public: #endif private: - size_t _transferSize { 0 }; #if THREADED_TEXTURE_BUFFERING void startBuffering(); #endif