mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 15:06:32 +00:00
Store read/draw buffers for FBOs in initial data
* This avoids spamming of glReadBuffer/glDrawBuffer calls pointlessly into the pre-frame chunk stream. * The default FBO stores its ReadBuffer and DrawBuffers in the initial frame state vector.
This commit is contained in:
@@ -1422,7 +1422,7 @@ bool WrappedOpenGL::Serialise_BeginCaptureFrame(bool applyInitialState)
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
state.FetchState();
|
||||
state.FetchState(GetCtx(), this);
|
||||
}
|
||||
|
||||
state.Serialise(m_State, GetCtx(), this);
|
||||
@@ -1430,7 +1430,7 @@ bool WrappedOpenGL::Serialise_BeginCaptureFrame(bool applyInitialState)
|
||||
if(m_State <= EXECUTING && applyInitialState)
|
||||
{
|
||||
m_DoStateVerify = false;
|
||||
state.ApplyState();
|
||||
state.ApplyState(GetCtx(), this);
|
||||
m_DoStateVerify = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,12 @@ struct FeedbackInitialData
|
||||
uint64_t Size[4];
|
||||
};
|
||||
|
||||
struct FramebufferInitialData
|
||||
{
|
||||
GLenum DrawBuffers[8];
|
||||
GLenum ReadBuffer;
|
||||
};
|
||||
|
||||
template<>
|
||||
void Serialiser::Serialise(const char *name, VertexAttribInitialData &el)
|
||||
{
|
||||
@@ -91,6 +97,14 @@ void Serialiser::Serialise(const char *name, FeedbackInitialData &el)
|
||||
Serialise<4>("Size", el.Size);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Serialiser::Serialise(const char *name, FramebufferInitialData &el)
|
||||
{
|
||||
ScopedContext scope(this, this, name, "FramebufferInitialData", 0, true);
|
||||
Serialise<8>("DrawBuffers", el.DrawBuffers);
|
||||
Serialise("ReadBuffer", el.ReadBuffer);
|
||||
}
|
||||
|
||||
struct TextureStateInitialData
|
||||
{
|
||||
int32_t baseLevel, maxLevel;
|
||||
@@ -280,6 +294,34 @@ bool GLResourceManager::Prepare_InitialState(GLResource res)
|
||||
|
||||
SetInitialContents(Id, InitialContentData(TextureRes(res.Context, tex), 0, (byte *)state));
|
||||
}
|
||||
else if(res.Namespace == eResFramebuffer)
|
||||
{
|
||||
// need to be on the right context, as feedback objects are never shared
|
||||
void *oldctx = m_GL->SwitchToContext(res.Context);
|
||||
|
||||
GLuint prevread = 0, prevdraw = 0;
|
||||
gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw);
|
||||
gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread);
|
||||
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, res.name);
|
||||
gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, res.name);
|
||||
|
||||
FramebufferInitialData *data = (FramebufferInitialData *)Serialiser::AllocAlignedBuffer(sizeof(FramebufferInitialData));
|
||||
RDCEraseMem(data, sizeof(FramebufferInitialData));
|
||||
|
||||
for(int i=0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++)
|
||||
gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&data->DrawBuffers[i]);
|
||||
|
||||
gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&data->ReadBuffer);
|
||||
|
||||
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, (byte *)data));
|
||||
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw);
|
||||
gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread);
|
||||
|
||||
// restore the previous context
|
||||
m_GL->SwitchToContext(oldctx);
|
||||
}
|
||||
else if(res.Namespace == eResFeedback)
|
||||
{
|
||||
// need to be on the right context, as feedback objects are never shared
|
||||
@@ -795,6 +837,26 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
|
||||
gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]);
|
||||
}
|
||||
}
|
||||
else if(res.Namespace == eResFramebuffer)
|
||||
{
|
||||
FramebufferInitialData data;
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
FramebufferInitialData *initialdata = (FramebufferInitialData *)GetInitialContents(Id).blob;
|
||||
memcpy(&data, initialdata, sizeof(data));
|
||||
}
|
||||
|
||||
m_pSerialiser->Serialise("Framebuffer object Buffers", data);
|
||||
|
||||
if(m_State < WRITING)
|
||||
{
|
||||
byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data));
|
||||
memcpy(blob, &data, sizeof(data));
|
||||
|
||||
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob));
|
||||
}
|
||||
}
|
||||
else if(res.Namespace == eResFeedback)
|
||||
{
|
||||
FeedbackInitialData data;
|
||||
@@ -936,6 +998,25 @@ void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData i
|
||||
{
|
||||
CopyProgramUniforms(gl, initial.resource.name, live.name);
|
||||
}
|
||||
else if(live.Namespace == eResFramebuffer)
|
||||
{
|
||||
GLuint prevread = 0, prevdraw = 0;
|
||||
gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw);
|
||||
gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread);
|
||||
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, live.name);
|
||||
gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, live.name);
|
||||
|
||||
FramebufferInitialData *data = (FramebufferInitialData *)initial.blob;
|
||||
|
||||
for(int i=0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++)
|
||||
gl.glDrawBuffers(ARRAY_COUNT(data->DrawBuffers), data->DrawBuffers);
|
||||
|
||||
gl.glReadBuffer(data->ReadBuffer);
|
||||
|
||||
gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw);
|
||||
gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread);
|
||||
}
|
||||
else if(live.Namespace == eResFeedback)
|
||||
{
|
||||
GLuint prevfeedback = 0;
|
||||
|
||||
@@ -37,7 +37,7 @@ GLRenderState::~GLRenderState()
|
||||
{
|
||||
}
|
||||
|
||||
void GLRenderState::FetchState()
|
||||
void GLRenderState::FetchState(void *ctx, WrappedOpenGL *gl)
|
||||
{
|
||||
GLint boolread = 0;
|
||||
// TODO check GL_MAX_*
|
||||
@@ -211,9 +211,17 @@ void GLRenderState::FetchState()
|
||||
m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&DrawFBO);
|
||||
m_Real->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&ReadFBO);
|
||||
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0);
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0);
|
||||
|
||||
for(size_t i=0; i < ARRAY_COUNT(DrawBuffers); i++)
|
||||
m_Real->glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&DrawBuffers[i]);
|
||||
|
||||
m_Real->glGetIntegerv(eGL_READ_BUFFER, (GLint *)&ReadBuffer);
|
||||
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO);
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO);
|
||||
|
||||
m_Real->glGetIntegerv(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, (GLint *)&Hints.Derivatives);
|
||||
m_Real->glGetIntegerv(eGL_LINE_SMOOTH_HINT, (GLint *)&Hints.LineSmooth);
|
||||
m_Real->glGetIntegerv(eGL_POLYGON_SMOOTH_HINT, (GLint *)&Hints.PolySmooth);
|
||||
@@ -287,7 +295,7 @@ void GLRenderState::FetchState()
|
||||
m_Real->glGetIntegerv(eGL_CULL_FACE_MODE, (GLint *)&CullFace);
|
||||
}
|
||||
|
||||
void GLRenderState::ApplyState()
|
||||
void GLRenderState::ApplyState(void *ctx, WrappedOpenGL *gl)
|
||||
{
|
||||
{
|
||||
GLenum pnames[] =
|
||||
@@ -437,9 +445,6 @@ void GLRenderState::ApplyState()
|
||||
m_Real->glDisablei(eGL_SCISSOR_TEST, s);
|
||||
}
|
||||
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO);
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO);
|
||||
|
||||
GLenum DBs[8] = { eGL_NONE };
|
||||
uint32_t numDBs = 0;
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(DrawBuffers); i++)
|
||||
@@ -469,7 +474,17 @@ void GLRenderState::ApplyState()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// apply drawbuffers/readbuffer to default framebuffer
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, gl->GetFakeBBFBO());
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, gl->GetFakeBBFBO());
|
||||
m_Real->glDrawBuffers(numDBs, DBs);
|
||||
|
||||
// see above for reasoning for this
|
||||
m_Real->glReadBuffer(eGL_COLOR_ATTACHMENT0);
|
||||
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO);
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO);
|
||||
|
||||
m_Real->glHint(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, Hints.Derivatives);
|
||||
m_Real->glHint(eGL_LINE_SMOOTH_HINT, Hints.LineSmooth);
|
||||
@@ -565,6 +580,7 @@ void GLRenderState::Clear()
|
||||
RDCEraseEl(DrawFBO);
|
||||
RDCEraseEl(ReadFBO);
|
||||
RDCEraseEl(DrawBuffers);
|
||||
RDCEraseEl(ReadBuffer);
|
||||
|
||||
RDCEraseEl(PatchParams);
|
||||
RDCEraseEl(PolygonMode);
|
||||
@@ -746,7 +762,8 @@ void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl)
|
||||
m_pSerialiser->Serialise("GL_SCISSOR.enabled", Scissors[i].enabled);
|
||||
}
|
||||
|
||||
m_pSerialiser->Serialise<8>("GL_DRAWBUFFERS", DrawBuffers);
|
||||
m_pSerialiser->Serialise<8>("GL_DRAW_BUFFERS", DrawBuffers);
|
||||
m_pSerialiser->Serialise("GL_READ_BUFFER", ReadBuffer);
|
||||
|
||||
m_pSerialiser->Serialise("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", Hints.Derivatives);
|
||||
m_pSerialiser->Serialise("GL_LINE_SMOOTH_HINT", Hints.LineSmooth);
|
||||
|
||||
@@ -36,8 +36,8 @@ struct GLRenderState
|
||||
GLRenderState(const GLHookSet *funcs, Serialiser *ser, LogState state);
|
||||
~GLRenderState();
|
||||
|
||||
void FetchState();
|
||||
void ApplyState();
|
||||
void FetchState(void *ctx, WrappedOpenGL *gl);
|
||||
void ApplyState(void *ctx, WrappedOpenGL *gl);
|
||||
void Clear();
|
||||
void Serialise(LogState state, void *ctx, WrappedOpenGL *gl);
|
||||
|
||||
@@ -151,12 +151,15 @@ struct GLRenderState
|
||||
} Scissors[16];
|
||||
|
||||
GLuint ReadFBO, DrawFBO;
|
||||
|
||||
// these refer to the states on the default framebuffer.
|
||||
// Other FBOs serialise them in their resource records.
|
||||
GLenum ReadBuffer;
|
||||
GLenum DrawBuffers[8];
|
||||
|
||||
// TODO:
|
||||
// Image state (GL_IMAGE_BINDING_NAME)
|
||||
// multisampling
|
||||
// provoking vertex
|
||||
// other misc state :)
|
||||
|
||||
struct
|
||||
|
||||
@@ -820,7 +820,7 @@ void GLReplay::SavePipelineState()
|
||||
MakeCurrentReplayContext(&m_ReplayCtx);
|
||||
|
||||
GLRenderState rs(&gl.GetHookset(), NULL, READING);
|
||||
rs.FetchState();
|
||||
rs.FetchState(m_ReplayCtx.ctx, &gl);
|
||||
|
||||
// Index buffer
|
||||
|
||||
|
||||
@@ -728,26 +728,19 @@ void WrappedOpenGL::glReadBuffer(GLenum mode)
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(READ_BUFFER);
|
||||
Serialise_glReadBuffer(mode);
|
||||
|
||||
if(m_State == WRITING_IDLE)
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
{
|
||||
if(GetCtxData().m_ReadFramebufferRecord)
|
||||
{
|
||||
Chunk *last = GetCtxData().m_ReadFramebufferRecord->GetLastChunk();
|
||||
if(last->GetChunkType() == READ_BUFFER)
|
||||
{
|
||||
delete last;
|
||||
GetCtxData().m_ReadFramebufferRecord->PopChunk();
|
||||
}
|
||||
GetCtxData().m_ReadFramebufferRecord->AddChunk(scope.Get());
|
||||
}
|
||||
else
|
||||
m_DeviceRecord->AddChunk(scope.Get());
|
||||
SCOPED_SERIALISE_CONTEXT(READ_BUFFER);
|
||||
Serialise_glReadBuffer(mode);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
}
|
||||
else
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
{
|
||||
GLResourceRecord *readrecord = GetCtxData().m_ReadFramebufferRecord;
|
||||
if(readrecord)
|
||||
GetResourceManager()->MarkDirtyResource(readrecord->GetResourceID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,12 +806,21 @@ bool WrappedOpenGL::Serialise_glDrawBuffer(GLenum buf)
|
||||
|
||||
void WrappedOpenGL::glDrawBuffer(GLenum buf)
|
||||
{
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER);
|
||||
Serialise_glDrawBuffer(buf);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER);
|
||||
Serialise_glDrawBuffer(buf);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
}
|
||||
else
|
||||
{
|
||||
GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord;
|
||||
if(drawrecord)
|
||||
GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID());
|
||||
}
|
||||
}
|
||||
|
||||
m_Real.glDrawBuffer(buf);
|
||||
@@ -872,15 +874,24 @@ void WrappedOpenGL::glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, c
|
||||
|
||||
void WrappedOpenGL::glDrawBuffers(GLsizei n, const GLenum *bufs)
|
||||
{
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS);
|
||||
if(GetCtxData().m_DrawFramebufferRecord)
|
||||
Serialise_glFramebufferDrawBuffersEXT(GetResourceManager()->GetCurrentResource(GetCtxData().m_DrawFramebufferRecord->GetResourceID()).name, n, bufs);
|
||||
GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord;
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
{
|
||||
SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS);
|
||||
if(drawrecord)
|
||||
Serialise_glFramebufferDrawBuffersEXT(GetResourceManager()->GetCurrentResource(drawrecord->GetResourceID()).name, n, bufs);
|
||||
else
|
||||
Serialise_glFramebufferDrawBuffersEXT(0, n, bufs);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
}
|
||||
else
|
||||
Serialise_glFramebufferDrawBuffersEXT(0, n, bufs);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
{
|
||||
if(drawrecord)
|
||||
GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID());
|
||||
}
|
||||
}
|
||||
|
||||
m_Real.glDrawBuffers(n, bufs);
|
||||
|
||||
Reference in New Issue
Block a user