Add some simple protection against binding bad GL texture handles

This commit is contained in:
baldurk
2020-11-27 15:52:24 +00:00
parent 949cff30a2
commit c5480aa622
2 changed files with 119 additions and 10 deletions
@@ -253,10 +253,20 @@ void WrappedOpenGL::glBindBuffer(GLenum target, GLuint buffer)
Chunk *chunk = NULL;
if(buffer == 0)
{
cd.m_BufferRecord[idx] = NULL;
}
else
{
cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
if(cd.m_BufferRecord[idx] == NULL)
{
RDCERR("Called glBindBuffer with unrecognised or deleted buffer");
return;
}
}
{
USE_SCRATCH_SERIALISER();
SCOPED_SERIALISE_CHUNK(gl_CurChunk);
@@ -543,10 +553,17 @@ void WrappedOpenGL::glBufferStorage(GLenum target, GLsizeiptr size, const void *
SERIALISE_TIME_CALL(GL.glBufferStorage(target, size, data, flags));
if(IsCaptureMode(m_State))
Common_glNamedBufferStorageEXT(GetCtxData().m_BufferRecord[BufferIdx(target)]->GetResourceID(),
size, data, origflags);
{
GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)];
RDCASSERTMSG("Couldn't identify object used in function. Unbound or bad GLuint?", record);
if(record)
Common_glNamedBufferStorageEXT(record->GetResourceID(), size, data, origflags);
}
else
{
RDCERR("Internal buffers should be allocated via dsa interfaces");
}
SAFE_DELETE_ARRAY(dummy);
}
@@ -1132,6 +1149,9 @@ void WrappedOpenGL::glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeB
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), writeBuffer));
RDCASSERT(readrecord && writerecord);
if(!readrecord || !writerecord)
return;
if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() &&
IsBackgroundCapturing(m_State))
return;
@@ -1201,6 +1221,9 @@ void WrappedOpenGL::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, G
GLResourceRecord *writerecord = GetCtxData().m_BufferRecord[BufferIdx(writeTarget)];
RDCASSERT(readrecord && writerecord);
if(!readrecord || !writerecord)
return;
if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() &&
IsBackgroundCapturing(m_State))
return;
@@ -1275,11 +1298,21 @@ void WrappedOpenGL::glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
GLResourceRecord *r = NULL;
if(buffer == 0)
{
r = cd.m_BufferRecord[idx] = NULL;
}
else
{
r = cd.m_BufferRecord[idx] =
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
if(r == NULL)
{
RDCERR("Called glBindBufferBase with unrecognised or deleted buffer");
return;
}
}
if(target == eGL_ATOMIC_COUNTER_BUFFER)
cd.m_MaxAtomicBind = RDCMAX((GLint)index + 1, cd.m_MaxAtomicBind);
else if(target == eGL_SHADER_STORAGE_BUFFER)
@@ -1409,11 +1442,21 @@ void WrappedOpenGL::glBindBufferRange(GLenum target, GLuint index, GLuint buffer
GLResourceRecord *r = NULL;
if(buffer == 0)
{
r = cd.m_BufferRecord[idx] = NULL;
}
else
{
r = cd.m_BufferRecord[idx] =
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
if(r == NULL)
{
RDCERR("Called glBindBufferBase with unrecognised or deleted buffer");
return;
}
}
if(target == eGL_ATOMIC_COUNTER_BUFFER)
cd.m_MaxAtomicBind = RDCMAX((GLint)index + 1, cd.m_MaxAtomicBind);
else if(target == eGL_SHADER_STORAGE_BUFFER)
@@ -1559,11 +1602,21 @@ void WrappedOpenGL::glBindBuffersBase(GLenum target, GLuint first, GLsizei count
GLResourceRecord *r = NULL;
if(buffers == NULL || buffers[0] == 0)
{
r = cd.m_BufferRecord[idx] = NULL;
}
else
{
r = cd.m_BufferRecord[idx] =
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0]));
if(r == NULL)
{
RDCERR("Called glBindBuffersBase with unrecognised or deleted buffer");
return;
}
}
if(target == eGL_ATOMIC_COUNTER_BUFFER)
cd.m_MaxAtomicBind = RDCMAX((GLint)first + count, cd.m_MaxAtomicBind);
else if(target == eGL_SHADER_STORAGE_BUFFER)
@@ -1615,7 +1668,7 @@ void WrappedOpenGL::glBindBuffersBase(GLenum target, GLuint first, GLsizei count
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i]));
// it's legal to re-type buffers, generate another BindBuffer chunk to rename
if(bufrecord->datatype != target)
if(bufrecord && bufrecord->datatype != target)
{
Chunk *chunk = NULL;
@@ -1772,11 +1825,21 @@ void WrappedOpenGL::glBindBuffersRange(GLenum target, GLuint first, GLsizei coun
size_t idx = BufferIdx(target);
if(buffers == NULL || buffers[0] == 0)
{
cd.m_BufferRecord[idx] = NULL;
}
else
{
cd.m_BufferRecord[idx] =
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0]));
if(cd.m_BufferRecord[idx] == NULL)
{
RDCERR("Called glBindBuffersRange with unrecognised or deleted buffer");
return;
}
}
if(target == eGL_ATOMIC_COUNTER_BUFFER)
cd.m_MaxAtomicBind = RDCMAX((GLint)first + count, cd.m_MaxAtomicBind);
else if(target == eGL_SHADER_STORAGE_BUFFER)
@@ -1829,7 +1892,7 @@ void WrappedOpenGL::glBindBuffersRange(GLenum target, GLuint first, GLsizei coun
GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i]));
// it's legal to re-type buffers, generate another BindBuffer chunk to rename
if(r->datatype != target)
if(r && r->datatype != target)
{
Chunk *chunk = NULL;
@@ -2259,6 +2322,12 @@ void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GL
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
if(!record)
{
RDCERR("Called glMapNamedBufferRange with unrecognised or deleted buffer");
return GL.glMapNamedBufferRangeEXT(buffer, offset, length, access);
}
// if the buffer was recently orphaned, unset the flag. If the map is unsynchronised then sync
// ourselves to allow our dummy upload of uninitialised 0xdddddddd to complete.
if(record->Map.orphaned)
@@ -2607,6 +2676,13 @@ GLboolean WrappedOpenGL::glUnmapNamedBufferEXT(GLuint buffer)
if(IsCaptureMode(m_State))
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer));
if(!record)
{
RDCERR("Called glUnmapNamedBuffer with unrecognised or deleted buffer");
return GL.glUnmapNamedBufferEXT(buffer);
}
auto status = record->Map.status;
if(IsActiveCapturing(m_State))
@@ -2800,6 +2876,9 @@ void WrappedOpenGL::glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr off
RDCASSERTMSG("Couldn't identify object passed to function. Mismatched or bad GLuint?", record,
buffer);
if(!record)
return;
if(IsBackgroundCapturing(m_State))
{
GetResourceManager()->MarkResourceFrameReferenced(record, eFrameRef_ReadBeforeWrite);
@@ -295,6 +295,13 @@ void WrappedOpenGL::glBindTexture(GLenum target, GLuint texture)
if(IsCaptureMode(m_State))
{
GLResourceRecord *r = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
if(r == NULL)
{
RDCERR("Called glBindTexture with unrecognised or deleted texture");
return;
}
cd.SetActiveTexRecord(target, r);
if(r->datatype)
@@ -398,9 +405,12 @@ void WrappedOpenGL::glBindTextures(GLuint first, GLsizei count, const GLuint *te
{
GLResourceRecord *texrecord =
GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), textures[i]));
GLenum target = TextureTarget(texrecord->datatype);
if(texrecord)
{
GLenum target = TextureTarget(texrecord->datatype);
cd.SetTexUnitRecordIndexed(target, first + i, texrecord);
cd.SetTexUnitRecordIndexed(target, first + i, texrecord);
}
}
}
}
@@ -460,6 +470,13 @@ void WrappedOpenGL::glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint
if(IsCaptureMode(m_State))
{
GLResourceRecord *r = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
if(!r)
{
RDCERR("Called glBindMultiTextureEXT with unrecognised or deleted buffer");
return;
}
cd.SetTexUnitRecord(target, texunit, r);
if(r->datatype)
@@ -532,9 +549,13 @@ void WrappedOpenGL::glBindTextureUnit(GLuint unit, GLuint texture)
{
GLResourceRecord *texrecord =
GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
GLenum target = TextureTarget(texrecord->datatype);
cd.SetTexUnitRecordIndexed(target, unit, texrecord);
if(texrecord)
{
GLenum target = TextureTarget(texrecord->datatype);
cd.SetTexUnitRecordIndexed(target, unit, texrecord);
}
}
}
}
@@ -1025,6 +1046,10 @@ void WrappedOpenGL::glInvalidateTexImage(GLuint texture, GLint level)
if(IsCaptureMode(m_State))
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERTMSG("Couldn't identify texture object. Unbound or bad GLuint?", record, texture);
if(!record)
return;
if(IsActiveCapturing(m_State))
{
@@ -1178,6 +1203,10 @@ void WrappedOpenGL::glInvalidateTexSubImage(GLuint texture, GLint level, GLint x
if(IsCaptureMode(m_State))
{
GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture));
RDCASSERTMSG("Couldn't identify texture object. Unbound or bad GLuint?", record, texture);
if(!record)
return;
if(IsActiveCapturing(m_State))
{
@@ -1293,8 +1322,9 @@ void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint s
{
GLResourceRecord *dstrecord = GetResourceManager()->GetResourceRecord(dstRes);
GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(),
eFrameRef_CompleteWrite);
if(dstrecord)
GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(),
eFrameRef_CompleteWrite);
}
SERIALISE_TIME_CALL(GL.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,