blob: 7bec1e15f53454b3c6b1375270ed21ff4fadbc61 [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
Geoff Lang97073d12016-04-20 10:42:34 -070024const GLColor GLColor::black = GLColor(0u, 0u, 0u, 255u);
25const 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::transparentBlack = GLColor(0u, 0u, 0u, 0u);
30const GLColor GLColor::white = GLColor(255u, 255u, 255u, 255u);
31const GLColor GLColor::yellow = GLColor(255u, 255u, 0, 255u);
Olli Etuahoa314b612016-03-10 16:43:00 +020032
Vincent Lang25ab4512016-05-13 18:13:59 +020033const GLColor16 GLColor16::white = GLColor16(65535u, 65535u, 65535u, 65535u);
34
Jamie Madill1fbc59f2016-02-24 15:25:51 -050035namespace
36{
37float ColorNorm(GLubyte channelValue)
38{
39 return static_cast<float>(channelValue) / 255.0f;
40}
Jamie Madill776a75b2016-05-17 13:43:17 -040041
Jamie Madillec0b5802016-07-04 13:11:59 -040042GLubyte ColorDenorm(float colorValue)
43{
44 return static_cast<GLubyte>(colorValue * 255.0f);
45}
46
Jamie Madill776a75b2016-05-17 13:43:17 -040047// Use a custom ANGLE platform class to capture and report internal errors.
48class TestPlatform : public angle::Platform
49{
50 public:
51 TestPlatform() : mIgnoreMessages(false) {}
52
53 void logError(const char *errorMessage) override;
54 void logWarning(const char *warningMessage) override;
55 void logInfo(const char *infoMessage) override;
56
57 void ignoreMessages();
58 void enableMessages();
59
60 private:
61 bool mIgnoreMessages;
62};
63
64void TestPlatform::logError(const char *errorMessage)
65{
66 if (mIgnoreMessages)
67 return;
68
69 FAIL() << errorMessage;
70}
71
72void TestPlatform::logWarning(const char *warningMessage)
73{
74 if (mIgnoreMessages)
75 return;
76
77 std::cerr << "Warning: " << warningMessage << std::endl;
78}
79
80void TestPlatform::logInfo(const char *infoMessage)
81{
82 if (mIgnoreMessages)
83 return;
84
85 angle::WriteDebugMessage("%s\n", infoMessage);
86}
87
88void TestPlatform::ignoreMessages()
89{
90 mIgnoreMessages = true;
91}
92
93void TestPlatform::enableMessages()
94{
95 mIgnoreMessages = false;
96}
97
98TestPlatform g_testPlatformInstance;
Jamie Madillec0b5802016-07-04 13:11:59 -040099
100std::array<Vector3, 4> GetIndexedQuadVertices()
101{
102 std::array<Vector3, 4> vertices;
103 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
104 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
105 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
106 vertices[3] = Vector3(1.0f, 1.0f, 0.5f);
107 return vertices;
108}
109
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500110} // anonymous namespace
111
Jamie Madill9fc7b4c2016-06-08 15:30:14 -0700112GLColorRGB::GLColorRGB() : R(0), G(0), B(0)
113{
114}
115
116GLColorRGB::GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b)
117{
118}
119
Jamie Madillec0b5802016-07-04 13:11:59 -0400120GLColorRGB::GLColorRGB(const Vector3 &floatColor)
121 : R(ColorDenorm(floatColor.x)), G(ColorDenorm(floatColor.y)), B(ColorDenorm(floatColor.z))
122{
123}
124
Jamie Madill0dfa8072016-01-22 15:27:21 -0500125GLColor::GLColor() : R(0), G(0), B(0), A(0)
126{
127}
128
129GLColor::GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a)
130{
131}
132
Jamie Madillec0b5802016-07-04 13:11:59 -0400133GLColor::GLColor(const Vector4 &floatColor)
134 : R(ColorDenorm(floatColor.x)),
135 G(ColorDenorm(floatColor.y)),
136 B(ColorDenorm(floatColor.z)),
137 A(ColorDenorm(floatColor.w))
138{
139}
140
141GLColor::GLColor(const GLColor16 &color16)
142 : R(static_cast<GLubyte>(color16.R)),
143 G(static_cast<GLubyte>(color16.G)),
144 B(static_cast<GLubyte>(color16.B)),
145 A(static_cast<GLubyte>(color16.A))
146{
147}
148
Jamie Madille2509a32016-02-01 14:09:05 -0500149GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
150{
151 memcpy(&R, &colorValue, sizeof(GLuint));
152}
153
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500154Vector4 GLColor::toNormalizedVector() const
155{
156 return Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
157}
158
Jamie Madill0dfa8072016-01-22 15:27:21 -0500159GLColor ReadColor(GLint x, GLint y)
160{
161 GLColor actual;
162 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
163 EXPECT_GL_NO_ERROR();
164 return actual;
165}
166
167bool operator==(const GLColor &a, const GLColor &b)
168{
169 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
170}
171
172std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
173{
174 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
175 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
176 << ", " << static_cast<unsigned int>(color.A) << ")";
177 return ostream;
178}
179
Vincent Lang25ab4512016-05-13 18:13:59 +0200180GLColor16::GLColor16() : R(0), G(0), B(0), A(0)
181{
182}
183
184GLColor16::GLColor16(GLushort r, GLushort g, GLushort b, GLushort a) : R(r), G(g), B(b), A(a)
185{
186}
187
188GLColor16 ReadColor16(GLint x, GLint y)
189{
190 GLColor16 actual;
191 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, &actual.R);
192 EXPECT_GL_NO_ERROR();
193 return actual;
194}
195
196bool operator==(const GLColor16 &a, const GLColor16 &b)
197{
198 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
199}
200
201std::ostream &operator<<(std::ostream &ostream, const GLColor16 &color)
202{
203 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
204 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
205 << ", " << static_cast<unsigned int>(color.A) << ")";
206 return ostream;
207}
208
Jamie Madill0dfa8072016-01-22 15:27:21 -0500209} // namespace angle
210
Jamie Madillec0b5802016-07-04 13:11:59 -0400211// static
212std::array<Vector3, 6> ANGLETest::GetQuadVertices()
213{
214 std::array<Vector3, 6> vertices;
215 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
216 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
217 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
218 vertices[3] = Vector3(-1.0f, 1.0f, 0.5f);
219 vertices[4] = Vector3(1.0f, -1.0f, 0.5f);
220 vertices[5] = Vector3(1.0f, 1.0f, 0.5f);
221 return vertices;
222}
223
Jamie Madillfa05f602015-05-07 13:47:11 -0400224ANGLETest::ANGLETest()
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400225 : mEGLWindow(nullptr),
226 mWidth(16),
227 mHeight(16),
228 mIgnoreD3D11SDKLayersWarnings(false),
229 mQuadVertexBuffer(0)
Geoff Lang8a079e52013-10-18 16:13:33 -0400230{
Geoff Lang5ade8452015-09-02 11:00:30 -0400231 mEGLWindow =
232 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -0400233}
234
235ANGLETest::~ANGLETest()
236{
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400237 if (mQuadVertexBuffer)
238 {
239 glDeleteBuffers(1, &mQuadVertexBuffer);
240 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400241 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400242}
243
Geoff Lang8a079e52013-10-18 16:13:33 -0400244void ANGLETest::SetUp()
245{
Jamie Madill776a75b2016-05-17 13:43:17 -0400246 angle::g_testPlatformInstance.enableMessages();
247
Corentin Wallezb44440d2015-07-22 17:54:20 -0400248 // Resize the window before creating the context so that the first make current
249 // sets the viewport and scissor box to the right size.
250 bool needSwap = false;
251 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +0000252 {
Corentin Wallezb44440d2015-07-22 17:54:20 -0400253 if (!mOSWindow->resize(mWidth, mHeight))
254 {
255 FAIL() << "Failed to resize ANGLE test window.";
256 }
257 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +0000258 }
259
Geoff Lang8a079e52013-10-18 16:13:33 -0400260 if (!createEGLContext())
261 {
262 FAIL() << "egl context creation failed.";
263 }
Corentin Wallezb828b322015-07-16 17:51:30 -0400264
Corentin Wallezb44440d2015-07-22 17:54:20 -0400265 if (needSwap)
266 {
267 // Swap the buffers so that the default framebuffer picks up the resize
268 // which will allow follow-up test code to assume the framebuffer covers
269 // the whole window.
270 swapBuffers();
271 }
Corentin Wallez096725b2015-07-20 16:58:57 -0400272
Geoff Lang7f8dc492015-07-23 21:29:33 +0000273 // This Viewport command is not strictly necessary but we add it so that programs
274 // taking OpenGL traces can guess the size of the default framebuffer and show it
275 // in their UIs
276 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -0500277
278 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
279 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -0400280}
281
282void ANGLETest::TearDown()
283{
Austin Kinrossd544cc92016-01-11 15:26:42 -0800284 checkD3D11SDKLayersMessages();
285
Jamie Madill508a5b72015-12-08 11:26:14 -0500286 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
287 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
288
Geoff Lang8a079e52013-10-18 16:13:33 -0400289 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -0400290 mOSWindow->messageLoop();
291
Geoff Lang8a079e52013-10-18 16:13:33 -0400292 if (!destroyEGLContext())
293 {
294 FAIL() << "egl context destruction failed.";
295 }
Jamie Madill8add0eb2014-08-26 13:16:35 -0400296
297 // Check for quit message
298 Event myEvent;
299 while (mOSWindow->popEvent(&myEvent))
300 {
301 if (myEvent.Type == Event::EVENT_CLOSED)
302 {
303 exit(0);
304 }
305 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400306}
307
308void ANGLETest::swapBuffers()
309{
Jamie Madill77a72f62015-04-14 11:18:32 -0400310 if (mEGLWindow->isGLInitialized())
311 {
312 mEGLWindow->swap();
313 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400314}
315
Jamie Madill52b09c22016-04-11 14:12:31 -0400316void ANGLETest::setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
317{
318 if (mQuadVertexBuffer == 0)
319 {
320 glGenBuffers(1, &mQuadVertexBuffer);
321 }
322
323 auto quadVertices = GetQuadVertices();
324 for (Vector3 &vertex : quadVertices)
325 {
326 vertex.x *= positionAttribXYScale;
327 vertex.y *= positionAttribXYScale;
328 vertex.z = positionAttribZ;
329 }
330
331 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
332 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
333}
334
Jamie Madillec0b5802016-07-04 13:11:59 -0400335void ANGLETest::setupIndexedQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
336{
337 if (mQuadVertexBuffer == 0)
338 {
339 glGenBuffers(1, &mQuadVertexBuffer);
340 }
341
342 auto quadVertices = angle::GetIndexedQuadVertices();
343 for (Vector3 &vertex : quadVertices)
344 {
345 vertex.x *= positionAttribXYScale;
346 vertex.y *= positionAttribXYScale;
347 vertex.z = positionAttribZ;
348 }
349
350 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
351 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, quadVertices.data(), GL_STATIC_DRAW);
352}
353
Jamie Madill52b09c22016-04-11 14:12:31 -0400354// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200355void ANGLETest::drawQuad(GLuint program,
356 const std::string &positionAttribName,
357 GLfloat positionAttribZ)
358{
359 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
360}
361
Jamie Madill52b09c22016-04-11 14:12:31 -0400362// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200363void ANGLETest::drawQuad(GLuint program,
364 const std::string &positionAttribName,
365 GLfloat positionAttribZ,
366 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400367{
Jamie Madill52b09c22016-04-11 14:12:31 -0400368 drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
369}
370
371void ANGLETest::drawQuad(GLuint program,
372 const std::string &positionAttribName,
373 GLfloat positionAttribZ,
374 GLfloat positionAttribXYScale,
375 bool useVertexBuffer)
376{
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200377 GLint previousProgram = 0;
378 glGetIntegerv(GL_CURRENT_PROGRAM, &previousProgram);
379 if (previousProgram != static_cast<GLint>(program))
380 {
381 glUseProgram(program);
382 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400383
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200384 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
Geoff Lang8a079e52013-10-18 16:13:33 -0400385
Jamie Madill52b09c22016-04-11 14:12:31 -0400386 if (useVertexBuffer)
387 {
388 setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
389 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
390 glBindBuffer(GL_ARRAY_BUFFER, 0);
391 }
392 else
393 {
394 auto quadVertices = GetQuadVertices();
395 for (Vector3 &vertex : quadVertices)
396 {
397 vertex.x *= positionAttribXYScale;
398 vertex.y *= positionAttribXYScale;
399 vertex.z = positionAttribZ;
400 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400401
Jamie Madill52b09c22016-04-11 14:12:31 -0400402 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
403 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400404 glEnableVertexAttribArray(positionLocation);
405
406 glDrawArrays(GL_TRIANGLES, 0, 6);
407
408 glDisableVertexAttribArray(positionLocation);
409 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
410
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200411 if (previousProgram != static_cast<GLint>(program))
412 {
413 glUseProgram(previousProgram);
414 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400415}
416
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400417void ANGLETest::drawIndexedQuad(GLuint program,
418 const std::string &positionAttribName,
419 GLfloat positionAttribZ)
420{
421 drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
422}
423
424void ANGLETest::drawIndexedQuad(GLuint program,
425 const std::string &positionAttribName,
426 GLfloat positionAttribZ,
427 GLfloat positionAttribXYScale)
428{
429 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
430
Jamie Madill52b09c22016-04-11 14:12:31 -0400431 GLint activeProgram = 0;
432 glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
433 if (static_cast<GLuint>(activeProgram) != program)
434 {
435 glUseProgram(program);
436 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400437
438 GLuint prevBinding = 0;
439 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevBinding));
440
Jamie Madillec0b5802016-07-04 13:11:59 -0400441 setupIndexedQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400442
443 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
444 glEnableVertexAttribArray(positionLocation);
445 glBindBuffer(GL_ARRAY_BUFFER, prevBinding);
446
447 const GLushort indices[] = {
448 0, 1, 2, 0, 2, 3,
449 };
450
451 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
452
453 glDisableVertexAttribArray(positionLocation);
454 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
455
Jamie Madill52b09c22016-04-11 14:12:31 -0400456 if (static_cast<GLuint>(activeProgram) != program)
457 {
458 glUseProgram(static_cast<GLuint>(activeProgram));
459 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400460}
461
Geoff Langefc551f2013-10-31 10:20:28 -0400462GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
463{
464 GLuint shader = glCreateShader(type);
465
466 const char *sourceArray[1] = { source.c_str() };
467 glShaderSource(shader, 1, sourceArray, NULL);
468 glCompileShader(shader);
469
470 GLint compileResult;
471 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
472
473 if (compileResult == 0)
474 {
475 GLint infoLogLength;
476 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
477
Jamie Madilld2c52e32015-10-14 17:07:05 -0400478 if (infoLogLength == 0)
479 {
480 std::cerr << "shader compilation failed with empty log." << std::endl;
481 }
482 else
483 {
484 std::vector<GLchar> infoLog(infoLogLength);
485 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400486
Jamie Madilld2c52e32015-10-14 17:07:05 -0400487 std::cerr << "shader compilation failed: " << &infoLog[0];
488 }
Geoff Langefc551f2013-10-31 10:20:28 -0400489
490 glDeleteShader(shader);
491 shader = 0;
492 }
493
494 return shader;
495}
496
Austin Kinrossd544cc92016-01-11 15:26:42 -0800497void ANGLETest::checkD3D11SDKLayersMessages()
498{
499#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
500 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
501 // were outputted by the test
502 if (mIgnoreD3D11SDKLayersWarnings ||
503 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
504 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
505 {
506 return;
507 }
508
509 const char *extensionString =
510 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
511 if (!strstr(extensionString, "EGL_EXT_device_query"))
512 {
513 return;
514 }
515
516 EGLAttrib device = 0;
517 EGLAttrib angleDevice = 0;
518
519 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
520 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
521
522 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
523 eglGetProcAddress("eglQueryDisplayAttribEXT"));
524 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
525 eglGetProcAddress("eglQueryDeviceAttribEXT"));
526 ASSERT_NE(nullptr, queryDisplayAttribEXT);
527 ASSERT_NE(nullptr, queryDeviceAttribEXT);
528
529 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
530 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
531 EGL_D3D11_DEVICE_ANGLE, &device));
532 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
533
534 ID3D11InfoQueue *infoQueue = nullptr;
535 HRESULT hr =
536 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
537 if (SUCCEEDED(hr))
538 {
539 UINT64 numStoredD3DDebugMessages =
540 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
541
542 if (numStoredD3DDebugMessages > 0)
543 {
544 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
545 {
546 SIZE_T messageLength = 0;
547 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
548
549 if (SUCCEEDED(hr))
550 {
551 D3D11_MESSAGE *pMessage =
552 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
553 infoQueue->GetMessage(i, pMessage, &messageLength);
554
555 std::cout << "Message " << i << ":"
556 << " " << pMessage->pDescription << "\n";
557 free(pMessage);
558 }
559 }
560
561 FAIL() << numStoredD3DDebugMessages
562 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
563 }
564 }
565
566 SafeRelease(infoQueue);
567#endif
568}
569
Geoff Lang63046e22015-07-21 12:43:50 -0400570static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
571{
572 return strstr(allExtensions, extName.c_str()) != nullptr;
573}
574
Geoff Lang8a079e52013-10-18 16:13:33 -0400575bool ANGLETest::extensionEnabled(const std::string &extName)
576{
Geoff Lang63046e22015-07-21 12:43:50 -0400577 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
578 extName);
579}
580
581bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
582{
583 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
584}
585
586bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
587{
588 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400589}
590
Geoff Lang8a079e52013-10-18 16:13:33 -0400591void ANGLETest::setWindowWidth(int width)
592{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400593 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400594}
595
596void ANGLETest::setWindowHeight(int height)
597{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400598 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400599}
600
Geoff Langefc551f2013-10-31 10:20:28 -0400601void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400602{
Jamie Madill62af5462014-08-26 13:16:37 -0400603 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400604}
605
Geoff Langefc551f2013-10-31 10:20:28 -0400606void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400607{
Jamie Madill62af5462014-08-26 13:16:37 -0400608 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400609}
610
Geoff Langefc551f2013-10-31 10:20:28 -0400611void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400612{
Jamie Madill62af5462014-08-26 13:16:37 -0400613 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400614}
615
Geoff Langefc551f2013-10-31 10:20:28 -0400616void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400617{
Jamie Madill62af5462014-08-26 13:16:37 -0400618 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400619}
620
Geoff Langefc551f2013-10-31 10:20:28 -0400621void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400622{
Jamie Madill62af5462014-08-26 13:16:37 -0400623 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400624}
625
Geoff Langefc551f2013-10-31 10:20:28 -0400626void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400627{
Jamie Madill62af5462014-08-26 13:16:37 -0400628 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400629}
630
631void ANGLETest::setMultisampleEnabled(bool enabled)
632{
Jamie Madill62af5462014-08-26 13:16:37 -0400633 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400634}
635
Geoff Lang70d0f492015-12-10 17:45:46 -0500636void ANGLETest::setDebugEnabled(bool enabled)
637{
638 mEGLWindow->setDebugEnabled(enabled);
639}
640
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500641void ANGLETest::setNoErrorEnabled(bool enabled)
642{
643 mEGLWindow->setNoErrorEnabled(enabled);
644}
645
Geoff Langc287ea62016-09-16 14:46:51 -0400646void ANGLETest::setWebGLCompatibilityEnabled(bool webglCompatibility)
647{
648 mEGLWindow->setWebGLCompatibilityEnabled(webglCompatibility);
649}
650
Martin Radev1be913c2016-07-11 17:59:16 +0300651int ANGLETest::getClientMajorVersion() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400652{
Geoff Lang5ade8452015-09-02 11:00:30 -0400653 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400654}
655
Vincent Lang25ab4512016-05-13 18:13:59 +0200656int ANGLETest::getClientMinorVersion() const
657{
658 return mEGLWindow->getClientMinorVersion();
659}
660
Geoff Langb9266272015-01-29 13:25:14 +0000661EGLWindow *ANGLETest::getEGLWindow() const
662{
663 return mEGLWindow;
664}
665
Geoff Lang8a079e52013-10-18 16:13:33 -0400666int ANGLETest::getWindowWidth() const
667{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400668 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400669}
670
671int ANGLETest::getWindowHeight() const
672{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400673 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400674}
675
Geoff Langefc551f2013-10-31 10:20:28 -0400676bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400677{
Jamie Madill62af5462014-08-26 13:16:37 -0400678 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400679}
680
681bool ANGLETest::createEGLContext()
682{
Jamie Madill62af5462014-08-26 13:16:37 -0400683 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400684}
685
686bool ANGLETest::destroyEGLContext()
687{
Jamie Madill62af5462014-08-26 13:16:37 -0400688 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400689 return true;
690}
Geoff Langbb134672013-10-23 13:06:46 -0400691
Geoff Lang0d3683c2014-10-23 11:08:16 -0400692bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400693{
694 mOSWindow = CreateOSWindow();
695 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
696 {
697 return false;
698 }
699
Geoff Lang0d3683c2014-10-23 11:08:16 -0400700 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400701
702 return true;
703}
704
Geoff Lang0d3683c2014-10-23 11:08:16 -0400705bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400706{
707 if (mOSWindow)
708 {
709 mOSWindow->destroy();
710 delete mOSWindow;
711 mOSWindow = NULL;
712 }
713
714 return true;
715}
716
Geoff Lang0d3683c2014-10-23 11:08:16 -0400717void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400718{
Jamie Madill4119ed32014-10-01 10:41:40 -0400719 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400720}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400721
Jamie Madill518b9fa2016-03-02 11:26:02 -0500722bool IsIntel()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500723{
724 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
725 return (rendererString.find("Intel") != std::string::npos);
726}
727
Yuly Novikovd3647802016-06-16 15:58:35 -0400728bool IsAdreno()
729{
730 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
731 return (rendererString.find("Adreno") != std::string::npos);
732}
733
Jamie Madill518b9fa2016-03-02 11:26:02 -0500734bool IsAMD()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500735{
736 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
737 return (rendererString.find("AMD") != std::string::npos) ||
738 (rendererString.find("ATI") != std::string::npos);
739}
740
Jamie Madill518b9fa2016-03-02 11:26:02 -0500741bool IsNVIDIA()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500742{
743 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
744 return (rendererString.find("NVIDIA") != std::string::npos);
745}
746
Jamie Madill518b9fa2016-03-02 11:26:02 -0500747bool IsD3D11()
Jamie Madilld55d2832015-10-27 13:59:19 -0400748{
749 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
750 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
751}
752
Jamie Madill518b9fa2016-03-02 11:26:02 -0500753bool IsD3D11_FL93()
Jamie Madill9fc36822015-11-18 13:08:07 -0500754{
755 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
756 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
757}
758
Jamie Madill518b9fa2016-03-02 11:26:02 -0500759bool IsD3D9()
Jamie Madill9fc36822015-11-18 13:08:07 -0500760{
761 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
762 return (rendererString.find("Direct3D9") != std::string::npos);
763}
764
Jamie Madill518b9fa2016-03-02 11:26:02 -0500765bool IsD3DSM3()
Jamie Madill9fc36822015-11-18 13:08:07 -0500766{
Jamie Madill518b9fa2016-03-02 11:26:02 -0500767 return IsD3D9() || IsD3D11_FL93();
Jamie Madill9fc36822015-11-18 13:08:07 -0500768}
769
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400770bool IsDesktopOpenGL()
771{
772 return IsOpenGL() && !IsOpenGLES();
773}
774
775bool IsOpenGLES()
776{
777 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
778 return (rendererString.find("OpenGL ES") != std::string::npos);
779}
780
781bool IsOpenGL()
782{
783 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
784 return (rendererString.find("OpenGL") != std::string::npos);
785}
786
Yuly Novikovd3647802016-06-16 15:58:35 -0400787bool IsAndroid()
788{
789#if defined(ANGLE_PLATFORM_ANDROID)
790 return true;
791#else
792 return false;
793#endif
794}
795
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400796bool IsLinux()
797{
798#if defined(ANGLE_PLATFORM_LINUX)
799 return true;
800#else
801 return false;
802#endif
803}
804
Jamie Madill518b9fa2016-03-02 11:26:02 -0500805bool IsOSX()
Ian Ewell292f0052016-02-04 10:37:32 -0500806{
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400807#if defined(ANGLE_PLATFORM_APPLE)
Ian Ewell292f0052016-02-04 10:37:32 -0500808 return true;
809#else
810 return false;
811#endif
812}
813
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400814bool IsWindows()
Jamie Madill518b9fa2016-03-02 11:26:02 -0500815{
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400816#if defined(ANGLE_PLATFORM_WINDOWS)
817 return true;
818#else
819 return false;
820#endif
Olli Etuaho87fc71c2016-05-11 14:25:21 +0300821}
822
Jamie Madillc3b9b262015-01-30 14:00:51 -0500823EGLint ANGLETest::getPlatformRenderer() const
824{
Jamie Madillf6859912015-01-30 17:05:35 -0500825 assert(mEGLWindow);
826 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500827}
828
Austin Kinrossd544cc92016-01-11 15:26:42 -0800829void ANGLETest::ignoreD3D11SDKLayersWarnings()
830{
831 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
832 mIgnoreD3D11SDKLayersWarnings = true;
833}
834
Geoff Lang0d3683c2014-10-23 11:08:16 -0400835OSWindow *ANGLETest::mOSWindow = NULL;
836
837void ANGLETestEnvironment::SetUp()
838{
Jamie Madill776a75b2016-05-17 13:43:17 -0400839 mGLESLibrary.reset(angle::loadLibrary("libGLESv2"));
840 if (mGLESLibrary)
841 {
842 auto initFunc = reinterpret_cast<ANGLEPlatformInitializeFunc>(
843 mGLESLibrary->getSymbol("ANGLEPlatformInitialize"));
844 if (initFunc)
845 {
846 initFunc(&angle::g_testPlatformInstance);
847 }
848 }
849
Geoff Lang0d3683c2014-10-23 11:08:16 -0400850 if (!ANGLETest::InitTestWindow())
851 {
852 FAIL() << "Failed to create ANGLE test window.";
853 }
854}
855
856void ANGLETestEnvironment::TearDown()
857{
858 ANGLETest::DestroyTestWindow();
Jamie Madill776a75b2016-05-17 13:43:17 -0400859
860 if (mGLESLibrary)
861 {
862 auto shutdownFunc = reinterpret_cast<ANGLEPlatformShutdownFunc>(
863 mGLESLibrary->getSymbol("ANGLEPlatformShutdown"));
864 if (shutdownFunc)
865 {
866 shutdownFunc();
867 }
868 }
869}
870
871void IgnoreANGLEPlatformMessages()
872{
873 // Negative tests may trigger expected errors/warnings in the ANGLE Platform.
874 angle::g_testPlatformInstance.ignoreMessages();
Geoff Lang0d3683c2014-10-23 11:08:16 -0400875}