Path: blob/main_old/src/tests/gl_tests/ExternalBufferTest.cpp
1693 views
//1// Copyright 2020 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// ExternalBufferTest:6// Tests the correctness of external buffer ext extension.7//89#include "test_utils/ANGLETest.h"10#include "test_utils/gl_raii.h"11#include "util/EGLWindow.h"1213#include "common/android_util.h"1415#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 2616# define ANGLE_AHARDWARE_BUFFER_SUPPORT17// NDK header file for access to Android Hardware Buffers18# include <android/hardware_buffer.h>19#endif2021namespace angle22{2324class ExternalBufferTestES31 : public ANGLETest25{26protected:27ExternalBufferTestES31()28{29setWindowWidth(16);30setWindowHeight(16);31setConfigRedBits(8);32setConfigGreenBits(8);33setConfigBlueBits(8);34setConfigAlphaBits(8);35setConfigDepthBits(24);36}3738AHardwareBuffer *createAndroidHardwareBuffer(size_t size, const GLubyte *data)39{40#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)41// The height and width are number of pixels of size format42AHardwareBuffer_Desc aHardwareBufferDescription = {};43aHardwareBufferDescription.width = size;44aHardwareBufferDescription.height = 1;45aHardwareBufferDescription.layers = 1;46aHardwareBufferDescription.format = AHARDWAREBUFFER_FORMAT_BLOB;47aHardwareBufferDescription.usage =48AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;49aHardwareBufferDescription.stride = 0;5051// Allocate memory from Android Hardware Buffer52AHardwareBuffer *aHardwareBuffer = nullptr;53EXPECT_EQ(0, AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer));5455void *mappedMemory = nullptr;56EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,57-1, nullptr, &mappedMemory));5859// Need to grab the stride the implementation might have enforced60AHardwareBuffer_describe(aHardwareBuffer, &aHardwareBufferDescription);6162memcpy(mappedMemory, data, size);6364EXPECT_EQ(0, AHardwareBuffer_unlock(aHardwareBuffer, nullptr));65return aHardwareBuffer;66#else67return nullptr;68#endif // ANGLE_PLATFORM_ANDROID69}7071void destroyAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)72{73#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)74AHardwareBuffer_release(aHardwareBuffer);75#endif76}7778void *lockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)79{80void *data = nullptr;81#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)82EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,83-1, nullptr, &data));84#endif85return data;86}8788void unlockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)89{90#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)91AHardwareBuffer_unlock(aHardwareBuffer, nullptr);92#endif93}94};9596// Testing subdata update with external buffer from AHB97TEST_P(ExternalBufferTestES31, BufferSubData)98{99ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||100!IsGLExtensionEnabled("GL_EXT_buffer_storage"));101constexpr uint8_t kBufferSize = 16;102std::vector<GLubyte> initData(kBufferSize, 0xA);103104// Create the Image105AHardwareBuffer *aHardwareBuffer;106constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;107aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());108109GLBuffer buffer;110glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);111glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,112eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);113ASSERT_GL_NO_ERROR();114115std::vector<GLubyte> expectedData(kBufferSize, 0xFF);116117glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());118glFinish();119120ASSERT_GL_NO_ERROR();121122// Inspect the data written into the buffer using CPU access.123uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));124125for (uint32_t i = 0; i < kBufferSize; ++i)126{127EXPECT_EQ(data[i], 0xFF);128}129130unlockAndroidHardwareBuffer(aHardwareBuffer);131132glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);133// Delete the source AHB134destroyAndroidHardwareBuffer(aHardwareBuffer);135}136137// Verify that subdata updates to an external buffer backed by an AHB doesn't orphan the AHB138TEST_P(ExternalBufferTestES31, SubDataDoesNotCauseOrphaning)139{140ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||141!IsGLExtensionEnabled("GL_EXT_buffer_storage"));142constexpr uint8_t kBufferSize = 16;143std::vector<GLubyte> initData(kBufferSize, 0xA);144145// Create the AHB146AHardwareBuffer *aHardwareBuffer;147constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;148aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());149150// Create externalBuffer151GLBuffer externalBuffer;152glBindBuffer(GL_SHADER_STORAGE_BUFFER, externalBuffer);153glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,154eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);155ASSERT_GL_NO_ERROR();156157// Create a copy read buffer158std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);159GLBuffer copyReadBuffer;160glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);161glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);162ASSERT_GL_NO_ERROR();163164// Copy from copyReadBuffer to externalBuffer165glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);166ASSERT_GL_NO_ERROR();167168// Update externalBuffer169std::vector<GLubyte> expectedData(kBufferSize, 0xFF);170glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());171glFinish();172ASSERT_GL_NO_ERROR();173174// Inspect the data written into the AHB, through externalBuffer, using CPU access.175uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));176177for (uint32_t i = 0; i < kBufferSize; ++i)178{179EXPECT_EQ(data[i], 0xFF);180}181182unlockAndroidHardwareBuffer(aHardwareBuffer);183184glBindBuffer(GL_COPY_READ_BUFFER, 0);185glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);186// Delete the source AHB187destroyAndroidHardwareBuffer(aHardwareBuffer);188}189190// Testing dispatch compute shader external from source AHB191TEST_P(ExternalBufferTestES31, DispatchCompute)192{193ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||194!IsGLExtensionEnabled("GL_EXT_buffer_storage"));195constexpr char kCS[] = R"(#version 310 es196layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;197layout(std430, binding=0) buffer Output {198uint data[];199} bOutput;200void main() {201bOutput.data[gl_GlobalInvocationID.x] =202gl_GlobalInvocationID.x * 3u;203}204)";205206constexpr uint8_t kBufferSize = 16 * 4;207std::vector<GLubyte> initData(kBufferSize, 0xA);208209// Create the Image210AHardwareBuffer *aHardwareBuffer;211constexpr GLbitfield kFlags = GL_MAP_READ_BIT;212aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());213214GLBuffer buffer;215glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);216glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,217eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);218219ASSERT_GL_NO_ERROR();220221GLProgram program;222program.makeCompute(kCS);223ASSERT_NE(program.get(), 0U);224ASSERT_GL_NO_ERROR();225226glUseProgram(program);227glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);228glDispatchCompute(kBufferSize, 1, 1);229glFinish();230ASSERT_GL_NO_ERROR();231232// Inspect the data written into the buffer using CPU access.233uint32_t *data = static_cast<uint32_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));234235for (uint32_t i = 0; i < (kBufferSize / sizeof(uint32_t)); ++i)236{237EXPECT_EQ(data[i], static_cast<uint32_t>(i * 3));238}239240unlockAndroidHardwareBuffer(aHardwareBuffer);241242glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);243// Delete the source AHB244destroyAndroidHardwareBuffer(aHardwareBuffer);245}246247// Test interaction between GL_OES_mapbuffer and GL_EXT_external_buffer extensions.248TEST_P(ExternalBufferTestES31, MapBuffer)249{250ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||251!IsGLExtensionEnabled("GL_EXT_buffer_storage") ||252!IsGLExtensionEnabled("GL_EXT_map_buffer_range"));253constexpr uint8_t kBufferSize = 16;254std::vector<GLubyte> initData(kBufferSize, 0xFF);255256// Create the AHB257AHardwareBuffer *aHardwareBuffer;258constexpr GLbitfield kFlags = (GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT);259aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());260261GLBuffer buffer;262glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);263glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,264eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);265266ASSERT_GL_NO_ERROR();267268// Inspect the data written into the buffer using CPU access.269uint8_t *data = static_cast<uint8_t *>(270glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT_EXT));271ASSERT_GL_NO_ERROR();272273for (uint32_t i = 0; i < kBufferSize; ++i)274{275EXPECT_EQ(data[i], 0xFF);276}277278glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);279280glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);281// Delete the source AHB282destroyAndroidHardwareBuffer(aHardwareBuffer);283}284285// Verify that mapping an external buffer backed by an AHB doesn't orphan the AHB286TEST_P(ExternalBufferTestES31, MapBufferDoesNotCauseOrphaning)287{288ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||289!IsGLExtensionEnabled("GL_EXT_buffer_storage") ||290!IsGLExtensionEnabled("GL_EXT_map_buffer_range"));291constexpr uint8_t kBufferSize = 16;292std::vector<GLubyte> initData(kBufferSize, 0xA);293294// Create the AHB295AHardwareBuffer *aHardwareBuffer;296constexpr GLbitfield kFlags =297(GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT | GL_DYNAMIC_STORAGE_BIT_EXT);298aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());299300GLBuffer buffer;301glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);302glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,303eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);304ASSERT_GL_NO_ERROR();305306// Create a copy read buffer307std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);308GLBuffer copyReadBuffer;309glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);310glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);311ASSERT_GL_NO_ERROR();312313// Copy from copyReadBuffer to externalBuffer314glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);315ASSERT_GL_NO_ERROR();316317// Inspect the data written into the buffer using map buffer API.318constexpr GLbitfield kMapFlags = (GL_MAP_WRITE_BIT_EXT | GL_MAP_INVALIDATE_BUFFER_BIT);319uint8_t *mapData = static_cast<uint8_t *>(320glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, kMapFlags));321ASSERT_GL_NO_ERROR();322EXPECT_NE(mapData, nullptr);323glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);324325// Update externalBuffer326std::vector<GLubyte> expectedData(kBufferSize, 0xFF);327glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());328glFinish();329ASSERT_GL_NO_ERROR();330331// Inspect the data written into the AHB, through externalBuffer, using CPU access.332uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));333334for (uint32_t i = 0; i < kBufferSize; ++i)335{336EXPECT_EQ(data[i], 0xFF);337}338339unlockAndroidHardwareBuffer(aHardwareBuffer);340341glBindBuffer(GL_COPY_READ_BUFFER, 0);342glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);343// Delete the source AHB344destroyAndroidHardwareBuffer(aHardwareBuffer);345}346347GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ExternalBufferTestES31);348ANGLE_INSTANTIATE_TEST_ES31(ExternalBufferTestES31);349} // namespace angle350351352