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() ...@@ -1525,7 +1525,7 @@ Buffer *Context::getArrayBuffer()
return mState.arrayBuffer.get(); return mState.arrayBuffer.get();
} }
Buffer *Context::getElementArrayBuffer() Buffer *Context::getElementArrayBuffer() const
{ {
return getCurrentVertexArray()->getElementArrayBuffer(); return getCurrentVertexArray()->getElementArrayBuffer();
} }
...@@ -4053,6 +4053,33 @@ void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const ...@@ -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" extern "C"
......
...@@ -339,7 +339,7 @@ class Context ...@@ -339,7 +339,7 @@ class Context
Buffer *getTargetBuffer(GLenum target) const; Buffer *getTargetBuffer(GLenum target) const;
Buffer *getArrayBuffer(); Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer(); Buffer *getElementArrayBuffer() const;
ProgramBinary *getCurrentProgramBinary(); ProgramBinary *getCurrentProgramBinary();
Texture *getTargetTexture(GLenum target) const; Texture *getTargetTexture(GLenum target) const;
...@@ -454,6 +454,8 @@ class Context ...@@ -454,6 +454,8 @@ class Context
void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, void invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
GLint x, GLint y, GLsizei width, GLsizei height); GLint x, GLint y, GLsizei width, GLsizei height);
bool hasMappedBuffer(GLenum target) const;
rx::Renderer *getRenderer() { return mRenderer; } rx::Renderer *getRenderer() { return mRenderer; }
private: private:
......
...@@ -639,6 +639,11 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, ...@@ -639,6 +639,11 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (buffer->mapped())
{
return gl::error(GL_INVALID_OPERATION);
}
if ((size_t)size + offset > buffer->size()) if ((size_t)size + offset > buffer->size())
{ {
return gl::error(GL_INVALID_VALUE); return gl::error(GL_INVALID_VALUE);
...@@ -1578,6 +1583,12 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -1578,6 +1583,12 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
gl::Context *context = gl::getNonLostContext(); gl::Context *context = gl::getNonLostContext();
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
if (context) if (context)
{ {
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
...@@ -1614,6 +1625,12 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun ...@@ -1614,6 +1625,12 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
{ {
gl::Context *context = gl::getNonLostContext(); gl::Context *context = gl::getNonLostContext();
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
if (context) if (context)
{ {
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
...@@ -1675,6 +1692,12 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv ...@@ -1675,6 +1692,12 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return gl::error(GL_INVALID_OPERATION); 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); context->drawElements(mode, count, type, indices, 0);
} }
} }
...@@ -1725,6 +1748,12 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t ...@@ -1725,6 +1748,12 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
return gl::error(GL_INVALID_OPERATION); 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); context->drawElements(mode, count, type, indices, primcount);
} }
} }
...@@ -6586,8 +6615,23 @@ GLboolean __stdcall glUnmapBuffer(GLenum target) ...@@ -6586,8 +6615,23 @@ GLboolean __stdcall glUnmapBuffer(GLenum target)
return gl::error(GL_INVALID_OPERATION, GL_FALSE); return gl::error(GL_INVALID_OPERATION, GL_FALSE);
} }
// glUnmapBuffer if (!gl::ValidBufferTarget(context, target))
UNIMPLEMENTED(); {
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&) catch(std::bad_alloc&)
...@@ -7038,8 +7082,72 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le ...@@ -7038,8 +7082,72 @@ GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le
return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL));
} }
// glMapBufferRange if (!gl::ValidBufferTarget(context, target))
UNIMPLEMENTED(); {
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&) catch(std::bad_alloc&)
...@@ -7065,8 +7173,39 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip ...@@ -7065,8 +7173,39 @@ void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
// glFlushMappedBufferRange if (offset < 0 || length < 0)
UNIMPLEMENTED(); {
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&) catch(std::bad_alloc&)
...@@ -8316,6 +8455,11 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp ...@@ -8316,6 +8455,11 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (readBuffer->mapped() || writeBuffer->mapped())
{
return gl::error(GL_INVALID_OPERATION);
}
if (readOffset < 0 || writeOffset < 0 || size < 0 || if (readOffset < 0 || writeOffset < 0 || size < 0 ||
static_cast<unsigned int>(readOffset + size) > readBuffer->size() || static_cast<unsigned int>(readOffset + size) > readBuffer->size() ||
static_cast<unsigned int>(writeOffset + size) > writeBuffer->size()) static_cast<unsigned int>(writeOffset + size) > writeBuffer->size())
......
...@@ -272,7 +272,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -272,7 +272,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
return gl::error(GL_INVALID_OPERATION, false); 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; 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