Commit ae3000b4 by Jamie Madill

Move validation from IndexDataManager to the API.

This validates all necessary buffer sizes for element array buffers in the validation layer, before we start the draw. BUG=angle:571 Change-Id: I602744ca1ea493e9f0f7e1ccbeb85fc4ae5c9f5a Reviewed-on: https://chromium-review.googlesource.com/210648Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 83da0ec5
...@@ -58,7 +58,7 @@ class Buffer : public RefCountObject ...@@ -58,7 +58,7 @@ class Buffer : public RefCountObject
rx::BufferImpl *mBuffer; rx::BufferImpl *mBuffer;
GLenum mUsage; GLenum mUsage;
GLsizeiptr mSize; GLint64 mSize;
GLint mAccessFlags; GLint mAccessFlags;
GLboolean mMapped; GLboolean mMapped;
GLvoid *mMapPointer; GLvoid *mMapPointer;
......
...@@ -125,17 +125,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer ...@@ -125,17 +125,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
default: UNREACHABLE(); alignedOffset = false; default: UNREACHABLE(); alignedOffset = false;
} }
// check for integer overflows ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeInfo.bytes) ||
typeInfo.bytes * static_cast<unsigned int>(count) + offset < offset)
{
return GL_OUT_OF_MEMORY;
}
if (typeInfo.bytes * static_cast<unsigned int>(count) + offset > storage->getSize())
{
return GL_INVALID_OPERATION;
}
indices = static_cast<const GLubyte*>(storage->getData()) + offset; indices = static_cast<const GLubyte*>(storage->getData()) + offset;
} }
...@@ -197,11 +187,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer ...@@ -197,11 +187,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
} }
} }
if (!indexBuffer) ASSERT(indexBuffer);
{
ERR("No valid index buffer.");
return GL_INVALID_OPERATION;
}
if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes) if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
{ {
......
...@@ -1489,6 +1489,32 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count ...@@ -1489,6 +1489,32 @@ bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
} }
if (elementArrayBuffer)
{
const gl::Type &typeInfo = gl::GetTypeInfo(type);
GLint64 offset = reinterpret_cast<GLint64>(indices);
GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset;
// check for integer overflows
if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
{
return gl::error(GL_OUT_OF_MEMORY, false);
}
// Check for reading past the end of the bound buffer object
if (byteCount > elementArrayBuffer->getSize())
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
else if (!indices)
{
// Catch this programming error here
return gl::error(GL_INVALID_OPERATION, false);
}
// Use max index to validate if our vertex buffers are large enough for the pull. // Use max index to validate if our vertex buffers are large enough for the pull.
// TODO: offer fast path, with disabled index validation. // TODO: offer fast path, with disabled index validation.
// TODO: also disable index checking on back-ends that are robust to out-of-range accesses. // TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment