Backdoor context for opengl resource retrieval

This commit is contained in:
thisisjimmyfb
2020-01-20 13:38:30 +00:00
committed by baldurk
parent 11f1f30b46
commit c7c929eca9
6 changed files with 111 additions and 47 deletions
+17 -36
View File
@@ -644,8 +644,6 @@ WrappedOpenGL::WrappedOpenGL(GLPlatform &platform)
m_DrawcallStack.push_back(&m_ParentDrawcall);
m_ShareGroupID = UINTPTR_MAX - 2000;
m_CurEventID = 0;
m_CurDrawcallID = 0;
m_FirstEventID = 0;
@@ -1028,7 +1026,9 @@ void WrappedOpenGL::DeleteContext(void *contextHandle)
// if this is the last context in the share group, delete the group.
if(lastInGroup)
GetResourceManager()->DeleteContext(ctxdata.shareGroup);
{
delete ctxdata.shareGroup;
}
if(ctxdata.built && ctxdata.ready)
{
@@ -1125,16 +1125,13 @@ void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext,
if(shareContext == NULL)
{
// no sharing, allocate a new group ID
ctxdata.shareGroup = (void *)m_ShareGroupID;
// we're counting down from UINTPTR_MAX when allocating IDs
m_ShareGroupID--;
// no sharing, allocate a new group
ctxdata.shareGroup = new ContextShareGroup(m_Platform, winData);
}
else
{
// use the same shareGroup ID as the share context.
ctxdata.shareGroup = ShareCtx(shareContext);
ctxdata.shareGroup = GetShareGroup(shareContext);
}
RenderDoc::Inst().AddDeviceFrameCapturer(ctxdata.ctx, this);
@@ -1178,16 +1175,13 @@ void WrappedOpenGL::RegisterReplayContext(GLWindowingData winData, void *shareCo
if(shareContext == NULL)
{
// no sharing, allocate a new group ID
ctxdata.shareGroup = (void *)m_ShareGroupID;
// we're counting down from UINTPTR_MAX when allocating IDs
m_ShareGroupID--;
// create the sharegroup
ctxdata.shareGroup = new ContextShareGroup(m_Platform, winData);
}
else
{
// use the same shareGroup ID as the share context.
ctxdata.shareGroup = ShareCtx(shareContext);
ctxdata.shareGroup = GetShareGroup(shareContext);
}
ActivateContext(winData);
@@ -1260,7 +1254,7 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
//
// First we process any queued fetches from the context itself (i.e. non-shared resources),
// then from the context's share group.
for(void *ctx : {(void *)winData.ctx, ShareCtx(winData.ctx)})
for(void *ctx : {(void *)winData.ctx, (void *)GetShareGroup(winData.ctx)})
{
QueuedResource fetch;
fetch.res.ContextShareGroup = ctx;
@@ -1285,7 +1279,7 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
// also if there are any queued releases, process them now
if(!m_QueuedReleases.empty())
{
for(void *ctx : {(void *)winData.ctx, ShareCtx(winData.ctx)})
for(void *ctx : {(void *)winData.ctx, (void *)GetShareGroup(winData.ctx)})
{
QueuedResource fetch;
fetch.res.ContextShareGroup = ctx;
@@ -1316,12 +1310,12 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
if(tlsData)
{
tlsData->ctxPair = {winData.ctx, ShareCtx(winData.ctx)};
tlsData->ctxPair = {winData.ctx, GetShareGroup(winData.ctx)};
tlsData->ctxRecord = ctxdata.m_ContextDataRecord;
}
else
{
tlsData = new GLContextTLSData(ContextPair({winData.ctx, ShareCtx(winData.ctx)}),
tlsData = new GLContextTLSData(ContextPair({winData.ctx, GetShareGroup(winData.ctx)}),
ctxdata.m_ContextDataRecord);
m_CtxDataVector.push_back(tlsData);
@@ -2692,24 +2686,11 @@ void WrappedOpenGL::QueuePrepareInitialState(GLResource res)
void WrappedOpenGL::QueueResourceRelease(GLResource res)
{
if(res.name == 0)
return;
QueuedResource q;
q.res = res;
ContextPair &ctx = GetCtx();
if(res.ContextShareGroup == ctx.ctx || res.ContextShareGroup == ctx.shareGroup)
{
// if we're already on a context, delete immediately
ReleaseResource(res);
}
else
{
// otherwise, queue for next time this becomes active
QueuedResource q;
q.res = res;
auto insertPos = std::lower_bound(m_QueuedReleases.begin(), m_QueuedReleases.end(), q);
m_QueuedReleases.insert(insertPos - m_QueuedReleases.begin(), q);
}
auto insertPos = std::lower_bound(m_QueuedReleases.begin(), m_QueuedReleases.end(), q);
m_QueuedReleases.insert(insertPos - m_QueuedReleases.begin(), q);
}
void WrappedOpenGL::CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint,
+20 -4
View File
@@ -78,6 +78,24 @@ struct Replacement
GLResource res;
};
struct ContextShareGroup
{
GLPlatform &m_Platform;
GLWindowingData m_BackDoor; // holds the backdoor context for the share group
explicit ContextShareGroup(GLPlatform &platform, const GLWindowingData &windata)
: m_Platform(platform)
{
// create a backdoor context for the purpose of retrieving resources
m_BackDoor = m_Platform.CloneTemporaryContext(windata);
}
~ContextShareGroup()
{
// destroy the backdoor context
m_Platform.DeleteClonedContext(m_BackDoor);
}
};
class WrappedOpenGL : public IFrameCapturer
{
private:
@@ -157,8 +175,6 @@ private:
uint64_t m_CurCtxDataTLS;
rdcarray<GLContextTLSData *> m_CtxDataVector;
uintptr_t m_ShareGroupID;
uint32_t m_InternalShader = 0;
rdcarray<GLWindowingData> m_LastContexts;
@@ -371,7 +387,7 @@ private:
void *ctx;
void *shareGroup;
ContextShareGroup *shareGroup;
GLDEBUGPROC m_RealDebugFunc;
const void *m_RealDebugFuncParam;
@@ -585,7 +601,7 @@ public:
void PushInternalShader() { m_InternalShader++; }
void PopInternalShader() { m_InternalShader--; }
bool IsInternalShader() { return m_InternalShader > 0; }
void *ShareCtx(void *ctx) { return ctx ? m_ContextData[ctx].shareGroup : NULL; }
ContextShareGroup *GetShareGroup(void *ctx) { return ctx ? m_ContextData[ctx].shareGroup : NULL; }
void SetStructuredExport(uint64_t sectionVersion)
{
m_SectionVersion = sectionVersion;
+47
View File
@@ -553,14 +553,32 @@ bool GLResourceManager::Prepare_InitialState(GLResource res)
// and we just start getting commands there, but that case already isn't supported as we don't
// detect it and insert state-change chunks, we assume all commands will come from a single
// thread.
RDCASSERT(res.ContextShareGroup);
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup == ctx.ctx || res.ContextShareGroup == ctx.shareGroup)
{
// call immediately, we are on the right context or share group
ContextPrepare_InitialState(res);
}
else if(IsResourceTrackedForPersistency(res))
{
GLWindowingData oldContextData = m_Driver->m_ActiveContexts[Threading::GetCurrentID()];
ContextShareGroup *shareGroup = (ContextShareGroup *)res.ContextShareGroup;
m_Driver->m_ActiveContexts[Threading::GetCurrentID()] = shareGroup->m_BackDoor;
m_Driver->m_Platform.MakeContextCurrent(shareGroup->m_BackDoor);
ContextPrepare_InitialState(res);
// restore the context
m_Driver->m_ActiveContexts[Threading::GetCurrentID()] = oldContextData;
m_Driver->m_Platform.MakeContextCurrent(oldContextData);
}
else
{
// queue if we can't use the backdoor
m_Driver->QueuePrepareInitialState(res);
}
@@ -1783,6 +1801,35 @@ template bool GLResourceManager::Serialise_InitialState<>(WriteSerialiser &ser,
GLResourceRecord *record,
const GLInitialContents *initial);
bool GLResourceManager::Serialise_InitialState(WriteSerialiser &ser, ResourceId id,
GLResourceRecord *record,
const GLInitialContents *initial)
{
GLResource res = GetCurrentResource(id);
if(IsResourceTrackedForPersistency(res))
{
GLWindowingData oldContextData = m_Driver->m_ActiveContexts[Threading::GetCurrentID()];
GLWindowingData backdoor = ((ContextShareGroup *)res.ContextShareGroup)->m_BackDoor;
m_Driver->m_Platform.MakeContextCurrent(backdoor);
m_Driver->m_ActiveContexts[Threading::GetCurrentID()] = backdoor;
bool success = Serialise_InitialState<WriteSerialiser>(ser, id, record, initial);
// restore the context
m_Driver->m_ActiveContexts[Threading::GetCurrentID()] = oldContextData;
m_Driver->m_Platform.MakeContextCurrent(oldContextData);
return success;
}
return Serialise_InitialState<WriteSerialiser>(ser, id, record, initial);
}
void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool hasData)
{
if(IsStructuredExporting(m_State))
+24 -1
View File
@@ -134,6 +134,29 @@ bool GLResourceManager::ResourceTypeRelease(GLResource res)
if(HasCurrentResource(res))
UnregisterResource(res);
m_Driver->QueueResourceRelease(res);
if(res.name)
{
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup == ctx.ctx || res.ContextShareGroup == ctx.shareGroup)
{
m_Driver->ReleaseResource(res);
}
else if(IsResourceTrackedForPersistency(res))
{
ContextShareGroup *contextShareGroup = (ContextShareGroup *)res.ContextShareGroup;
m_Driver->m_Platform.MakeContextCurrent(contextShareGroup->m_BackDoor);
m_Driver->ReleaseResource(res);
// restore the context
m_Driver->m_Platform.MakeContextCurrent(m_Driver->m_ActiveContexts[Threading::GetCurrentID()]);
}
else
{
// queue if we can't use the backdoor
m_Driver->QueueResourceRelease(res);
}
}
return true;
}
+2 -5
View File
@@ -270,13 +270,10 @@ public:
template <typename SerialiserType>
bool Serialise_InitialState(SerialiserType &ser, ResourceId id, GLResourceRecord *record,
const GLInitialContents *initial);
bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, GLResourceRecord *record,
const GLInitialContents *initial);
void ContextPrepare_InitialState(GLResource res);
bool Serialise_InitialState(WriteSerialiser &ser, ResourceId id, GLResourceRecord *record,
const GLInitialContents *initial)
{
return Serialise_InitialState<WriteSerialiser>(ser, id, record, initial);
}
void SetInternalResource(GLResource res);
+1 -1
View File
@@ -1852,7 +1852,7 @@ MeshFormat GLReplay::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uint32_
// no multiview support
(void)viewID;
ContextPair ctx = {m_ReplayCtx.ctx, m_pDriver->ShareCtx(m_ReplayCtx.ctx)};
ContextPair ctx = {m_ReplayCtx.ctx, m_pDriver->GetShareGroup(m_ReplayCtx.ctx)};
if(m_PostVSData.find(eventId) != m_PostVSData.end())
postvs = m_PostVSData[eventId];