From 5cb6edffb84a455a74162984f5d90e64c609282a Mon Sep 17 00:00:00 2001 From: Baldur Karlsson Date: Fri, 27 Jun 2014 13:13:46 +0100 Subject: [PATCH] For VAOs, track and deduplicate redundant chunks * This is really a spot optimisation but I have a feeling it might be useful for more programs. * If a program uses a single VAO and updates the attrib pointers/enables and disables them, then this will prevent an unbounded number of chunks building up pointlessly while READING and pushing into the record. * A 'better' fix for this would be to gather pointer/enabled state as initial contents and not tracking any of this except for in CAPFRAME, but that isn't happening at the moment. --- renderdoc/core/resource_manager.h | 14 ++++++++ renderdoc/driver/gl/gl_resources.h | 5 +++ .../driver/gl/wrappers/gl_buffer_funcs.cpp | 36 ++++++++++++++++--- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index b6c1f38a8..af80c073f 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -139,6 +139,20 @@ struct ResourceRecord ResourceId GetResourceID() const { return ResID; } + void RemoveChunk(Chunk *chunk) + { + LockChunks(); + for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it) + { + if(it->second == chunk) + { + m_Chunks.erase(it); + break; + } + } + UnlockChunks(); + } + void AddChunk(Chunk *chunk, int32_t ID = 0) { LockChunks(); diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index 3b5500a40..3e78c0d20 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -101,6 +101,8 @@ struct GLResourceRecord : public ResourceRecord usage(eGL_UNKNOWN_ENUM) { RDCEraseEl(ShadowPtr); + RDCEraseEl(ptrchunks); + RDCEraseEl(enabledchunks); } ~GLResourceRecord() @@ -154,6 +156,9 @@ struct GLResourceRecord : public ResourceRecord { return ShadowPtr[p]; } + + Chunk *ptrchunks[12]; + Chunk *enabledchunks[12]; private: byte *ShadowPtr[2]; diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index d6727bbda..9fb9768d6 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -1120,9 +1120,16 @@ void WrappedOpenGL::glVertexAttribPointer(GLuint index, GLint size, GLenum type, Serialise_glVertexAttribPointer(index, size, type, normalized, stride, pointer); if(m_State == WRITING_CAPFRAME) + { m_ContextRecord->AddChunk(scope.Get()); + } else - r->AddChunk(scope.Get()); + { + r->RemoveChunk(r->ptrchunks[index]); + delete r->ptrchunks[index]; + Chunk *newchunk = r->ptrchunks[index] = scope.Get(); + r->AddChunk(newchunk); + } } } @@ -1166,9 +1173,16 @@ void WrappedOpenGL::glVertexAttribIPointer(GLuint index, GLint size, GLenum type Serialise_glVertexAttribIPointer(index, size, type, stride, pointer); if(m_State == WRITING_CAPFRAME) + { m_ContextRecord->AddChunk(scope.Get()); + } else - r->AddChunk(scope.Get()); + { + r->RemoveChunk(r->ptrchunks[index]); + delete r->ptrchunks[index]; + Chunk *newchunk = r->ptrchunks[index] = scope.Get(); + r->AddChunk(newchunk); + } } } @@ -1207,9 +1221,16 @@ void WrappedOpenGL::glEnableVertexAttribArray(GLuint index) Serialise_glEnableVertexAttribArray(index); if(m_State == WRITING_CAPFRAME) + { m_ContextRecord->AddChunk(scope.Get()); + } else - r->AddChunk(scope.Get()); + { + r->RemoveChunk(r->enabledchunks[index]); + delete r->enabledchunks[index]; + Chunk *newchunk = r->enabledchunks[index] = scope.Get(); + r->AddChunk(newchunk); + } } } @@ -1247,9 +1268,16 @@ void WrappedOpenGL::glDisableVertexAttribArray(GLuint index) Serialise_glDisableVertexAttribArray(index); if(m_State == WRITING_CAPFRAME) + { m_ContextRecord->AddChunk(scope.Get()); + } else - r->AddChunk(scope.Get()); + { + r->RemoveChunk(r->enabledchunks[index]); + delete r->enabledchunks[index]; + Chunk *newchunk = r->enabledchunks[index] = scope.Get(); + r->AddChunk(newchunk); + } } }