blob: 7707a4a568b4a84bab42622aaf70e24a6e0a1ec5 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Jamie Madilld2f0c742016-11-02 10:34:41 -04008#include "test_utils/gl_raii.h"
Jamie Madill80b95282014-05-06 13:57:43 -04009
Corentin Wallez178e5972015-09-14 11:52:44 -070010#include <stdint.h>
Jamie Madill18afd772014-08-04 13:22:22 -040011
Jamie Madillfa05f602015-05-07 13:47:11 -040012using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070013
Jamie Madill80b95282014-05-06 13:57:43 -040014class BufferDataTest : public ANGLETest
15{
Jamie Madill5c1e58d2014-08-04 10:47:58 -040016 protected:
Jamie Madillfa05f602015-05-07 13:47:11 -040017 BufferDataTest()
Jamie Madill80b95282014-05-06 13:57:43 -040018 {
19 setWindowWidth(16);
20 setWindowHeight(16);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 setConfigDepthBits(24);
Austin Kinross18b931d2014-09-29 12:58:31 -070026
27 mBuffer = 0;
28 mProgram = 0;
29 mAttribLocation = -1;
Jamie Madill80b95282014-05-06 13:57:43 -040030 }
31
Jamie Madill3dfcdcb2015-08-10 14:28:54 -040032 void SetUp() override
Jamie Madill80b95282014-05-06 13:57:43 -040033 {
34 ANGLETest::SetUp();
35
36 const char * vsSource = SHADER_SOURCE
37 (
38 attribute vec4 position;
39 attribute float in_attrib;
40 varying float v_attrib;
41 void main()
42 {
43 v_attrib = in_attrib;
44 gl_Position = position;
45 }
46 );
47
48 const char * fsSource = SHADER_SOURCE
49 (
50 precision mediump float;
51 varying float v_attrib;
52 void main()
53 {
54 gl_FragColor = vec4(v_attrib, 0, 0, 1);
55 }
56 );
57
58 glGenBuffers(1, &mBuffer);
59 ASSERT_NE(mBuffer, 0U);
60
Jamie Madill5599c8f2014-08-26 13:16:39 -040061 mProgram = CompileProgram(vsSource, fsSource);
Jamie Madill80b95282014-05-06 13:57:43 -040062 ASSERT_NE(mProgram, 0U);
63
64 mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
65 ASSERT_NE(mAttribLocation, -1);
66
67 glClearColor(0, 0, 0, 0);
68 glClearDepthf(0.0);
69 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
70
71 glDisable(GL_DEPTH_TEST);
72
73 ASSERT_GL_NO_ERROR();
74 }
75
Jamie Madill3dfcdcb2015-08-10 14:28:54 -040076 void TearDown() override
Jamie Madill80b95282014-05-06 13:57:43 -040077 {
78 glDeleteBuffers(1, &mBuffer);
79 glDeleteProgram(mProgram);
80
81 ANGLETest::TearDown();
82 }
83
84 GLuint mBuffer;
85 GLuint mProgram;
86 GLint mAttribLocation;
87};
88
Jamie Madillfa05f602015-05-07 13:47:11 -040089TEST_P(BufferDataTest, NULLData)
Jamie Madill80b95282014-05-06 13:57:43 -040090{
91 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
92 EXPECT_GL_NO_ERROR();
93
94 const int numIterations = 128;
95 for (int i = 0; i < numIterations; ++i)
96 {
97 GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
98 glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
99 EXPECT_GL_NO_ERROR();
100
101 for (int j = 0; j < bufferSize; j++)
102 {
103 for (int k = 0; k < bufferSize - j; k++)
104 {
105 glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
Jamie Madille2e406c2016-06-02 13:04:10 -0400106 ASSERT_GL_NO_ERROR();
Jamie Madill80b95282014-05-06 13:57:43 -0400107 }
108 }
109 }
110}
111
Jamie Madillfa05f602015-05-07 13:47:11 -0400112TEST_P(BufferDataTest, ZeroNonNULLData)
Jamie Madille09f1c82014-06-12 11:10:12 -0400113{
114 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
115 EXPECT_GL_NO_ERROR();
116
117 char *zeroData = new char[0];
118 glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
119 EXPECT_GL_NO_ERROR();
120
121 glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
122 EXPECT_GL_NO_ERROR();
123
124 delete [] zeroData;
125}
126
Jamie Madillfa05f602015-05-07 13:47:11 -0400127TEST_P(BufferDataTest, NULLResolvedData)
Jamie Madillee009b82014-09-19 13:17:51 -0400128{
129 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
130 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
131
132 glUseProgram(mProgram);
133 glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
134 glEnableVertexAttribArray(mAttribLocation);
135 glBindBuffer(GL_ARRAY_BUFFER, 0);
136
137 drawQuad(mProgram, "position", 0.5f);
138}
139
Jamie Madille50bf152015-01-20 16:04:41 -0500140// Tests that a huge allocation returns GL_OUT_OF_MEMORY
141// TODO(jmadill): Figure out how to test this reliably on the Chromium bots
Jamie Madillfa05f602015-05-07 13:47:11 -0400142TEST_P(BufferDataTest, DISABLED_HugeSetDataShouldNotCrash)
Jamie Madill80b95282014-05-06 13:57:43 -0400143{
144 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
145 EXPECT_GL_NO_ERROR();
146
Jamie Madill18afd772014-08-04 13:22:22 -0400147 GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2;
Jamie Madill80b95282014-05-06 13:57:43 -0400148
Jamie Madill18afd772014-08-04 13:22:22 -0400149 uint8_t *data = NULL;
150 while (data == NULL && allocSize >= 4)
Jamie Madill80b95282014-05-06 13:57:43 -0400151 {
Jamie Madill18afd772014-08-04 13:22:22 -0400152 data = new (std::nothrow) uint8_t[allocSize];
153
154 if (data == NULL)
155 {
Jamie Madill4f2bf3a2014-08-20 16:03:52 -0400156 allocSize >>= 1;
Jamie Madill18afd772014-08-04 13:22:22 -0400157 }
Jamie Madill80b95282014-05-06 13:57:43 -0400158 }
159
Jamie Madill18afd772014-08-04 13:22:22 -0400160 ASSERT_NE(static_cast<uint8_t*>(NULL), data);
161 memset(data, 0, allocSize);
Jamie Madill80b95282014-05-06 13:57:43 -0400162
163 float * fValue = reinterpret_cast<float*>(data);
164 for (unsigned int f = 0; f < 6; f++)
165 {
166 fValue[f] = 1.0f;
167 }
168
Jamie Madill18afd772014-08-04 13:22:22 -0400169 glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW);
Jamie Madill80b95282014-05-06 13:57:43 -0400170
171 GLenum error = glGetError();
172 if (error == GL_NO_ERROR)
173 {
174 // If we didn't fail because of an out of memory error, try drawing a quad
175 // using the large buffer
176
177 // DISABLED because it takes a long time, but left for posterity
178
179 //glUseProgram(mProgram);
180 //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
181 //glEnableVertexAttribArray(mAttribLocation);
182 //glBindBuffer(GL_ARRAY_BUFFER, 0);
183 //drawQuad(mProgram, "position", 0.5f);
184 //swapBuffers();
185
186 //// Draw operations can also generate out-of-memory, which is in-spec
187 //error = glGetError();
188 //if (error == GL_NO_ERROR)
189 //{
190 // GLint viewportSize[4];
191 // glGetIntegerv(GL_VIEWPORT, viewportSize);
192
193 // GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
194 // GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;
195
196 // EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
197 //}
198 //else
199 //{
200 // EXPECT_EQ(GL_OUT_OF_MEMORY, error);
201 //}
202 }
203 else
204 {
Corentin Wallez322653b2015-06-17 18:33:56 +0200205 EXPECT_GLENUM_EQ(GL_OUT_OF_MEMORY, error);
Jamie Madill80b95282014-05-06 13:57:43 -0400206 }
207
208 delete[] data;
209}
210
Jamie Madill52b09c22016-04-11 14:12:31 -0400211// Internally in D3D, we promote dynamic data to static after many draw loops. This code tests
212// path.
213TEST_P(BufferDataTest, RepeatedDrawWithDynamic)
214{
215 std::vector<GLfloat> data;
216 for (int i = 0; i < 16; ++i)
217 {
218 data.push_back(static_cast<GLfloat>(i));
219 }
220
221 glUseProgram(mProgram);
222 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
223 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * data.size(), data.data(), GL_DYNAMIC_DRAW);
224 glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
225 glBindBuffer(GL_ARRAY_BUFFER, 0);
226 glEnableVertexAttribArray(mAttribLocation);
227
228 for (int drawCount = 0; drawCount < 40; ++drawCount)
229 {
230 drawQuad(mProgram, "position", 0.5f);
231 }
232
233 EXPECT_GL_NO_ERROR();
234}
235
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400236class IndexedBufferCopyTest : public ANGLETest
237{
238 protected:
Jamie Madillfa05f602015-05-07 13:47:11 -0400239 IndexedBufferCopyTest()
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400240 {
241 setWindowWidth(16);
242 setWindowHeight(16);
243 setConfigRedBits(8);
244 setConfigGreenBits(8);
245 setConfigBlueBits(8);
246 setConfigAlphaBits(8);
247 setConfigDepthBits(24);
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400248 }
249
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400250 void SetUp() override
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400251 {
252 ANGLETest::SetUp();
253
254 const char * vsSource = SHADER_SOURCE
255 (
256 attribute vec3 in_attrib;
257 varying vec3 v_attrib;
258 void main()
259 {
260 v_attrib = in_attrib;
261 gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
262 gl_PointSize = 100.0;
263 }
264 );
265
266 const char * fsSource = SHADER_SOURCE
267 (
268 precision mediump float;
269 varying vec3 v_attrib;
270 void main()
271 {
272 gl_FragColor = vec4(v_attrib, 1);
273 }
274 );
275
276 glGenBuffers(2, mBuffers);
277 ASSERT_NE(mBuffers[0], 0U);
278 ASSERT_NE(mBuffers[1], 0U);
279
280 glGenBuffers(1, &mElementBuffer);
281 ASSERT_NE(mElementBuffer, 0U);
282
Jamie Madill5599c8f2014-08-26 13:16:39 -0400283 mProgram = CompileProgram(vsSource, fsSource);
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400284 ASSERT_NE(mProgram, 0U);
285
286 mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
287 ASSERT_NE(mAttribLocation, -1);
288
289 glClearColor(0, 0, 0, 0);
290 glDisable(GL_DEPTH_TEST);
291 glClear(GL_COLOR_BUFFER_BIT);
292
293 ASSERT_GL_NO_ERROR();
294 }
295
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400296 void TearDown() override
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400297 {
298 glDeleteBuffers(2, mBuffers);
299 glDeleteBuffers(1, &mElementBuffer);
300 glDeleteProgram(mProgram);
301
302 ANGLETest::TearDown();
303 }
304
305 GLuint mBuffers[2];
306 GLuint mElementBuffer;
307 GLuint mProgram;
308 GLint mAttribLocation;
309};
310
311// The following test covers an ANGLE bug where our index ranges
312// weren't updated from CopyBufferSubData calls
313// https://code.google.com/p/angleproject/issues/detail?id=709
Jamie Madillfa05f602015-05-07 13:47:11 -0400314TEST_P(IndexedBufferCopyTest, IndexRangeBug)
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400315{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500316 // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291)
Jamie Madill518b9fa2016-03-02 11:26:02 -0500317 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Lange0cc2a42016-01-20 10:58:17 -0500318 {
319 std::cout << "Test disabled on AMD OpenGL." << std::endl;
320 return;
321 }
322
Jamie Madill5c1e58d2014-08-04 10:47:58 -0400323 unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 };
324 unsigned int indexData[] = { 0, 1 };
325
326 glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
327 glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW);
328
329 glUseProgram(mProgram);
330 glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL);
331 glEnableVertexAttribArray(mAttribLocation);
332
333 ASSERT_GL_NO_ERROR();
334
335 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer);
336 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW);
337
338 glUseProgram(mProgram);
339
340 ASSERT_GL_NO_ERROR();
341
342 glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
343
344 EXPECT_GL_NO_ERROR();
345 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
346
347 glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]);
348 glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW);
349
350 glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer);
351
352 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int));
353
354 ASSERT_GL_NO_ERROR();
355
356 glClear(GL_COLOR_BUFFER_BIT);
357 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
358
359 unsigned char newData[] = { 0, 255, 0 };
360 glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData);
361
362 glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL);
363
364 EXPECT_GL_NO_ERROR();
365 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
366}
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000367
Jamie Madillfa05f602015-05-07 13:47:11 -0400368class BufferDataTestES3 : public BufferDataTest
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000369{
370};
371
372// The following test covers an ANGLE bug where the buffer storage
373// is not resized by Buffer11::getLatestBufferStorage when needed.
374// https://code.google.com/p/angleproject/issues/detail?id=897
Jamie Madillfa05f602015-05-07 13:47:11 -0400375TEST_P(BufferDataTestES3, BufferResizing)
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000376{
377 glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
378 ASSERT_GL_NO_ERROR();
379
380 // Allocate a buffer with one byte
381 uint8_t singleByte[] = { 0xaa };
382 glBufferData(GL_ARRAY_BUFFER, 1, singleByte, GL_STATIC_DRAW);
383
384 // Resize the buffer
385 // To trigger the bug, the buffer need to be big enough because some hardware copy buffers
386 // by chunks of pages instead of the minimum number of bytes neeeded.
387 const size_t numBytes = 4096*4;
388 glBufferData(GL_ARRAY_BUFFER, numBytes, NULL, GL_STATIC_DRAW);
389
390 // Copy the original data to the buffer
391 uint8_t srcBytes[numBytes];
392 for (size_t i = 0; i < numBytes; ++i)
393 {
Minmin Gong794e0002015-04-07 18:31:54 -0700394 srcBytes[i] = static_cast<uint8_t>(i);
Gregoire Payen de La Garanderie4b3a29e2015-01-23 15:46:22 +0000395 }
396
397 void *dest = glMapBufferRange(GL_ARRAY_BUFFER, 0, numBytes, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
398
399 ASSERT_GL_NO_ERROR();
400
401 memcpy(dest, srcBytes, numBytes);
402 glUnmapBuffer(GL_ARRAY_BUFFER);
403
404 EXPECT_GL_NO_ERROR();
405
406 // Create a new buffer and copy the data to it
407 GLuint readBuffer;
408 glGenBuffers(1, &readBuffer);
409 glBindBuffer(GL_COPY_WRITE_BUFFER, readBuffer);
410 uint8_t zeros[numBytes];
411 for (size_t i = 0; i < numBytes; ++i)
412 {
413 zeros[i] = 0;
414 }
415 glBufferData(GL_COPY_WRITE_BUFFER, numBytes, zeros, GL_STATIC_DRAW);
416 glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, numBytes);
417
418 ASSERT_GL_NO_ERROR();
419
420 // Read back the data and compare it to the original
421 uint8_t *data = reinterpret_cast<uint8_t*>(glMapBufferRange(GL_COPY_WRITE_BUFFER, 0, numBytes, GL_MAP_READ_BIT));
422
423 ASSERT_GL_NO_ERROR();
424
425 for (size_t i = 0; i < numBytes; ++i)
426 {
427 EXPECT_EQ(srcBytes[i], data[i]);
428 }
429 glUnmapBuffer(GL_COPY_WRITE_BUFFER);
430
431 glDeleteBuffers(1, &readBuffer);
432
433 EXPECT_GL_NO_ERROR();
434}
Jamie Madillfa05f602015-05-07 13:47:11 -0400435
436// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500437ANGLE_INSTANTIATE_TEST(BufferDataTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
438ANGLE_INSTANTIATE_TEST(BufferDataTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
439ANGLE_INSTANTIATE_TEST(IndexedBufferCopyTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillfa05f602015-05-07 13:47:11 -0400440
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400441#ifdef _WIN64
442
443// Test a bug where an integer overflow bug could trigger a crash in D3D.
444// The test uses 8 buffers with a size just under 0x2000000 to overflow max uint
445// (with the internal D3D rounding to 16-byte values) and trigger the bug.
446// Only handle this bug on 64-bit Windows for now. Harder to repro on 32-bit.
447class BufferDataOverflowTest : public ANGLETest
448{
449 protected:
450 BufferDataOverflowTest()
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400451 {
452 }
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400453};
454
455// See description above.
456TEST_P(BufferDataOverflowTest, VertexBufferIntegerOverflow)
457{
458 // These values are special, to trigger the rounding bug.
459 unsigned int numItems = 0x7FFFFFE;
Jamie Madilld2f0c742016-11-02 10:34:41 -0400460 constexpr GLsizei bufferCnt = 8;
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400461
Jamie Madilld2f0c742016-11-02 10:34:41 -0400462 std::vector<GLBuffer> buffers(bufferCnt);
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400463
464 std::stringstream vertexShaderStr;
465
466 for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex)
467 {
468 vertexShaderStr << "attribute float attrib" << bufferIndex << ";\n";
469 }
470
471 vertexShaderStr << "attribute vec2 position;\n"
472 "varying float v_attrib;\n"
473 "void main() {\n"
474 " gl_Position = vec4(position, 0, 1);\n"
475 " v_attrib = 0.0;\n";
476
477 for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex)
478 {
479 vertexShaderStr << "v_attrib += attrib" << bufferIndex << ";\n";
480 }
481
482 vertexShaderStr << "}";
483
484 const std::string &fragmentShader =
485 "varying highp float v_attrib;\n"
486 "void main() {\n"
487 " gl_FragColor = vec4(v_attrib, 0, 0, 1);\n"
488 "}";
489
Jamie Madilld2f0c742016-11-02 10:34:41 -0400490 ANGLE_GL_PROGRAM(program, vertexShaderStr.str(), fragmentShader);
491 glUseProgram(program.get());
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400492
493 std::vector<GLfloat> data(numItems, 1.0f);
494
495 for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex)
496 {
Jamie Madilld2f0c742016-11-02 10:34:41 -0400497 glBindBuffer(GL_ARRAY_BUFFER, buffers[bufferIndex].get());
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400498 glBufferData(GL_ARRAY_BUFFER, numItems * sizeof(float), &data[0], GL_DYNAMIC_DRAW);
499
500 std::stringstream attribNameStr;
501 attribNameStr << "attrib" << bufferIndex;
502
Jamie Madilld2f0c742016-11-02 10:34:41 -0400503 GLint attribLocation = glGetAttribLocation(program.get(), attribNameStr.str().c_str());
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400504 ASSERT_NE(-1, attribLocation);
505
506 glVertexAttribPointer(attribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
507 glEnableVertexAttribArray(attribLocation);
508 }
509
Jamie Madilld2f0c742016-11-02 10:34:41 -0400510 GLint positionLocation = glGetAttribLocation(program.get(), "position");
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400511 ASSERT_NE(-1, positionLocation);
512 glDisableVertexAttribArray(positionLocation);
513 glVertexAttrib2f(positionLocation, 1.0f, 1.0f);
514
515 EXPECT_GL_NO_ERROR();
516 glDrawArrays(GL_TRIANGLES, 0, numItems);
517 EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
518}
519
Jamie Madilld2f0c742016-11-02 10:34:41 -0400520// Tests a security bug in our CopyBufferSubData validation (integer overflow).
521TEST_P(BufferDataOverflowTest, CopySubDataValidation)
522{
523 GLBuffer readBuffer, writeBuffer;
524
525 glBindBuffer(GL_COPY_READ_BUFFER, readBuffer.get());
526 glBindBuffer(GL_COPY_WRITE_BUFFER, writeBuffer.get());
527
528 constexpr int bufSize = 100;
529
530 glBufferData(GL_COPY_READ_BUFFER, bufSize, nullptr, GL_STATIC_DRAW);
531 glBufferData(GL_COPY_WRITE_BUFFER, bufSize, nullptr, GL_STATIC_DRAW);
532
533 GLintptr big = std::numeric_limits<GLintptr>::max() - bufSize + 90;
534
535 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, big, 0, 50);
536 EXPECT_GL_ERROR(GL_INVALID_VALUE);
537
538 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, big, 50);
539 EXPECT_GL_ERROR(GL_INVALID_VALUE);
540}
541
Jamie Madill3dfcdcb2015-08-10 14:28:54 -0400542ANGLE_INSTANTIATE_TEST(BufferDataOverflowTest, ES3_D3D11());
543
544#endif // _WIN64