Commit 7a5f738b by Jamie Madill

Implement buffer map related entry points and errors.

BUG=angle:565 Change-Id: I14cee4eec032d4b6b8d9479da4234b81e4ec6bec Reviewed-on: https://chromium-review.googlesource.com/188202Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8c96d58a
......@@ -1525,7 +1525,7 @@ Buffer *Context::getArrayBuffer()
return mState.arrayBuffer.get();
}
Buffer *Context::getElementArrayBuffer()
Buffer *Context::getElementArrayBuffer() const
{
return getCurrentVertexArray()->getElementArrayBuffer();
}
......@@ -4053,6 +4053,33 @@ void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const
}
}
bool Context::hasMappedBuffer(GLenum target) const
{
if (target == GL_ARRAY_BUFFER)
{
for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
{
const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get();
if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped())
{
return true;
}
}
}
else if (target == GL_ELEMENT_ARRAY_BUFFER)
{
Buffer *elementBuffer = getElementArrayBuffer();
return (elementBuffer && elementBuffer->mapped());
}
else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
{
UNIMPLEMENTED();
}
else UNREACHABLE();
return false;
}
}
extern "C"
......
......@@ -339,7 +339,7 @@ class Context
Buffer *getTargetBuffer(GLenum target) const;
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
Buffer *getElementArrayBuffer() const;
ProgramBinary *getCurrentProgramBinary();
Texture *getTargetTexture(GLenum target) const;
......@@ -454,6 +454,8 @@ class Context
void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
GLint x, GLint y, GLsizei width, GLsizei height);
bool hasMappedBuffer(GLenum target) const;
rx::Renderer *getRenderer() { return mRenderer; }
private:
......
......@@ -639,6 +639,11 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
return gl::error(GL_INVALID_OPERATION);
}
if (buffer->mapped())
{
return gl::error(GL_INVALID_OPERATION);
}
if ((size_t)size + offset > buffer->size())
{
return gl::error(GL_INVALID_VALUE);
......@@ -1578,6 +1583,12 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
gl::Context *context = gl::getNonLostContext();
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
if (context)
{
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
......@@ -1614,6 +1625,12 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
{
gl::Context *context = gl::getNonLostContext();
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
if (context)
{
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
......@@ -1675,6 +1692,12 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return gl::error(GL_INVALID_OPERATION);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
context->drawElements(mode, count, type, indices, 0);
}
}
......@@ -1725,6 +1748,12 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
return gl::error(GL_INVALID_OPERATION);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
context->drawElements(mode, count, type, indices, primcount);
}
}
......@@ -6586,8 +6615,23 @@ GLboolean __stdcall glUnmapBuffer(GLenum target)
return gl::error(GL_INVALID_OPERATION, GL_FALSE);
}
// glUnmapBuffer
UNIMPLEMENTED();
if (!gl::ValidBufferTarget(context, target))
{
return gl::error(GL_INVALID_ENUM, GL_FALSE);
}
gl::Buffer *buffer = context->getTargetBuffer(target);
if (buffer == NULL || !buffer->mapped())
{
return gl::error(GL_INVALID_OPERATION, GL_FALSE);
}
// TODO: detect if we had corruption. if so, throw an error and return false.
buffer->unmap();
return GL_TRUE;
}
}
catch(std::bad_alloc&)
......@@ -7038,8 +7082,72 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
// glMapBufferRange
UNIMPLEMENTED();
if (!gl::ValidBufferTarget(context, target))
{
return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL));
}
if (offset < 0 || length < 0)
{
return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
}
gl::Buffer *buffer = context->getTargetBuffer(target);
if (buffer == NULL)
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
// Check for buffer overflow
size_t offsetSize = static_cast<size_t>(offset);
size_t lengthSize = static_cast<size_t>(length);
if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
offsetSize + lengthSize > static_cast<size_t>(buffer->size()))
{
return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
}
// Check for invalid bits in the mask
GLbitfield allAccessBits = GL_MAP_READ_BIT |
GL_MAP_WRITE_BIT |
GL_MAP_INVALIDATE_RANGE_BIT |
GL_MAP_INVALIDATE_BUFFER_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT |
GL_MAP_UNSYNCHRONIZED_BIT;
if (access & ~(allAccessBits))
{
return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL));
}
if (length == 0 || buffer->mapped())
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
// Check for invalid bit combinations
if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT |
GL_MAP_INVALIDATE_BUFFER_BIT |
GL_MAP_UNSYNCHRONIZED_BIT;
if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
{
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
}
return buffer->mapRange(offset, length, access);
}
}
catch(std::bad_alloc&)
......@@ -7065,8 +7173,39 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip
return gl::error(GL_INVALID_OPERATION);
}
// glFlushMappedBufferRange
UNIMPLEMENTED();
if (offset < 0 || length < 0)
{
return gl::error(GL_INVALID_VALUE);
}
if (!gl::ValidBufferTarget(context, target))
{
return gl::error(GL_INVALID_ENUM);
}
gl::Buffer *buffer = context->getTargetBuffer(target);
if (buffer == NULL)
{
return gl::error(GL_INVALID_OPERATION);
}
if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
{
return gl::error(GL_INVALID_OPERATION);
}
// Check for buffer overflow
size_t offsetSize = static_cast<size_t>(offset);
size_t lengthSize = static_cast<size_t>(length);
if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength()))
{
return gl::error(GL_INVALID_VALUE);
}
// We do not currently support a non-trivial implementation of FlushMappedBufferRange
}
}
catch(std::bad_alloc&)
......@@ -8316,6 +8455,11 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
return gl::error(GL_INVALID_OPERATION);
}
if (readBuffer->mapped() || writeBuffer->mapped())
{
return gl::error(GL_INVALID_OPERATION);
}
if (readOffset < 0 || writeOffset < 0 || size < 0 ||
static_cast<unsigned int>(readOffset + size) > readBuffer->size() ||
static_cast<unsigned int>(writeOffset + size) > writeBuffer->size())
......
......@@ -272,7 +272,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
return gl::error(GL_INVALID_OPERATION, false);
}
// TODO: ...the buffer object's data store is currently mapped.
// ...the buffer object's data store is currently mapped.
if (pixelUnpackBuffer->mapped())
{
return gl::error(GL_INVALID_OPERATION, false);
}
}
return true;
......
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