moving per-thread records to the TLS-context

This commit is contained in:
tuxerr authored and Baldur Karlsson committed 2018-06-11 19:18:02 +01:00
1 parent 891b1f61ef
commit cc9d50cf2e
4 files changed
+119 -119

No files matched your search

+92 -106
View File
@@ -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 &params, 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();
}
}
+16 -11
View File
@@ -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)
{
+8
View File
@@ -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);
}
}
}