• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ExternalBufferTest:
7 //   Tests the correctness of external buffer ext extension.
8 //
9 
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12 #include "util/EGLWindow.h"
13 
14 #include "common/android_util.h"
15 
16 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
17 #    define ANGLE_AHARDWARE_BUFFER_SUPPORT
18 // NDK header file for access to Android Hardware Buffers
19 #    include <android/hardware_buffer.h>
20 #endif
21 
22 namespace angle
23 {
24 
25 class ExternalBufferTestES31 : public ANGLETest<>
26 {
27   protected:
ExternalBufferTestES31()28     ExternalBufferTestES31()
29     {
30         setWindowWidth(16);
31         setWindowHeight(16);
32         setConfigRedBits(8);
33         setConfigGreenBits(8);
34         setConfigBlueBits(8);
35         setConfigAlphaBits(8);
36         setConfigDepthBits(24);
37     }
38 
createAndroidHardwareBuffer(size_t size,const GLubyte * data)39     AHardwareBuffer *createAndroidHardwareBuffer(size_t size, const GLubyte *data)
40     {
41 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
42         // The height and width are number of pixels of size format
43         AHardwareBuffer_Desc aHardwareBufferDescription = {};
44         aHardwareBufferDescription.width                = size;
45         aHardwareBufferDescription.height               = 1;
46         aHardwareBufferDescription.layers               = 1;
47         aHardwareBufferDescription.format               = AHARDWAREBUFFER_FORMAT_BLOB;
48         aHardwareBufferDescription.usage =
49             AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
50         aHardwareBufferDescription.stride = 0;
51 
52         // Allocate memory from Android Hardware Buffer
53         AHardwareBuffer *aHardwareBuffer = nullptr;
54         EXPECT_EQ(0, AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer));
55 
56         void *mappedMemory = nullptr;
57         EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,
58                                           -1, nullptr, &mappedMemory));
59 
60         // Need to grab the stride the implementation might have enforced
61         AHardwareBuffer_describe(aHardwareBuffer, &aHardwareBufferDescription);
62 
63         memcpy(mappedMemory, data, size);
64 
65         EXPECT_EQ(0, AHardwareBuffer_unlock(aHardwareBuffer, nullptr));
66         return aHardwareBuffer;
67 #else
68         return nullptr;
69 #endif  // ANGLE_PLATFORM_ANDROID
70     }
71 
destroyAndroidHardwareBuffer(AHardwareBuffer * aHardwareBuffer)72     void destroyAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
73     {
74 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
75         AHardwareBuffer_release(aHardwareBuffer);
76 #endif
77     }
78 
lockAndroidHardwareBuffer(AHardwareBuffer * aHardwareBuffer)79     void *lockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
80     {
81         void *data = nullptr;
82 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
83         EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
84                                           -1, nullptr, &data));
85 #endif
86         return data;
87     }
88 
unlockAndroidHardwareBuffer(AHardwareBuffer * aHardwareBuffer)89     void unlockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
90     {
91 #if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
92         AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
93 #endif
94     }
95 };
96 
97 // Testing subdata update with external buffer from AHB
TEST_P(ExternalBufferTestES31,BufferSubData)98 TEST_P(ExternalBufferTestES31, BufferSubData)
99 {
100     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
101                        !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
102     constexpr uint8_t kBufferSize = 16;
103     std::vector<GLubyte> initData(kBufferSize, 0xA);
104 
105     // Create the Image
106     AHardwareBuffer *aHardwareBuffer;
107     constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;
108     aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());
109 
110     GLBuffer buffer;
111     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
112     glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
113                                eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
114     ASSERT_GL_NO_ERROR();
115 
116     std::vector<GLubyte> expectedData(kBufferSize, 0xFF);
117 
118     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
119     glFinish();
120 
121     ASSERT_GL_NO_ERROR();
122 
123     // Inspect the data written into the buffer using CPU access.
124     uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));
125 
126     for (uint32_t i = 0; i < kBufferSize; ++i)
127     {
128         EXPECT_EQ(data[i], 0xFF);
129     }
130 
131     unlockAndroidHardwareBuffer(aHardwareBuffer);
132 
133     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
134     // Delete the source AHB
135     destroyAndroidHardwareBuffer(aHardwareBuffer);
136 }
137 
138 // Verify that subdata updates to an external buffer backed by an AHB doesn't orphan the AHB
TEST_P(ExternalBufferTestES31,SubDataDoesNotCauseOrphaning)139 TEST_P(ExternalBufferTestES31, SubDataDoesNotCauseOrphaning)
140 {
141     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
142                        !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
143     constexpr uint8_t kBufferSize = 16;
144     std::vector<GLubyte> initData(kBufferSize, 0xA);
145 
146     // Create the AHB
147     AHardwareBuffer *aHardwareBuffer;
148     constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;
149     aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());
150 
151     // Create externalBuffer
152     GLBuffer externalBuffer;
153     glBindBuffer(GL_SHADER_STORAGE_BUFFER, externalBuffer);
154     glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
155                                eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
156     ASSERT_GL_NO_ERROR();
157 
158     // Create a copy read buffer
159     std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);
160     GLBuffer copyReadBuffer;
161     glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);
162     glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);
163     ASSERT_GL_NO_ERROR();
164 
165     // Copy from copyReadBuffer to externalBuffer
166     glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);
167     ASSERT_GL_NO_ERROR();
168 
169     // Update externalBuffer
170     std::vector<GLubyte> expectedData(kBufferSize, 0xFF);
171     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
172     glFinish();
173     ASSERT_GL_NO_ERROR();
174 
175     // Inspect the data written into the AHB, through externalBuffer, using CPU access.
176     uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));
177 
178     for (uint32_t i = 0; i < kBufferSize; ++i)
179     {
180         EXPECT_EQ(data[i], 0xFF);
181     }
182 
183     unlockAndroidHardwareBuffer(aHardwareBuffer);
184 
185     glBindBuffer(GL_COPY_READ_BUFFER, 0);
186     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
187     // Delete the source AHB
188     destroyAndroidHardwareBuffer(aHardwareBuffer);
189 }
190 
191 // Testing dispatch compute shader external from source AHB
TEST_P(ExternalBufferTestES31,DispatchCompute)192 TEST_P(ExternalBufferTestES31, DispatchCompute)
193 {
194     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
195                        !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
196     constexpr char kCS[] = R"(#version 310 es
197     layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
198     layout(std430, binding=0) buffer Output {
199         uint data[];
200     } bOutput;
201     void main() {
202         bOutput.data[gl_GlobalInvocationID.x] =
203             gl_GlobalInvocationID.x * 3u;
204     }
205 )";
206 
207     constexpr uint8_t kBufferSize = 16 * 4;
208     std::vector<GLubyte> initData(kBufferSize, 0xA);
209 
210     // Create the Image
211     AHardwareBuffer *aHardwareBuffer;
212     constexpr GLbitfield kFlags = GL_MAP_READ_BIT;
213     aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());
214 
215     GLBuffer buffer;
216     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
217     glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
218                                eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
219 
220     ASSERT_GL_NO_ERROR();
221 
222     GLProgram program;
223     program.makeCompute(kCS);
224     ASSERT_NE(program.get(), 0U);
225     ASSERT_GL_NO_ERROR();
226 
227     glUseProgram(program);
228     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
229     glDispatchCompute(kBufferSize, 1, 1);
230     glFinish();
231     ASSERT_GL_NO_ERROR();
232 
233     // Inspect the data written into the buffer using CPU access.
234     uint32_t *data = static_cast<uint32_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));
235 
236     for (uint32_t i = 0; i < (kBufferSize / sizeof(uint32_t)); ++i)
237     {
238         EXPECT_EQ(data[i], static_cast<uint32_t>(i * 3));
239     }
240 
241     unlockAndroidHardwareBuffer(aHardwareBuffer);
242 
243     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
244     // Delete the source AHB
245     destroyAndroidHardwareBuffer(aHardwareBuffer);
246 }
247 
248 // Test interaction between GL_OES_mapbuffer and GL_EXT_external_buffer extensions.
TEST_P(ExternalBufferTestES31,MapBuffer)249 TEST_P(ExternalBufferTestES31, MapBuffer)
250 {
251     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
252                        !IsGLExtensionEnabled("GL_EXT_buffer_storage") ||
253                        !IsGLExtensionEnabled("GL_EXT_map_buffer_range"));
254     constexpr uint8_t kBufferSize = 16;
255     std::vector<GLubyte> initData(kBufferSize, 0xFF);
256 
257     // Create the AHB
258     AHardwareBuffer *aHardwareBuffer;
259     constexpr GLbitfield kFlags = (GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT);
260     aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());
261 
262     GLBuffer buffer;
263     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
264     glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
265                                eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
266 
267     ASSERT_GL_NO_ERROR();
268 
269     // Inspect the data written into the buffer using CPU access.
270     uint8_t *data = static_cast<uint8_t *>(
271         glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT_EXT));
272     ASSERT_GL_NO_ERROR();
273 
274     for (uint32_t i = 0; i < kBufferSize; ++i)
275     {
276         EXPECT_EQ(data[i], 0xFF);
277     }
278 
279     glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);
280 
281     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
282     // Delete the source AHB
283     destroyAndroidHardwareBuffer(aHardwareBuffer);
284 }
285 
286 // Verify that mapping an external buffer backed by an AHB doesn't orphan the AHB
TEST_P(ExternalBufferTestES31,MapBufferDoesNotCauseOrphaning)287 TEST_P(ExternalBufferTestES31, MapBufferDoesNotCauseOrphaning)
288 {
289     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
290                        !IsGLExtensionEnabled("GL_EXT_buffer_storage") ||
291                        !IsGLExtensionEnabled("GL_EXT_map_buffer_range"));
292     constexpr uint8_t kBufferSize = 16;
293     std::vector<GLubyte> initData(kBufferSize, 0xA);
294 
295     // Create the AHB
296     AHardwareBuffer *aHardwareBuffer;
297     constexpr GLbitfield kFlags =
298         (GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT | GL_DYNAMIC_STORAGE_BIT_EXT);
299     aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());
300 
301     GLBuffer buffer;
302     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
303     glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
304                                eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
305     ASSERT_GL_NO_ERROR();
306 
307     // Create a copy read buffer
308     std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);
309     GLBuffer copyReadBuffer;
310     glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);
311     glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);
312     ASSERT_GL_NO_ERROR();
313 
314     // Copy from copyReadBuffer to externalBuffer
315     glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);
316     ASSERT_GL_NO_ERROR();
317 
318     // Inspect the data written into the buffer using map buffer API.
319     constexpr GLbitfield kMapFlags = (GL_MAP_WRITE_BIT_EXT | GL_MAP_INVALIDATE_BUFFER_BIT);
320     uint8_t *mapData               = static_cast<uint8_t *>(
321         glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, kMapFlags));
322     ASSERT_GL_NO_ERROR();
323     EXPECT_NE(mapData, nullptr);
324     glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);
325 
326     // Update externalBuffer
327     std::vector<GLubyte> expectedData(kBufferSize, 0xFF);
328     glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
329     glFinish();
330     ASSERT_GL_NO_ERROR();
331 
332     // Inspect the data written into the AHB, through externalBuffer, using CPU access.
333     uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));
334 
335     for (uint32_t i = 0; i < kBufferSize; ++i)
336     {
337         EXPECT_EQ(data[i], 0xFF);
338     }
339 
340     unlockAndroidHardwareBuffer(aHardwareBuffer);
341 
342     glBindBuffer(GL_COPY_READ_BUFFER, 0);
343     glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
344     // Delete the source AHB
345     destroyAndroidHardwareBuffer(aHardwareBuffer);
346 }
347 
348 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ExternalBufferTestES31);
349 ANGLE_INSTANTIATE_TEST_ES31(ExternalBufferTestES31);
350 }  // namespace angle
351