GLES: Expose OES_mapbuffer in GLES2 on GLES3.
This extension is mandatory for EXT_map_buffer_range support. We can
emulate it using GLES 3.0 core map functionality.
BUG=angleproject:1751
Change-Id: Idba09ce7276603d5556039f4a49aa0b87cae22aa
Reviewed-on: https://chromium-review.googlesource.com/431826
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/tests/gl_tests/BufferDataTest.cpp b/src/tests/gl_tests/BufferDataTest.cpp
index 7707a4a..5ba705d 100644
--- a/src/tests/gl_tests/BufferDataTest.cpp
+++ b/src/tests/gl_tests/BufferDataTest.cpp
@@ -7,6 +7,8 @@
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
+#include "random_utils.h"
+
#include <stdint.h>
using namespace angle;
@@ -433,6 +435,54 @@
EXPECT_GL_NO_ERROR();
}
+// Verify OES_mapbuffer is present if EXT_map_buffer_range is.
+TEST_P(BufferDataTest, ExtensionDependency)
+{
+ if (extensionEnabled("GL_EXT_map_buffer_range"))
+ {
+ ASSERT_TRUE(extensionEnabled("GL_OES_mapbuffer"));
+ }
+}
+
+// Test mapping with the OES extension.
+TEST_P(BufferDataTest, MapBufferOES)
+{
+ if (!extensionEnabled("GL_EXT_map_buffer_range"))
+ {
+ // Needed for test validation.
+ return;
+ }
+
+ std::vector<uint8_t> data(1024);
+ FillVectorWithRandomUBytes(&data);
+
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
+ glBufferData(GL_ARRAY_BUFFER, data.size(), nullptr, GL_STATIC_DRAW);
+
+ // Validate that other map flags don't work.
+ void *badMapPtr = glMapBufferOES(GL_ARRAY_BUFFER, GL_MAP_READ_BIT);
+ EXPECT_EQ(nullptr, badMapPtr);
+ EXPECT_GL_ERROR(GL_INVALID_ENUM);
+
+ // Map and write.
+ void *mapPtr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
+ ASSERT_NE(nullptr, mapPtr);
+ ASSERT_GL_NO_ERROR();
+ memcpy(mapPtr, data.data(), data.size());
+ glUnmapBufferOES(GL_ARRAY_BUFFER);
+
+ // Validate data with EXT_map_buffer_range
+ void *readMapPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, data.size(), GL_MAP_READ_BIT_EXT);
+ ASSERT_NE(nullptr, readMapPtr);
+ ASSERT_GL_NO_ERROR();
+ std::vector<uint8_t> actualData(data.size());
+ memcpy(actualData.data(), readMapPtr, data.size());
+ glUnmapBufferOES(GL_ARRAY_BUFFER);
+
+ EXPECT_EQ(data, actualData);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(BufferDataTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
ANGLE_INSTANTIATE_TEST(BufferDataTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
diff --git a/src/tests/gl_tests/SimpleOperationTest.cpp b/src/tests/gl_tests/SimpleOperationTest.cpp
index b11fb9f..4806abd 100644
--- a/src/tests/gl_tests/SimpleOperationTest.cpp
+++ b/src/tests/gl_tests/SimpleOperationTest.cpp
@@ -10,6 +10,9 @@
#include <vector>
+#include "random_utils.h"
+#include "test_utils/gl_raii.h"
+
using namespace angle;
namespace
@@ -27,8 +30,28 @@
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
+
+ void verifyBuffer(const std::vector<uint8_t> &data, GLenum binding);
};
+void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum binding)
+{
+ if (!extensionEnabled("GL_EXT_map_buffer_range"))
+ {
+ return;
+ }
+
+ uint8_t *mapPointer =
+ static_cast<uint8_t *>(glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 1024, GL_MAP_READ_BIT));
+ ASSERT_GL_NO_ERROR();
+
+ std::vector<uint8_t> readbackData(data.size());
+ memcpy(readbackData.data(), mapPointer, data.size());
+ glUnmapBufferOES(GL_ARRAY_BUFFER);
+
+ EXPECT_EQ(data, readbackData);
+}
+
TEST_P(SimpleOperationTest, CompileVertexShader)
{
const std::string source = SHADER_SOURCE
@@ -154,46 +177,47 @@
TEST_P(SimpleOperationTest, BufferDataWithData)
{
- GLuint buffer;
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
std::vector<uint8_t> data(1024);
+ FillVectorWithRandomUBytes(&data);
glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
- glDeleteBuffers(1, &buffer);
+ verifyBuffer(data, GL_ARRAY_BUFFER);
EXPECT_GL_NO_ERROR();
}
TEST_P(SimpleOperationTest, BufferDataWithNoData)
{
- GLuint buffer;
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
- glDeleteBuffers(1, &buffer);
EXPECT_GL_NO_ERROR();
}
TEST_P(SimpleOperationTest, BufferSubData)
{
- GLuint buffer;
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ GLBuffer buffer;
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
- const size_t bufferSize = 1024;
+ constexpr size_t bufferSize = 1024;
+ std::vector<uint8_t> data(bufferSize);
+ FillVectorWithRandomUBytes(&data);
+
glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
- const size_t subDataCount = 16;
- std::vector<uint8_t> data(bufferSize / subDataCount);
+ constexpr size_t subDataCount = 16;
+ constexpr size_t sliceSize = bufferSize / subDataCount;
for (size_t i = 0; i < subDataCount; i++)
{
- glBufferSubData(GL_ARRAY_BUFFER, data.size() * i, data.size(), &data[0]);
+ size_t offset = i * sliceSize;
+ glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
}
- glDeleteBuffers(1, &buffer);
+ verifyBuffer(data, GL_ARRAY_BUFFER);
EXPECT_GL_NO_ERROR();
}