diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 2780442a2..cf5ba814e 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -709,6 +709,7 @@ extern bool IsGLES; EXT_TO_CHECK(43, 31, ARB_compute_shader) \ EXT_TO_CHECK(43, 32, ARB_copy_image) \ EXT_TO_CHECK(43, 30, ARB_ES3_compatibility) \ + EXT_TO_CHECK(43, 30, ARB_invalidate_subdata) \ EXT_TO_CHECK(43, 99, ARB_internalformat_query2) \ EXT_TO_CHECK(43, 31, ARB_program_interface_query) \ EXT_TO_CHECK(43, 31, ARB_shader_storage_buffer_object) \ @@ -756,7 +757,8 @@ extern bool IsGLES; EXT_TO_CHECK(99, 99, NV_read_depth_stencil) \ EXT_TO_CHECK(99, 99, EXT_disjoint_timer_query) \ EXT_TO_CHECK(99, 99, EXT_multisampled_render_to_texture) \ - EXT_TO_CHECK(99, 99, OVR_multiview) + EXT_TO_CHECK(99, 99, OVR_multiview) \ + EXT_TO_CHECK(99, 99, EXT_discard_framebuffer) // GL extensions equivalents // Either promoted extensions from EXT to ARB, or diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 6fd77bdad..a97ef8212 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -3735,6 +3735,10 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) return Serialise_glFramebufferReadBufferEXT(ser, 0, eGL_NONE); case GLChunk::glBindFramebufferEXT: case GLChunk::glBindFramebuffer: return Serialise_glBindFramebuffer(ser, eGL_NONE, 0); + case GLChunk::glDiscardFramebufferEXT: + case GLChunk::glInvalidateFramebuffer: + case GLChunk::glInvalidateNamedFramebufferData: + return Serialise_glInvalidateNamedFramebufferData(ser, 0, 0, 0); case GLChunk::glDrawBuffer: case GLChunk::glNamedFramebufferDrawBuffer: case GLChunk::glFramebufferDrawBufferEXT: @@ -4727,11 +4731,8 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) case GLChunk::glProgramBinary: case GLChunk::glReleaseShaderCompiler: case GLChunk::glFrameTerminatorGREMEDY: - case GLChunk::glDiscardFramebufferEXT: case GLChunk::glInvalidateBufferData: case GLChunk::glInvalidateBufferSubData: - case GLChunk::glInvalidateFramebuffer: - case GLChunk::glInvalidateNamedFramebufferData: case GLChunk::glInvalidateNamedFramebufferSubData: case GLChunk::glInvalidateSubFramebuffer: case GLChunk::glInvalidateTexImage: diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 02bead81a..a59b9287d 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -913,6 +913,8 @@ public: IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffer, GLenum buf); IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffers, GLsizei n, const GLenum *bufs); IMPLEMENT_FUNCTION_SERIALISED(void, glBindFramebuffer, GLenum target, GLuint framebuffer); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferData, GLuint framebufferHandle, + GLsizei numAttachments, const GLenum *attachments); IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture, GLenum target, GLenum attachment, GLuint texture, GLint level); IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture1D, GLenum target, GLenum attachment, @@ -2241,9 +2243,6 @@ public: GLuint buffer); IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackBufferRange, GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferData, GLuint framebuffer, - GLsizei numAttachments, const GLenum *attachments); IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferSubData, GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); diff --git a/renderdoc/driver/gl/wrappers/gl_emulated.cpp b/renderdoc/driver/gl/wrappers/gl_emulated.cpp index 7d6c359b7..e1c620585 100644 --- a/renderdoc/driver/gl/wrappers/gl_emulated.cpp +++ b/renderdoc/driver/gl/wrappers/gl_emulated.cpp @@ -314,6 +314,25 @@ void APIENTRY _glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum atta GL.glFramebufferRenderbuffer(eGL_DRAW_FRAMEBUFFER, attachment, renderbuffertarget, renderbuffer); } +void APIENTRY _glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, + const GLenum *attachments) +{ + if(HasExt[ARB_invalidate_subdata]) + { + PushPopFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + GL.glInvalidateFramebuffer(eGL_DRAW_FRAMEBUFFER, numAttachments, attachments); + } + else if(HasExt[EXT_discard_framebuffer]) + { + PushPopFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + GL.glDiscardFramebufferEXT(eGL_DRAW_FRAMEBUFFER, numAttachments, attachments); + } + else + { + RDCERR("No support for framebuffer invalidate on GL %d", GLCoreVersion); + } +} + #pragma endregion #pragma region Renderbuffers @@ -3313,6 +3332,7 @@ void GLDispatchTable::EmulateRequiredExtensions() EMULATE_FUNC(glBlitNamedFramebuffer) EMULATE_FUNC(glVertexArrayElementBuffer); EMULATE_FUNC(glVertexArrayVertexBuffers) + EMULATE_FUNC(glInvalidateNamedFramebufferData); } } diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 7b362a6c6..5f05598d2 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -1708,12 +1708,34 @@ void WrappedOpenGL::glDrawBuffers(GLsizei n, const GLenum *bufs) } } +template +bool WrappedOpenGL::Serialise_glInvalidateNamedFramebufferData(SerialiserType &ser, + GLuint framebufferHandle, + GLsizei numAttachments, + const GLenum *attachments) +{ + SERIALISE_ELEMENT_LOCAL(framebuffer, FramebufferRes(GetCtx(), framebufferHandle)); + SERIALISE_ELEMENT(numAttachments); + SERIALISE_ELEMENT_ARRAY(attachments, numAttachments); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + if(framebuffer.name == 0) + framebuffer.name = m_CurrentDefaultFBO; + + GL.glInvalidateNamedFramebufferData(framebuffer.name, numAttachments, attachments); + } + + return true; +} + void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) { - GL.glInvalidateFramebuffer(target, numAttachments, attachments); - - if(IsBackgroundCapturing(m_State)) + SERIALISE_TIME_CALL(GL.glInvalidateFramebuffer(target, numAttachments, attachments)); + if(IsCaptureMode(m_State)) { GLResourceRecord *record = NULL; @@ -1728,7 +1750,21 @@ void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachment record = GetCtxData().m_ReadFramebufferRecord; } - if(record) + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + if(record) + Serialise_glInvalidateNamedFramebufferData(ser, record->Resource.name, numAttachments, + attachments); + else + Serialise_glInvalidateNamedFramebufferData(ser, 0, numAttachments, attachments); + + GetContextRecord()->AddChunk(scope.Get()); + if(record) + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + } + else if(record) { record->MarkParentsDirty(GetResourceManager()); } @@ -1740,9 +1776,9 @@ void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachment void WrappedOpenGL::glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) { - GL.glDiscardFramebufferEXT(target, numAttachments, attachments); + SERIALISE_TIME_CALL(GL.glDiscardFramebufferEXT(target, numAttachments, attachments)); - if(IsBackgroundCapturing(m_State)) + if(IsCaptureMode(m_State)) { GLResourceRecord *record = NULL; @@ -1757,7 +1793,21 @@ void WrappedOpenGL::glDiscardFramebufferEXT(GLenum target, GLsizei numAttachment record = GetCtxData().m_ReadFramebufferRecord; } - if(record) + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + if(record) + Serialise_glInvalidateNamedFramebufferData(ser, record->Resource.name, numAttachments, + attachments); + else + Serialise_glInvalidateNamedFramebufferData(ser, 0, numAttachments, attachments); + + GetContextRecord()->AddChunk(scope.Get()); + if(record) + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + } + else if(record) { record->MarkParentsDirty(GetResourceManager()); } @@ -1767,15 +1817,31 @@ void WrappedOpenGL::glDiscardFramebufferEXT(GLenum target, GLsizei numAttachment void WrappedOpenGL::glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments) { - GL.glInvalidateNamedFramebufferData(framebuffer, numAttachments, attachments); + SERIALISE_TIME_CALL(GL.glInvalidateNamedFramebufferData(framebuffer, numAttachments, attachments)); - if(IsBackgroundCapturing(m_State)) + if(IsCaptureMode(m_State)) { GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(record) + if(IsActiveCapturing(m_State)) + { + USE_SCRATCH_SERIALISER(); + SCOPED_SERIALISE_CHUNK(gl_CurChunk); + if(record) + Serialise_glInvalidateNamedFramebufferData(ser, record->Resource.name, numAttachments, + attachments); + else + Serialise_glInvalidateNamedFramebufferData(ser, 0, numAttachments, attachments); + + GetContextRecord()->AddChunk(scope.Get()); + if(record) + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + } + else if(record) + { record->MarkParentsDirty(GetResourceManager()); + } } } @@ -2769,6 +2835,8 @@ INSTANTIATE_FUNCTION_SERIALISED(void, glNamedFramebufferParameteriEXT, GLuint fr INSTANTIATE_FUNCTION_SERIALISED(void, glFramebufferReadBufferEXT, GLuint framebufferHandle, GLenum mode); INSTANTIATE_FUNCTION_SERIALISED(void, glBindFramebuffer, GLenum target, GLuint framebufferHandle); +INSTANTIATE_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferData, GLuint framebufferHandle, + GLsizei numAttachments, const GLenum *attachments); INSTANTIATE_FUNCTION_SERIALISED(void, glFramebufferDrawBufferEXT, GLuint framebufferHandle, GLenum buf); INSTANTIATE_FUNCTION_SERIALISED(void, glFramebufferDrawBuffersEXT, GLuint framebufferHandle,