From 5be7a4eef3c669e0f591dc81ed8aa520a659d728 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 15 Nov 2014 14:01:02 +0000 Subject: [PATCH] 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. --- renderdoc/driver/gl/gl_manager.cpp | 112 +++++++++- .../driver/gl/wrappers/gl_texture_funcs.cpp | 196 ++++++++++++++---- 2 files changed, 257 insertions(+), 51 deletions(-) diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 5d3345500..0f30c1c4f 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -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) { diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index bf211b448..7d0783c3d 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -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()); + } + } } }