From 6785272944eab9068700d3838958cc0cb0b639cf Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 27 Jun 2018 13:50:09 +0100 Subject: [PATCH] Copy stored compressed data on GLES in glCopyImageSubData * Could be a common pattern with texture streaming to copy a smaller texture's mips into the mip-tail of a larger texture, then only provide data for higher mips. --- renderdoc/driver/gl/gl_driver.h | 12 ++--- .../driver/gl/wrappers/gl_texture_funcs.cpp | 45 ++++++++++++++++--- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 10df7f7c9..82459ab50 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -236,7 +236,7 @@ private: list m_DrawcallStack; - map > m_ResourceUses; + map> m_ResourceUses; bool m_FetchCounters; @@ -253,6 +253,9 @@ private: map m_Buffers; + // map with key being mip level, value being stored data + typedef std::map> CompressedDataStore; + struct TextureData { TextureData() @@ -288,13 +291,12 @@ private: // since compressed textures cannot be read back on GLES we have to store them during the // uploading - // level -> data - map > compressedData; + CompressedDataStore compressedData; void GetCompressedImageDataGLES(int mip, GLenum target, size_t size, byte *buf); }; - map m_Textures; + std::map m_Textures; struct ShaderData { @@ -365,7 +367,7 @@ private: map m_Shaders; map m_Programs; map m_Pipelines; - vector > m_DependentReplacements; + vector> m_DependentReplacements; GLuint m_FakeBB_FBO; GLuint m_FakeBB_Color; diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index 4f1006c99..20f7cbba2 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -948,7 +948,42 @@ void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint s } else if(IsBackgroundCapturing(m_State)) { - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), dstName)); + GLResourceRecord *srcrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), srcName)); + GLResourceRecord *dstrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), dstName)); + + GetResourceManager()->MarkDirtyResource(dstrecord->GetResourceID()); + + // copy over compressed data, if it exists + if(IsGLES) + { + TextureData &srcData = m_Textures[srcrecord->GetResourceID()]; + + // if we have source compressed data to copy (for uncompressed textures, we won't) + if(srcData.compressedData.find(srcLevel) != srcData.compressedData.end()) + { + TextureData &dstData = m_Textures[dstrecord->GetResourceID()]; + + if(srcX == 0 || srcY == 0 || srcZ == 0 || dstX == 0 || dstY == 0 || dstZ == 0) + { + // we only support whole copies - sub-copies will not work correctly. + RDCASSERT(srcWidth == RDCMAX(1, srcData.width >> srcLevel)); + RDCASSERT(srcHeight == RDCMAX(1, srcData.height >> srcLevel)); + RDCASSERT(srcDepth == RDCMAX(1, srcData.depth >> srcLevel)); + + RDCASSERT(srcWidth == RDCMAX(1, dstData.width >> dstLevel)); + RDCASSERT(srcHeight == RDCMAX(1, dstData.height >> dstLevel)); + RDCASSERT(srcDepth == RDCMAX(1, dstData.depth >> dstLevel)); + + dstData.compressedData[dstLevel] = srcData.compressedData[srcLevel]; + } + else + { + RDCWARN("glCopyImageSubData doesn't support offsetted copies of compressed data"); + } + } + } } } @@ -2924,8 +2959,8 @@ void WrappedOpenGL::StoreCompressedTexData(ResourceId texId, GLenum target, GLin { size_t compressedImageSize = GetCompressedByteSize(width, height, 1, format); RDCASSERT(compressedImageSize == (size_t)imageSize); - auto &cd = m_Textures[texId].compressedData; - auto &cdData = cd[level]; + CompressedDataStore &cd = m_Textures[texId].compressedData; + std::vector &cdData = cd[level]; GLint zoff = IsCubeFace(target) ? CubeTargetIndex(target) : zoffset; size_t startOffset = imageSize * zoff; if(cdData.size() < startOffset + imageSize) @@ -2942,8 +2977,8 @@ void WrappedOpenGL::StoreCompressedTexData(ResourceId texId, GLenum target, GLin if(zoffset == 0) { RDCASSERT(GetCompressedByteSize(width, height, depth, format) == (size_t)imageSize); - auto &cd = m_Textures[texId].compressedData; - auto &cdData = cd[level]; + CompressedDataStore &cd = m_Textures[texId].compressedData; + std::vector &cdData = cd[level]; cdData.resize(imageSize); memcpy(cdData.data(), srcPixels, imageSize); }