From 86c2352a375e915c26651e3ae904ce718b1fa3de Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Oct 2019 18:02:15 +0000 Subject: [PATCH] Fix a few issues with 1D array textures on GL --- renderdoc/driver/gl/gl_initstate.cpp | 35 ++++++++++++++++++++---- renderdoc/driver/gl/gl_rendertexture.cpp | 3 ++ renderdoc/driver/gl/gl_replay.cpp | 7 +++-- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/renderdoc/driver/gl/gl_initstate.cpp b/renderdoc/driver/gl/gl_initstate.cpp index bb195767b..294e62db5 100644 --- a/renderdoc/driver/gl/gl_initstate.cpp +++ b/renderdoc/driver/gl/gl_initstate.cpp @@ -895,9 +895,17 @@ void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, Resourc if(details.curType == eGL_TEXTURE_CUBE_MAP) d *= 6; else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || - details.curType == eGL_TEXTURE_1D_ARRAY || details.curType == eGL_TEXTURE_2D_ARRAY) + details.curType == eGL_TEXTURE_2D_ARRAY) d = details.depth; + // glCopyImageSubData treats 1D arrays sanely - with depth as array size - but at odds + // with the rest of the API. + if(details.curType == eGL_TEXTURE_1D_ARRAY) + { + h = 1; + d = details.height; + } + // AMD throws an error copying mips that are smaller than the block size in one dimension, // so do copy via CPU instead (will be slow, potentially we could optimise this if there's a // different GPU-side image copy routine that works on these dimensions. Hopefully there'll @@ -1116,10 +1124,12 @@ uint64_t GLResourceManager::GetSize_InitialState(ResourceId resid, const GLIniti uint32_t h = RDCMAX(TextureState.height >> i, 1U); uint32_t d = RDCMAX(TextureState.depth >> i, 1U); - if(TextureState.type == eGL_TEXTURE_CUBE_MAP_ARRAY || - TextureState.type == eGL_TEXTURE_1D_ARRAY || TextureState.type == eGL_TEXTURE_2D_ARRAY) + if(TextureState.type == eGL_TEXTURE_CUBE_MAP_ARRAY || TextureState.type == eGL_TEXTURE_2D_ARRAY) d = TextureState.depth; + if(TextureState.type == eGL_TEXTURE_1D_ARRAY) + h = TextureState.height; + uint32_t size = 0; // calculate the actual byte size of this mip @@ -1518,10 +1528,12 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId i d = RDCMAX(1, d >> 1); if(TextureState.type == eGL_TEXTURE_CUBE_MAP_ARRAY || - TextureState.type == eGL_TEXTURE_1D_ARRAY || TextureState.type == eGL_TEXTURE_2D_ARRAY) d = (GLsizei)TextureState.depth; + if(TextureState.type == eGL_TEXTURE_1D_ARRAY) + h = (GLsizei)TextureState.height; + // if this mip doesn't exist yet, we must create it with dummy data. if(m >= liveMips) { @@ -1640,9 +1652,12 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId i uint32_t d = RDCMAX(TextureState.depth >> i, 1U); if(TextureState.type == eGL_TEXTURE_CUBE_MAP_ARRAY || - TextureState.type == eGL_TEXTURE_1D_ARRAY || TextureState.type == eGL_TEXTURE_2D_ARRAY) + TextureState.type == eGL_TEXTURE_2D_ARRAY) d = TextureState.depth; + if(TextureState.type == eGL_TEXTURE_1D_ARRAY) + h = TextureState.height; + // calculate the actual byte size of this mip if(isCompressed) size = (uint32_t)GetCompressedByteSize(w, h, d, TextureState.internalformat); @@ -1960,9 +1975,17 @@ void GLResourceManager::Apply_InitialState(GLResource live, const GLInitialConte if(details.curType == eGL_TEXTURE_CUBE_MAP) d *= 6; else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || - details.curType == eGL_TEXTURE_1D_ARRAY || details.curType == eGL_TEXTURE_2D_ARRAY) + details.curType == eGL_TEXTURE_2D_ARRAY) d = details.depth; + // glCopyImageSubData treats 1D arrays sanely - with depth as array size - but at odds + // with the rest of the API. + if(details.curType == eGL_TEXTURE_1D_ARRAY) + { + h = 1; + d = details.height; + } + // AMD throws an error copying mips that are smaller than the block size in one dimension, // so do copy via CPU instead (will be slow, potentially we could optimise this if there's // a different GPU-side image copy routine that works on these dimensions. Hopefully diff --git a/renderdoc/driver/gl/gl_rendertexture.cpp b/renderdoc/driver/gl/gl_rendertexture.cpp index c8a72110b..0e0ea2c13 100644 --- a/renderdoc/driver/gl/gl_rendertexture.cpp +++ b/renderdoc/driver/gl/gl_rendertexture.cpp @@ -372,6 +372,9 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags) if(texDetails.curType == eGL_TEXTURE_CUBE_MAP) depth *= 6; + if(texDetails.curType == eGL_TEXTURE_1D_ARRAY) + depth = RDCMAX((uint32_t)texDetails.height, 1U); + uint32_t numSlices = depth * RDCMAX((uint32_t)texDetails.samples, 1U); uint32_t sliceFace = RDCCLAMP(cfg.sliceFace, 0U, numSlices - 1); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 0a7651acd..9ebce42a6 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -565,7 +565,7 @@ void GLReplay::CacheTexture(ResourceId id) case eGL_TEXTURE_1D_ARRAY: tex.dimension = 1; tex.width = (uint32_t)width; - tex.arraysize = depth; + tex.arraysize = height; break; case eGL_TEXTURE_2D: case eGL_TEXTURE_RECTANGLE: @@ -3125,6 +3125,9 @@ void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t GLint width = RDCMAX(1, texdetails.width >> mip); GLint height = RDCMAX(1, texdetails.height >> mip); + if(target == eGL_TEXTURE_1D_ARRAY) + height = 1; + if(IsCompressedFormat(fmt)) { if(target == eGL_TEXTURE_1D) @@ -3262,7 +3265,7 @@ void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t } // copy this slice into the 2D MSAA texture - CopyArrayToTex2DMS(tex, uploadTex, width, height, 1, texdetails.samples, + CopyArrayToTex2DMS(tex, uploadTex, width, height, texdetails.depth, texdetails.samples, texdetails.internalFormat, arrayIdx); // delete the temporary texture