diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index c02b81fe2..8d4b7206c 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -726,5 +726,7 @@ enum GLChunkType PRIMITIVE_BOUNDING_BOX, + FRAMEBUFFER_TEX2DMS, + NUM_OPENGL_CHUNKS, }; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index bc3b49ccb..5a757523b 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -322,6 +322,8 @@ const char *GLChunkNames[] = { "wglDXLockObjectsNV", "glPrimitiveBoundingBox", + + "glFramebufferTexture2DMultisample", }; GLInitParams::GLInitParams() @@ -3710,6 +3712,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) case FRAMEBUFFER_TEX2D: Serialise_glNamedFramebufferTexture2DEXT(0, eGL_NONE, eGL_NONE, 0, 0); break; + case FRAMEBUFFER_TEX2DMS: + Serialise_glFramebufferTexture2DMultisampleEXT(0, eGL_NONE, eGL_NONE, eGL_NONE, 0, 0, 0); + break; case FRAMEBUFFER_TEX3D: Serialise_glNamedFramebufferTexture3DEXT(0, eGL_NONE, eGL_NONE, 0, 0, 0); break; diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 5b8a93934..1e5dddc19 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -2449,6 +2449,12 @@ public: glPrimitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)); + + bool Serialise_glFramebufferTexture2DMultisampleEXT(GLuint framebuffer, GLenum target, + GLenum attachment, GLenum textarget, + GLuint texture, GLint level, GLsizei samples); + void glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level, GLsizei samples); }; class ScopedDebugContext diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 303cf50a2..1d23dc6bf 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -606,6 +606,9 @@ struct GLHookSet // GLES core PFNGLPRIMITIVEBOUNDINGBOXEXTPROC glPrimitiveBoundingBox; // aliases glPrimitiveBoundingBoxEXT, glPrimitiveBoundingBoxOES + // GLES: EXT_multisampled_render_to_texture + PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; + // ARB_shading_language_include PFNGLNAMEDSTRINGARBPROC glNamedStringARB; PFNGLDELETENAMEDSTRINGARBPROC glDeleteNamedStringARB; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index f6e1c060e..4b491a6b9 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -1125,6 +1125,7 @@ HookExtension(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox); \ HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxEXT); \ HookExtensionAlias(PFNGLPRIMITIVEBOUNDINGBOXOESPROC, glPrimitiveBoundingBox, glPrimitiveBoundingBoxOES); \ + HookExtension(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC, glFramebufferTexture2DMultisampleEXT); \ HookExtension(PFNWGLDXSETRESOURCESHAREHANDLENVPROC, wglDXSetResourceShareHandleNV); \ HookExtension(PFNWGLDXOPENDEVICENVPROC, wglDXOpenDeviceNV); \ HookExtension(PFNWGLDXCLOSEDEVICENVPROC, wglDXCloseDeviceNV); \ @@ -1978,6 +1979,7 @@ HookWrapper0(void, glFrameTerminatorGREMEDY); \ HookWrapper2(void, glStringMarkerGREMEDY, GLsizei, len, const void *, string); \ HookWrapper8(void, glPrimitiveBoundingBox, GLfloat, minX, GLfloat, minY, GLfloat, minZ, GLfloat, minW, GLfloat, maxX, GLfloat, maxY, GLfloat, maxZ, GLfloat, maxW); \ + HookWrapper6(void, glFramebufferTexture2DMultisampleEXT, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level, GLsizei, samples); \ HookWrapper2(BOOL, wglDXSetResourceShareHandleNV, void *, dxObject, HANDLE, shareHandle); \ HookWrapper1(HANDLE, wglDXOpenDeviceNV, void *, dxDevice); \ HookWrapper1(BOOL, wglDXCloseDeviceNV, HANDLE, hDevice); \ @@ -3639,7 +3641,6 @@ HookWrapper3(void, glflushmappedbufferrangeext, GLenum, target, GLintptr, offset, GLsizeiptr, length); \ HookWrapper4(void, glmultidrawarraysindirectext, GLenum, mode, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ HookWrapper5(void, glmultidrawelementsindirectext, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ - HookWrapper6(void, glframebuffertexture2dmultisampleext, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level, GLsizei, samples); \ HookWrapper2(void, glreadbufferindexedext, GLenum, src, GLint, index); \ HookWrapper3(void, gldrawbuffersindexedext, GLint, n, const GLenum *, location, const GLint *, indices); \ HookWrapper3(void, glgetintegeri_vext, GLenum, target, GLuint, index, GLint *, data); \ @@ -5667,7 +5668,6 @@ HandleUnsupported(PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC, glflushmappedbufferrangeext); \ HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC, glmultidrawarraysindirectext); \ HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC, glmultidrawelementsindirectext); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC, glframebuffertexture2dmultisampleext); \ HandleUnsupported(PFNGLREADBUFFERINDEXEDEXTPROC, glreadbufferindexedext); \ HandleUnsupported(PFNGLDRAWBUFFERSINDEXEDEXTPROC, gldrawbuffersindexedext); \ HandleUnsupported(PFNGLGETINTEGERI_VEXTPROC, glgetintegeri_vext); \ diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 3a0f3406a..9570df6c4 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -568,6 +568,113 @@ void WrappedOpenGL::glFramebufferTexture2D(GLenum target, GLenum attachment, GLe } } +bool WrappedOpenGL::Serialise_glFramebufferTexture2DMultisampleEXT(GLuint framebuffer, + GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level, GLsizei samples) + +{ + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, TexTarget, textarget); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(uint32_t, Samples, samples); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); + + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + + GLuint prevread = 0, prevdraw = 0; + m_Real.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw); + m_Real.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread); + + GLuint fbbinding = (fbid == ResourceId()) ? 0 : GetResourceManager()->GetLiveResource(fbid).name; + m_Real.glBindFramebuffer(Target, fbbinding); + + m_Real.glFramebufferTexture2DMultisampleEXT(Target, Attach, TexTarget, tex, Level, Samples); + + m_Real.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw); + m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread); + + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= TextureCategory::ColorTarget; + } + } + + return true; +} + +void WrappedOpenGL::glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level, GLsizei samples) +{ + m_Real.glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples); + + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; + + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } + + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX2DMS); + Serialise_glFramebufferTexture2DMultisampleEXT(record->Resource.name, target, attachment, + textarget, texture, level, samples); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } +} + bool WrappedOpenGL::Serialise_glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) @@ -717,6 +824,7 @@ void WrappedOpenGL::glFramebufferTexture3D(GLenum target, GLenum attachment, GLe } } } + bool WrappedOpenGL::Serialise_glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)