mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-10-12 15:19:14 +00:00
moving per-thread records to the TLS-context
This commit is contained in:
1 parent
891b1f61ef
commit
cc9d50cf2e
4 files changed
+119
-119
No files matched your search
@@ -32,7 +32,6 @@
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
std::map<uint64_t, GLWindowingData> WrappedOpenGL::m_ActiveContexts;
|
||||
std::map<uint64_t, ResourceId> 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<int32_t, Chunk *> 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,17 +131,16 @@ private:
|
||||
StreamReader *m_FrameReader = NULL;
|
||||
|
||||
static std::map<uint64_t, GLWindowingData> m_ActiveContexts;
|
||||
static std::map<uint64_t, ResourceId> m_ActiveContextResourceIDs;
|
||||
|
||||
ContextPair m_EmptyPair;
|
||||
uint64_t m_CurCtxPairTLS;
|
||||
std::vector<ContextPair *> m_CtxPairs;
|
||||
GLContextTLSData m_EmptyTLSData;
|
||||
uint64_t m_CurCtxDataTLS;
|
||||
std::vector<GLContextTLSData *> m_CtxDataVector;
|
||||
|
||||
uintptr_t m_ShareGroupID;
|
||||
|
||||
std::vector<GLWindowingData> m_LastContexts;
|
||||
|
||||
std::set<uint64_t> m_AcceptedThreads;
|
||||
std::set<void *> 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 <typename SerialiserType>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user