Save texture state parameters with initial state

* If the user code calls glTexParameter many times (defined as > 12) then
  we treat that texture as dirty and stop saving those chunks.
This commit is contained in:
baldurk
2014-11-15 14:01:02 +00:00
parent 5acc53bae0
commit 5be7a4eef3
2 changed files with 257 additions and 51 deletions
+101 -11
View File
@@ -41,6 +41,56 @@ struct VertexArrayInitialData
uint32_t size;
};
template<>
void Serialiser::Serialise(const char *name, VertexArrayInitialData &el)
{
ScopedContext scope(this, this, name, "VertexArrayInitialData", 0, true);
Serialise("enabled", el.enabled);
Serialise("vbslot", el.vbslot);
Serialise("offset", el.offset);
Serialise("type", el.type);
Serialise("normalized", el.normalized);
Serialise("integer", el.integer);
Serialise("size", el.size);
}
struct TextureStateInitialData
{
TextureStateInitialData()
{
RDCEraseEl(*this);
}
int32_t baseLevel, maxLevel;
float minLod, maxLod;
GLenum depthMode;
GLenum compareFunc, compareMode;
GLenum minFilter, magFilter;
GLenum swizzle[4];
GLenum wrap[3];
float border[4];
float lodBias;
};
template<>
void Serialiser::Serialise(const char *name, TextureStateInitialData &el)
{
ScopedContext scope(this, this, name, "TextureStateInitialData", 0, true);
Serialise("baseLevel", el.baseLevel);
Serialise("maxLevel", el.maxLevel);
Serialise("minLod", el.minLod);
Serialise("maxLod", el.maxLod);
Serialise("depthMode", el.depthMode);
Serialise("compareFunc", el.compareFunc);
Serialise("compareMode", el.compareMode);
Serialise("minFilter", el.minFilter);
Serialise("magFilter", el.magFilter);
Serialise<4>("swizzle", el.swizzle);
Serialise<3>("wrap", el.wrap);
Serialise<4>("border", el.border);
Serialise("lodBias", el.lodBias);
}
bool GLResourceManager::SerialisableResource(ResourceId id, GLResourceRecord *record)
{
if(id == m_GL->GetContextResourceID())
@@ -147,7 +197,27 @@ bool GLResourceManager::Prepare_InitialState(GLResource res)
gl.glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex, details.curType, i, 0, 0, 0, w, h, d);
}
SetInitialContents(Id, InitialContentData(TextureRes(res.Context, tex), 0, NULL));
TextureStateInitialData *state = (TextureStateInitialData *)Serialiser::AllocAlignedBuffer(sizeof(TextureStateInitialData));
{
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, (GLint *)&state->depthMode);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_BASE_LEVEL, (GLint *)&state->baseLevel);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, (GLint *)&state->compareFunc);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_MODE, (GLint *)&state->compareMode);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MIN_FILTER, (GLint *)&state->minFilter);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAG_FILTER, (GLint *)&state->magFilter);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)&state->swizzle[0]);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_R, (GLint *)&state->wrap[0]);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_S, (GLint *)&state->wrap[1]);
gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_T, (GLint *)&state->wrap[2]);
gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod);
gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod);
gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_BORDER_COLOR, &state->border[0]);
gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias);
}
SetInitialContents(Id, InitialContentData(TextureRes(res.Context, tex), 0, (byte *)state));
gl.glBindTexture(details.curType, oldtex);
}
@@ -301,6 +371,10 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
gl.glGetTexParameteriv(details.curType, eGL_TEXTURE_IMMUTABLE_LEVELS, (GLint *)&imgmips);
else
gl.glGetTexParameteriv(details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&imgmips);
TextureStateInitialData *state = (TextureStateInitialData *)GetInitialContents(Id).blob;
SERIALISE_ELEMENT(TextureStateInitialData, stateData, *state);
SERIALISE_ELEMENT(uint32_t, width, details.width);
SERIALISE_ELEMENT(uint32_t, height, details.height);
@@ -445,6 +519,10 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0);
gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1);
TextureStateInitialData *state = (TextureStateInitialData *)Serialiser::AllocAlignedBuffer(sizeof(TextureStateInitialData));
m_pSerialiser->Serialise("state", *state);
SERIALISE_ELEMENT(uint32_t, width, 0);
SERIALISE_ELEMENT(uint32_t, height, 0);
SERIALISE_ELEMENT(uint32_t, depth, 0);
@@ -567,7 +645,7 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
}
}
SetInitialContents(Id, InitialContentData(TextureRes(m_GL->GetCtx(), tex), 0, NULL));
SetInitialContents(Id, InitialContentData(TextureRes(m_GL->GetCtx(), tex), 0, (byte *)state));
gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub);
@@ -594,15 +672,7 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
}
for(GLuint i=0; i < 16; i++)
{
m_pSerialiser->Serialise("data[].enabled", data[i].enabled);
m_pSerialiser->Serialise("data[].vbslot", data[i].vbslot);
m_pSerialiser->Serialise("data[].offset", data[i].offset);
m_pSerialiser->Serialise("data[].type", data[i].type);
m_pSerialiser->Serialise("data[].normalized", data[i].normalized);
m_pSerialiser->Serialise("data[].integer", data[i].integer);
m_pSerialiser->Serialise("data[].size", data[i].size);
}
m_pSerialiser->Serialise("data[]", data[i]);
if(m_State < WRITING)
{
@@ -667,6 +737,26 @@ void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData i
gl.glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name, details.curType, i, 0, 0, 0, w, h, d);
}
TextureStateInitialData *state = (TextureStateInitialData *)initial.blob;
{
gl.glTextureParameterivEXT(live.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, (GLint *)&state->depthMode);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_BASE_LEVEL, (GLint *)&state->baseLevel);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, (GLint *)&state->compareFunc);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_MODE, (GLint *)&state->compareMode);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MIN_FILTER, (GLint *)&state->minFilter);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAG_FILTER, (GLint *)&state->magFilter);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)state->swizzle);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_R, (GLint *)&state->wrap[0]);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_S, (GLint *)&state->wrap[1]);
gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_T, (GLint *)&state->wrap[2]);
gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod);
gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod);
gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_BORDER_COLOR, state->border);
gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias);
}
}
else if(live.Namespace == eResProgram)
{
+156 -40
View File
@@ -714,16 +714,30 @@ void WrappedOpenGL::glTextureParameteriEXT(GLuint texture, GLenum target, GLenum
if(m_State >= WRITING)
{
if(m_HighTrafficResources.find(TextureRes(GetCtx(), texture)) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERT(record);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI);
Serialise_glTextureParameteriEXT(texture, target, pname, param);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(TextureRes(GetCtx(), texture));
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -736,14 +750,29 @@ void WrappedOpenGL::glTexParameteri(GLenum target, GLenum pname, GLint param)
GLResourceRecord *record = m_TextureRecord[m_TextureUnit];
RDCASSERT(record);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI);
Serialise_glTextureParameteriEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
target, pname, param);
GLResource res = GetResourceManager()->GetCurrentResource(record->GetResourceID());
if(m_HighTrafficResources.find(res) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI);
Serialise_glTextureParameteriEXT(res.name, target, pname, param);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(res);
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -771,16 +800,30 @@ void WrappedOpenGL::glTextureParameterivEXT(GLuint texture, GLenum target, GLenu
if(m_State >= WRITING)
{
if(m_HighTrafficResources.find(TextureRes(GetCtx(), texture)) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERT(record);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIV);
Serialise_glTextureParameterivEXT(texture, target, pname, params);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(TextureRes(GetCtx(), texture));
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -792,15 +835,30 @@ void WrappedOpenGL::glTexParameteriv(GLenum target, GLenum pname, const GLint *p
{
GLResourceRecord *record = m_TextureRecord[m_TextureUnit];
RDCASSERT(record);
GLResource res = GetResourceManager()->GetCurrentResource(record->GetResourceID());
if(m_HighTrafficResources.find(res) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIV);
Serialise_glTextureParameterivEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
target, pname, params);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
Serialise_glTextureParameterivEXT(res.name, target, pname, params);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(res);
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -825,16 +883,30 @@ void WrappedOpenGL::glTextureParameterfEXT(GLuint texture, GLenum target, GLenum
if(m_State >= WRITING)
{
if(m_HighTrafficResources.find(TextureRes(GetCtx(), texture)) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERT(record);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERF);
Serialise_glTextureParameterfEXT(texture, target, pname, param);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(TextureRes(GetCtx(), texture));
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -846,15 +918,30 @@ void WrappedOpenGL::glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
GLResourceRecord *record = m_TextureRecord[m_TextureUnit];
RDCASSERT(record);
GLResource res = GetResourceManager()->GetCurrentResource(record->GetResourceID());
if(m_HighTrafficResources.find(res) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERF);
Serialise_glTextureParameterfEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
target, pname, param);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
Serialise_glTextureParameterfEXT(res.name, target, pname, param);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(res);
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -882,16 +969,30 @@ void WrappedOpenGL::glTextureParameterfvEXT(GLuint texture, GLenum target, GLenu
if(m_State >= WRITING)
{
if(m_HighTrafficResources.find(TextureRes(GetCtx(), texture)) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERT(record);
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERFV);
Serialise_glTextureParameterfvEXT(texture, target, pname, params);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(TextureRes(GetCtx(), texture));
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}
@@ -903,15 +1004,30 @@ void WrappedOpenGL::glTexParameterfv(GLenum target, GLenum pname, const GLfloat
{
GLResourceRecord *record = m_TextureRecord[m_TextureUnit];
RDCASSERT(record);
GLResource res = GetResourceManager()->GetCurrentResource(record->GetResourceID());
if(m_HighTrafficResources.find(res) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME)
return;
SCOPED_SERIALISE_CONTEXT(TEXPARAMETERFV);
Serialise_glTextureParameterfvEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
target, pname, params);
if(m_State == WRITING_IDLE)
record->AddChunk(scope.Get());
else
Serialise_glTextureParameterfvEXT(res.name, target, pname, params);
if(m_State == WRITING_CAPFRAME)
{
m_ContextRecord->AddChunk(scope.Get());
}
else
{
record->AddChunk(scope.Get());
record->UpdateCount++;
if(record->UpdateCount > 12)
{
m_HighTrafficResources.insert(res);
GetResourceManager()->MarkDirtyResource(record->GetResourceID());
}
}
}
}