diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 935d9983c..e65e4c4ac 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -83,8 +83,12 @@ enum GLChunkType GEN_TEXTURE, BIND_TEXTURE, ACTIVE_TEXTURE, + TEXSTORAGE1D, TEXSTORAGE2D, + TEXSTORAGE3D, + TEXSUBIMAGE1D, TEXSUBIMAGE2D, + TEXSUBIMAGE3D, PIXELSTORE, TEXPARAMETERI, GENERATE_MIPMAP, diff --git a/renderdoc/driver/gl/gl_device_driver.cpp b/renderdoc/driver/gl/gl_device_driver.cpp index b2897e81d..183dc8014 100644 --- a/renderdoc/driver/gl/gl_device_driver.cpp +++ b/renderdoc/driver/gl/gl_device_driver.cpp @@ -171,6 +171,43 @@ void WrappedOpenGL::glBindTexture(GLenum target, GLuint texture) } } +bool WrappedOpenGL::Serialise_glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Levels, levels); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID()); + + if(m_State == READING) + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + + m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name); + m_Real.glTexStorage1D(Target, Levels, Format, Width); + } + + return true; +} + +void WrappedOpenGL::glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +{ + m_Real.glTexStorage1D(target, levels, internalformat, width); + + if(m_State >= WRITING) + { + RDCASSERT(m_TextureRecord[m_TextureUnit]); + + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE1D); + Serialise_glTexStorage1D(target, levels, internalformat, width); + + m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { SERIALISE_ELEMENT(GLenum, Target, target); @@ -209,6 +246,88 @@ void WrappedOpenGL::glTexStorage2D(GLenum target, GLsizei levels, GLenum interna } } +bool WrappedOpenGL::Serialise_glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Levels, levels); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID()); + + if(m_State == READING) + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = Depth; + + m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name); + m_Real.glTexStorage3D(Target, Levels, Format, Width, Height, Depth); + } + + return true; +} + +void WrappedOpenGL::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +{ + m_Real.glTexStorage3D(target, levels, internalformat, width, height, depth); + + if(m_State >= WRITING) + { + RDCASSERT(m_TextureRecord[m_TextureUnit]); + + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3D); + Serialise_glTexStorage3D(target, levels, internalformat, width, height, depth); + + m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get()); + } +} + +bool WrappedOpenGL::Serialise_glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID()); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + + size_t subimageSize = GetByteSize(Width, 1, 1, Format, Type, Level, align); + + SERIALISE_ELEMENT_BUF(byte *, buf, pixels, subimageSize); + + if(m_State == READING) + { + m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name); + m_Real.glTexSubImage1D(Target, Level, xoff, Width, Format, Type, buf); + + delete[] buf; + } + + return true; +} + +void WrappedOpenGL::glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +{ + m_Real.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + + if(m_State >= WRITING) + { + RDCASSERT(m_TextureRecord[m_TextureUnit]); + + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE1D); + Serialise_glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + + m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { SERIALISE_ELEMENT(GLenum, Target, target); @@ -243,8 +362,10 @@ void WrappedOpenGL::glTexSubImage2D(GLenum target, GLint level, GLint xoffset, G { m_Real.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - RDCASSERT(m_TextureRecord[m_TextureUnit]); + if(m_State >= WRITING) { + RDCASSERT(m_TextureRecord[m_TextureUnit]); + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D); Serialise_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); @@ -252,6 +373,53 @@ void WrappedOpenGL::glTexSubImage2D(GLenum target, GLint level, GLint xoffset, G } } +bool WrappedOpenGL::Serialise_glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(int32_t, yoff, yoffset); + SERIALISE_ELEMENT(int32_t, zoff, zoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, m_TextureRecord[m_TextureUnit]->GetResourceID()); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + + size_t subimageSize = GetByteSize(Width, Height, Depth, Format, Type, Level, align); + + SERIALISE_ELEMENT_BUF(byte *, buf, pixels, subimageSize); + + if(m_State == READING) + { + m_Real.glBindTexture(Target, GetResourceManager()->GetLiveResource(id).name); + m_Real.glTexSubImage3D(Target, Level, xoff, yoff, zoff, Width, Height, Depth, Format, Type, buf); + + delete[] buf; + } + + return true; +} + +void WrappedOpenGL::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +{ + m_Real.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + if(m_State >= WRITING) + { + RDCASSERT(m_TextureRecord[m_TextureUnit]); + + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE3D); + Serialise_glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + m_TextureRecord[m_TextureUnit]->AddChunk(scope.Get()); + } +} + bool WrappedOpenGL::Serialise_glGenerateMipmap(GLenum target) { SERIALISE_ELEMENT(GLenum, Target, target); diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 8b6b20e24..788f8afa1 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -40,8 +40,12 @@ const char *GLChunkNames[] = "glGenTextures", "glBindTexture", "glActiveTexture", + "glTexStorage1D", "glTexStorage2D", + "glTexStorage3D", + "glTexSubImage1D", "glTexSubImage2D", + "glTexSubImage3D", "glPixelStore", "glTexParameteri", "glGenerateMipmap", @@ -900,12 +904,24 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case BIND_TEXTURE: Serialise_glBindTexture(eGL_UNKNOWN_ENUM, 0); break; + case TEXSTORAGE1D: + Serialise_glTexStorage1D(eGL_UNKNOWN_ENUM, 0, eGL_UNKNOWN_ENUM, 0); + break; case TEXSTORAGE2D: Serialise_glTexStorage2D(eGL_UNKNOWN_ENUM, 0, eGL_UNKNOWN_ENUM, 0, 0); break; + case TEXSTORAGE3D: + Serialise_glTexStorage3D(eGL_UNKNOWN_ENUM, 0, eGL_UNKNOWN_ENUM, 0, 0, 0); + break; + case TEXSUBIMAGE1D: + Serialise_glTexSubImage1D(eGL_UNKNOWN_ENUM, 0, 0, 0, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, NULL); + break; case TEXSUBIMAGE2D: Serialise_glTexSubImage2D(eGL_UNKNOWN_ENUM, 0, 0, 0, 0, 0, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, NULL); break; + case TEXSUBIMAGE3D: + Serialise_glTexSubImage3D(eGL_UNKNOWN_ENUM, 0, 0, 0, 0, 0, 0, 0, eGL_UNKNOWN_ENUM, eGL_UNKNOWN_ENUM, NULL); + break; case PIXELSTORE: Serialise_glPixelStorei(eGL_UNKNOWN_ENUM, 0); break; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 219887122..d6fdd68e1 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -343,8 +343,12 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam)); IMPLEMENT_FUNCTION_SERIALISED(void, glActiveTexture(GLenum texture)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)); IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)); IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)); IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateMipmap(GLenum target)); IMPLEMENT_FUNCTION_SERIALISED(void, glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)); diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index f683c9e0f..1714af94d 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -93,8 +93,12 @@ struct GLHookSet // ++ gl PFNGLACTIVETEXTUREPROC glActiveTexture; + PFNGLTEXSTORAGE1DPROC glTexStorage1D; PFNGLTEXSTORAGE2DPROC glTexStorage2D; + PFNGLTEXSTORAGE3DPROC glTexStorage3D; + PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D; PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D; + PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; PFNGLGENERATEMIPMAPPROC glGenerateMipmap; PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ; PFNGLGETINTERNALFORMATI64VPROC glGetInternalformati64v; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 5b359fa0f..beef54c0e 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -104,8 +104,12 @@ // gl extensions #define HookCheckGLExtensions() \ HookExtension(PFNGLACTIVETEXTUREPROC, glActiveTexture); \ + HookExtension(PFNGLTEXSTORAGE1DPROC, glTexStorage1D); \ HookExtension(PFNGLTEXSTORAGE2DPROC, glTexStorage2D); \ + HookExtension(PFNGLTEXSTORAGE3DPROC, glTexStorage3D); \ + HookExtension(PFNGLTEXSUBIMAGE1DPROC, glTexSubImage1D); \ HookExtension(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); \ + HookExtension(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D); \ HookExtension(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap); \ HookExtension(PFNGLGETINTERNALFORMATIVPROC, glGetInternalformativ); \ HookExtension(PFNGLGETINTERNALFORMATI64VPROC, glGetInternalformati64v); \ @@ -343,8 +347,12 @@ // gl extensions #define DefineGLExtensionHooks() \ HookWrapper1(void, glActiveTexture, GLenum, texture); \ + HookWrapper4(void, glTexStorage1D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width); \ HookWrapper5(void, glTexStorage2D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height); \ + HookWrapper6(void, glTexStorage3D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth); \ + HookWrapper7(void, glTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ HookWrapper9(void, glTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper11(void, glTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ HookWrapper1(void, glGenerateMipmap, GLenum, target); \ HookWrapper5(void, glGetInternalformativ, GLenum, target, GLenum, internalformat, GLenum, pname, GLsizei, bufSize, GLint *, params); \ HookWrapper5(void, glGetInternalformati64v, GLenum, target, GLenum, internalformat, GLenum, pname, GLsizei, bufSize, GLint64 *, params); \ diff --git a/renderdoc/hooks/gl_linux_hooks.cpp b/renderdoc/hooks/gl_linux_hooks.cpp index 051506f5f..d58d322b2 100644 --- a/renderdoc/hooks/gl_linux_hooks.cpp +++ b/renderdoc/hooks/gl_linux_hooks.cpp @@ -142,6 +142,11 @@ typedef void (*PFNGLXSWAPBUFFERSPROC)(Display *dpy, GLXDrawable drawable); extern "C" __attribute__ ((visibility ("default"))) \ ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ { return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ + typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + extern "C" __attribute__ ((visibility ("default"))) \ + ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ + { return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } class OpenGLHook : LibraryHook @@ -392,4 +397,4 @@ bool OpenGLHook::PopulateHooks() OpenGLHook OpenGLHook::glhooks; -const GLHookSet &GetRealFunctions() { return OpenGLHook::glhooks.GetRealFunctions(); } \ No newline at end of file +const GLHookSet &GetRealFunctions() { return OpenGLHook::glhooks.GetRealFunctions(); } diff --git a/renderdoc/hooks/gl_win32_hooks.cpp b/renderdoc/hooks/gl_win32_hooks.cpp index bf18f3172..c0a6c5554 100644 --- a/renderdoc/hooks/gl_win32_hooks.cpp +++ b/renderdoc/hooks/gl_win32_hooks.cpp @@ -150,6 +150,12 @@ static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ { return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ + Hook CONCAT(function, _hook); \ + typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ + { return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + class OpenGLHook : LibraryHook { public: