From c1a5fc9a62ee2bfcd89a20f574b0330c8707174a Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 23 Nov 2014 17:06:15 +0000 Subject: [PATCH] Implement glInvalidate* just by marking resource as GPU dirty --- renderdoc/core/resource_manager.h | 6 +++ renderdoc/driver/gl/gl_driver.h | 6 +++ renderdoc/driver/gl/gl_hookset.h | 6 +++ renderdoc/driver/gl/gl_hookset_defs.h | 12 +++++ .../driver/gl/wrappers/gl_buffer_funcs.cpp | 16 ++++++ .../gl/wrappers/gl_framebuffer_funcs.cpp | 50 +++++++++++++++++++ .../driver/gl/wrappers/gl_texture_funcs.cpp | 16 ++++++ 7 files changed, 112 insertions(+) diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index 7fb416a32..f70ecfbbe 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -99,6 +99,12 @@ struct ResourceRecord } } + void MarkParentsDirty(ResourceRecordHandler *mgr) + { + for(auto it = Parents.begin(); it != Parents.end(); ++it) + mgr->MarkDirtyResource((*it)->GetResourceID()); + } + void FreeParents(ResourceRecordHandler *mgr) { for(auto it = Parents.begin(); it != Parents.end(); ++it) diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index e7abcc98e..460156175 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -540,6 +540,12 @@ class WrappedOpenGL IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data)); IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferData(GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateTexImage(GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)); enum AttribType { diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 115486a50..c179845e7 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -447,6 +447,12 @@ struct GLHookSet PFNGLCLEARBUFFERSUBDATAPROC glClearBufferSubData; PFNGLCLEARTEXIMAGEPROC glClearTexImage; PFNGLCLEARTEXSUBIMAGEPROC glClearTexSubImage; + PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData; + PFNGLINVALIDATEBUFFERSUBDATAPROC glInvalidateBufferSubData; + PFNGLINVALIDATEFRAMEBUFFERPROC glInvalidateFramebuffer; + PFNGLINVALIDATESUBFRAMEBUFFERPROC glInvalidateSubFramebuffer; + PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage; + PFNGLINVALIDATETEXSUBIMAGEPROC glInvalidateTexSubImage; PFNGLSCISSORARRAYVPROC glScissorArrayv; PFNGLSCISSORINDEXEDPROC glScissorIndexed; PFNGLSCISSORINDEXEDVPROC glScissorIndexedv; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index e69183b1d..e9f710bee 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -477,6 +477,12 @@ HookExtension(PFNGLCLEARBUFFERSUBDATAPROC, glClearBufferSubData); \ HookExtension(PFNGLCLEARTEXIMAGEPROC, glClearTexImage); \ HookExtension(PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage); \ + HookExtension(PFNGLINVALIDATEBUFFERDATAPROC, glInvalidateBufferData); \ + HookExtension(PFNGLINVALIDATEBUFFERSUBDATAPROC, glInvalidateBufferSubData); \ + HookExtension(PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateFramebuffer); \ + HookExtension(PFNGLINVALIDATESUBFRAMEBUFFERPROC, glInvalidateSubFramebuffer); \ + HookExtension(PFNGLINVALIDATETEXIMAGEPROC, glInvalidateTexImage); \ + HookExtension(PFNGLINVALIDATETEXSUBIMAGEPROC, glInvalidateTexSubImage); \ HookExtension(PFNGLSCISSORARRAYVPROC, glScissorArrayv); \ HookExtension(PFNGLSCISSORINDEXEDPROC, glScissorIndexed); \ HookExtension(PFNGLSCISSORINDEXEDVPROC, glScissorIndexedv); \ @@ -1126,6 +1132,12 @@ HookWrapper7(void, glClearBufferSubData, GLenum, target, GLenum, internalformat, GLintptr, offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ HookWrapper5(void, glClearTexImage, GLuint, texture, GLint, level, GLenum, format, GLenum, type, const void *, data); \ HookWrapper11(void, glClearTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, data); \ + HookWrapper1(void, glInvalidateBufferData, GLuint, buffer); \ + HookWrapper3(void, glInvalidateBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, length); \ + HookWrapper3(void, glInvalidateFramebuffer, GLenum, target, GLsizei, numAttachments, const GLenum *, attachments); \ + HookWrapper7(void, glInvalidateSubFramebuffer, GLenum, target, GLsizei, numAttachments, const GLenum *, attachments, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper2(void, glInvalidateTexImage, GLuint, texture, GLint, level); \ + HookWrapper8(void, glInvalidateTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth); \ HookWrapper3(void, glScissorArrayv, GLuint, first, GLsizei, count, const GLint *, v); \ HookWrapper5(void, glScissorIndexed, GLuint, index, GLint, left, GLint, bottom, GLsizei, width, GLsizei, height); \ HookWrapper2(void, glScissorIndexedv, GLuint, index, const GLint *, v); \ diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index 5f04a7f64..9a5a4f414 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -755,6 +755,22 @@ void WrappedOpenGL::glBindBuffersRange(GLenum target, GLuint first, GLsizei coun } } +void WrappedOpenGL::glInvalidateBufferData(GLuint buffer) +{ + m_Real.glInvalidateBufferData(buffer); + + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); +} + +void WrappedOpenGL::glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length) +{ + m_Real.glInvalidateBufferSubData(buffer, offset, length); + + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); +} + #pragma endregion #pragma region Mapping diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 6f6dfe521..78313293e 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -828,6 +828,56 @@ void WrappedOpenGL::glDrawBuffers(GLsizei n, const GLenum *bufs) m_Real.glDrawBuffers(n, bufs); } +void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) +{ + m_Real.glInvalidateFramebuffer(target, numAttachments, attachments); + + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = NULL; + + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(m_DrawFramebufferRecord) record = m_DrawFramebufferRecord; + } + else + { + if(m_ReadFramebufferRecord) record = m_ReadFramebufferRecord; + } + + if(record) + { + record->MarkParentsDirty(GetResourceManager()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } +} + +void WrappedOpenGL::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + m_Real.glInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = NULL; + + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(m_DrawFramebufferRecord) record = m_DrawFramebufferRecord; + } + else + { + if(m_ReadFramebufferRecord) record = m_ReadFramebufferRecord; + } + + if(record) + { + record->MarkParentsDirty(GetResourceManager()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } +} + bool WrappedOpenGL::Serialise_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { SERIALISE_ELEMENT(int32_t, sX0, srcX0); diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index 8b2f0d059..4e2a0d8ac 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -465,6 +465,22 @@ void WrappedOpenGL::glGenerateMipmap(GLenum target) } } +void WrappedOpenGL::glInvalidateTexImage(GLuint texture, GLint level) +{ + m_Real.glInvalidateTexImage(texture, level); + + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); +} + +void WrappedOpenGL::glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +{ + m_Real.glInvalidateTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth); + + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); +} + bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)