mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-27 20:31:02 +00:00
Cache FBO attachments to avoid repeated query & lookup
This commit is contained in:
@@ -67,55 +67,118 @@ void GLResourceManager::MarkFBOReferenced(GLResource res, FrameRefType ref)
|
||||
if(res.name == 0)
|
||||
return;
|
||||
|
||||
MarkResourceFrameReferenced(res, ref);
|
||||
rdcpair<ResourceId, GLResourceRecord *> &it = m_CurrentResources[res];
|
||||
|
||||
ContextPair &ctx = m_Driver->GetCtx();
|
||||
MarkResourceFrameReferenced(it.first, ref);
|
||||
|
||||
GLint numCols = 8;
|
||||
GL.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols);
|
||||
MarkFBOAttachmentsReferenced(it.first, it.second, ref, false);
|
||||
}
|
||||
|
||||
GLenum type = eGL_TEXTURE;
|
||||
GLuint name = 0;
|
||||
void GLResourceManager::MarkFBODirtyWithWriteReference(GLResourceRecord *record)
|
||||
{
|
||||
MarkFBOAttachmentsReferenced(record->GetResourceID(), record, eFrameRef_ReadBeforeWrite, true);
|
||||
}
|
||||
|
||||
for(int c = 0; c < numCols; c++)
|
||||
void GLResourceManager::MarkFBOAttachmentsReferenced(ResourceId fboid, GLResourceRecord *record,
|
||||
FrameRefType ref, bool markDirty)
|
||||
{
|
||||
FBOCache *cache = m_FBOAttachmentsCache[fboid];
|
||||
|
||||
if(!cache)
|
||||
{
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0 + c),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
(GLint *)&name);
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0 + c),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
|
||||
(GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
MarkResourceFrameReferenced(RenderbufferRes(ctx, name), ref);
|
||||
else
|
||||
MarkResourceFrameReferenced(TextureRes(ctx, name), ref);
|
||||
cache = m_FBOAttachmentsCache[fboid] = new FBOCache;
|
||||
// ensure the starting age is wrong, for whatever age we have
|
||||
cache->age = (record->age ^ 1);
|
||||
}
|
||||
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name);
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type);
|
||||
|
||||
if(name)
|
||||
if(cache->age != record->age)
|
||||
{
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
MarkResourceFrameReferenced(RenderbufferRes(ctx, name), ref);
|
||||
else
|
||||
MarkResourceFrameReferenced(TextureRes(ctx, name), ref);
|
||||
cache->age = record->age;
|
||||
cache->attachments.clear();
|
||||
|
||||
GLuint fbo = record->Resource.name;
|
||||
|
||||
ContextPair &ctx = m_Driver->GetCtx();
|
||||
|
||||
GLint numCols = 8;
|
||||
GL.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols);
|
||||
|
||||
GLenum type = eGL_TEXTURE;
|
||||
GLuint name = 0;
|
||||
|
||||
ResourceId id;
|
||||
|
||||
for(int c = 0; c < numCols; c++)
|
||||
{
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(fbo, GLenum(eGL_COLOR_ATTACHMENT0 + c),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
(GLint *)&name);
|
||||
|
||||
if(name)
|
||||
{
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(fbo, GLenum(eGL_COLOR_ATTACHMENT0 + c),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
|
||||
(GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
id = GetResID(RenderbufferRes(ctx, name));
|
||||
else
|
||||
id = GetResID(TextureRes(ctx, name));
|
||||
|
||||
cache->attachments.push_back(id);
|
||||
GLResourceRecord *r = GetResourceRecord(id);
|
||||
if(r && r->viewSource != ResourceId())
|
||||
cache->attachments.push_back(r->viewSource);
|
||||
}
|
||||
}
|
||||
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
fbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name);
|
||||
|
||||
if(name)
|
||||
{
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
fbo, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
id = GetResID(RenderbufferRes(ctx, name));
|
||||
else
|
||||
id = GetResID(TextureRes(ctx, name));
|
||||
|
||||
cache->attachments.push_back(id);
|
||||
GLResourceRecord *r = GetResourceRecord(id);
|
||||
if(r && r->viewSource != ResourceId())
|
||||
cache->attachments.push_back(r->viewSource);
|
||||
}
|
||||
|
||||
GLuint stencilName = 0;
|
||||
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
fbo, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&stencilName);
|
||||
|
||||
if(stencilName && stencilName != name)
|
||||
{
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
fbo, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
id = GetResID(RenderbufferRes(ctx, stencilName));
|
||||
else
|
||||
id = GetResID(TextureRes(ctx, stencilName));
|
||||
|
||||
cache->attachments.push_back(id);
|
||||
GLResourceRecord *r = GetResourceRecord(id);
|
||||
if(r && r->viewSource != ResourceId())
|
||||
cache->attachments.push_back(r->viewSource);
|
||||
}
|
||||
}
|
||||
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name);
|
||||
GL.glGetNamedFramebufferAttachmentParameterivEXT(
|
||||
res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type);
|
||||
|
||||
if(name)
|
||||
// we took care of viewSource above so we can directly call the real thing
|
||||
for(ResourceId id : cache->attachments)
|
||||
{
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
MarkResourceFrameReferenced(RenderbufferRes(ctx, name), ref);
|
||||
else
|
||||
MarkResourceFrameReferenced(TextureRes(ctx, name), ref);
|
||||
ResourceManager::MarkResourceFrameReferenced(id, ref);
|
||||
if(markDirty)
|
||||
ResourceManager::MarkDirtyResource(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,13 @@ public:
|
||||
EraseLiveResource(it->second.first);
|
||||
ReleaseCurrentResource(it->second.first);
|
||||
m_CurrentResources.erase(res);
|
||||
|
||||
auto fboit = m_FBOAttachmentsCache.find(it->second.first);
|
||||
if(fboit != m_FBOAttachmentsCache.end())
|
||||
{
|
||||
delete fboit->second;
|
||||
m_FBOAttachmentsCache.erase(fboit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,6 +302,7 @@ public:
|
||||
// this would be handled by record parenting, but that would be a nightmare to track.
|
||||
void MarkVAOReferenced(GLResource res, FrameRefType ref, bool allowFake0 = false);
|
||||
void MarkFBOReferenced(GLResource res, FrameRefType ref);
|
||||
void MarkFBODirtyWithWriteReference(GLResourceRecord *record);
|
||||
|
||||
bool IsResourceTrackedForPersistency(const GLResource &res);
|
||||
|
||||
@@ -320,6 +328,9 @@ private:
|
||||
void Create_InitialState(ResourceId id, GLResource live, bool hasData);
|
||||
void Apply_InitialState(GLResource live, const GLInitialContents &initial);
|
||||
|
||||
void MarkFBOAttachmentsReferenced(ResourceId id, GLResourceRecord *record, FrameRefType ref,
|
||||
bool markDirty);
|
||||
|
||||
// unfortunately not all resources have a record even at capture time (certain special resources
|
||||
// do not) so we store a pair to ensure we can always lookup the resource ID
|
||||
rdcflatmap<GLResource, rdcpair<ResourceId, GLResourceRecord *>> m_CurrentResources;
|
||||
@@ -331,5 +342,13 @@ private:
|
||||
std::map<ResourceId, rdcstr> m_Names;
|
||||
volatile int64_t m_SyncName;
|
||||
|
||||
struct FBOCache
|
||||
{
|
||||
uint32_t age = 0;
|
||||
rdcarray<ResourceId> attachments;
|
||||
};
|
||||
|
||||
rdcflatmap<ResourceId, FBOCache *> m_FBOAttachmentsCache;
|
||||
|
||||
WrappedOpenGL *m_Driver;
|
||||
};
|
||||
|
||||
@@ -611,64 +611,7 @@ void GLRenderState::MarkDirty(WrappedOpenGL *driver)
|
||||
|
||||
if(ctxData.m_DrawFramebufferRecord)
|
||||
{
|
||||
name = ctxData.m_DrawFramebufferRecord->Resource.name;
|
||||
|
||||
static GLint fboCount = 0;
|
||||
if(fboCount == 0)
|
||||
GL.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &fboCount);
|
||||
|
||||
GLenum type = eGL_TEXTURE;
|
||||
for(GLint i = 0; i < fboCount; i++)
|
||||
{
|
||||
GL.glGetFramebufferAttachmentParameteriv(
|
||||
eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name);
|
||||
|
||||
if(name)
|
||||
{
|
||||
GL.glGetFramebufferAttachmentParameteriv(
|
||||
eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i),
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
manager->MarkDirtyResource(RenderbufferRes(ctx, name));
|
||||
else
|
||||
manager->MarkDirtyWithWriteReference(TextureRes(ctx, name));
|
||||
}
|
||||
}
|
||||
|
||||
GL.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT,
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name);
|
||||
|
||||
if(name)
|
||||
{
|
||||
GL.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT,
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
|
||||
(GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
manager->MarkDirtyResource(RenderbufferRes(ctx, name));
|
||||
else
|
||||
manager->MarkDirtyWithWriteReference(TextureRes(ctx, name));
|
||||
}
|
||||
|
||||
GLuint stencilName = 0;
|
||||
GL.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT,
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
(GLint *)&stencilName);
|
||||
|
||||
// almost always this will be the same as the depth, so we can skip it if so
|
||||
if(stencilName && stencilName != name)
|
||||
{
|
||||
GL.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT,
|
||||
eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
|
||||
(GLint *)&type);
|
||||
|
||||
if(type == eGL_RENDERBUFFER)
|
||||
manager->MarkDirtyResource(RenderbufferRes(ctx, stencilName));
|
||||
else
|
||||
manager->MarkDirtyWithWriteReference(TextureRes(ctx, stencilName));
|
||||
}
|
||||
manager->MarkFBODirtyWithWriteReference(ctxData.m_DrawFramebufferRecord);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -258,7 +258,11 @@ struct GLResourceRecord : public ResourceRecord
|
||||
}
|
||||
|
||||
bool AlreadyDataType(GLenum target) { return datatype == TextureBinding(target); }
|
||||
GLenum datatype;
|
||||
union
|
||||
{
|
||||
GLenum datatype;
|
||||
uint32_t age;
|
||||
};
|
||||
GLenum usage;
|
||||
|
||||
// for texture buffers, this points from the texture to the real buffer, for texture views this
|
||||
|
||||
@@ -215,6 +215,8 @@ void WrappedOpenGL::glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum atta
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -269,6 +271,8 @@ void WrappedOpenGL::glFramebufferTexture(GLenum target, GLenum attachment, GLuin
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -353,6 +357,8 @@ void WrappedOpenGL::glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum at
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -409,6 +415,8 @@ void WrappedOpenGL::glFramebufferTexture1D(GLenum target, GLenum attachment, GLe
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -494,6 +502,8 @@ void WrappedOpenGL::glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum at
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -550,6 +560,8 @@ void WrappedOpenGL::glFramebufferTexture2D(GLenum target, GLenum attachment, GLe
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -659,6 +671,8 @@ void WrappedOpenGL::glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum a
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -748,6 +762,8 @@ void WrappedOpenGL::glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum at
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -806,6 +822,8 @@ void WrappedOpenGL::glFramebufferTexture3D(GLenum target, GLenum attachment, GLe
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -892,6 +910,8 @@ void WrappedOpenGL::glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
@@ -945,6 +965,8 @@ void WrappedOpenGL::glFramebufferRenderbuffer(GLenum target, GLenum attachment,
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
@@ -1026,6 +1048,8 @@ void WrappedOpenGL::glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum
|
||||
GLResourceRecord *record =
|
||||
GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer));
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -1082,6 +1106,8 @@ void WrappedOpenGL::glFramebufferTextureLayer(GLenum target, GLenum attachment,
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -1187,6 +1213,8 @@ void WrappedOpenGL::glFramebufferTextureMultiviewOVR(GLenum target, GLenum attac
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
@@ -1303,6 +1331,8 @@ void WrappedOpenGL::glFramebufferTextureMultisampleMultiviewOVR(GLenum target, G
|
||||
record = GetCtxData().m_ReadFramebufferRecord;
|
||||
}
|
||||
|
||||
record->age++;
|
||||
|
||||
if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture)))
|
||||
{
|
||||
GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture));
|
||||
|
||||
Reference in New Issue
Block a user