From cc9d50cf2eace63b060ac6bcdc6d508af99fc00a Mon Sep 17 00:00:00 2001 From: tuxerr Date: Fri, 8 Jun 2018 14:07:26 -0700 Subject: [PATCH] moving per-thread records to the TLS-context --- renderdoc/driver/gl/gl_driver.cpp | 198 ++++++++---------- renderdoc/driver/gl/gl_driver.h | 27 ++- renderdoc/driver/gl/gl_resources.h | 8 + .../driver/gl/wrappers/gl_debug_funcs.cpp | 5 +- 4 files changed, 119 insertions(+), 119 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 9f318d0d9..59cb90610 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -32,7 +32,6 @@ #include "strings/string_utils.h" std::map WrappedOpenGL::m_ActiveContexts; -std::map WrappedOpenGL::m_ActiveContextResourceIDs; void WrappedOpenGL::BuildGLExtensions() { @@ -571,8 +570,6 @@ WrappedOpenGL::WrappedOpenGL(const GLHookSet &funcs, GLPlatform &platform) m_ContextRecord->Length = 0; m_ContextRecord->SpecialResource = true; - GetContextRecord(); // create context resourceId and record for future use - // we register an ID for the backbuffer, this will be tied to the fake-created backbuffer on // replay, and every context's FBO 0 will be pointed to it with ReplaceResource m_FBO0_ID = ResourceIDGen::GetNewUniqueID(); @@ -594,7 +591,7 @@ WrappedOpenGL::WrappedOpenGL(const GLHookSet &funcs, GLPlatform &platform) m_CurChunkOffset = 0; m_AddedDrawcall = false; - m_CurCtxPairTLS = Threading::AllocateTLSSlot(); + m_CurCtxDataTLS = Threading::AllocateTLSSlot(); } void WrappedOpenGL::Initialise(GLInitParams ¶ms, uint64_t sectionVersion) @@ -742,50 +739,6 @@ std::string WrappedOpenGL::GetChunkName(uint32_t idx) return ToStr((GLChunk)idx); } -ResourceId WrappedOpenGL::GetContextResourceID() -{ - uint64_t currentId = Threading::GetCurrentID(); - if(m_ActiveContextResourceIDs.find(currentId) == m_ActiveContextResourceIDs.end()) - { - m_ActiveContextResourceIDs[currentId] = - GetResourceManager()->RegisterResource(GLResource(NULL, eResSpecial, eSpecialResContext)); - } - return m_ActiveContextResourceIDs[currentId]; -} - -GLResourceRecord *WrappedOpenGL::GetContextRecord() -{ - ResourceId currentResourceId = GetContextResourceID(); - if(!GetResourceManager()->HasResourceRecord(currentResourceId)) - { - GLResourceRecord *contextRecord = GetResourceManager()->AddResourceRecord(currentResourceId); - contextRecord->DataInSerialiser = false; - contextRecord->Length = 0; - contextRecord->SpecialResource = true; - } - return GetResourceManager()->GetResourceRecord(currentResourceId); -} - -bool WrappedOpenGL::RecordingHasChunks() -{ - if(m_ContextRecord->HasChunks()) - { - return true; - } - - for(auto it = m_ActiveContextResourceIDs.begin(); it != m_ActiveContextResourceIDs.end(); ++it) - { - if(GetResourceManager()->HasCurrentResource(it->second)) - { - if(GetResourceManager()->GetResourceRecord(it->second)->HasChunks()) - { - return true; - } - } - } - return false; -} - WrappedOpenGL::~WrappedOpenGL() { if(m_FakeBB_FBO) @@ -801,20 +754,19 @@ WrappedOpenGL::~WrappedOpenGL() GetResourceManager()->ReleaseCurrentResource(m_DeviceResourceID); - for(auto it = m_ActiveContextResourceIDs.begin(); it != m_ActiveContextResourceIDs.end(); ++it) + for(auto it = m_ContextData.begin(); it != m_ContextData.end(); ++it) { - if(GetResourceManager()->HasCurrentResource(it->second)) + if(it->second.m_ContextDataRecord) { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(it->second); - RDCASSERT(record->GetRefCount() == 1); - record->Delete(GetResourceManager()); - GetResourceManager()->ReleaseCurrentResource(it->second); + RDCASSERT(it->second.m_ContextDataRecord->GetRefCount() == 1); + it->second.m_ContextDataRecord->Delete(GetResourceManager()); + GetResourceManager()->ReleaseCurrentResource(it->second.m_ContextDataResourceID); } } - m_ActiveContextResourceIDs.clear(); if(m_ContextRecord) { + RDCASSERT(m_ContextRecord->GetRefCount() == 1); m_ContextRecord->Delete(GetResourceManager()); } GetResourceManager()->ReleaseCurrentResource(m_ContextResourceID); @@ -835,10 +787,25 @@ WrappedOpenGL::~WrappedOpenGL() ContextPair &WrappedOpenGL::GetCtx() { - ContextPair *ret = (ContextPair *)Threading::GetTLSValue(m_CurCtxPairTLS); + GLContextTLSData *ret = (GLContextTLSData *)Threading::GetTLSValue(m_CurCtxDataTLS); if(ret) - return *ret; - return m_EmptyPair; + return ret->ctxPair; + return m_EmptyTLSData.ctxPair; +} + +GLResourceRecord *WrappedOpenGL::GetContextRecord() +{ + GLContextTLSData *ret = (GLContextTLSData *)Threading::GetTLSValue(m_CurCtxDataTLS); + if(ret && ret->ctxRecord) + { + return ret->ctxRecord; + } + else + { + ContextData dat = GetCtxData(); + dat.CreateResourceRecord(this, GetCtx().ctx); + return dat.m_ContextDataRecord; + } } WrappedOpenGL::ContextData &WrappedOpenGL::GetCtxData() @@ -937,6 +904,21 @@ void WrappedOpenGL::ContextData::AssociateWindow(WrappedOpenGL *gl, void *wndHan windows[wndHandle] = Timing::GetUnixTimestamp(); } +void WrappedOpenGL::ContextData::CreateResourceRecord(WrappedOpenGL *gl, void *suppliedCtx) +{ + if(m_ContextDataResourceID == ResourceId::Null() || + !gl->GetResourceManager()->HasResourceRecord(m_ContextDataResourceID)) + { + m_ContextDataResourceID = gl->GetResourceManager()->RegisterResource( + GLResource(suppliedCtx, eResSpecial, eSpecialResContext)); + + m_ContextDataRecord = gl->GetResourceManager()->AddResourceRecord(m_ContextDataResourceID); + m_ContextDataRecord->DataInSerialiser = false; + m_ContextDataRecord->Length = 0; + m_ContextDataRecord->SpecialResource = true; + } +} + void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core, bool attribsCreate) { @@ -1010,23 +992,6 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) m_LastContexts.erase(m_LastContexts.begin()); } - // update thread-local context pair - { - ContextPair *ctx = (ContextPair *)Threading::GetTLSValue(m_CurCtxPairTLS); - - if(ctx) - { - *ctx = {winData.ctx, ShareCtx(winData.ctx)}; - } - else - { - ctx = new ContextPair({winData.ctx, ShareCtx(winData.ctx)}); - m_CtxPairs.push_back(ctx); - - Threading::SetTLSValue(m_CurCtxPairTLS, ctx); - } - } - // TODO: support multiple GL contexts more explicitly Keyboard::AddInputWindow((void *)winData.wnd); @@ -1280,6 +1245,27 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) } } + ctxdata.CreateResourceRecord(this, winData.ctx); + + // update thread-local context pair + { + GLContextTLSData *tlsData = (GLContextTLSData *)Threading::GetTLSValue(m_CurCtxDataTLS); + + if(tlsData) + { + tlsData->ctxPair = {winData.ctx, ShareCtx(winData.ctx)}; + tlsData->ctxRecord = ctxdata.m_ContextDataRecord; + } + else + { + tlsData = new GLContextTLSData(ContextPair({winData.ctx, ShareCtx(winData.ctx)}), + ctxdata.m_ContextDataRecord); + m_CtxDataVector.push_back(tlsData); + + Threading::SetTLSValue(m_CurCtxDataTLS, tlsData); + } + } + // this is hack but GL context creation is an *utter mess*. For first-frame captures, only // consider an attribs created context, to avoid starting capturing when the user is creating // dummy contexts to be able to create the real one. @@ -1931,20 +1917,22 @@ bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd) } { - RDCDEBUG("Accumulating context resource list for %d contexts", - m_ActiveContextResourceIDs.size()); + RDCDEBUG("Accumulating context resource list"); + map recordlist; m_ContextRecord->Insert(recordlist); - for(auto it = m_ActiveContextResourceIDs.begin(); it != m_ActiveContextResourceIDs.end(); ++it) + for(auto it = m_ContextData.begin(); it != m_ContextData.end(); ++it) { - if(m_AcceptedThreads.empty() || - m_AcceptedThreads.find(it->first) != m_AcceptedThreads.end()) + if(m_AcceptedCtx.empty() || m_AcceptedCtx.find(it->first) != m_AcceptedCtx.end()) { - GLResourceRecord *record = m_ResourceManager->GetResourceRecord(it->second); - RDCDEBUG("Getting Resource Record for thread ID %llu with %d chunks", it->first, - record->NumChunks()); - record->Insert(recordlist); + GLResourceRecord *record = it->second.m_ContextDataRecord; + if(record) + { + RDCDEBUG("Getting Resource Record for context ID %llu with %zu chunks", + it->second.m_ContextDataResourceID, record->NumChunks()); + record->Insert(recordlist); + } } } @@ -2263,19 +2251,22 @@ void WrappedOpenGL::ContextEndFrame() m_ContextRecord->AddChunk(scope.Get()); } -void WrappedOpenGL::CleanupResourceRecord(GLResourceRecord *record) +void WrappedOpenGL::CleanupResourceRecord(GLResourceRecord *record, bool freeParents) { - record->LockChunks(); - while(record->HasChunks()) + if(record) { - Chunk *chunk = record->GetLastChunk(); + record->LockChunks(); + while(record->HasChunks()) + { + Chunk *chunk = record->GetLastChunk(); - SAFE_DELETE(chunk); - record->PopChunk(); + SAFE_DELETE(chunk); + record->PopChunk(); + } + record->UnlockChunks(); + if(freeParents) + record->FreeParents(GetResourceManager()); } - record->UnlockChunks(); - - record->FreeParents(GetResourceManager()); } void WrappedOpenGL::CleanupCapture() @@ -2283,12 +2274,11 @@ void WrappedOpenGL::CleanupCapture() m_SuccessfulCapture = true; m_FailureReason = CaptureSucceeded; - CleanupResourceRecord(m_ContextRecord); + CleanupResourceRecord(m_ContextRecord, true); - for(auto it = m_ActiveContextResourceIDs.begin(); it != m_ActiveContextResourceIDs.end(); ++it) + for(auto it = m_ContextData.begin(); it != m_ContextData.end(); ++it) { - GLResourceRecord *contextRecord = GetResourceManager()->GetResourceRecord(it->second); - CleanupResourceRecord(contextRecord); + CleanupResourceRecord(it->second.m_ContextDataRecord, true); } for(auto it = m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) @@ -2359,21 +2349,17 @@ void WrappedOpenGL::AttemptCapture() m_DebugMessages.clear(); { - RDCDEBUG("GL Context %llu Attempting capture", GetContextResourceID()); + RDCDEBUG("GL Context %llu Attempting capture", m_ContextResourceID); m_SuccessfulCapture = true; m_FailureReason = CaptureSucceeded; - GLResourceRecord *contextRecord = GetContextRecord(); - contextRecord->LockChunks(); - while(contextRecord->HasChunks()) - { - Chunk *chunk = contextRecord->GetLastChunk(); + CleanupResourceRecord(m_ContextRecord, false); - SAFE_DELETE(chunk); - contextRecord->PopChunk(); + for(auto it = m_ContextData.begin(); it != m_ContextData.end(); ++it) + { + CleanupResourceRecord(it->second.m_ContextDataRecord, false); } - contextRecord->UnlockChunks(); } } diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 0829a51a1..b9ff3b2a7 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -131,17 +131,16 @@ private: StreamReader *m_FrameReader = NULL; static std::map m_ActiveContexts; - static std::map m_ActiveContextResourceIDs; - ContextPair m_EmptyPair; - uint64_t m_CurCtxPairTLS; - std::vector m_CtxPairs; + GLContextTLSData m_EmptyTLSData; + uint64_t m_CurCtxDataTLS; + std::vector m_CtxDataVector; uintptr_t m_ShareGroupID; std::vector m_LastContexts; - std::set m_AcceptedThreads; + std::set m_AcceptedCtx; public: enum @@ -380,7 +379,7 @@ private: bool HasSuccessfulCapture(CaptureFailReason &reason) { reason = m_FailureReason; - return m_SuccessfulCapture && RecordingHasChunks(); + return m_SuccessfulCapture; } void AttemptCapture(); template @@ -389,7 +388,7 @@ private: void FinishCapture(); void ContextEndFrame(); - void CleanupResourceRecord(GLResourceRecord *record); + void CleanupResourceRecord(GLResourceRecord *record, bool freeParents); void CleanupCapture(); void FreeCaptureData(); @@ -409,13 +408,14 @@ private: CharSize = CharAspect = 0.0f; RDCEraseEl(m_TextureRecord); RDCEraseEl(m_BufferRecord); - m_VertexArrayRecord = m_FeedbackRecord = m_DrawFramebufferRecord = NULL; + m_VertexArrayRecord = m_FeedbackRecord = m_DrawFramebufferRecord = m_ContextDataRecord = NULL; m_ReadFramebufferRecord = NULL; m_Renderbuffer = ResourceId(); m_TextureUnit = 0; m_ProgramPipeline = m_Program = 0; RDCEraseEl(m_ClientMemoryVBOs); m_ClientMemoryIBO = 0; + m_ContextDataResourceID = ResourceId(); } void *ctx; @@ -443,6 +443,8 @@ private: void CreateDebugData(const GLHookSet &gl); + void CreateResourceRecord(WrappedOpenGL *gl, void *suppliedCtx); + bool Legacy() { return !attribsCreate || (!IsGLES && version < 32) || (IsGLES && version < 20); @@ -477,6 +479,9 @@ private: // temporary VBOs so that input mesh data is recorded. See struct ClientMemoryData GLuint m_ClientMemoryVBOs[16]; GLuint m_ClientMemoryIBO; + + ResourceId m_ContextDataResourceID; + GLResourceRecord *m_ContextDataRecord; }; struct ClientMemoryData @@ -570,9 +575,7 @@ public: static std::string GetChunkName(uint32_t idx); GLResourceManager *GetResourceManager() { return m_ResourceManager; } ResourceId GetDeviceResourceID() { return m_DeviceResourceID; } - ResourceId GetContextResourceID(); - GLResourceRecord *GetContextRecord(); - bool RecordingHasChunks(); + ResourceId GetContextResourceID() { return m_ContextResourceID; } CaptureState GetState() { return m_State; } GLReplay *GetReplay() { return &m_Replay; } WriteSerialiser &GetSerialiser() { return m_ScratchSerialiser; } @@ -581,6 +584,8 @@ public: RDCDriver GetDriverType() { return m_DriverType; } GLInitParams &GetInitParams() { return m_InitParams; } ContextPair &GetCtx(); + GLResourceRecord *GetContextRecord(); + void *ShareCtx(void *ctx) { return ctx ? m_ContextData[ctx].shareGroup : NULL; } void SetStructuredExport(uint64_t sectionVersion) { diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index 05a0e8d36..957fb4956 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -321,3 +321,11 @@ private: byte *ShadowPtr[2]; size_t ShadowSize; }; + +struct GLContextTLSData +{ + GLContextTLSData() {} + GLContextTLSData(ContextPair p, GLResourceRecord *r) : ctxPair(p), ctxRecord(r) {} + ContextPair ctxPair; + GLResourceRecord *ctxRecord; +}; diff --git a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp index d114d6d8b..d9af45df8 100644 --- a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp @@ -206,8 +206,9 @@ void WrappedOpenGL::HandleVRFrameMarkers(const GLchar *buf, GLsizei length) if(IsActiveCapturing(m_State)) { - m_AcceptedThreads.clear(); - m_AcceptedThreads.insert(Threading::GetCurrentID()); + m_AcceptedCtx.clear(); + m_AcceptedCtx.insert(GetCtx().ctx); + RDCDEBUG("Only resource ID accepted is %llu", GetCtxData().m_ContextDataResourceID); } } }