blob: d99c25ed0844fb91827547a28d6e614c125e4706 [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
Jamie Madill1fbc59f2016-02-24 15:25:51 -050033namespace
34{
35float ColorNorm(GLubyte channelValue)
36{
37 return static_cast<float>(channelValue) / 255.0f;
38}
Jamie Madill776a75b2016-05-17 13:43:17 -040039
Jamie Madillec0b5802016-07-04 13:11:59 -040040GLubyte ColorDenorm(float colorValue)
41{
42 return static_cast<GLubyte>(colorValue * 255.0f);
43}
44
Jamie Madill776a75b2016-05-17 13:43:17 -040045// Use a custom ANGLE platform class to capture and report internal errors.
46class TestPlatform : public angle::Platform
47{
48 public:
49 TestPlatform() : mIgnoreMessages(false) {}
50
51 void logError(const char *errorMessage) override;
52 void logWarning(const char *warningMessage) override;
53 void logInfo(const char *infoMessage) override;
54
55 void ignoreMessages();
56 void enableMessages();
57
58 private:
59 bool mIgnoreMessages;
60};
61
62void TestPlatform::logError(const char *errorMessage)
63{
64 if (mIgnoreMessages)
65 return;
66
67 FAIL() << errorMessage;
68}
69
70void TestPlatform::logWarning(const char *warningMessage)
71{
72 if (mIgnoreMessages)
73 return;
74
75 std::cerr << "Warning: " << warningMessage << std::endl;
76}
77
78void TestPlatform::logInfo(const char *infoMessage)
79{
80 if (mIgnoreMessages)
81 return;
82
83 angle::WriteDebugMessage("%s\n", infoMessage);
84}
85
86void TestPlatform::ignoreMessages()
87{
88 mIgnoreMessages = true;
89}
90
91void TestPlatform::enableMessages()
92{
93 mIgnoreMessages = false;
94}
95
96TestPlatform g_testPlatformInstance;
Jamie Madillec0b5802016-07-04 13:11:59 -040097
98std::array<Vector3, 4> GetIndexedQuadVertices()
99{
100 std::array<Vector3, 4> vertices;
101 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
102 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
103 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
104 vertices[3] = Vector3(1.0f, 1.0f, 0.5f);
105 return vertices;
106}
107
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500108} // anonymous namespace
109
Jamie Madill9fc7b4c2016-06-08 15:30:14 -0700110GLColorRGB::GLColorRGB() : R(0), G(0), B(0)
111{
112}
113
114GLColorRGB::GLColorRGB(GLubyte r, GLubyte g, GLubyte b) : R(r), G(g), B(b)
115{
116}
117
Jamie Madillec0b5802016-07-04 13:11:59 -0400118GLColorRGB::GLColorRGB(const Vector3 &floatColor)
119 : R(ColorDenorm(floatColor.x)), G(ColorDenorm(floatColor.y)), B(ColorDenorm(floatColor.z))
120{
121}
122
Jamie Madill0dfa8072016-01-22 15:27:21 -0500123GLColor::GLColor() : R(0), G(0), B(0), A(0)
124{
125}
126
127GLColor::GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a)
128{
129}
130
Jamie Madillec0b5802016-07-04 13:11:59 -0400131GLColor::GLColor(const Vector4 &floatColor)
132 : R(ColorDenorm(floatColor.x)),
133 G(ColorDenorm(floatColor.y)),
134 B(ColorDenorm(floatColor.z)),
135 A(ColorDenorm(floatColor.w))
136{
137}
138
Jamie Madille2509a32016-02-01 14:09:05 -0500139GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
140{
141 memcpy(&R, &colorValue, sizeof(GLuint));
142}
143
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500144Vector4 GLColor::toNormalizedVector() const
145{
146 return Vector4(ColorNorm(R), ColorNorm(G), ColorNorm(B), ColorNorm(A));
147}
148
Jamie Madill0dfa8072016-01-22 15:27:21 -0500149GLColor ReadColor(GLint x, GLint y)
150{
151 GLColor actual;
152 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
153 EXPECT_GL_NO_ERROR();
154 return actual;
155}
156
157bool operator==(const GLColor &a, const GLColor &b)
158{
159 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
160}
161
162std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
163{
164 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
165 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
166 << ", " << static_cast<unsigned int>(color.A) << ")";
167 return ostream;
168}
169
170} // namespace angle
171
Jamie Madillec0b5802016-07-04 13:11:59 -0400172// static
173std::array<Vector3, 6> ANGLETest::GetQuadVertices()
174{
175 std::array<Vector3, 6> vertices;
176 vertices[0] = Vector3(-1.0f, 1.0f, 0.5f);
177 vertices[1] = Vector3(-1.0f, -1.0f, 0.5f);
178 vertices[2] = Vector3(1.0f, -1.0f, 0.5f);
179 vertices[3] = Vector3(-1.0f, 1.0f, 0.5f);
180 vertices[4] = Vector3(1.0f, -1.0f, 0.5f);
181 vertices[5] = Vector3(1.0f, 1.0f, 0.5f);
182 return vertices;
183}
184
Jamie Madillfa05f602015-05-07 13:47:11 -0400185ANGLETest::ANGLETest()
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400186 : mEGLWindow(nullptr),
187 mWidth(16),
188 mHeight(16),
189 mIgnoreD3D11SDKLayersWarnings(false),
190 mQuadVertexBuffer(0)
Geoff Lang8a079e52013-10-18 16:13:33 -0400191{
Geoff Lang5ade8452015-09-02 11:00:30 -0400192 mEGLWindow =
193 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -0400194}
195
196ANGLETest::~ANGLETest()
197{
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400198 if (mQuadVertexBuffer)
199 {
200 glDeleteBuffers(1, &mQuadVertexBuffer);
201 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400202 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400203}
204
Geoff Lang8a079e52013-10-18 16:13:33 -0400205void ANGLETest::SetUp()
206{
Jamie Madill776a75b2016-05-17 13:43:17 -0400207 angle::g_testPlatformInstance.enableMessages();
208
Corentin Wallezb44440d2015-07-22 17:54:20 -0400209 // Resize the window before creating the context so that the first make current
210 // sets the viewport and scissor box to the right size.
211 bool needSwap = false;
212 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +0000213 {
Corentin Wallezb44440d2015-07-22 17:54:20 -0400214 if (!mOSWindow->resize(mWidth, mHeight))
215 {
216 FAIL() << "Failed to resize ANGLE test window.";
217 }
218 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +0000219 }
220
Geoff Lang8a079e52013-10-18 16:13:33 -0400221 if (!createEGLContext())
222 {
223 FAIL() << "egl context creation failed.";
224 }
Corentin Wallezb828b322015-07-16 17:51:30 -0400225
Corentin Wallezb44440d2015-07-22 17:54:20 -0400226 if (needSwap)
227 {
228 // Swap the buffers so that the default framebuffer picks up the resize
229 // which will allow follow-up test code to assume the framebuffer covers
230 // the whole window.
231 swapBuffers();
232 }
Corentin Wallez096725b2015-07-20 16:58:57 -0400233
Geoff Lang7f8dc492015-07-23 21:29:33 +0000234 // This Viewport command is not strictly necessary but we add it so that programs
235 // taking OpenGL traces can guess the size of the default framebuffer and show it
236 // in their UIs
237 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -0500238
239 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
240 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -0400241}
242
243void ANGLETest::TearDown()
244{
Austin Kinrossd544cc92016-01-11 15:26:42 -0800245 checkD3D11SDKLayersMessages();
246
Jamie Madill508a5b72015-12-08 11:26:14 -0500247 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
248 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
249
Geoff Lang8a079e52013-10-18 16:13:33 -0400250 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -0400251 mOSWindow->messageLoop();
252
Geoff Lang8a079e52013-10-18 16:13:33 -0400253 if (!destroyEGLContext())
254 {
255 FAIL() << "egl context destruction failed.";
256 }
Jamie Madill8add0eb2014-08-26 13:16:35 -0400257
258 // Check for quit message
259 Event myEvent;
260 while (mOSWindow->popEvent(&myEvent))
261 {
262 if (myEvent.Type == Event::EVENT_CLOSED)
263 {
264 exit(0);
265 }
266 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400267}
268
269void ANGLETest::swapBuffers()
270{
Jamie Madill77a72f62015-04-14 11:18:32 -0400271 if (mEGLWindow->isGLInitialized())
272 {
273 mEGLWindow->swap();
274 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400275}
276
Jamie Madill52b09c22016-04-11 14:12:31 -0400277void ANGLETest::setupQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
278{
279 if (mQuadVertexBuffer == 0)
280 {
281 glGenBuffers(1, &mQuadVertexBuffer);
282 }
283
284 auto quadVertices = GetQuadVertices();
285 for (Vector3 &vertex : quadVertices)
286 {
287 vertex.x *= positionAttribXYScale;
288 vertex.y *= positionAttribXYScale;
289 vertex.z = positionAttribZ;
290 }
291
292 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
293 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
294}
295
Jamie Madillec0b5802016-07-04 13:11:59 -0400296void ANGLETest::setupIndexedQuadVertexBuffer(GLfloat positionAttribZ, GLfloat positionAttribXYScale)
297{
298 if (mQuadVertexBuffer == 0)
299 {
300 glGenBuffers(1, &mQuadVertexBuffer);
301 }
302
303 auto quadVertices = angle::GetIndexedQuadVertices();
304 for (Vector3 &vertex : quadVertices)
305 {
306 vertex.x *= positionAttribXYScale;
307 vertex.y *= positionAttribXYScale;
308 vertex.z = positionAttribZ;
309 }
310
311 glBindBuffer(GL_ARRAY_BUFFER, mQuadVertexBuffer);
312 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, quadVertices.data(), GL_STATIC_DRAW);
313}
314
Jamie Madill52b09c22016-04-11 14:12:31 -0400315// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200316void ANGLETest::drawQuad(GLuint program,
317 const std::string &positionAttribName,
318 GLfloat positionAttribZ)
319{
320 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
321}
322
Jamie Madill52b09c22016-04-11 14:12:31 -0400323// static
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200324void ANGLETest::drawQuad(GLuint program,
325 const std::string &positionAttribName,
326 GLfloat positionAttribZ,
327 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400328{
Jamie Madill52b09c22016-04-11 14:12:31 -0400329 drawQuad(program, positionAttribName, positionAttribZ, positionAttribXYScale, false);
330}
331
332void ANGLETest::drawQuad(GLuint program,
333 const std::string &positionAttribName,
334 GLfloat positionAttribZ,
335 GLfloat positionAttribXYScale,
336 bool useVertexBuffer)
337{
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200338 GLint previousProgram = 0;
339 glGetIntegerv(GL_CURRENT_PROGRAM, &previousProgram);
340 if (previousProgram != static_cast<GLint>(program))
341 {
342 glUseProgram(program);
343 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400344
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200345 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
Geoff Lang8a079e52013-10-18 16:13:33 -0400346
Jamie Madill52b09c22016-04-11 14:12:31 -0400347 if (useVertexBuffer)
348 {
349 setupQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
350 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
351 glBindBuffer(GL_ARRAY_BUFFER, 0);
352 }
353 else
354 {
355 auto quadVertices = GetQuadVertices();
356 for (Vector3 &vertex : quadVertices)
357 {
358 vertex.x *= positionAttribXYScale;
359 vertex.y *= positionAttribXYScale;
360 vertex.z = positionAttribZ;
361 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400362
Jamie Madill52b09c22016-04-11 14:12:31 -0400363 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
364 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400365 glEnableVertexAttribArray(positionLocation);
366
367 glDrawArrays(GL_TRIANGLES, 0, 6);
368
369 glDisableVertexAttribArray(positionLocation);
370 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
371
Olli Etuahoc3e55a42016-03-09 16:29:18 +0200372 if (previousProgram != static_cast<GLint>(program))
373 {
374 glUseProgram(previousProgram);
375 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400376}
377
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400378void ANGLETest::drawIndexedQuad(GLuint program,
379 const std::string &positionAttribName,
380 GLfloat positionAttribZ)
381{
382 drawIndexedQuad(program, positionAttribName, positionAttribZ, 1.0f);
383}
384
385void ANGLETest::drawIndexedQuad(GLuint program,
386 const std::string &positionAttribName,
387 GLfloat positionAttribZ,
388 GLfloat positionAttribXYScale)
389{
390 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
391
Jamie Madill52b09c22016-04-11 14:12:31 -0400392 GLint activeProgram = 0;
393 glGetIntegerv(GL_CURRENT_PROGRAM, &activeProgram);
394 if (static_cast<GLuint>(activeProgram) != program)
395 {
396 glUseProgram(program);
397 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400398
399 GLuint prevBinding = 0;
400 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, reinterpret_cast<GLint *>(&prevBinding));
401
Jamie Madillec0b5802016-07-04 13:11:59 -0400402 setupIndexedQuadVertexBuffer(positionAttribZ, positionAttribXYScale);
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400403
404 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
405 glEnableVertexAttribArray(positionLocation);
406 glBindBuffer(GL_ARRAY_BUFFER, prevBinding);
407
408 const GLushort indices[] = {
409 0, 1, 2, 0, 2, 3,
410 };
411
412 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
413
414 glDisableVertexAttribArray(positionLocation);
415 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
416
Jamie Madill52b09c22016-04-11 14:12:31 -0400417 if (static_cast<GLuint>(activeProgram) != program)
418 {
419 glUseProgram(static_cast<GLuint>(activeProgram));
420 }
Jamie Madillbc4c4bc2016-03-23 21:04:43 -0400421}
422
Geoff Langefc551f2013-10-31 10:20:28 -0400423GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
424{
425 GLuint shader = glCreateShader(type);
426
427 const char *sourceArray[1] = { source.c_str() };
428 glShaderSource(shader, 1, sourceArray, NULL);
429 glCompileShader(shader);
430
431 GLint compileResult;
432 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
433
434 if (compileResult == 0)
435 {
436 GLint infoLogLength;
437 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
438
Jamie Madilld2c52e32015-10-14 17:07:05 -0400439 if (infoLogLength == 0)
440 {
441 std::cerr << "shader compilation failed with empty log." << std::endl;
442 }
443 else
444 {
445 std::vector<GLchar> infoLog(infoLogLength);
446 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400447
Jamie Madilld2c52e32015-10-14 17:07:05 -0400448 std::cerr << "shader compilation failed: " << &infoLog[0];
449 }
Geoff Langefc551f2013-10-31 10:20:28 -0400450
451 glDeleteShader(shader);
452 shader = 0;
453 }
454
455 return shader;
456}
457
Austin Kinrossd544cc92016-01-11 15:26:42 -0800458void ANGLETest::checkD3D11SDKLayersMessages()
459{
460#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
461 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
462 // were outputted by the test
463 if (mIgnoreD3D11SDKLayersWarnings ||
464 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
465 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
466 {
467 return;
468 }
469
470 const char *extensionString =
471 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
472 if (!strstr(extensionString, "EGL_EXT_device_query"))
473 {
474 return;
475 }
476
477 EGLAttrib device = 0;
478 EGLAttrib angleDevice = 0;
479
480 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
481 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
482
483 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
484 eglGetProcAddress("eglQueryDisplayAttribEXT"));
485 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
486 eglGetProcAddress("eglQueryDeviceAttribEXT"));
487 ASSERT_NE(nullptr, queryDisplayAttribEXT);
488 ASSERT_NE(nullptr, queryDeviceAttribEXT);
489
490 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
491 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
492 EGL_D3D11_DEVICE_ANGLE, &device));
493 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
494
495 ID3D11InfoQueue *infoQueue = nullptr;
496 HRESULT hr =
497 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
498 if (SUCCEEDED(hr))
499 {
500 UINT64 numStoredD3DDebugMessages =
501 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
502
503 if (numStoredD3DDebugMessages > 0)
504 {
505 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
506 {
507 SIZE_T messageLength = 0;
508 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
509
510 if (SUCCEEDED(hr))
511 {
512 D3D11_MESSAGE *pMessage =
513 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
514 infoQueue->GetMessage(i, pMessage, &messageLength);
515
516 std::cout << "Message " << i << ":"
517 << " " << pMessage->pDescription << "\n";
518 free(pMessage);
519 }
520 }
521
522 FAIL() << numStoredD3DDebugMessages
523 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
524 }
525 }
526
527 SafeRelease(infoQueue);
528#endif
529}
530
Geoff Lang63046e22015-07-21 12:43:50 -0400531static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
532{
533 return strstr(allExtensions, extName.c_str()) != nullptr;
534}
535
Geoff Lang8a079e52013-10-18 16:13:33 -0400536bool ANGLETest::extensionEnabled(const std::string &extName)
537{
Geoff Lang63046e22015-07-21 12:43:50 -0400538 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
539 extName);
540}
541
542bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
543{
544 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
545}
546
547bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
548{
549 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400550}
551
Geoff Lang8a079e52013-10-18 16:13:33 -0400552void ANGLETest::setWindowWidth(int width)
553{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400554 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400555}
556
557void ANGLETest::setWindowHeight(int height)
558{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400559 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400560}
561
Geoff Langefc551f2013-10-31 10:20:28 -0400562void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400563{
Jamie Madill62af5462014-08-26 13:16:37 -0400564 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400565}
566
Geoff Langefc551f2013-10-31 10:20:28 -0400567void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400568{
Jamie Madill62af5462014-08-26 13:16:37 -0400569 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400570}
571
Geoff Langefc551f2013-10-31 10:20:28 -0400572void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400573{
Jamie Madill62af5462014-08-26 13:16:37 -0400574 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400575}
576
Geoff Langefc551f2013-10-31 10:20:28 -0400577void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400578{
Jamie Madill62af5462014-08-26 13:16:37 -0400579 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400580}
581
Geoff Langefc551f2013-10-31 10:20:28 -0400582void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400583{
Jamie Madill62af5462014-08-26 13:16:37 -0400584 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400585}
586
Geoff Langefc551f2013-10-31 10:20:28 -0400587void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400588{
Jamie Madill62af5462014-08-26 13:16:37 -0400589 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400590}
591
592void ANGLETest::setMultisampleEnabled(bool enabled)
593{
Jamie Madill62af5462014-08-26 13:16:37 -0400594 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400595}
596
Geoff Lang70d0f492015-12-10 17:45:46 -0500597void ANGLETest::setDebugEnabled(bool enabled)
598{
599 mEGLWindow->setDebugEnabled(enabled);
600}
601
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500602void ANGLETest::setNoErrorEnabled(bool enabled)
603{
604 mEGLWindow->setNoErrorEnabled(enabled);
605}
606
Geoff Langc287ea62016-09-16 14:46:51 -0400607void ANGLETest::setWebGLCompatibilityEnabled(bool webglCompatibility)
608{
609 mEGLWindow->setWebGLCompatibilityEnabled(webglCompatibility);
610}
611
Martin Radev1be913c2016-07-11 17:59:16 +0300612int ANGLETest::getClientMajorVersion() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400613{
Geoff Lang5ade8452015-09-02 11:00:30 -0400614 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400615}
616
Vincent Lang25ab4512016-05-13 18:13:59 +0200617int ANGLETest::getClientMinorVersion() const
618{
619 return mEGLWindow->getClientMinorVersion();
620}
621
Geoff Langb9266272015-01-29 13:25:14 +0000622EGLWindow *ANGLETest::getEGLWindow() const
623{
624 return mEGLWindow;
625}
626
Geoff Lang8a079e52013-10-18 16:13:33 -0400627int ANGLETest::getWindowWidth() const
628{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400629 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400630}
631
632int ANGLETest::getWindowHeight() const
633{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400634 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400635}
636
Geoff Langefc551f2013-10-31 10:20:28 -0400637bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400638{
Jamie Madill62af5462014-08-26 13:16:37 -0400639 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400640}
641
642bool ANGLETest::createEGLContext()
643{
Jamie Madill62af5462014-08-26 13:16:37 -0400644 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400645}
646
647bool ANGLETest::destroyEGLContext()
648{
Jamie Madill62af5462014-08-26 13:16:37 -0400649 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400650 return true;
651}
Geoff Langbb134672013-10-23 13:06:46 -0400652
Geoff Lang0d3683c2014-10-23 11:08:16 -0400653bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400654{
655 mOSWindow = CreateOSWindow();
656 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
657 {
658 return false;
659 }
660
Geoff Lang0d3683c2014-10-23 11:08:16 -0400661 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400662
663 return true;
664}
665
Geoff Lang0d3683c2014-10-23 11:08:16 -0400666bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400667{
668 if (mOSWindow)
669 {
670 mOSWindow->destroy();
671 delete mOSWindow;
672 mOSWindow = NULL;
673 }
674
675 return true;
676}
677
Geoff Lang0d3683c2014-10-23 11:08:16 -0400678void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400679{
Jamie Madill4119ed32014-10-01 10:41:40 -0400680 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400681}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400682
Jamie Madill518b9fa2016-03-02 11:26:02 -0500683bool IsIntel()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500684{
685 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
686 return (rendererString.find("Intel") != std::string::npos);
687}
688
Yuly Novikovd3647802016-06-16 15:58:35 -0400689bool IsAdreno()
690{
691 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
692 return (rendererString.find("Adreno") != std::string::npos);
693}
694
Jamie Madill518b9fa2016-03-02 11:26:02 -0500695bool IsAMD()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500696{
697 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
698 return (rendererString.find("AMD") != std::string::npos) ||
699 (rendererString.find("ATI") != std::string::npos);
700}
701
Jamie Madill518b9fa2016-03-02 11:26:02 -0500702bool IsNVIDIA()
Jamie Madillc3b9b262015-01-30 14:00:51 -0500703{
704 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
705 return (rendererString.find("NVIDIA") != std::string::npos);
706}
707
Jamie Madill518b9fa2016-03-02 11:26:02 -0500708bool IsD3D11()
Jamie Madilld55d2832015-10-27 13:59:19 -0400709{
710 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
711 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
712}
713
Jamie Madill518b9fa2016-03-02 11:26:02 -0500714bool IsD3D11_FL93()
Jamie Madill9fc36822015-11-18 13:08:07 -0500715{
716 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
717 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
718}
719
Jamie Madill518b9fa2016-03-02 11:26:02 -0500720bool IsD3D9()
Jamie Madill9fc36822015-11-18 13:08:07 -0500721{
722 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
723 return (rendererString.find("Direct3D9") != std::string::npos);
724}
725
Jamie Madill518b9fa2016-03-02 11:26:02 -0500726bool IsD3DSM3()
Jamie Madill9fc36822015-11-18 13:08:07 -0500727{
Jamie Madill518b9fa2016-03-02 11:26:02 -0500728 return IsD3D9() || IsD3D11_FL93();
Jamie Madill9fc36822015-11-18 13:08:07 -0500729}
730
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400731bool IsDesktopOpenGL()
732{
733 return IsOpenGL() && !IsOpenGLES();
734}
735
736bool IsOpenGLES()
737{
738 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
739 return (rendererString.find("OpenGL ES") != std::string::npos);
740}
741
742bool IsOpenGL()
743{
744 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
745 return (rendererString.find("OpenGL") != std::string::npos);
746}
747
Yuly Novikovd3647802016-06-16 15:58:35 -0400748bool IsAndroid()
749{
750#if defined(ANGLE_PLATFORM_ANDROID)
751 return true;
752#else
753 return false;
754#endif
755}
756
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400757bool IsLinux()
758{
759#if defined(ANGLE_PLATFORM_LINUX)
760 return true;
761#else
762 return false;
763#endif
764}
765
Jamie Madill518b9fa2016-03-02 11:26:02 -0500766bool IsOSX()
Ian Ewell292f0052016-02-04 10:37:32 -0500767{
Corentin Wallez9e3c6152016-03-29 21:58:33 -0400768#if defined(ANGLE_PLATFORM_APPLE)
Ian Ewell292f0052016-02-04 10:37:32 -0500769 return true;
770#else
771 return false;
772#endif
773}
774
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400775bool IsWindows()
Jamie Madill518b9fa2016-03-02 11:26:02 -0500776{
Corentin Wallezc7f59d02016-06-20 10:12:08 -0400777#if defined(ANGLE_PLATFORM_WINDOWS)
778 return true;
779#else
780 return false;
781#endif
Olli Etuaho87fc71c2016-05-11 14:25:21 +0300782}
783
Jamie Madillc3b9b262015-01-30 14:00:51 -0500784EGLint ANGLETest::getPlatformRenderer() const
785{
Jamie Madillf6859912015-01-30 17:05:35 -0500786 assert(mEGLWindow);
787 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500788}
789
Austin Kinrossd544cc92016-01-11 15:26:42 -0800790void ANGLETest::ignoreD3D11SDKLayersWarnings()
791{
792 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
793 mIgnoreD3D11SDKLayersWarnings = true;
794}
795
Geoff Lang0d3683c2014-10-23 11:08:16 -0400796OSWindow *ANGLETest::mOSWindow = NULL;
797
798void ANGLETestEnvironment::SetUp()
799{
Jamie Madill776a75b2016-05-17 13:43:17 -0400800 mGLESLibrary.reset(angle::loadLibrary("libGLESv2"));
801 if (mGLESLibrary)
802 {
803 auto initFunc = reinterpret_cast<ANGLEPlatformInitializeFunc>(
804 mGLESLibrary->getSymbol("ANGLEPlatformInitialize"));
805 if (initFunc)
806 {
807 initFunc(&angle::g_testPlatformInstance);
808 }
809 }
810
Geoff Lang0d3683c2014-10-23 11:08:16 -0400811 if (!ANGLETest::InitTestWindow())
812 {
813 FAIL() << "Failed to create ANGLE test window.";
814 }
815}
816
817void ANGLETestEnvironment::TearDown()
818{
819 ANGLETest::DestroyTestWindow();
Jamie Madill776a75b2016-05-17 13:43:17 -0400820
821 if (mGLESLibrary)
822 {
823 auto shutdownFunc = reinterpret_cast<ANGLEPlatformShutdownFunc>(
824 mGLESLibrary->getSymbol("ANGLEPlatformShutdown"));
825 if (shutdownFunc)
826 {
827 shutdownFunc();
828 }
829 }
830}
831
832void IgnoreANGLEPlatformMessages()
833{
834 // Negative tests may trigger expected errors/warnings in the ANGLE Platform.
835 angle::g_testPlatformInstance.ignoreMessages();
Geoff Lang0d3683c2014-10-23 11:08:16 -0400836}