From 892bc28772e8f3ded462239d41beec0d6c79564f Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 5 Jun 2018 15:19:12 +0100 Subject: [PATCH] To be backwards compatible with older captures, create global fake VAO 0 --- renderdoc/driver/gl/gl_driver.cpp | 14 +++++- renderdoc/driver/gl/gl_driver.h | 3 ++ renderdoc/driver/gl/gl_renderstate.cpp | 5 ++- .../driver/gl/wrappers/gl_buffer_funcs.cpp | 45 +++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 62b602d55..89bf58704 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -2725,7 +2725,6 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) { case GLChunk::DeviceInitialisation: { - // legacy behaviour where we had a single global VAO 0. Ignore ResourceId vao; SERIALISE_ELEMENT(vao).Hidden(); SERIALISE_ELEMENT(m_FBO0_ID).Named("FBO 0 ID"); @@ -2734,6 +2733,19 @@ bool WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) if(IsReplayingAndReading()) { + // legacy behaviour where we had a single global VAO 0. Create a corresponding VAO so that + // it can be bound and have initial contents applied to it + if(vao != ResourceId()) + { + glGenVertexArrays(1, &m_Fake_VAO0); + glBindVertexArray(m_Fake_VAO0); + GetResourceManager()->AddLiveResource(vao, VertexArrayRes(GetCtx(), m_Fake_VAO0)); + AddResource(vao, ResourceType::StateObject, "Vertex Array"); + GetReplay()->GetResourceDesc(vao).SetCustomName("Default VAO"); + + GetReplay()->GetResourceDesc(vao).initialisationChunks.push_back(m_InitChunkIndex); + } + GetResourceManager()->AddLiveResource(m_FBO0_ID, FramebufferRes(GetCtx(), m_FakeBB_FBO)); AddResource(m_FBO0_ID, ResourceType::SwapchainImage, ""); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index cfa13e184..5a8c7f0e5 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -356,6 +356,8 @@ private: GLuint m_FakeBB_DepthStencil; ResourceId m_FBO0_ID; + GLuint m_Fake_VAO0; + uint32_t m_InitChunkIndex = 0; bool ProcessChunk(ReadSerialiser &ser, GLChunk chunk); @@ -598,6 +600,7 @@ public: void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); + GLuint GetFakeVAO0() { return m_Fake_VAO0; } GLuint GetFakeBBFBO() { return m_FakeBB_FBO; } FrameRecord &GetFrameRecord() { return m_FrameRecord; } const APIEvent &GetEvent(uint32_t eventId); diff --git a/renderdoc/driver/gl/gl_renderstate.cpp b/renderdoc/driver/gl/gl_renderstate.cpp index 9a717bc56..da0bd841c 100644 --- a/renderdoc/driver/gl/gl_renderstate.cpp +++ b/renderdoc/driver/gl/gl_renderstate.cpp @@ -1337,7 +1337,10 @@ void GLRenderState::ApplyState(WrappedOpenGL *gl) m_Real->glActiveTexture(ActiveTexture); - m_Real->glBindVertexArray(VAO.name); + if(VAO.name) + m_Real->glBindVertexArray(VAO.name); + else + m_Real->glBindVertexArray(gl->GetFakeVAO0()); if(HasExt[ARB_transform_feedback2]) m_Real->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, FeedbackObj.name); diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index e8f13c53c..d40c11697 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -3042,6 +3042,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribOffsetEXT( if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // some intel drivers don't properly update query states (like GL_VERTEX_ATTRIB_ARRAY_SIZE) // unless the VAO is also bound when performing EXT_dsa functions :( GLuint prevVAO = 0; @@ -3165,6 +3168,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIOffsetEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // some intel drivers don't properly update query states (like GL_VERTEX_ATTRIB_ARRAY_SIZE) // unless the VAO is also bound when performing EXT_dsa functions :( GLuint prevVAO = 0; @@ -3288,6 +3294,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLOffsetEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // some intel drivers don't properly update query states (like GL_VERTEX_ATTRIB_ARRAY_SIZE) // unless the VAO is also bound when performing EXT_dsa functions :( GLuint prevVAO = 0; @@ -3406,6 +3415,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribBindingEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glVertexArrayVertexAttribBindingEXT(vaobj.name, attribindex, bindingindex); } return true; @@ -3488,6 +3500,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribFormatEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glVertexArrayVertexAttribFormatEXT(vaobj.name, attribindex, size, type, normalized, relativeoffset); } @@ -3576,6 +3591,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIFormatEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj.name, attribindex, size, type, relativeoffset); } @@ -3660,6 +3678,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLFormatEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj.name, attribindex, size, type, relativeoffset); } @@ -3741,6 +3762,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribDivisorEXT(SerialiserType if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // at the time of writing, AMD driver seems to not have this entry point if(m_Real.glVertexArrayVertexAttribDivisorEXT) { @@ -3828,6 +3852,9 @@ bool WrappedOpenGL::Serialise_glEnableVertexArrayAttribEXT(SerialiserType &ser, if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + GLint prevVAO = 0; m_Real.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, &prevVAO); @@ -3908,6 +3935,9 @@ bool WrappedOpenGL::Serialise_glDisableVertexArrayAttribEXT(SerialiserType &ser, if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + GLint prevVAO = 0; m_Real.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, &prevVAO); @@ -4104,6 +4134,9 @@ bool WrappedOpenGL::Serialise_glBindVertexArray(SerialiserType &ser, GLuint vaob if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glBindVertexArray(vaobj.name); } @@ -4152,6 +4185,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayElementBuffer(SerialiserType &ser, GL if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // might not have the live resource if this is a pre-capture chunk, and the buffer was never // referenced at all in the actual frame if(buffer.name) @@ -4220,6 +4256,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayBindVertexBufferEXT(SerialiserType &s if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + if(buffer.name) { m_Buffers[GetResourceManager()->GetID(buffer)].curType = eGL_ARRAY_BUFFER; @@ -4354,6 +4393,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexBuffers(SerialiserType &ser, GL offs.push_back((GLintptr)offsets[i]); } + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If // we are running without ARB_dsa support, these functions are emulated in the obvious way. This // is necessary since these functions can be serialised even if ARB_dsa was not used originally, @@ -4480,6 +4522,9 @@ bool WrappedOpenGL::Serialise_glVertexArrayVertexBindingDivisorEXT(SerialiserTyp if(IsReplayingAndReading()) { + if(vaobj.name == 0) + vaobj.name = m_Fake_VAO0; + m_Real.glVertexArrayVertexBindingDivisorEXT(vaobj.name, bindingindex, divisor); }