mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Add initial contents and dirtying for high-frequency samplers
* For samplers that are updated a lot we fall back to fetching & applying their state as initial contents.
This commit is contained in:
@@ -1141,6 +1141,10 @@ bool GLInitParams::IsSupportedVersion(uint64_t ver)
|
||||
if(ver == 0x1D)
|
||||
return true;
|
||||
|
||||
// 0x1E -> 0x1F - added initial states for samplers that are modified a lot
|
||||
if(ver == 0x1E)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ struct GLInitParams
|
||||
bool isYFlipped;
|
||||
|
||||
// check if a frame capture section version is supported
|
||||
static const uint64_t CurrentVersion = 0x1E;
|
||||
static const uint64_t CurrentVersion = 0x1F;
|
||||
static bool IsSupportedVersion(uint64_t ver);
|
||||
};
|
||||
|
||||
|
||||
@@ -108,6 +108,22 @@ void DoSerialise(SerialiserType &ser, PipelineInitialData &el)
|
||||
SERIALISE_MEMBER(programs);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, SamplerInitialData &el)
|
||||
{
|
||||
SERIALISE_MEMBER(valid);
|
||||
SERIALISE_MEMBER(border);
|
||||
SERIALISE_MEMBER(compareFunc);
|
||||
SERIALISE_MEMBER(compareMode);
|
||||
SERIALISE_MEMBER(lodBias);
|
||||
SERIALISE_MEMBER(minLod);
|
||||
SERIALISE_MEMBER(maxLod);
|
||||
SERIALISE_MEMBER(minFilter);
|
||||
SERIALISE_MEMBER(magFilter);
|
||||
SERIALISE_MEMBER(maxAniso);
|
||||
SERIALISE_MEMBER(wrap);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, TextureStateInitialData &el)
|
||||
{
|
||||
@@ -287,6 +303,47 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
|
||||
GL.glGetProgramPipelineiv(res.name, eGL_TESS_EVALUATION_SHADER, (GLint *)&data.programs[2].name);
|
||||
GL.glGetProgramPipelineiv(res.name, eGL_COMPUTE_SHADER, (GLint *)&data.programs[5].name);
|
||||
}
|
||||
else if(res.Namespace == eResSampler)
|
||||
{
|
||||
SamplerInitialData &data = initContents.samp;
|
||||
|
||||
RDCASSERT(!data.valid);
|
||||
data.valid = true;
|
||||
|
||||
GLenum activeTexture = eGL_TEXTURE0;
|
||||
GL.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&activeTexture);
|
||||
|
||||
GL.glActiveTexture(eGL_TEXTURE0);
|
||||
|
||||
GLuint prevsampler = 0;
|
||||
GL.glGetIntegerv(eGL_SAMPLER_BINDING, (GLint *)&prevsampler);
|
||||
|
||||
{
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_COMPARE_FUNC, (GLint *)&data.compareFunc);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_COMPARE_MODE, (GLint *)&data.compareMode);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_MIN_FILTER, (GLint *)&data.minFilter);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_MAG_FILTER, (GLint *)&data.magFilter);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_WRAP_R, (GLint *)&data.wrap[0]);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_WRAP_S, (GLint *)&data.wrap[1]);
|
||||
GL.glGetSamplerParameteriv(res.name, eGL_TEXTURE_WRAP_T, (GLint *)&data.wrap[2]);
|
||||
GL.glGetSamplerParameterfv(res.name, eGL_TEXTURE_MIN_LOD, &data.minLod);
|
||||
GL.glGetSamplerParameterfv(res.name, eGL_TEXTURE_MAX_LOD, &data.maxLod);
|
||||
if(!IsGLES)
|
||||
GL.glGetSamplerParameterfv(res.name, eGL_TEXTURE_LOD_BIAS, &data.lodBias);
|
||||
|
||||
// technically border color has been in since GL 1.0, but since this extension was really
|
||||
// early and dovetails nicely with OES_texture_border_color which added both border colors and
|
||||
// clamping, we check it.
|
||||
if(HasExt[ARB_texture_border_clamp])
|
||||
GL.glGetSamplerParameterfv(res.name, eGL_TEXTURE_BORDER_COLOR, &data.border[0]);
|
||||
else
|
||||
data.border[0] = data.border[1] = data.border[2] = data.border[3] = 1.0f;
|
||||
}
|
||||
|
||||
GL.glBindSampler(0, prevsampler);
|
||||
|
||||
GL.glActiveTexture(activeTexture);
|
||||
}
|
||||
else if(res.Namespace == eResFeedback)
|
||||
{
|
||||
FeedbackInitialData &data = initContents.xfb;
|
||||
@@ -500,6 +557,20 @@ bool GLResourceManager::Prepare_InitialState(GLResource res)
|
||||
ContextPrepare_InitialState(res);
|
||||
}
|
||||
}
|
||||
else if(res.Namespace == eResSampler)
|
||||
{
|
||||
// queue initial state fetching if we're not on the right context, see above in FBOs for more
|
||||
// explanation of this.
|
||||
ContextPair &ctx = m_Driver->GetCtx();
|
||||
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
|
||||
{
|
||||
m_Driver->QueuePrepareInitialState(res);
|
||||
}
|
||||
else
|
||||
{
|
||||
ContextPrepare_InitialState(res);
|
||||
}
|
||||
}
|
||||
else if(res.Namespace == eResFeedback)
|
||||
{
|
||||
// queue initial state fetching if we're not on the right context, see above in FBOs for more
|
||||
@@ -1088,6 +1159,11 @@ uint32_t GLResourceManager::GetSize_InitialState(ResourceId resid, GLResource re
|
||||
{
|
||||
return sizeof(FramebufferInitialData);
|
||||
}
|
||||
else if(res.Namespace == eResSampler)
|
||||
{
|
||||
// reserve some extra size to account for array count
|
||||
return sizeof(SamplerInitialData) + 32;
|
||||
}
|
||||
else if(res.Namespace == eResFeedback)
|
||||
{
|
||||
return sizeof(FeedbackInitialData);
|
||||
@@ -1671,6 +1747,22 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r
|
||||
SetInitialContents(Id, initContents);
|
||||
}
|
||||
}
|
||||
else if(Type == eResSampler)
|
||||
{
|
||||
SamplerInitialData &SamplerState = initContents.samp;
|
||||
|
||||
SERIALISE_ELEMENT(SamplerState);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
byte *blob = AllocAlignedBuffer(sizeof(SamplerState));
|
||||
memcpy(blob, &SamplerState, sizeof(SamplerState));
|
||||
|
||||
SetInitialContents(Id, initContents);
|
||||
}
|
||||
}
|
||||
else if(Type == eResFeedback)
|
||||
{
|
||||
FeedbackInitialData &TransformFeedbackState = initContents.xfb;
|
||||
@@ -2180,6 +2272,43 @@ void GLResourceManager::Apply_InitialState(GLResource live, GLInitialContents in
|
||||
GL.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread);
|
||||
}
|
||||
}
|
||||
else if(live.Namespace == eResSampler)
|
||||
{
|
||||
const SamplerInitialData &data = initial.samp;
|
||||
|
||||
if(data.valid)
|
||||
{
|
||||
GLenum activeTexture = eGL_TEXTURE0;
|
||||
GL.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&activeTexture);
|
||||
|
||||
GL.glActiveTexture(eGL_TEXTURE0);
|
||||
|
||||
GLuint prevsampler = 0;
|
||||
GL.glGetIntegerv(eGL_SAMPLER_BINDING, (GLint *)&prevsampler);
|
||||
|
||||
{
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_COMPARE_FUNC, (GLint)data.compareFunc);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_COMPARE_MODE, (GLint)data.compareMode);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_MIN_FILTER, (GLint)data.minFilter);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_MAG_FILTER, (GLint)data.magFilter);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_WRAP_R, (GLint)data.wrap[0]);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_WRAP_S, (GLint)data.wrap[1]);
|
||||
GL.glSamplerParameteri(live.name, eGL_TEXTURE_WRAP_T, (GLint)data.wrap[2]);
|
||||
GL.glSamplerParameterf(live.name, eGL_TEXTURE_MIN_LOD, data.minLod);
|
||||
GL.glSamplerParameterf(live.name, eGL_TEXTURE_MAX_LOD, data.maxLod);
|
||||
if(!IsGLES)
|
||||
GL.glSamplerParameterf(live.name, eGL_TEXTURE_LOD_BIAS, data.lodBias);
|
||||
|
||||
// see fetch in PrepareTextureInitialContents
|
||||
if(HasExt[ARB_texture_border_clamp])
|
||||
GL.glSamplerParameterfv(live.name, eGL_TEXTURE_BORDER_COLOR, &data.border[0]);
|
||||
}
|
||||
|
||||
GL.glBindSampler(0, prevsampler);
|
||||
|
||||
GL.glActiveTexture(activeTexture);
|
||||
}
|
||||
}
|
||||
else if(live.Namespace == eResFeedback)
|
||||
{
|
||||
const FeedbackInitialData &data = initial.xfb;
|
||||
|
||||
@@ -99,6 +99,20 @@ struct FramebufferInitialData
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(FramebufferInitialData);
|
||||
|
||||
struct SamplerInitialData
|
||||
{
|
||||
bool valid;
|
||||
float border[4];
|
||||
GLenum compareFunc, compareMode;
|
||||
float lodBias;
|
||||
float minLod, maxLod;
|
||||
GLenum minFilter, magFilter;
|
||||
float maxAniso;
|
||||
GLenum wrap[3];
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(SamplerInitialData);
|
||||
|
||||
struct PipelineInitialData
|
||||
{
|
||||
bool valid;
|
||||
@@ -164,6 +178,7 @@ struct GLInitialContents
|
||||
VAOInitialData vao;
|
||||
FeedbackInitialData xfb;
|
||||
FramebufferInitialData fbo;
|
||||
SamplerInitialData samp;
|
||||
PipelineInitialData pipe;
|
||||
TextureStateInitialData tex;
|
||||
};
|
||||
|
||||
@@ -273,13 +273,26 @@ void WrappedOpenGL::glSamplerParameteri(GLuint sampler, GLenum pname, GLint para
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameteri(ser, sampler, pname, param);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,13 +333,26 @@ void WrappedOpenGL::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat pa
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameterf(ser, sampler, pname, param);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -368,13 +394,26 @@ void WrappedOpenGL::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLi
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameteriv(ser, sampler, pname, params);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -416,13 +455,26 @@ void WrappedOpenGL::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLf
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameterfv(ser, sampler, pname, params);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -464,13 +516,26 @@ void WrappedOpenGL::glSamplerParameterIiv(GLuint sampler, GLenum pname, const GL
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameterIiv(ser, sampler, pname, params);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -512,13 +577,26 @@ void WrappedOpenGL::glSamplerParameterIuiv(GLuint sampler, GLenum pname, const G
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler));
|
||||
|
||||
if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() &&
|
||||
IsBackgroundCapturing(m_State))
|
||||
return;
|
||||
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
|
||||
Serialise_glSamplerParameterIuiv(ser, sampler, pname, params);
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get());
|
||||
record->AddChunk(scope.Get());
|
||||
record->UpdateCount++;
|
||||
|
||||
if(record->UpdateCount > 20)
|
||||
{
|
||||
m_HighTrafficResources.insert(record->GetResourceID());
|
||||
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user