From 1f090d8148210566f9bd2f2595dd7a002676cd1c Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Mon, 22 May 2017 01:00:34 -0700 Subject: [PATCH] Debugging the size problem and fixing the compression size evaluation --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 9 ++-- libraries/gpu-gl/src/gpu/gl/GLTexture.h | 6 +-- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 4 +- .../src/gpu/gl41/GL41BackendTexture.cpp | 18 ++++++-- libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 9 +++- .../src/gpu/gl45/GL45BackendTexture.cpp | 8 +++- .../gpu/gl45/GL45BackendVariableTexture.cpp | 46 +++++++++++++++++-- libraries/gpu/src/gpu/Context.cpp | 2 + libraries/gpu/src/gpu/Format.h | 2 + libraries/gpu/src/gpu/Texture.h | 6 ++- libraries/render/src/render/EngineStats.cpp | 2 + libraries/render/src/render/EngineStats.h | 2 + .../utilities/render/textureMonitor.qml | 5 ++ 13 files changed, 97 insertions(+), 22 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index afc257fcd1..15fdbace4c 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -115,19 +115,20 @@ GLTexture::~GLTexture() { } } -void GLTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const { +Size GLTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const { if (!_gpuObject.isStoredMipFaceAvailable(sourceMip)) { - return; + return 0; } - auto size = _gpuObject.evalMipDimensions(sourceMip); + auto dim = _gpuObject.evalMipDimensions(sourceMip); auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face); if (mipData) { GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); - copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.internalFormat, texelFormat.format, texelFormat.type, mipSize, mipData->readData()); + return copyMipFaceLinesFromTexture(targetMip, face, dim, 0, texelFormat.internalFormat, texelFormat.format, texelFormat.type, mipSize, mipData->readData()); } else { qCDebug(gpugllogging) << "Missing mipData level=" << sourceMip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str(); } + return 0; } diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.h b/libraries/gpu-gl/src/gpu/gl/GLTexture.h index c6ce2a2495..61312f588a 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.h +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.h @@ -174,8 +174,8 @@ public: protected: virtual Size size() const = 0; virtual void generateMips() const = 0; - virtual void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const = 0; - virtual void copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final; + virtual Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const = 0; + virtual Size copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final; GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); }; @@ -188,7 +188,7 @@ public: protected: GLExternalTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); void generateMips() const override {} - void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override {} + Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override { return 0;} Size size() const override { return 0; } }; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 003e7e83c3..e5c8b07aa8 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -54,7 +54,7 @@ public: protected: GL41Texture(const std::weak_ptr& backend, const Texture& texture); void generateMips() const override; - void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; + Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; virtual void syncSampler() const; void withPreservedTexture(std::function f) const; @@ -110,7 +110,7 @@ public: void promote() override; void demote() override; void populateTransferQueue() override; - void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; + Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; Size size() const override { return _size; } Size _size { 0 }; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 1dfad78d47..6cc8c0afb7 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -103,7 +103,8 @@ void GL41Texture::generateMips() const { (void)CHECK_GL_ERROR(); } -void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { +Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { + Size amountCopied = sourceSize; if (GL_TEXTURE_2D == _target) { switch (internalFormat) { case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: @@ -136,8 +137,10 @@ void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const } } else { assert(false); + amountCopied = 0; } (void)CHECK_GL_ERROR(); + return amountCopied; } void GL41Texture::syncSampler() const { @@ -274,18 +277,21 @@ GL41VariableAllocationTexture::GL41VariableAllocationTexture(const std::weak_ptr allocateStorage(allocatedMip); _memoryPressureStateStale = true; size_t maxFace = GLTexture::getFaceCount(_target); + Size amount = 0; for (uint16_t sourceMip = _populatedMip; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip - _allocatedMip; for (uint8_t face = 0; face < maxFace; ++face) { - copyMipFaceFromTexture(sourceMip, targetMip, face); + amount += copyMipFaceFromTexture(sourceMip, targetMip, face); } } + Backend::textureResourcePopulatedGPUMemSize.update(0, amount); syncSampler(); } GL41VariableAllocationTexture::~GL41VariableAllocationTexture() { Backend::textureResourceCount.decrement(); Backend::textureResourceGPUMemSize.update(_size, 0); + Backend::textureResourcePopulatedGPUMemSize.update(_size, 0); } void GL41VariableAllocationTexture::allocateStorage(uint16 allocatedMip) { @@ -309,10 +315,12 @@ void GL41VariableAllocationTexture::allocateStorage(uint16 allocatedMip) { } -void GL41VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { +Size GL41VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { + Size amountCopied = 0; withPreservedTexture([&] { - Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer); + amountCopied = Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer); }); + return amountCopied; } void GL41VariableAllocationTexture::syncSampler() const { @@ -477,6 +485,7 @@ void GL41VariableAllocationTexture::promote() { glDeleteTextures(1, &oldId); // update the memory usage Backend::textureResourceGPUMemSize.update(oldSize, 0); + // no change to Backend::textureResourcePopulatedGPUMemSize populateTransferQueue(); } @@ -508,6 +517,7 @@ void GL41VariableAllocationTexture::demote() { glDeleteTextures(1, &oldId); // update the memory usage Backend::textureResourceGPUMemSize.update(oldSize, 0); + Backend::textureResourcePopulatedGPUMemSize.update(oldSize, _size); // Demoting unpopulate the memory delta old - _size populateTransferQueue(); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index a0a919f4ad..46599e072c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -50,7 +50,7 @@ public: protected: GL45Texture(const std::weak_ptr& backend, const Texture& texture); void generateMips() const override; - void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; + Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; virtual void syncSampler() const; }; @@ -98,12 +98,17 @@ public: friend class GL45Backend; using PromoteLambda = std::function; + // Overight copy to inject counter for populated amount + Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override; protected: GL45VariableAllocationTexture(const std::weak_ptr& backend, const Texture& texture); ~GL45VariableAllocationTexture(); Size size() const override { return _size; } Size _size { 0 }; + void incrementPopulatedSize(Size delta) const; + void decrementPopulatedSize(Size delta) const; + mutable Size _populatedSize { 0 }; }; class GL45ResourceTexture : public GL45VariableAllocationTexture { @@ -118,7 +123,7 @@ public: void populateTransferQueue() override; void allocateStorage(uint16 mip); - void copyMipsFromTexture(); + Size copyMipsFromTexture(); }; #if 0 diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 60408b05fb..7dbd5c0ace 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -133,7 +133,8 @@ void GL45Texture::generateMips() const { (void)CHECK_GL_ERROR(); } -void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { +Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { + Size amountCopied = sourceSize; if (GL_TEXTURE_2D == _target) { switch (internalFormat) { case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: @@ -176,9 +177,12 @@ void GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const break; } } else { - Q_ASSERT(false); + assert(false); + amountCopied = 0; } (void)CHECK_GL_ERROR(); + + return amountCopied; } void GL45Texture::syncSampler() const { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index d78e068487..5bf022d515 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -37,6 +37,31 @@ GL45VariableAllocationTexture::GL45VariableAllocationTexture(const std::weak_ptr GL45VariableAllocationTexture::~GL45VariableAllocationTexture() { Backend::textureResourceCount.decrement(); Backend::textureResourceGPUMemSize.update(_size, 0); + Backend::textureResourcePopulatedGPUMemSize.update(_populatedSize, 0); +} +void GL45VariableAllocationTexture::incrementPopulatedSize(Size delta) const { + _populatedSize += delta; + if (_size < _populatedSize) { + + Backend::textureResourcePopulatedGPUMemSize.update(0, delta); + } else { + Backend::textureResourcePopulatedGPUMemSize.update(0, delta); + } +} +void GL45VariableAllocationTexture::decrementPopulatedSize(Size delta) const { + _populatedSize -= delta; + if (_size < _populatedSize) { + Backend::textureResourcePopulatedGPUMemSize.update(delta, 0); + } else { + Backend::textureResourcePopulatedGPUMemSize.update(delta, 0); + } +} + +Size GL45VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const { + Size amountCopied = 0; + amountCopied = Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer); + incrementPopulatedSize(amountCopied); + return amountCopied; } // Managed size resource textures @@ -63,7 +88,6 @@ GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr& backend _memoryPressureStateStale = true; copyMipsFromTexture(); syncSampler(); - } void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { @@ -75,22 +99,24 @@ void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); auto mipLevels = _gpuObject.getNumMips(); _size = 0; + bool wtf = false; for (uint16_t mip = _allocatedMip; mip < mipLevels; ++mip) { _size += _gpuObject.evalMipSize(mip); } - Backend::textureResourceGPUMemSize.update(0, _size); } -void GL45ResourceTexture::copyMipsFromTexture() { +Size GL45ResourceTexture::copyMipsFromTexture() { auto mipLevels = _gpuObject.getNumMips(); size_t maxFace = GLTexture::getFaceCount(_target); + Size amount = 0; for (uint16_t sourceMip = _populatedMip; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip - _allocatedMip; for (uint8_t face = 0; face < maxFace; ++face) { - copyMipFaceFromTexture(sourceMip, targetMip, face); + amount += copyMipFaceFromTexture(sourceMip, targetMip, face); } } + return amount; } void GL45ResourceTexture::syncSampler() const { @@ -141,6 +167,7 @@ void GL45ResourceTexture::promote() { glDeleteTextures(1, &oldId); // update the memory usage Backend::textureResourceGPUMemSize.update(oldSize, 0); + // no change to Backend::textureResourcePopulatedGPUMemSize syncSampler(); populateTransferQueue(); } @@ -150,6 +177,7 @@ void GL45ResourceTexture::demote() { Q_ASSERT(_allocatedMip < _maxAllocatedMip); auto oldId = _id; auto oldSize = _size; + auto oldPopulatedMip = _populatedMip; // allocate new texture const_cast(_id) = allocate(_gpuObject); @@ -165,6 +193,16 @@ void GL45ResourceTexture::demote() { glDeleteTextures(1, &oldId); // update the memory usage Backend::textureResourceGPUMemSize.update(oldSize, 0); + // Demoting unpopulate the memory delta + if (oldPopulatedMip != _populatedMip) { + auto numPopulatedDemoted = _populatedMip - oldPopulatedMip; + Size amountUnpopulated = 0; + for (int i = 0; i < numPopulatedDemoted; i++) { + //amountUnpopulated += _gpuObject.getStoredMipSize(oldPopulatedMip + i); + amountUnpopulated += _gpuObject.evalMipSize(oldPopulatedMip + i); + } + decrementPopulatedSize(amountUnpopulated); + } syncSampler(); populateTransferQueue(); } diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 140019f96f..2116ffd6fe 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -256,6 +256,8 @@ ContextMetricSize Backend::textureExternalGPUMemSize; ContextMetricCount Backend::texturePendingGPUTransferCount; ContextMetricSize Backend::texturePendingGPUTransferMemSize; +ContextMetricSize Backend::textureResourcePopulatedGPUMemSize; + Size Context::getFreeGPUMemSize() { return Backend::freeGPUMemSize.getValue(); } diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 729a1bbdc0..8fab7f9be7 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -63,6 +63,8 @@ static const int TYPE_SIZE[NUM_TYPES] = { 2, 2, 1, + 1, + 1 }; // Array answering the question Does this type is integer or not diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 3e4fdf113a..39398558fe 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -424,8 +424,12 @@ public: uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); } uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); } - // The size of a face is a multiple of the padded line = (width * texelFormat_size + alignment padding) + // The true size of a line or a sirface depends on the format and the padding + // is a multiple of the padded line = (width * texelFormat_size + alignment padding) + // + uint16 evaTiledWidth(uint16 width) const { return width >> 2 + width & 0x03; } Size evalMipLineSize(uint16 level) const { return evalPaddedSize(evalMipWidth(level) * getTexelFormat().getSize()); } + Size evalMipSurfaceSize(uint16 level) const { return evalPaddedSize(evalMipWidth(level) * getTexelFormat().getSize()); } // Size for each face of a mip at a particular level uint32 evalMipFaceNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index b2b78cf2a7..9e45be5dbd 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -46,6 +46,8 @@ void EngineStats::run(const RenderContextPointer& renderContext) { config->texturePendingGPUTransferCount = gpu::Context::getTexturePendingGPUTransferCount(); config->texturePendingGPUTransferSize = gpu::Context::getTexturePendingGPUTransferMemSize(); + config->textureResourcePopulatedGPUMemSize = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + renderContext->args->_context->getFrameStats(_gpuStats); config->frameAPIDrawcallCount = _gpuStats._DSNumAPIDrawcalls; diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index b8a52b6ed0..46be372d5d 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -45,6 +45,7 @@ namespace render { Q_PROPERTY(quint32 texturePendingGPUTransferCount MEMBER texturePendingGPUTransferCount NOTIFY dirty) Q_PROPERTY(qint64 texturePendingGPUTransferSize MEMBER texturePendingGPUTransferSize NOTIFY dirty) + Q_PROPERTY(qint64 textureResourcePopulatedGPUMemSize MEMBER textureResourcePopulatedGPUMemSize NOTIFY dirty) Q_PROPERTY(quint32 frameAPIDrawcallCount MEMBER frameAPIDrawcallCount NOTIFY dirty) Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty) @@ -84,6 +85,7 @@ namespace render { qint64 textureResourceGPUMemSize { 0 }; qint64 textureExternalGPUMemSize { 0 }; qint64 texturePendingGPUTransferSize { 0 }; + qint64 textureResourcePopulatedGPUMemSize { 0 }; quint32 frameAPIDrawcallCount{ 0 }; quint32 frameDrawcallCount{ 0 }; diff --git a/scripts/developer/utilities/render/textureMonitor.qml b/scripts/developer/utilities/render/textureMonitor.qml index 9a79bf62a9..1df51031c1 100644 --- a/scripts/developer/utilities/render/textureMonitor.qml +++ b/scripts/developer/utilities/render/textureMonitor.qml @@ -102,6 +102,11 @@ Item { prop: "textureFramebufferGPUMemSize", label: "Framebuffer", color: "#EF93D1" + }, + { + prop: "textureResourcePopulatedGPUMemSize", + label: "Populated", + color: "#C6A61F" } ] }