blob: 5dcf29fd88d2d4b3b7ab86b4266fdc254db7e136 [file] [log] [blame]
Jamie Madill80b95282014-05-06 13:57:43 -04001#include "ANGLETest.h"
2
Jamie Madill18afd772014-08-04 13:22:22 -04003#include <cstdint>
4
Austin Kinross18b931d2014-09-29 12:58:31 -07005// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang0d3683c2014-10-23 11:08:16 -04006ANGLE_TYPED_TEST_CASE(BufferDataTest, ES2_D3D9, ES2_D3D11);
Austin Kinross18b931d2014-09-29 12:58:31 -07007
8template<typename T>
Jamie Madill80b95282014-05-06 13:57:43 -04009class BufferDataTest : public ANGLETest
10{
Jamie Madill5c1e58d2014-08-04 10:47:58 -040011 protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -040012 BufferDataTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Jamie Madill80b95282014-05-06 13:57:43 -040013 {
14 setWindowWidth(16);
15 setWindowHeight(16);
16 setConfigRedBits(8);
17 setConfigGreenBits(8);
18 setConfigBlueBits(8);
19 setConfigAlphaBits(8);
20 setConfigDepthBits(24);
Austin Kinross18b931d2014-09-29 12:58:31 -070021
22 mBuffer = 0;
23 mProgram = 0;
24 mAttribLocation = -1;
Jamie Madill80b95282014-05-06 13:57:43 -040025 }
26
27 virtual void SetUp()
28 {
29 ANGLETest::SetUp();
30
31 const char * vsSource = SHADER_SOURCE
32 (
33 attribute vec4 position;
34 attribute float in_attrib;
35 varying float v_attrib;
36 void main()
37 {
38 v_attrib = in_attrib;
39 gl_Position = position;
40 }
41 );
42
43 const char * fsSource = SHADER_SOURCE
44 (
45 precision mediump float;
46 varying float v_attrib;
47 void main()
48 {
49 gl_FragColor = vec4(v_attrib, 0, 0, 1);
50 }
51 );
52
53 glGenBuffers(1, &mBuffer);
54 ASSERT_NE(mBuffer, 0U);
55
Jamie Madill5599c8f2014-08-26 13:16:39 -040056 mProgram = CompileProgram(vsSource, fsSource);
Jamie Madill80b95282014-05-06 13:57:43 -040057 ASSERT_NE(mProgram, 0U);
58
59 mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
60 ASSERT_NE(mAttribLocation, -1);
61
62 glClearColor(0, 0, 0, 0);
63 glClearDepthf(0.0);
64 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
65
66 glDisable(GL_DEPTH_TEST);
67
68 ASSERT_GL_NO_ERROR();
69 }
70
71 virtual void TearDown()
72 {
73 glDeleteBuffers(1, &mBuffer);
74 glDeleteProgram(mProgram);
75
76 ANGLETest::TearDown();
77 }
78
79 GLuint mBuffer;
80 GLuint mProgram;
81 GLint mAttribLocation;
82};
83
Austin Kinross18b931d2014-09-29 12:58:31 -070084TYPED_TEST(BufferDataTest, NULLData)
Jamie Madill80b95282014-05-06 13:57:43 -040085{
86 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
87 EXPECT_GL_NO_ERROR();
88
89 const int numIterations = 128;
90 for (int i = 0; i < numIterations; ++i)
91 {
92 GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
93 glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
94 EXPECT_GL_NO_ERROR();
95
96 for (int j = 0; j < bufferSize; j++)
97 {
98 for (int k = 0; k < bufferSize - j; k++)
99 {
100 glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
101 EXPECT_GL_NO_ERROR();
102 }
103 }
104 }
105}
106
Austin Kinross18b931d2014-09-29 12:58:31 -0700107TYPED_TEST(BufferDataTest, ZeroNonNULLData)
Jamie Madille09f1c82014-06-12 11:10:12 -0400108{
109 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
110 EXPECT_GL_NO_ERROR();
111
112 char *zeroData = new char[0];
113 glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
114 EXPECT_GL_NO_ERROR();
115
116 glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
117 EXPECT_GL_NO_ERROR();
118
119 delete [] zeroData;
120}
121
Austin Kinross18b931d2014-09-29 12:58:31 -0700122TYPED_TEST(BufferDataTest, NULLResolvedData)
Jamie Madillee009b82014-09-19 13:17:51 -0400123{
124 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
125 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
126
127 glUseProgram(mProgram);
128 glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
129 glEnableVertexAttribArray(mAttribLocation);
130 glBindBuffer(GL_ARRAY_BUFFER, 0);
131
132 drawQuad(mProgram, "position", 0.5f);
133}
134
Jamie Madille50bf152015-01-20 16:04:41 -0500135// Tests that a huge allocation returns GL_OUT_OF_MEMORY
136// TODO(jmadill): Figure out how to test this reliably on the Chromium bots
137TYPED_TEST(BufferDataTest, DISABLED_HugeSetDataShouldNotCrash)
Jamie Madill80b95282014-05-06 13:57:43 -0400138{
139 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
140 EXPECT_GL_NO_ERROR();
141
Jamie Madill18afd772014-08-04 13:22:22 -0400142 GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
Jamie Madill80b95282014-05-06 13:57:43 -0400143
Jamie Madill18afd772014-08-04 13:22:22 -0400144 uint8_t *data = NULL;
145 while (data == NULL && allocSize >= 4)
Jamie Madill80b95282014-05-06 13:57:43 -0400146 {
Jamie Madill18afd772014-08-04 13:22:22 -0400147 data = new (std::nothrow) uint8_t[allocSize];
148
149 if (data == NULL)
150 {
Jamie Madill4f2bf3a2014-08-20 16:03:52 -0400151 allocSize >>= 1;
Jamie Madill18afd772014-08-04 13:22:22 -0400152 }
Jamie Madill80b95282014-05-06 13:57:43 -0400153 }
154
Jamie Madill18afd772014-08-04 13:22:22 -0400155 ASSERT_NE(static_cast<uint8_t*>(NULL), data);
156 memset(data, 0, allocSize);
Jamie Madill80b95282014-05-06 13:57:43 -0400157
158 float * fValue = reinterpret_cast<float*>(data);
159 for (unsigned int f = 0; f < 6; f++)
160 {
161 fValue[f] = 1.0f;
162 }
163
Jamie Madill18afd772014-08-04 13:22:22 -0400164 glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
Jamie Madill80b95282014-05-06 13:57:43 -0400165
166 GLenum error = glGetError();
167 if (error == GL_NO_ERROR)
168 {
169 // If we didn't fail because of an out of memory error, try drawing a quad
170 // using the large buffer
171
172 // DISABLED because it takes a long time, but left for posterity
173
174 //glUseProgram(mProgram);
175 //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
176 //glEnableVertexAttribArray(mAttribLocation);
177 //glBindBuffer(GL_ARRAY_BUFFER, 0);
178 //drawQuad(mProgram, "position", 0.5f);
179 //swapBuffers();
180
181 //// Draw operations can also generate out-of-memory, which is in-spec
182 //error = glGetError();
183 //if (error == GL_NO_ERROR)
184 //{
185 // GLint viewportSize[4];
186 // glGetIntegerv(GL_VIEWPORT, viewportSize);
187
188 // GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
189 // GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
190
191 // EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
192 //}
193 //else
194 //{
195 // EXPECT_EQ(GL_OUT_OF_MEMORY, error);
196 //}
197 }
198 else
199 {
200 EXPECT_EQ(GL_OUT_OF_MEMORY, error);
201 }
202
203 delete[] data;
204}
205
Austin Kinross18b931d2014-09-29 12:58:31 -0700206// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang0d3683c2014-10-23 11:08:16 -0400207ANGLE_TYPED_TEST_CASE(IndexedBufferCopyTest, ES3_D3D11);
Austin Kinross18b931d2014-09-29 12:58:31 -0700208
209template<typename T>
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400210class IndexedBufferCopyTest : public ANGLETest
211{
212 protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -0400213 IndexedBufferCopyTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400214 {
215 setWindowWidth(16);
216 setWindowHeight(16);
217 setConfigRedBits(8);
218 setConfigGreenBits(8);
219 setConfigBlueBits(8);
220 setConfigAlphaBits(8);
221 setConfigDepthBits(24);
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400222 }
223
224 virtual void SetUp()
225 {
226 ANGLETest::SetUp();
227
228 const char * vsSource = SHADER_SOURCE
229 (
230 attribute vec3 in_attrib;
231 varying vec3 v_attrib;
232 void main()
233 {
234 v_attrib = in_attrib;
235 gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
236 gl_PointSize = 100.0;
237 }
238 );
239
240 const char * fsSource = SHADER_SOURCE
241 (
242 precision mediump float;
243 varying vec3 v_attrib;
244 void main()
245 {
246 gl_FragColor = vec4(v_attrib, 1);
247 }
248 );
249
250 glGenBuffers(2, mBuffers);
251 ASSERT_NE(mBuffers[0], 0U);
252 ASSERT_NE(mBuffers[1], 0U);
253
254 glGenBuffers(1, &mElementBuffer);
255 ASSERT_NE(mElementBuffer, 0U);
256
Jamie Madill5599c8f2014-08-26 13:16:39 -0400257 mProgram = CompileProgram(vsSource, fsSource);
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400258 ASSERT_NE(mProgram, 0U);
259
260 mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
261 ASSERT_NE(mAttribLocation, -1);
262
263 glClearColor(0, 0, 0, 0);
264 glDisable(GL_DEPTH_TEST);
265 glClear(GL_COLOR_BUFFER_BIT);
266
267 ASSERT_GL_NO_ERROR();
268 }
269
270 virtual void TearDown()
271 {
272 glDeleteBuffers(2, mBuffers);
273 glDeleteBuffers(1, &mElementBuffer);
274 glDeleteProgram(mProgram);
275
276 ANGLETest::TearDown();
277 }
278
279 GLuint mBuffers[2];
280 GLuint mElementBuffer;
281 GLuint mProgram;
282 GLint mAttribLocation;
283};
284
285// The following test covers an ANGLE bug where our index ranges
286// weren't updated from CopyBufferSubData calls
287// https://code.google.com/p/angleproject/issues/detail?id=709
Austin Kinross18b931d2014-09-29 12:58:31 -0700288TYPED_TEST(IndexedBufferCopyTest, IndexRangeBug)
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400289{
290 unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 };
291 unsigned int indexData[] = { 0, 1 };
292
293 glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
294 glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW);
295
296 glUseProgram(mProgram);
297 glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL);
298 glEnableVertexAttribArray(mAttribLocation);
299
300 ASSERT_GL_NO_ERROR();
301
302 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer);
303 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW);
304
305 glUseProgram(mProgram);
306
307 ASSERT_GL_NO_ERROR();
308
309 glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
310
311 EXPECT_GL_NO_ERROR();
312 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
313
314 glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]);
315 glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW);
316
317 glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer);
318
319 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int));
320
321 ASSERT_GL_NO_ERROR();
322
323 glClear(GL_COLOR_BUFFER_BIT);
324 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
325
326 unsigned char newData[] = { 0, 255, 0 };
327 glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData);
328
329 glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
330
331 EXPECT_GL_NO_ERROR();
332 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
333}
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000334
335// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
336ANGLE_TYPED_TEST_CASE(BufferDataTestES3, ES3_D3D11);
337
338template<typename T>
339class BufferDataTestES3 : public BufferDataTest<T>
340{
341};
342
343// The following test covers an ANGLE bug where the buffer storage
344// is not resized by Buffer11::getLatestBufferStorage when needed.
345// https://code.google.com/p/angleproject/issues/detail?id=897
346TYPED_TEST(BufferDataTestES3, BufferResizing)
347{
348 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
349 ASSERT_GL_NO_ERROR();
350
351 // Allocate a buffer with one byte
352 uint8_t singleByte[] = { 0xaa };
353 glBufferData(GL_ARRAY_BUFFER, 1, singleByte, GL_STATIC_DRAW);
354
355 // Resize the buffer
356 // To trigger the bug, the buffer need to be big enough because some hardware copy buffers
357 // by chunks of pages instead of the minimum number of bytes neeeded.
358 const size_t numBytes = 4096*4;
359 glBufferData(GL_ARRAY_BUFFER, numBytes, NULL, GL_STATIC_DRAW);
360
361 // Copy the original data to the buffer
362 uint8_t srcBytes[numBytes];
363 for (size_t i = 0; i < numBytes; ++i)
364 {
Minmin Gong3b26e232015-04-07 18:31:54 -0700365 srcBytes[i] = static_cast<uint8_t>(i);
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000366 }
367
368 void *dest = glMapBufferRange(GL_ARRAY_BUFFER, 0, numBytes, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
369
370 ASSERT_GL_NO_ERROR();
371
372 memcpy(dest, srcBytes, numBytes);
373 glUnmapBuffer(GL_ARRAY_BUFFER);
374
375 EXPECT_GL_NO_ERROR();
376
377 // Create a new buffer and copy the data to it
378 GLuint readBuffer;
379 glGenBuffers(1, &readBuffer);
380 glBindBuffer(GL_COPY_WRITE_BUFFER, readBuffer);
381 uint8_t zeros[numBytes];
382 for (size_t i = 0; i < numBytes; ++i)
383 {
384 zeros[i] = 0;
385 }
386 glBufferData(GL_COPY_WRITE_BUFFER, numBytes, zeros, GL_STATIC_DRAW);
387 glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, numBytes);
388
389 ASSERT_GL_NO_ERROR();
390
391 // Read back the data and compare it to the original
392 uint8_t *data = reinterpret_cast<uint8_t*>(glMapBufferRange(GL_COPY_WRITE_BUFFER, 0, numBytes, GL_MAP_READ_BIT));
393
394 ASSERT_GL_NO_ERROR();
395
396 for (size_t i = 0; i < numBytes; ++i)
397 {
398 EXPECT_EQ(srcBytes[i], data[i]);
399 }
400 glUnmapBuffer(GL_COPY_WRITE_BUFFER);
401
402 glDeleteBuffers(1, &readBuffer);
403
404 EXPECT_GL_NO_ERROR();
405}