diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index f5f7de5cf..0b56647d9 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -604,6 +604,7 @@ private: // final check function to ensure we don't try and render with no index or vertex buffer bound, as // many drivers will still try to access memory via legacy behaviour even on core profile. bool Check_SafeDraw(bool indexed); + bool Check_SafeDrawAtEventID(uint32_t eid) const; void StoreCompressedTexData(ResourceId texId, GLenum target, GLint level, bool subUpdate, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index 30a0ce57d..5a004a42d 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -158,10 +158,15 @@ static constexpr uint32_t GetIdxSize(GLenum idxtype) return (idxtype == eGL_UNSIGNED_BYTE ? 1 : (idxtype == eGL_UNSIGNED_SHORT ? 2 : 4)); } +bool WrappedOpenGL::Check_SafeDrawAtEventID(uint32_t eid) const +{ + return m_UnsafeDraws.find(eid) == m_UnsafeDraws.end(); +} + bool WrappedOpenGL::Check_SafeDraw(bool indexed) { if(IsActiveReplaying(m_State)) - return m_UnsafeDraws.find(m_CurEventID) == m_UnsafeDraws.end(); + return Check_SafeDrawAtEventID(m_CurEventID); bool ret = true; @@ -2255,8 +2260,9 @@ bool WrappedOpenGL::Serialise_glMultiDrawArrays(SerialiserType &ser, GLenum mode // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the drawcount parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than drawcount) - GL.glMultiDrawArrays(mode, first, count, - RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID)); + if(drawcount == 0 || count == 0 || Check_SafeDrawAtEventID(baseEventID)) + GL.glMultiDrawArrays(mode, first, count, + RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID)); m_CurEventID += (uint32_t)drawcount; } @@ -2278,7 +2284,8 @@ bool WrappedOpenGL::Serialise_glMultiDrawArrays(SerialiserType &ser, GLenum mode for(uint32_t d = 0; d < firstDrawIdx; d++) modcount[d] = 0; - GL.glMultiDrawArrays(mode, first, count, lastDrawIdx + 1); + if(count == 0 || Check_SafeDrawAtEventID(baseEventID)) + GL.glMultiDrawArrays(mode, first, count, lastDrawIdx + 1); m_CurEventID += (uint32_t)RDCMIN((uint32_t)drawcount, lastDrawIdx - firstDrawIdx); } @@ -2423,7 +2430,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElements(SerialiserType &ser, GLenum mo // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(drawcount == 0 || count == 0 || Check_SafeDraw(true)) + if(drawcount == 0 || count == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElements(mode, count, type, inds.data(), RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID)); @@ -2447,7 +2454,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElements(SerialiserType &ser, GLenum mo for(uint32_t d = 0; d < firstDrawIdx; d++) modcount[d] = 0; - if(count == 0 || Check_SafeDraw(true)) + if(count == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElements(mode, count, type, inds.data(), lastDrawIdx + 1); m_CurEventID += (uint32_t)RDCMIN((uint32_t)drawcount, lastDrawIdx - firstDrawIdx); @@ -2596,7 +2603,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(SerialiserType &ser, // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(count == 0 || Check_SafeDraw(true)) + if(count == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsBaseVertex(mode, count, type, inds.data(), RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID), basevertex); @@ -2621,7 +2628,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(SerialiserType &ser, for(uint32_t d = 0; d < firstDrawIdx; d++) modcount[d] = 0; - if(count == 0 || Check_SafeDraw(true)) + if(count == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsBaseVertex(mode, count, type, inds.data(), lastDrawIdx + 1, basevertex); @@ -2788,7 +2795,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(SerialiserType &ser, GLe // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(drawcount == 0 || Check_SafeDraw(false)) + if(drawcount == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawArraysIndirect(mode, (const void *)offset, RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID), stride); @@ -2841,7 +2848,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(SerialiserType &ser, GLe // the offset is 0 because it's referring to our custom buffer, stride is 0 because we // tightly pack. - if(Check_SafeDraw(false)) + if(Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawArraysIndirect(mode, (const void *)0, lastDrawIdx + 1, 0); GL.glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, prevBuf); @@ -3018,7 +3025,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(SerialiserType &ser, G // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(Check_SafeDraw(true)) + if(Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsIndirect(mode, type, (const void *)offset, RDCMIN((uint32_t)drawcount, m_LastEventID - baseEventID), stride); @@ -3071,7 +3078,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(SerialiserType &ser, G // the offset is 0 because it's referring to our custom buffer, stride is 0 because we // tightly pack. - if(Check_SafeDraw(true)) + if(Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsIndirect(mode, type, (const void *)0, lastDrawIdx + 1, 0); GL.glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, prevBuf); @@ -3256,7 +3263,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCount(SerialiserType &ser // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(maxdrawcount == 0 || Check_SafeDraw(false)) + if(maxdrawcount == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawArraysIndirect(mode, (const void *)offset, RDCMIN((uint32_t)realdrawcount, m_LastEventID - baseEventID), stride); @@ -3309,7 +3316,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCount(SerialiserType &ser // the offset is 0 because it's referring to our custom buffer, stride is 0 because we // tightly pack. - if(Check_SafeDraw(false)) + if(Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawArraysIndirect(mode, (const void *)0, lastDrawIdx + 1, 0); GL.glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, prevBuf); @@ -3503,7 +3510,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCount(SerialiserType &s // if we're replaying part-way into a multidraw, we can replay the first part 'easily' // by just reducing the Count parameter to however many we want to replay. This only // works if we're replaying from the first multidraw to the nth (n less than Count) - if(maxdrawcount == 0 || Check_SafeDraw(true)) + if(maxdrawcount == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsIndirect( mode, type, (const void *)offset, RDCMIN((uint32_t)realdrawcount, m_LastEventID - baseEventID), stride); @@ -3556,7 +3563,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCount(SerialiserType &s // the offset is 0 because it's referring to our custom buffer, stride is 0 because we // tightly pack. - if(maxdrawcount == 0 || Check_SafeDraw(true)) + if(maxdrawcount == 0 || Check_SafeDrawAtEventID(baseEventID)) GL.glMultiDrawElementsIndirect(mode, type, (const void *)0, lastDrawIdx + 1, 0); GL.glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, prevBuf);