blob: 1b138348f76ae90bc237f618faadc51e38b20b09 [file] [log] [blame]
Jamie Madill508a5b72015-12-08 11:26:14 -05001//
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// ANGLETest:
7// Implementation of common ANGLE testing fixture.
8//
9
Geoff Lang8a079e52013-10-18 16:13:33 -040010#include "ANGLETest.h"
Jamie Madill62af5462014-08-26 13:16:37 -040011#include "EGLWindow.h"
Jamie Madill8add0eb2014-08-26 13:16:35 -040012#include "OSWindow.h"
Jamie Madill776a75b2016-05-17 13:43:17 -040013#include "platform/Platform.h"
Jamie Madill8add0eb2014-08-26 13:16:35 -040014
Jamie Madill0dfa8072016-01-22 15:27:21 -050015namespace angle
16{
17
Jamie Madillec0b5802016-07-04 13:11:59 -040018const GLColorRGB GLColorRGB::black(0u, 0u, 0u);
Jamie Madill9fc7b4c2016-06-08 15:30:14 -070019const GLColorRGB GLColorRGB::blue(0u, 0u, 255u);
20const GLColorRGB GLColorRGB::green(0u, 255u, 0u);
21const GLColorRGB GLColorRGB::red(255u, 0u, 0u);
22const GLColorRGB GLColorRGB::yellow(255u, 255u, 0);
23
Olli Etuahoa314b612016-03-10 16:43:00 +020024const GLColor GLColor::black = GLColor(0u, 0u, 0u, 255u);
Jamie Madill9b08a3d2016-06-08 15:30:12 -070025const GLColor GLColor::blue = GLColor(0u, 0u, 255u, 255u);
26const GLColor GLColor::cyan = GLColor(0u, 255u, 255u, 255u);
27const GLColor GLColor::green = GLColor(0u, 255u, 0u, 255u);
28const GLColor GLColor::red = GLColor(255u, 0u, 0u, 255u);
29const GLColor GLColor::yellow = GLColor(255u, 255u, 0, 255u);
Olli Etuaho190028d2016-05-13 12:11:29 +030030const GLColor GLColor::white = GLColor(255u, 255u, 255u, 255u);
Olli Etuahoa314b612016-03-10 16:43:00 +020031
Vincent Lang25ab4512016-05-13 18:13:59 +020032const GLColor16 GLColor16::white = GLColor16(65535u, 65535u, 65535u, 65535u);
33
Jamie Madill1fbc59f2016-02-24 15:25:51 -050034namespace
35{
36float ColorNorm(GLubyte channelValue)
37{
38 return static_cast<float>(channelValue) / 255.0f;
39}
Jamie Madill776a75b2016-05-17 13:43:17 -040040
Jamie Madillec0b5802016-07-04 13:11:59 -040041GLubyte ColorDenorm(float colorValue)
42{
43 return static_cast<GLubyte>(colorValue * 255.0f);
44}
45
Jamie Madill776a75b2016-05-17 13:43:17 -040046// Use a custom ANGLE platform class to capture and report internal errors.
47class TestPlatform : public angle::Platform
48{
49 public:
50 TestPlatform() : mIgnoreMessages(false) {}
51
52 void logError(const char *errorMessage) override;
53 void logWarning(const char *warningMessage) override;
54 void logInfo(const char *infoMessage) override;
55
56 void ignoreMessages();
57 void enableMessages();
58
59 private:
60 bool mIgnoreMessages;
61};
62
63void TestPlatform::logError(const char *errorMessage)
64{
65 if (mIgnoreMessages)
66 return;
67
68 FAIL() << errorMessage;
69}
70
71void TestPlatform::logWarning(const char *warningMessage)
72{
73 if (mIgnoreMessages)
74 return;
75
76 std::cerr << "Warning: " << warningMessage << std::endl;
77}
78
79void TestPlatform::logInfo(const char *infoMessage)
80{
81 if (mIgnoreMessages)
82 return;
83
84 angle::WriteDebugMessage("%s\n", infoMessage);
85}
86
87void TestPlatform::ignoreMessages()
88{
89 mIgnoreMessages = true;
90}
91
92void TestPlatform::enableMessages()
93{
94 mIgnoreMessages = false;
95}
96
97TestPlatform g_testPlatformInstance;
Jamie Madillec0b5802016-07-04 13:11:59 -040098
99std::array<Vector3, 4> GetIndexedQuadVertices()
100{
101 std::array<Vector3, 4> vertices;
102 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
103 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
104 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
105 vertices[3] = Vector3(1.0f, 1.0f, 0.5f);
106 return vertices;
107}
108
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500109} // anonymous namespace
110
Jamie Madill9fc7b4c2016-06-08 15:30:14 -0700111GLColorRGB::GLColorRGB() : R(0), G(0), B(0)
112{
113}
114
115GLColorRGB::GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b)
116{
117}
118
Jamie Madillec0b5802016-07-04 13:11:59 -0400119GLColorRGB::GLColorRGB(const Vector3 &floatColor)
120 : R(ColorDenorm(floatColor.x)), G(ColorDenorm(floatColor.y)), B(ColorDenorm(floatColor.z))
121{
122}
123
Jamie Madill0dfa8072016-01-22 15:27:21 -0500124GLColor::GLColor() : R(0), G(0), B(0), A(0)
125{
126}
127
128GLColor::GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a)
129{
130}
131
Jamie Madillec0b5802016-07-04 13:11:59 -0400132GLColor::GLColor(const Vector4 &floatColor)
133 : R(ColorDenorm(floatColor.x)),
134 G(ColorDenorm(floatColor.y)),
135 B(ColorDenorm(floatColor.z)),
136 A(ColorDenorm(floatColor.w))
137{
138}
139
140GLColor::GLColor(const GLColor16 &color16)
141 : R(static_cast<GLubyte>(color16.R)),
142 G(static_cast<GLubyte>(color16.G)),
143 B(static_cast<GLubyte>(color16.B)),
144 A(static_cast<GLubyte>(color16.A))
145{
146}
147
Jamie Madille2509a32016-02-01 14:09:05 -0500148GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
149{
150 memcpy(&R, &colorValue, sizeof(GLuint));
151}
152
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500153Vector4 GLColor::toNormalizedVector() const
154{
155 return Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
156}
157
Jamie Madill0dfa8072016-01-22 15:27:21 -0500158GLColor ReadColor(GLint x, GLint y)
159{
160 GLColor actual;
161 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
162 EXPECT_GL_NO_ERROR();
163 return actual;
164}
165
166bool operator==(const GLColor &a, const GLColor &b)
167{
168 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
169}
170
171std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
172{
173 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
174 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
175 << ", " << static_cast<unsigned int>(color.A) << ")";
176 return ostream;
177}
178
Vincent Lang25ab4512016-05-13 18:13:59 +0200179GLColor16::GLColor16() : R(0), G(0), B(0), A(0)
180{
181}
182
183GLColor16::GLColor16(GLushort r, GLushort g, GLushort b, GLushort a) : R(r), G(g), B(b), A(a)
184{
185}
186
187GLColor16 ReadColor16(GLint x, GLint y)
188{
189 GLColor16 actual;
190 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, &actual.R);
191 EXPECT_GL_NO_ERROR();
192 return actual;
193}
194
195bool operator==(const GLColor16 &a, const GLColor16 &b)
196{
197 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
198}
199
200std::ostream &operator<<(std::ostream &ostream, const GLColor16 &color)
201{
202 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
203 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
204 << ", " << static_cast<unsigned int>(color.A) << ")";
205 return ostream;
206}
207
Jamie Madill0dfa8072016-01-22 15:27:21 -0500208} // namespace angle
209
Jamie Madillec0b5802016-07-04 13:11:59 -0400210// static
211std::array<Vector3, 6> ANGLETest::GetQuadVertices()
212{
213 std::array<Vector3, 6> vertices;
214 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
215 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
216 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
217 vertices[3] = Vector3(-1.0f, 1.0f, 0.5f);
218 vertices[4] = Vector3(1.0f, -1.0f, 0.5f);
219 vertices[5] = Vector3(1.0f, 1.0f, 0.5f);
220 return vertices;
221}
222
Jamie Madillfa05f602015-05-07 13:47:11 -0400223ANGLETest::ANGLETest()
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400224 : mEGLWindow(nullptr),
225 mWidth(16),
226 mHeight(16),
227 mIgnoreD3D11SDKLayersWarnings(false),
228 mQuadVertexBuffer(0)
Geoff Lang8a079e52013-10-18 16:13:33 -0400229{
Geoff Lang5ade8452015-09-02 11:00:30 -0400230 mEGLWindow =
231 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -0400232}
233
234ANGLETest::~ANGLETest()
235{
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400236 if (mQuadVertexBuffer)
237 {
238 glDeleteBuffers(1, &mQuadVertexBuffer);
239 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400240 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400241}
242
Geoff Lang8a079e52013-10-18 16:13:33 -0400243void ANGLETest::SetUp()
244{
Jamie Madill776a75b2016-05-17 13:43:17 -0400245 angle::g_testPlatformInstance.enableMessages();
246
Corentin Wallezb44440d2015-07-22 17:54:20 -0400247 // Resize the window before creating the context so that the first make current
248 // sets the viewport and scissor box to the right size.
249 bool needSwap = false;
250 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +0000251 {
Corentin Wallezb44440d2015-07-22 17:54:20 -0400252 if (!mOSWindow->resize(mWidth, mHeight))
253 {
254 FAIL() << "Failed to resize ANGLE test window.";
255 }
256 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +0000257 }
258
Geoff Lang8a079e52013-10-18 16:13:33 -0400259 if (!createEGLContext())
260 {
261 FAIL() << "egl context creation failed.";
262 }
Corentin Wallezb828b322015-07-16 17:51:30 -0400263
Corentin Wallezb44440d2015-07-22 17:54:20 -0400264 if (needSwap)
265 {
266 // Swap the buffers so that the default framebuffer picks up the resize
267 // which will allow follow-up test code to assume the framebuffer covers
268 // the whole window.
269 swapBuffers();
270 }
Corentin Wallez096725b2015-07-20 16:58:57 -0400271
Geoff Lang7f8dc492015-07-23 21:29:33 +0000272 // This Viewport command is not strictly necessary but we add it so that programs
273 // taking OpenGL traces can guess the size of the default framebuffer and show it
274 // in their UIs
275 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -0500276
277 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
278 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -0400279}
280
281void ANGLETest::TearDown()
282{
Austin Kinrossd544cc92016-01-11 15:26:42 -0800283 checkD3D11SDKLayersMessages();
284
Jamie Madill508a5b72015-12-08 11:26:14 -0500285 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
286 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
287
Geoff Lang8a079e52013-10-18 16:13:33 -0400288 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -0400289 mOSWindow->messageLoop();
290
Geoff Lang8a079e52013-10-18 16:13:33 -0400291 if (!destroyEGLContext())
292 {
293 FAIL() << "egl context destruction failed.";
294 }
Jamie Madill8add0eb2014-08-26 13:16:35 -0400295
296 // Check for quit message
297 Event myEvent;
298 while (mOSWindow->popEvent(&myEvent))
299 {
300 if (myEvent.Type == Event::EVENT_CLOSED)
301 {
302 exit(0);
303 }
304 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400305}
306
307void ANGLETest::swapBuffers()
308{
Jamie Madill77a72f62015-04-14 11:18:32 -0400309 if (mEGLWindow->isGLInitialized())
310 {
311 mEGLWindow->swap();
312 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400313}
314
Jamie Madill52b09c22016-04-11 14:12:31 -0400315void ANGLETest::setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
316{
317 if (mQuadVertexBuffer == 0)
318 {
319 glGenBuffers(1, &mQuadVertexBuffer);
320 }
321
322 auto quadVertices = GetQuadVertices();
323 for (Vector3 &vertex : quadVertices)
324 {
325 vertex.x *= positionAttribXYScale;
326 vertex.y *= positionAttribXYScale;
327 vertex.z = positionAttribZ;
328 }
329
330 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
331 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
332}
333
Jamie Madillec0b5802016-07-04 13:11:59 -0400334void ANGLETest::setupIndexedQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
335{
336 if (mQuadVertexBuffer == 0)
337 {
338 glGenBuffers(1, &mQuadVertexBuffer);
339 }
340
341 auto quadVertices = angle::GetIndexedQuadVertices();
342 for (Vector3 &vertex : quadVertices)
343 {
344 vertex.x *= positionAttribXYScale;
345 vertex.y *= positionAttribXYScale;
346 vertex.z = positionAttribZ;
347 }
348
349 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
350 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, quadVertices.data(), GL_STATIC_DRAW);
351}
352
Jamie Madill52b09c22016-04-11 14:12:31 -0400353// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200354void ANGLETest::drawQuad(GLuint program,
355 const std::string &positionAttribName,
356 GLfloat positionAttribZ)
357{
358 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
359}
360
Jamie Madill52b09c22016-04-11 14:12:31 -0400361// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200362void ANGLETest::drawQuad(GLuint program,
363 const std::string &positionAttribName,
364 GLfloat positionAttribZ,
365 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400366{
Jamie Madill52b09c22016-04-11 14:12:31 -0400367 drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
368}
369
370void ANGLETest::drawQuad(GLuint program,
371 const std::string &positionAttribName,
372 GLfloat positionAttribZ,
373 GLfloat positionAttribXYScale,
374 bool useVertexBuffer)
375{
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200376 GLint previousProgram = 0;
377 glGetIntegerv(GL_CURRENT_PROGRAM, &previousProgram);
378 if (previousProgram != static_cast<GLint>(program))
379 {
380 glUseProgram(program);
381 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400382
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200383 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
Geoff Lang8a079e52013-10-18 16:13:33 -0400384
Jamie Madill52b09c22016-04-11 14:12:31 -0400385 if (useVertexBuffer)
386 {
387 setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
388 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
389 glBindBuffer(GL_ARRAY_BUFFER, 0);
390 }
391 else
392 {
393 auto quadVertices = GetQuadVertices();
394 for (Vector3 &vertex : quadVertices)
395 {
396 vertex.x *= positionAttribXYScale;
397 vertex.y *= positionAttribXYScale;
398 vertex.z = positionAttribZ;
399 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400400
Jamie Madill52b09c22016-04-11 14:12:31 -0400401 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
402 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400403 glEnableVertexAttribArray(positionLocation);
404
405 glDrawArrays(GL_TRIANGLES, 0, 6);
406
407 glDisableVertexAttribArray(positionLocation);
408 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
409
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200410 if (previousProgram != static_cast<GLint>(program))
411 {
412 glUseProgram(previousProgram);
413 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400414}
415
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400416void ANGLETest::drawIndexedQuad(GLuint program,
417 const std::string &positionAttribName,
418 GLfloat positionAttribZ)
419{
420 drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
421}
422
423void ANGLETest::drawIndexedQuad(GLuint program,
424 const std::string &positionAttribName,
425 GLfloat positionAttribZ,
426 GLfloat positionAttribXYScale)
427{
428 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
429
Jamie Madill52b09c22016-04-11 14:12:31 -0400430 GLint activeProgram = 0;
431 glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
432 if (static_cast<GLuint>(activeProgram) != program)
433 {
434 glUseProgram(program);
435 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400436
437 GLuint prevBinding = 0;
438 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevBinding));
439
Jamie Madillec0b5802016-07-04 13:11:59 -0400440 setupIndexedQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400441
442 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
443 glEnableVertexAttribArray(positionLocation);
444 glBindBuffer(GL_ARRAY_BUFFER, prevBinding);
445
446 const GLushort indices[] = {
447 0, 1, 2, 0, 2, 3,
448 };
449
450 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
451
452 glDisableVertexAttribArray(positionLocation);
453 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
454
Jamie Madill52b09c22016-04-11 14:12:31 -0400455 if (static_cast<GLuint>(activeProgram) != program)
456 {
457 glUseProgram(static_cast<GLuint>(activeProgram));
458 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400459}
460
Geoff Langefc551f2013-10-31 10:20:28 -0400461GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
462{
463 GLuint shader = glCreateShader(type);
464
465 const char *sourceArray[1] = { source.c_str() };
466 glShaderSource(shader, 1, sourceArray, NULL);
467 glCompileShader(shader);
468
469 GLint compileResult;
470 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
471
472 if (compileResult == 0)
473 {
474 GLint infoLogLength;
475 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
476
Jamie Madilld2c52e32015-10-14 17:07:05 -0400477 if (infoLogLength == 0)
478 {
479 std::cerr << "shader compilation failed with empty log." << std::endl;
480 }
481 else
482 {
483 std::vector<GLchar> infoLog(infoLogLength);
484 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400485
Jamie Madilld2c52e32015-10-14 17:07:05 -0400486 std::cerr << "shader compilation failed: " << &infoLog[0];
487 }
Geoff Langefc551f2013-10-31 10:20:28 -0400488
489 glDeleteShader(shader);
490 shader = 0;
491 }
492
493 return shader;
494}
495
Austin Kinrossd544cc92016-01-11 15:26:42 -0800496void ANGLETest::checkD3D11SDKLayersMessages()
497{
498#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
499 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
500 // were outputted by the test
501 if (mIgnoreD3D11SDKLayersWarnings ||
502 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
503 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
504 {
505 return;
506 }
507
508 const char *extensionString =
509 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
510 if (!strstr(extensionString, "EGL_EXT_device_query"))
511 {
512 return;
513 }
514
515 EGLAttrib device = 0;
516 EGLAttrib angleDevice = 0;
517
518 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
519 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
520
521 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
522 eglGetProcAddress("eglQueryDisplayAttribEXT"));
523 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
524 eglGetProcAddress("eglQueryDeviceAttribEXT"));
525 ASSERT_NE(nullptr, queryDisplayAttribEXT);
526 ASSERT_NE(nullptr, queryDeviceAttribEXT);
527
528 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
529 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
530 EGL_D3D11_DEVICE_ANGLE, &device));
531 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
532
533 ID3D11InfoQueue *infoQueue = nullptr;
534 HRESULT hr =
535 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
536 if (SUCCEEDED(hr))
537 {
538 UINT64 numStoredD3DDebugMessages =
539 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
540
541 if (numStoredD3DDebugMessages > 0)
542 {
543 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
544 {
545 SIZE_T messageLength = 0;
546 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
547
548 if (SUCCEEDED(hr))
549 {
550 D3D11_MESSAGE *pMessage =
551 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
552 infoQueue->GetMessage(i, pMessage, &messageLength);
553
554 std::cout << "Message " << i << ":"
555 << " " << pMessage->pDescription << "\n";
556 free(pMessage);
557 }
558 }
559
560 FAIL() << numStoredD3DDebugMessages
561 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
562 }
563 }
564
565 SafeRelease(infoQueue);
566#endif
567}
568
Geoff Lang63046e22015-07-21 12:43:50 -0400569static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
570{
571 return strstr(allExtensions, extName.c_str()) != nullptr;
572}
573
Geoff Lang8a079e52013-10-18 16:13:33 -0400574bool ANGLETest::extensionEnabled(const std::string &extName)
575{
Geoff Lang63046e22015-07-21 12:43:50 -0400576 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
577 extName);
578}
579
580bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
581{
582 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
583}
584
585bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
586{
587 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400588}
589
Geoff Lang8a079e52013-10-18 16:13:33 -0400590void ANGLETest::setWindowWidth(int width)
591{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400592 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400593}
594
595void ANGLETest::setWindowHeight(int height)
596{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400597 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400598}
599
Geoff Langefc551f2013-10-31 10:20:28 -0400600void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400601{
Jamie Madill62af5462014-08-26 13:16:37 -0400602 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400603}
604
Geoff Langefc551f2013-10-31 10:20:28 -0400605void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400606{
Jamie Madill62af5462014-08-26 13:16:37 -0400607 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400608}
609
Geoff Langefc551f2013-10-31 10:20:28 -0400610void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400611{
Jamie Madill62af5462014-08-26 13:16:37 -0400612 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400613}
614
Geoff Langefc551f2013-10-31 10:20:28 -0400615void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400616{
Jamie Madill62af5462014-08-26 13:16:37 -0400617 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400618}
619
Geoff Langefc551f2013-10-31 10:20:28 -0400620void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400621{
Jamie Madill62af5462014-08-26 13:16:37 -0400622 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400623}
624
Geoff Langefc551f2013-10-31 10:20:28 -0400625void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400626{
Jamie Madill62af5462014-08-26 13:16:37 -0400627 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400628}
629
630void ANGLETest::setMultisampleEnabled(bool enabled)
631{
Jamie Madill62af5462014-08-26 13:16:37 -0400632 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400633}
634
Geoff Lang70d0f492015-12-10 17:45:46 -0500635void ANGLETest::setDebugEnabled(bool enabled)
636{
637 mEGLWindow->setDebugEnabled(enabled);
638}
639
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500640void ANGLETest::setNoErrorEnabled(bool enabled)
641{
642 mEGLWindow->setNoErrorEnabled(enabled);
643}
644
Geoff Lang8a079e52013-10-18 16:13:33 -0400645int ANGLETest::getClientVersion() const
646{
Geoff Lang5ade8452015-09-02 11:00:30 -0400647 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400648}
649
Vincent Lang25ab4512016-05-13 18:13:59 +0200650int ANGLETest::getClientMinorVersion() const
651{
652 return mEGLWindow->getClientMinorVersion();
653}
654
Geoff Langb9266272015-01-29 13:25:14 +0000655EGLWindow *ANGLETest::getEGLWindow() const
656{
657 return mEGLWindow;
658}
659
Geoff Lang8a079e52013-10-18 16:13:33 -0400660int ANGLETest::getWindowWidth() const
661{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400662 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400663}
664
665int ANGLETest::getWindowHeight() const
666{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400667 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400668}
669
Geoff Langefc551f2013-10-31 10:20:28 -0400670bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400671{
Jamie Madill62af5462014-08-26 13:16:37 -0400672 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400673}
674
675bool ANGLETest::createEGLContext()
676{
Jamie Madill62af5462014-08-26 13:16:37 -0400677 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400678}
679
680bool ANGLETest::destroyEGLContext()
681{
Jamie Madill62af5462014-08-26 13:16:37 -0400682 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400683 return true;
684}
Geoff Langbb134672013-10-23 13:06:46 -0400685
Geoff Lang0d3683c2014-10-23 11:08:16 -0400686bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400687{
688 mOSWindow = CreateOSWindow();
689 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
690 {
691 return false;
692 }
693
Geoff Lang0d3683c2014-10-23 11:08:16 -0400694 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400695
696 return true;
697}
698
Geoff Lang0d3683c2014-10-23 11:08:16 -0400699bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400700{
701 if (mOSWindow)
702 {
703 mOSWindow->destroy();
704 delete mOSWindow;
705 mOSWindow = NULL;
706 }
707
708 return true;
709}
710
Geoff Lang0d3683c2014-10-23 11:08:16 -0400711void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400712{
Jamie Madill4119ed32014-10-01 10:41:40 -0400713 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400714}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400715
Jamie Madill518b9fa2016-03-02 11:26:02 -0500716bool IsIntel()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500717{
718 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
719 return (rendererString.find("Intel") != std::string::npos);
720}
721
Yuly Novikovd3647802016-06-16 15:58:35 -0400722bool IsAdreno()
723{
724 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
725 return (rendererString.find("Adreno") != std::string::npos);
726}
727
Jamie Madill518b9fa2016-03-02 11:26:02 -0500728bool IsAMD()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500729{
730 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
731 return (rendererString.find("AMD") != std::string::npos) ||
732 (rendererString.find("ATI") != std::string::npos);
733}
734
Jamie Madill518b9fa2016-03-02 11:26:02 -0500735bool IsNVIDIA()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500736{
737 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
738 return (rendererString.find("NVIDIA") != std::string::npos);
739}
740
Jamie Madill518b9fa2016-03-02 11:26:02 -0500741bool IsD3D11()
Jamie Madilld55d2832015-10-27 13:59:19 -0400742{
743 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
744 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
745}
746
Jamie Madill518b9fa2016-03-02 11:26:02 -0500747bool IsD3D11_FL93()
Jamie Madill9fc36822015-11-18 13:08:07 -0500748{
749 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
750 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
751}
752
Jamie Madill518b9fa2016-03-02 11:26:02 -0500753bool IsD3D9()
Jamie Madill9fc36822015-11-18 13:08:07 -0500754{
755 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
756 return (rendererString.find("Direct3D9") != std::string::npos);
757}
758
Jamie Madill518b9fa2016-03-02 11:26:02 -0500759bool IsD3DSM3()
Jamie Madill9fc36822015-11-18 13:08:07 -0500760{
Jamie Madill518b9fa2016-03-02 11:26:02 -0500761 return IsD3D9() || IsD3D11_FL93();
Jamie Madill9fc36822015-11-18 13:08:07 -0500762}
763
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400764bool IsDesktopOpenGL()
765{
766 return IsOpenGL() && !IsOpenGLES();
767}
768
769bool IsOpenGLES()
770{
771 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
772 return (rendererString.find("OpenGL ES") != std::string::npos);
773}
774
775bool IsOpenGL()
776{
777 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
778 return (rendererString.find("OpenGL") != std::string::npos);
779}
780
Yuly Novikovd3647802016-06-16 15:58:35 -0400781bool IsAndroid()
782{
783#if defined(ANGLE_PLATFORM_ANDROID)
784 return true;
785#else
786 return false;
787#endif
788}
789
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400790bool IsLinux()
791{
792#if defined(ANGLE_PLATFORM_LINUX)
793 return true;
794#else
795 return false;
796#endif
797}
798
Jamie Madill518b9fa2016-03-02 11:26:02 -0500799bool IsOSX()
Ian Ewell292f0052016-02-04 10:37:32 -0500800{
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400801#if defined(ANGLE_PLATFORM_APPLE)
Ian Ewell292f0052016-02-04 10:37:32 -0500802 return true;
803#else
804 return false;
805#endif
806}
807
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400808bool IsWindows()
Jamie Madill518b9fa2016-03-02 11:26:02 -0500809{
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400810#if defined(ANGLE_PLATFORM_WINDOWS)
811 return true;
812#else
813 return false;
814#endif
Olli Etuaho87fc71c2016-05-11 14:25:21 +0300815}
816
Jamie Madillc3b9b262015-01-30 14:00:51 -0500817EGLint ANGLETest::getPlatformRenderer() const
818{
Jamie Madillf6859912015-01-30 17:05:35 -0500819 assert(mEGLWindow);
820 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500821}
822
Austin Kinrossd544cc92016-01-11 15:26:42 -0800823void ANGLETest::ignoreD3D11SDKLayersWarnings()
824{
825 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
826 mIgnoreD3D11SDKLayersWarnings = true;
827}
828
Geoff Lang0d3683c2014-10-23 11:08:16 -0400829OSWindow *ANGLETest::mOSWindow = NULL;
830
831void ANGLETestEnvironment::SetUp()
832{
Jamie Madill776a75b2016-05-17 13:43:17 -0400833 mGLESLibrary.reset(angle::loadLibrary("libGLESv2"));
834 if (mGLESLibrary)
835 {
836 auto initFunc = reinterpret_cast<ANGLEPlatformInitializeFunc>(
837 mGLESLibrary->getSymbol("ANGLEPlatformInitialize"));
838 if (initFunc)
839 {
840 initFunc(&angle::g_testPlatformInstance);
841 }
842 }
843
Geoff Lang0d3683c2014-10-23 11:08:16 -0400844 if (!ANGLETest::InitTestWindow())
845 {
846 FAIL() << "Failed to create ANGLE test window.";
847 }
848}
849
850void ANGLETestEnvironment::TearDown()
851{
852 ANGLETest::DestroyTestWindow();
Jamie Madill776a75b2016-05-17 13:43:17 -0400853
854 if (mGLESLibrary)
855 {
856 auto shutdownFunc = reinterpret_cast<ANGLEPlatformShutdownFunc>(
857 mGLESLibrary->getSymbol("ANGLEPlatformShutdown"));
858 if (shutdownFunc)
859 {
860 shutdownFunc();
861 }
862 }
863}
864
865void IgnoreANGLEPlatformMessages()
866{
867 // Negative tests may trigger expected errors/warnings in the ANGLE Platform.
868 angle::g_testPlatformInstance.ignoreMessages();
Geoff Lang0d3683c2014-10-23 11:08:16 -0400869}