Commit 5d7014e4 by Cody Northrop Committed by Commit Bot

Unmap buffers targeted by glBufferData

When glBufferData is called on a mapped buffer, per the OpenGL ES 3.0 spec it is implicitly unmapped. Later calls to glMapBufferRange should not throw an error. This CL unmaps the buffer in BufferData if it is already mapped. Also adds a new test that verfies the behavior. Test: angle_end2end_tests --gtest_filter=BufferDataTestES3.BufferDataUnmap/* Test: Angry Birds 2 MEC Bug: angleproject:4599 Bug: b/157672184 Change-Id: I1a1e458aa5f50da4dfde9f6847f71cd5b6f6c08a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2233365 Commit-Queue: Cody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarManh Nguyen <nguyenmh@google.com>
parent 15328f69
...@@ -76,6 +76,19 @@ angle::Result Buffer::bufferData(Context *context, ...@@ -76,6 +76,19 @@ angle::Result Buffer::bufferData(Context *context,
{ {
const void *dataForImpl = data; const void *dataForImpl = data;
if (mState.isMapped())
{
// Per the OpenGL ES 3.0 spec, buffers are implicity unmapped when a call to
// BufferData happens on a mapped buffer:
//
// If any portion of the buffer object is mapped in the current context or any context
// current to another thread, it is as though UnmapBuffer (see section 2.10.3) is
// executed in each such context prior to deleting the existing data store.
//
GLboolean dontCare = GL_FALSE;
ANGLE_TRY(unmap(context, &dontCare));
}
// If we are using robust resource init, make sure the buffer starts cleared. // If we are using robust resource init, make sure the buffer starts cleared.
// Note: the Context is checked for nullptr because of some testing code. // Note: the Context is checked for nullptr because of some testing code.
// TODO(jmadill): Investigate lazier clearing. // TODO(jmadill): Investigate lazier clearing.
......
...@@ -698,6 +698,47 @@ TEST_P(BufferDataTestES3, NoBufferInitDataCopyBug) ...@@ -698,6 +698,47 @@ TEST_P(BufferDataTestES3, NoBufferInitDataCopyBug)
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
// Ensures that calling glBufferData on a mapped buffer results in an unmapped buffer
TEST_P(BufferDataTestES3, BufferDataUnmap)
{
// Per the OpenGL ES 3.0 spec, buffers are implicity unmapped when a call to
// BufferData happens on a mapped buffer:
//
// If any portion of the buffer object is mapped in the current context or
// any context current to another thread, it is as though UnmapBuffer
// (see section 2.10.3) is executed in each such context prior to deleting
// the existing data store.
//
std::vector<uint8_t> data1(16);
std::vector<uint8_t> data2(16);
GLBuffer dataBuffer;
glBindBuffer(GL_ARRAY_BUFFER, dataBuffer);
glBufferData(GL_ARRAY_BUFFER, data1.size(), data1.data(), GL_STATIC_DRAW);
// Map the buffer once
void *mappedBuffer =
glMapBufferRange(GL_ARRAY_BUFFER, 0, data1.size(),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
// Then repopulate the buffer. This should cause the buffer to become unmapped.
glBufferData(GL_ARRAY_BUFFER, data2.size(), data2.data(), GL_STATIC_DRAW);
ASSERT_GL_NO_ERROR();
// Try to unmap the buffer, this should fail
bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
ASSERT_EQ(result, false);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Try to map the buffer again, which should succeed
mappedBuffer = glMapBufferRange(GL_ARRAY_BUFFER, 0, data2.size(),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
ASSERT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(BufferDataTest); ANGLE_INSTANTIATE_TEST_ES2(BufferDataTest);
......
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