From b09454a67d4a2a950c5452722aea15a5485a5384 Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:29:16 +0200 Subject: [PATCH 1/7] Correctly set and restore pixel pack state when capturing thumbnail; don't set GL_PIXEL_UNPACK_BUFFER to zero in the process. --- renderdoc/driver/gl/gl_driver.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index bbfc53742..fdda8a713 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -582,14 +582,26 @@ void WrappedOpenGL::Present(void *windowHandle) { RDCGLenum prevReadBuf = eGL_BACK; GLint prevBuf = 0; - GLint unpackBufBind = 0; + GLint packBufBind = 0; + GLint prevPackRowLen = 0; + GLint prevPackSkipRows = 0; + GLint prevPackSkipPixels = 0; + GLint prevPackAlignment = 0; m_Real.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&prevReadBuf); m_Real.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, &prevBuf); - m_Real.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, &unpackBufBind); + m_Real.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, &packBufBind); + m_Real.glGetIntegerv(eGL_PACK_ROW_LENGTH, &prevPackRowLen); + m_Real.glGetIntegerv(eGL_PACK_SKIP_ROWS, &prevPackSkipRows); + m_Real.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &prevPackSkipPixels); + m_Real.glGetIntegerv(eGL_PACK_ALIGNMENT, &prevPackAlignment); m_Real.glReadBuffer(eGL_BACK); m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); + m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); + m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); + m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); + m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, 1); thwidth = m_InitParams.width; thheight = m_InitParams.height; @@ -617,9 +629,13 @@ void WrappedOpenGL::Present(void *windowHandle) } } - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackBufBind); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, packBufBind); m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevBuf); m_Real.glReadBuffer(prevReadBuf); + m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, prevPackRowLen); + m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, prevPackSkipRows); + m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, prevPackSkipPixels); + m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, prevPackAlignment); } byte *jpgbuf = NULL; From 8fda0a817b3a72901fba8cd5cf38355c1578070f Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:38:31 +0200 Subject: [PATCH 2/7] Don't throw an error when serializing GL buffer initial state. --- renderdoc/driver/gl/gl_manager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 4fe9ff112..b6c2a47cf 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -132,7 +132,11 @@ bool GLResourceManager::Serialise_InitialState(GLResource res) res = GLResource(MakeNullResource); } - if(res.Namespace == eResVertexArray) + if(res.Namespace == eResBuffer) + { + // Nothing to serialize + } + else if(res.Namespace == eResVertexArray) { VertexArrayInitialData data[16]; From 6241559c594d9abd37f50f7ef5515fb6de1aa0bc Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:40:46 +0200 Subject: [PATCH 3/7] Don't set the GLResourceManager pointer to the serializer to NULL. --- renderdoc/driver/gl/gl_manager.h | 1 - 1 file changed, 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index f88051bfb..dbcb7f158 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -37,7 +37,6 @@ class GLResourceManager : public ResourceManager GLResourceManager(LogState state, Serialiser *ser, WrappedOpenGL *gl) : ResourceManager(state, ser), m_GL(gl), m_SyncName(1) { - m_pSerialiser = NULL; } ~GLResourceManager() {} From 1a71922910834c65e0beac04153427f15bd79e6f Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:44:12 +0200 Subject: [PATCH 4/7] Pass the base format and data type to GetByteSize instead of the internal format in GLReplay::GetTexture. --- renderdoc/driver/gl/gl_replay.cpp | 2 +- renderdoc/driver/gl/gl_resources.cpp | 193 +++++++++++++++++++++++++++ renderdoc/driver/gl/gl_resources.h | 2 + 3 files changed, 196 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index abcb41d38..2c9b42f3e 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -468,7 +468,7 @@ FetchTexture GLReplay::GetTexture(ResourceId id) else if(tex.format.special) { tex.byteSize += GetByteSize(RDCMAX(1U, tex.width>>m), RDCMAX(1U, tex.height>>m), RDCMAX(1U, tex.depth>>m), - (GLenum)fmt, (GLenum)fmt, 1); + GetBaseFormat((GLenum)fmt), GetDataType((GLenum)fmt), 1); } else { diff --git a/renderdoc/driver/gl/gl_resources.cpp b/renderdoc/driver/gl/gl_resources.cpp index 8758f5c74..4f4c2ec76 100644 --- a/renderdoc/driver/gl/gl_resources.cpp +++ b/renderdoc/driver/gl/gl_resources.cpp @@ -80,6 +80,7 @@ size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type, case eGL_UNSIGNED_INT_8_8_8_8_REV: case eGL_UNSIGNED_INT_10_10_10_2: case eGL_UNSIGNED_INT_2_10_10_10_REV: + case eGL_UNSIGNED_INT_10F_11F_11F_REV: return ((w*4 + alignAdd) & alignMask)*h*d; case eGL_DEPTH_COMPONENT16: return ((w*2 + alignAdd) & alignMask)*h*d; @@ -87,8 +88,10 @@ size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type, case eGL_DEPTH24_STENCIL8: case eGL_DEPTH_COMPONENT32: case eGL_DEPTH_COMPONENT32F: + case eGL_UNSIGNED_INT_24_8: return ((w*4 + alignAdd) & alignMask)*h*d; case eGL_DEPTH32F_STENCIL8: + case eGL_FLOAT_32_UNSIGNED_INT_24_8_REV: return ((w*5 + alignAdd) & alignMask)*h*d; default: RDCERR("Unhandled Byte Size type %d!", type); @@ -126,3 +129,193 @@ size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type, return 0; } + +GLenum GetBaseFormat(GLenum internalFormat) +{ + switch(internalFormat) + { + case eGL_R8: + case eGL_R8_SNORM: + case eGL_R16: + case eGL_R16_SNORM: + case eGL_R16F: + case eGL_R8I: + case eGL_R8UI: + case eGL_R16I: + case eGL_R16UI: + case eGL_R32I: + case eGL_R32UI: + case eGL_R32F: + return eGL_RED; + case eGL_RG8: + case eGL_RG8_SNORM: + case eGL_RG16: + case eGL_RG16_SNORM: + case eGL_RG16F: + case eGL_RG32F: + case eGL_RG8I: + case eGL_RG8UI: + case eGL_RG16I: + case eGL_RG16UI: + case eGL_RG32I: + case eGL_RG32UI: + return eGL_RG; + case eGL_R3_G3_B2: + case eGL_RGB4: + case eGL_RGB5: + case eGL_RGB565: + case eGL_RGB8: + case eGL_RGB8_SNORM: + case eGL_RGB10: + case eGL_RGB12: + case eGL_RGB16: + case eGL_RGB16_SNORM: + case eGL_SRGB8: + case eGL_RGB16F: + case eGL_RGB32F: + case eGL_R11F_G11F_B10F: + case eGL_RGB9_E5: + case eGL_RGB8I: + case eGL_RGB8UI: + case eGL_RGB16I: + case eGL_RGB16UI: + case eGL_RGB32I: + case eGL_RGB32UI: + return eGL_RGB; + case eGL_RGBA2: + case eGL_RGBA4: + case eGL_RGB5_A1: + case eGL_RGBA8: + case eGL_RGBA8_SNORM: + case eGL_RGB10_A2: + case eGL_RGB10_A2UI: + case eGL_RGBA12: + case eGL_RGBA16: + case eGL_RGBA16_SNORM: + case eGL_SRGB8_ALPHA8: + case eGL_RGBA16F: + case eGL_RGBA32F: + case eGL_RGBA8I: + case eGL_RGBA8UI: + case eGL_RGBA16I: + case eGL_RGBA16UI: + case eGL_RGBA32UI: + case eGL_RGBA32I: + return eGL_RGBA; + case eGL_DEPTH_COMPONENT16: + case eGL_DEPTH_COMPONENT24: + case eGL_DEPTH_COMPONENT32: + case eGL_DEPTH_COMPONENT32F: + return eGL_DEPTH_COMPONENT; + case eGL_DEPTH24_STENCIL8: + case eGL_DEPTH32F_STENCIL8: + return eGL_DEPTH_STENCIL; + case eGL_STENCIL_INDEX1: + case eGL_STENCIL_INDEX4: + case eGL_STENCIL_INDEX8: + case eGL_STENCIL_INDEX16: + return eGL_STENCIL; + } + + RDCERR("Unhandled Base Format case!"); + + return eGL_NONE; +} + +GLenum GetDataType(GLenum internalFormat) +{ + switch(internalFormat) + { + case eGL_RGBA8UI: + case eGL_RG8UI: + case eGL_R8UI: + case eGL_RGBA8: + case eGL_RG8: + case eGL_R8: + case eGL_RGB8: + case eGL_RGB8UI: + return eGL_UNSIGNED_BYTE; + case eGL_RGBA8I: + case eGL_RG8I: + case eGL_R8I: + case eGL_RGBA8_SNORM: + case eGL_RG8_SNORM: + case eGL_R8_SNORM: + case eGL_RGB8_SNORM: + case eGL_SRGB8: + case eGL_RGB8I: + case eGL_SRGB8_ALPHA8: + return eGL_BYTE; + case eGL_RGBA16UI: + case eGL_RG16UI: + case eGL_R16UI: + case eGL_RGBA16: + case eGL_RG16: + case eGL_R16: + case eGL_RGB16: + case eGL_RGB16UI: + case eGL_DEPTH_COMPONENT16: + return eGL_UNSIGNED_SHORT; + case eGL_RGBA16I: + case eGL_RG16I: + case eGL_R16I: + case eGL_RGBA16_SNORM: + case eGL_RG16_SNORM: + case eGL_R16_SNORM: + case eGL_RGB16_SNORM: + case eGL_RGB16I: + return eGL_SHORT; + case eGL_RGBA32UI: + case eGL_RG32UI: + case eGL_R32UI: + case eGL_RGB32UI: + case eGL_DEPTH_COMPONENT24: + case eGL_DEPTH_COMPONENT32: + return eGL_UNSIGNED_INT; + case eGL_RGBA32I: + case eGL_RG32I: + case eGL_R32I: + case eGL_RGB32I: + return eGL_INT; + case eGL_RGBA16F: + case eGL_RG16F: + case eGL_RGB16F: + case eGL_R16F: + return eGL_HALF_FLOAT; + case eGL_RGBA32F: + case eGL_RG32F: + case eGL_R32F: + case eGL_DEPTH_COMPONENT32F: + return eGL_FLOAT; + case eGL_R11F_G11F_B10F: + return eGL_UNSIGNED_INT_10F_11F_11F_REV; + case eGL_RGB10_A2UI: + return eGL_INT_2_10_10_10_REV; + case eGL_RGB10_A2: + return eGL_UNSIGNED_INT_2_10_10_10_REV; + case eGL_R3_G3_B2: + return eGL_UNSIGNED_BYTE_3_3_2; + case eGL_RGB4: + case eGL_RGBA4: + return eGL_UNSIGNED_SHORT_4_4_4_4; + case eGL_RGB5: + case eGL_RGB5_A1: + return eGL_UNSIGNED_SHORT_5_5_5_1; + case eGL_RGB565: + return eGL_UNSIGNED_SHORT_5_6_5; + case eGL_RGB10: + return eGL_UNSIGNED_INT_10_10_10_2; + case eGL_RGB9_E5: + return eGL_UNSIGNED_INT_5_9_9_9_REV; + case eGL_DEPTH24_STENCIL8: + return eGL_UNSIGNED_INT_24_8; + case eGL_DEPTH32F_STENCIL8: + return eGL_FLOAT_32_UNSIGNED_INT_24_8_REV; + case eGL_STENCIL_INDEX8: + return eGL_UNSIGNED_BYTE; + } + + RDCERR("Unhandled Data Type case!"); + + return eGL_NONE; +} diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index 8cce2be0d..b71021f2e 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -30,6 +30,8 @@ #include "driver/gl/gl_common.h" size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type, int align); +GLenum GetBaseFormat(GLenum internalFormat); +GLenum GetDataType(GLenum internalFormat); enum GLNamespace { From 86a87f091c61697d01ab534fa794f3911bc05252 Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:45:53 +0200 Subject: [PATCH 5/7] Differentiate between glDepthRangef and glDepthRange when capturing. This prevents a crash when the captured application doesn't retrieve the glDepthRange pointer, and uses glDepthRangef instead. --- renderdoc/driver/gl/gl_common.h | 1 + renderdoc/driver/gl/gl_driver.cpp | 4 ++++ .../driver/gl/wrappers/gl_state_funcs.cpp | 21 ++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index f547c8e26..f78414fbc 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -171,6 +171,7 @@ enum GLChunkType DEPTH_FUNC, DEPTH_MASK, DEPTH_RANGE, + DEPTH_RANGEF, DEPTH_RANGEARRAY, DEPTH_BOUNDS, PATCH_PARAMI, diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index fdda8a713..b2c2aa726 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -121,6 +121,7 @@ const char *GLChunkNames[] = "glDepthFunc", "glDepthMask", "glDepthRange", + "glDepthRangef", "glDepthRangeArrayv", "glDepthBoundsEXT", "glPatchParameteri", @@ -1191,6 +1192,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case DEPTH_RANGE: Serialise_glDepthRange(0, 0); break; + case DEPTH_RANGEF: + Serialise_glDepthRangef(0, 0); + break; case DEPTH_RANGEARRAY: Serialise_glDepthRangeArrayv(0, 0, NULL); break; diff --git a/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp index 2b76d0d6e..919b37954 100644 --- a/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp @@ -506,9 +506,28 @@ void WrappedOpenGL::glDepthRange(GLdouble nearVal, GLdouble farVal) } } +bool WrappedOpenGL::Serialise_glDepthRangef(GLfloat nearVal, GLfloat farVal) +{ + SERIALISE_ELEMENT(GLfloat, n, nearVal); + SERIALISE_ELEMENT(GLfloat, f, farVal); + + if(m_State <= EXECUTING) + m_Real.glDepthRangef(n, f); + + return true; +} + void WrappedOpenGL::glDepthRangef(GLfloat nearVal, GLfloat farVal) { - glDepthRange(nearVal, farVal); + m_Real.glDepthRangef(nearVal, farVal); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_RANGEF); + Serialise_glDepthRangef(nearVal, farVal); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v) From fc4ba7ae814fa2e8a9696fe904d9281a1fd29227 Mon Sep 17 00:00:00 2001 From: valeriog Date: Tue, 14 Oct 2014 17:46:59 +0200 Subject: [PATCH 6/7] Avoid applying hooks to powrprof.dll as it causes a crash. --- renderdoc/os/win32/win32_hook.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/renderdoc/os/win32/win32_hook.cpp b/renderdoc/os/win32/win32_hook.cpp index 917f7dff2..8b5c68356 100644 --- a/renderdoc/os/win32/win32_hook.cpp +++ b/renderdoc/os/win32/win32_hook.cpp @@ -118,6 +118,7 @@ struct CachedHookData // for safety (and because we don't need to), ignore these modules if(!_stricmp(modName, "kernel32.dll") || + !_stricmp(modName, "powrprof.dll") || strstr(lowername, "msvcr") == lowername || strstr(lowername, "msvcp") == lowername) return; From e0450d79400c85633194be7dc8a27dbd27a7e23e Mon Sep 17 00:00:00 2001 From: valeriog Date: Wed, 15 Oct 2014 11:50:26 +0200 Subject: [PATCH 7/7] Fix for typo found in pull request conversation. --- renderdoc/driver/gl/gl_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index b2c2aa726..8b3f4e026 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -630,7 +630,7 @@ void WrappedOpenGL::Present(void *windowHandle) } } - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, packBufBind); + m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, packBufBind); m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevBuf); m_Real.glReadBuffer(prevReadBuf); m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, prevPackRowLen);