From d4372847f32831851ad9d05398f779853187a802 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 9 Jun 2015 22:02:05 +0200 Subject: [PATCH] Better handling of emulated (luminance/alpha) textures in initial states * To simplify things we assume there won't be any user swizzling on luminance or alpha textures, and just apply our own to emulate rather than attempting to store & stack them. --- renderdoc/driver/gl/gl_driver.h | 3 ++- renderdoc/driver/gl/gl_manager.cpp | 8 ++++++- renderdoc/driver/gl/gl_resources.cpp | 19 +++++++++++---- renderdoc/driver/gl/gl_resources.h | 2 +- .../driver/gl/wrappers/gl_texture_funcs.cpp | 24 ++++++++++++------- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 65648fe9d..04af03862 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -221,7 +221,7 @@ class WrappedOpenGL : public IFrameCapturer struct TextureData { TextureData() - : curType(eGL_NONE), dimension(0) + : curType(eGL_NONE), dimension(0), emulated(false) , width(0), height(0), depth(0), samples(0) , creationFlags(0), internalFormat(eGL_NONE) , renderbufferReadTex(0) @@ -231,6 +231,7 @@ class WrappedOpenGL : public IFrameCapturer GLResource resource; GLenum curType; GLint dimension; + bool emulated; GLint width, height, depth, samples; uint32_t creationFlags; GLenum internalFormat; diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 16a3ec437..1754077b8 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -987,6 +987,9 @@ bool GLResourceManager::Serialise_InitialState(GLResource res) gl.glBindTexture(textype, prevtex); } + GLenum dummy; + EmulateLuminanceFormat(gl, tex, textype, internalformat, dummy); + // create texture of identical format/size to store initial contents if(textype == eGL_TEXTURE_BUFFER) { @@ -1419,7 +1422,10 @@ void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData i gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_BASE_LEVEL, (GLint *)&state->baseLevel); gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)state->swizzle); + + // assume that emulated (luminance, alpha-only etc) textures are not swizzled + if(!details.emulated) + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)state->swizzle); if(!ms) { diff --git a/renderdoc/driver/gl/gl_resources.cpp b/renderdoc/driver/gl/gl_resources.cpp index bb264490a..aac299319 100644 --- a/renderdoc/driver/gl/gl_resources.cpp +++ b/renderdoc/driver/gl/gl_resources.cpp @@ -122,7 +122,7 @@ size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type) GLenum GetBaseFormat(GLenum internalFormat) { - switch(internalFormat) + switch((int)internalFormat) { case eGL_R8: case eGL_R8_SNORM: @@ -133,6 +133,12 @@ GLenum GetBaseFormat(GLenum internalFormat) return eGL_RED; case eGL_ALPHA8_EXT: return eGL_ALPHA; + case eGL_LUMINANCE: + return eGL_LUMINANCE; + case eGL_LUMINANCE_ALPHA: + return eGL_LUMINANCE_ALPHA; + case eGL_INTENSITY: + return eGL_INTENSITY; case eGL_R8I: case eGL_R16I: case eGL_R32I: @@ -222,7 +228,7 @@ GLenum GetBaseFormat(GLenum internalFormat) GLenum GetDataType(GLenum internalFormat) { - switch(internalFormat) + switch((int)internalFormat) { case eGL_RGBA8UI: case eGL_RG8UI: @@ -313,6 +319,9 @@ GLenum GetDataType(GLenum internalFormat) case eGL_STENCIL_INDEX8: return eGL_UNSIGNED_BYTE; case eGL_ALPHA8_EXT: + case eGL_LUMINANCE_ALPHA: + case eGL_LUMINANCE: + case eGL_INTENSITY: return eGL_UNSIGNED_BYTE; default: break; @@ -451,7 +460,7 @@ GLenum GetSizedFormat(const GLHookSet &gl, GLenum target, GLenum internalFormat) return internalFormat; } -void EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat) +bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat) { GLenum swizzle[] = { eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA }; @@ -534,11 +543,13 @@ void EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLen swizzle[3] = eGL_GREEN; break; default: - return; + return false; } if(tex) gl.glTextureParameterivEXT(tex, target, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)swizzle); + + return true; } bool IsCompressedFormat(GLenum internalFormat) diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index c72d7d81a..c5c975def 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -36,7 +36,7 @@ GLenum GetBaseFormat(GLenum internalFormat); GLenum GetDataType(GLenum internalFormat); GLenum GetSizedFormat(const GLHookSet &gl, GLenum target, GLenum internalFormat); -void EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat); +bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat); int GetNumMips(const GLHookSet &gl, GLenum target, GLuint tex, GLuint w, GLuint h, GLuint d); diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index a361106e5..f50a26ba1 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -1619,7 +1619,7 @@ bool WrappedOpenGL::Serialise_glTextureImage1DEXT(GLuint texture, GLenum target, if(m_State == READING) { - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); if(Level == 0) // assume level 0 will always get a glTexImage call { @@ -1630,6 +1630,7 @@ bool WrappedOpenGL::Serialise_glTextureImage1DEXT(GLuint texture, GLenum target, if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 1; m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; } // for creation type chunks we forcibly don't use the unpack buffers as we @@ -1774,7 +1775,7 @@ bool WrappedOpenGL::Serialise_glTextureImage2DEXT(GLuint texture, GLenum target, if(m_State == READING) { - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); if(Level == 0) // assume level 0 will always get a glTexImage call { @@ -1785,6 +1786,7 @@ bool WrappedOpenGL::Serialise_glTextureImage2DEXT(GLuint texture, GLenum target, if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 2; m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; } // for creation type chunks we forcibly don't use the unpack buffers as we @@ -1956,7 +1958,7 @@ bool WrappedOpenGL::Serialise_glTextureImage3DEXT(GLuint texture, GLenum target, if(m_State == READING) { - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); if(Level == 0) // assume level 0 will always get a glTexImage call { @@ -1967,6 +1969,7 @@ bool WrappedOpenGL::Serialise_glTextureImage3DEXT(GLuint texture, GLenum target, if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 3; m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; } // for creation type chunks we forcibly don't use the unpack buffers as we @@ -2836,7 +2839,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(GLuint texture, GLenum targe if(m_State == READING) { GLenum dummy; - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; @@ -2845,6 +2848,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(GLuint texture, GLenum targe if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 1; m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; if(Target != eGL_NONE) m_Real.glTextureStorage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width); @@ -2929,7 +2933,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DEXT(GLuint texture, GLenum targe if(m_State == READING) { GLenum dummy; - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; @@ -2938,6 +2942,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DEXT(GLuint texture, GLenum targe if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 2; m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; if(Target != eGL_NONE) m_Real.glTextureStorage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width, Height); @@ -3021,7 +3026,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DEXT(GLuint texture, GLenum targe if(m_State == READING) { GLenum dummy; - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; @@ -3030,6 +3035,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DEXT(GLuint texture, GLenum targe if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 3; m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; if(Target != eGL_NONE) m_Real.glTextureStorage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width, Height, Depth); @@ -3113,7 +3119,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DMultisampleEXT(GLuint texture, G if(m_State == READING) { GLenum dummy; - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; @@ -3123,6 +3129,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DMultisampleEXT(GLuint texture, G if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 2; m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; if(Target != eGL_NONE) m_Real.glTextureStorage2DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, Target, Samples, Format, Width, Height, Fixedlocs ? GL_TRUE : GL_FALSE); @@ -3221,7 +3228,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DMultisampleEXT(GLuint texture, G if(m_State == READING) { GLenum dummy; - EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; @@ -3231,6 +3238,7 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DMultisampleEXT(GLuint texture, G if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); m_Textures[liveId].dimension = 2; m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; if(Target != eGL_NONE) m_Real.glTextureStorage3DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, Target, Samples, Format, Width, Height, Depth, Fixedlocs ? GL_TRUE : GL_FALSE);