mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-24 23:46:41 +00:00
Use the baseEventID for checking if a glMultiDraw* is valid
Prevents driver crash is invalid data is passed to glMultiDraw* i.e. no vertex buffers.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user