blob: d2de0be549e5869eaa6bc4e20a6c409256dff84e [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 Madill508a5b72015-12-08 11:26:14 -050013#include "system_utils.h"
Jamie Madill8add0eb2014-08-26 13:16:35 -040014
Jamie Madill0dfa8072016-01-22 15:27:21 -050015namespace angle
16{
17
18GLColor::GLColor() : R(0), G(0), B(0), A(0)
19{
20}
21
22GLColor::GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a) : R(r), G(g), B(b), A(a)
23{
24}
25
26GLColor ReadColor(GLint x, GLint y)
27{
28 GLColor actual;
29 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
30 EXPECT_GL_NO_ERROR();
31 return actual;
32}
33
34bool operator==(const GLColor &a, const GLColor &b)
35{
36 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
37}
38
39std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
40{
41 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
42 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
43 << ", " << static_cast<unsigned int>(color.A) << ")";
44 return ostream;
45}
46
47} // namespace angle
48
Jamie Madillfa05f602015-05-07 13:47:11 -040049ANGLETest::ANGLETest()
Austin Kinrossd544cc92016-01-11 15:26:42 -080050 : mEGLWindow(nullptr), mWidth(16), mHeight(16), mIgnoreD3D11SDKLayersWarnings(false)
Geoff Lang8a079e52013-10-18 16:13:33 -040051{
Geoff Lang5ade8452015-09-02 11:00:30 -040052 mEGLWindow =
53 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -040054}
55
56ANGLETest::~ANGLETest()
57{
Jamie Madill77a72f62015-04-14 11:18:32 -040058 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -040059}
60
Geoff Lang8a079e52013-10-18 16:13:33 -040061void ANGLETest::SetUp()
62{
Corentin Wallezb44440d2015-07-22 17:54:20 -040063 // Resize the window before creating the context so that the first make current
64 // sets the viewport and scissor box to the right size.
65 bool needSwap = false;
66 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +000067 {
Corentin Wallezb44440d2015-07-22 17:54:20 -040068 if (!mOSWindow->resize(mWidth, mHeight))
69 {
70 FAIL() << "Failed to resize ANGLE test window.";
71 }
72 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +000073 }
74
Geoff Lang8a079e52013-10-18 16:13:33 -040075 if (!createEGLContext())
76 {
77 FAIL() << "egl context creation failed.";
78 }
Corentin Wallezb828b322015-07-16 17:51:30 -040079
Corentin Wallezb44440d2015-07-22 17:54:20 -040080 if (needSwap)
81 {
82 // Swap the buffers so that the default framebuffer picks up the resize
83 // which will allow follow-up test code to assume the framebuffer covers
84 // the whole window.
85 swapBuffers();
86 }
Corentin Wallez096725b2015-07-20 16:58:57 -040087
Geoff Lang7f8dc492015-07-23 21:29:33 +000088 // This Viewport command is not strictly necessary but we add it so that programs
89 // taking OpenGL traces can guess the size of the default framebuffer and show it
90 // in their UIs
91 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -050092
93 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
94 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -040095}
96
97void ANGLETest::TearDown()
98{
Austin Kinrossd544cc92016-01-11 15:26:42 -080099 checkD3D11SDKLayersMessages();
100
Jamie Madill508a5b72015-12-08 11:26:14 -0500101 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
102 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
103
Geoff Lang8a079e52013-10-18 16:13:33 -0400104 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -0400105 mOSWindow->messageLoop();
106
Geoff Lang8a079e52013-10-18 16:13:33 -0400107 if (!destroyEGLContext())
108 {
109 FAIL() << "egl context destruction failed.";
110 }
Jamie Madill8add0eb2014-08-26 13:16:35 -0400111
112 // Check for quit message
113 Event myEvent;
114 while (mOSWindow->popEvent(&myEvent))
115 {
116 if (myEvent.Type == Event::EVENT_CLOSED)
117 {
118 exit(0);
119 }
120 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400121}
122
123void ANGLETest::swapBuffers()
124{
Jamie Madill77a72f62015-04-14 11:18:32 -0400125 if (mEGLWindow->isGLInitialized())
126 {
127 mEGLWindow->swap();
128 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400129}
130
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200131void ANGLETest::drawQuad(GLuint program,
132 const std::string &positionAttribName,
133 GLfloat positionAttribZ)
134{
135 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
136}
137
138void ANGLETest::drawQuad(GLuint program,
139 const std::string &positionAttribName,
140 GLfloat positionAttribZ,
141 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400142{
143 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
144
145 glUseProgram(program);
146
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200147 const GLfloat vertices[] = {
148 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
149 -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
150 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400151
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200152 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
153 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
154 1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400155 };
156
157 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
158 glEnableVertexAttribArray(positionLocation);
159
160 glDrawArrays(GL_TRIANGLES, 0, 6);
161
162 glDisableVertexAttribArray(positionLocation);
163 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
164
165 glUseProgram(0);
166}
167
Geoff Langefc551f2013-10-31 10:20:28 -0400168GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
169{
170 GLuint shader = glCreateShader(type);
171
172 const char *sourceArray[1] = { source.c_str() };
173 glShaderSource(shader, 1, sourceArray, NULL);
174 glCompileShader(shader);
175
176 GLint compileResult;
177 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
178
179 if (compileResult == 0)
180 {
181 GLint infoLogLength;
182 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
183
Jamie Madilld2c52e32015-10-14 17:07:05 -0400184 if (infoLogLength == 0)
185 {
186 std::cerr << "shader compilation failed with empty log." << std::endl;
187 }
188 else
189 {
190 std::vector<GLchar> infoLog(infoLogLength);
191 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400192
Jamie Madilld2c52e32015-10-14 17:07:05 -0400193 std::cerr << "shader compilation failed: " << &infoLog[0];
194 }
Geoff Langefc551f2013-10-31 10:20:28 -0400195
196 glDeleteShader(shader);
197 shader = 0;
198 }
199
200 return shader;
201}
202
Austin Kinrossd544cc92016-01-11 15:26:42 -0800203void ANGLETest::checkD3D11SDKLayersMessages()
204{
205#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
206 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
207 // were outputted by the test
208 if (mIgnoreD3D11SDKLayersWarnings ||
209 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
210 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
211 {
212 return;
213 }
214
215 const char *extensionString =
216 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
217 if (!strstr(extensionString, "EGL_EXT_device_query"))
218 {
219 return;
220 }
221
222 EGLAttrib device = 0;
223 EGLAttrib angleDevice = 0;
224
225 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
226 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
227
228 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
229 eglGetProcAddress("eglQueryDisplayAttribEXT"));
230 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
231 eglGetProcAddress("eglQueryDeviceAttribEXT"));
232 ASSERT_NE(nullptr, queryDisplayAttribEXT);
233 ASSERT_NE(nullptr, queryDeviceAttribEXT);
234
235 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
236 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
237 EGL_D3D11_DEVICE_ANGLE, &device));
238 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
239
240 ID3D11InfoQueue *infoQueue = nullptr;
241 HRESULT hr =
242 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
243 if (SUCCEEDED(hr))
244 {
245 UINT64 numStoredD3DDebugMessages =
246 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
247
248 if (numStoredD3DDebugMessages > 0)
249 {
250 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
251 {
252 SIZE_T messageLength = 0;
253 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
254
255 if (SUCCEEDED(hr))
256 {
257 D3D11_MESSAGE *pMessage =
258 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
259 infoQueue->GetMessage(i, pMessage, &messageLength);
260
261 std::cout << "Message " << i << ":"
262 << " " << pMessage->pDescription << "\n";
263 free(pMessage);
264 }
265 }
266
267 FAIL() << numStoredD3DDebugMessages
268 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
269 }
270 }
271
272 SafeRelease(infoQueue);
273#endif
274}
275
Geoff Lang63046e22015-07-21 12:43:50 -0400276static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
277{
278 return strstr(allExtensions, extName.c_str()) != nullptr;
279}
280
Geoff Lang8a079e52013-10-18 16:13:33 -0400281bool ANGLETest::extensionEnabled(const std::string &extName)
282{
Geoff Lang63046e22015-07-21 12:43:50 -0400283 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
284 extName);
285}
286
287bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
288{
289 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
290}
291
292bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
293{
294 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400295}
296
Geoff Lang8a079e52013-10-18 16:13:33 -0400297void ANGLETest::setWindowWidth(int width)
298{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400299 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400300}
301
302void ANGLETest::setWindowHeight(int height)
303{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400304 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400305}
306
Geoff Langefc551f2013-10-31 10:20:28 -0400307void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400308{
Jamie Madill62af5462014-08-26 13:16:37 -0400309 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400310}
311
Geoff Langefc551f2013-10-31 10:20:28 -0400312void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400313{
Jamie Madill62af5462014-08-26 13:16:37 -0400314 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400315}
316
Geoff Langefc551f2013-10-31 10:20:28 -0400317void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400318{
Jamie Madill62af5462014-08-26 13:16:37 -0400319 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400320}
321
Geoff Langefc551f2013-10-31 10:20:28 -0400322void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400323{
Jamie Madill62af5462014-08-26 13:16:37 -0400324 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400325}
326
Geoff Langefc551f2013-10-31 10:20:28 -0400327void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400328{
Jamie Madill62af5462014-08-26 13:16:37 -0400329 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400330}
331
Geoff Langefc551f2013-10-31 10:20:28 -0400332void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400333{
Jamie Madill62af5462014-08-26 13:16:37 -0400334 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400335}
336
337void ANGLETest::setMultisampleEnabled(bool enabled)
338{
Jamie Madill62af5462014-08-26 13:16:37 -0400339 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400340}
341
Geoff Lang70d0f492015-12-10 17:45:46 -0500342void ANGLETest::setDebugEnabled(bool enabled)
343{
344 mEGLWindow->setDebugEnabled(enabled);
345}
346
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500347void ANGLETest::setNoErrorEnabled(bool enabled)
348{
349 mEGLWindow->setNoErrorEnabled(enabled);
350}
351
Geoff Lang8a079e52013-10-18 16:13:33 -0400352int ANGLETest::getClientVersion() const
353{
Geoff Lang5ade8452015-09-02 11:00:30 -0400354 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400355}
356
Geoff Langb9266272015-01-29 13:25:14 +0000357EGLWindow *ANGLETest::getEGLWindow() const
358{
359 return mEGLWindow;
360}
361
Geoff Lang8a079e52013-10-18 16:13:33 -0400362int ANGLETest::getWindowWidth() const
363{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400364 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400365}
366
367int ANGLETest::getWindowHeight() const
368{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400369 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400370}
371
Geoff Langefc551f2013-10-31 10:20:28 -0400372bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400373{
Jamie Madill62af5462014-08-26 13:16:37 -0400374 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400375}
376
377bool ANGLETest::createEGLContext()
378{
Jamie Madill62af5462014-08-26 13:16:37 -0400379 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400380}
381
382bool ANGLETest::destroyEGLContext()
383{
Jamie Madill62af5462014-08-26 13:16:37 -0400384 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400385 return true;
386}
Geoff Langbb134672013-10-23 13:06:46 -0400387
Geoff Lang0d3683c2014-10-23 11:08:16 -0400388bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400389{
390 mOSWindow = CreateOSWindow();
391 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
392 {
393 return false;
394 }
395
Geoff Lang0d3683c2014-10-23 11:08:16 -0400396 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400397
398 return true;
399}
400
Geoff Lang0d3683c2014-10-23 11:08:16 -0400401bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400402{
403 if (mOSWindow)
404 {
405 mOSWindow->destroy();
406 delete mOSWindow;
407 mOSWindow = NULL;
408 }
409
410 return true;
411}
412
Geoff Lang0d3683c2014-10-23 11:08:16 -0400413void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400414{
Jamie Madill4119ed32014-10-01 10:41:40 -0400415 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400416}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400417
Jamie Madillc3b9b262015-01-30 14:00:51 -0500418bool ANGLETest::isIntel() const
419{
420 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
421 return (rendererString.find("Intel") != std::string::npos);
422}
423
424bool ANGLETest::isAMD() const
425{
426 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
427 return (rendererString.find("AMD") != std::string::npos) ||
428 (rendererString.find("ATI") != std::string::npos);
429}
430
431bool ANGLETest::isNVidia() const
432{
433 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
434 return (rendererString.find("NVIDIA") != std::string::npos);
435}
436
Jamie Madilld55d2832015-10-27 13:59:19 -0400437bool ANGLETest::isD3D11() const
438{
439 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
440 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
441}
442
Jamie Madill9fc36822015-11-18 13:08:07 -0500443bool ANGLETest::isD3D11_FL93() const
444{
445 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
446 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
447}
448
449bool ANGLETest::isD3D9() const
450{
451 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
452 return (rendererString.find("Direct3D9") != std::string::npos);
453}
454
455bool ANGLETest::isD3DSM3() const
456{
457 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
458 return isD3D9() || isD3D11_FL93();
459}
460
Jamie Madillc3b9b262015-01-30 14:00:51 -0500461EGLint ANGLETest::getPlatformRenderer() const
462{
Jamie Madillf6859912015-01-30 17:05:35 -0500463 assert(mEGLWindow);
464 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500465}
466
Austin Kinrossd544cc92016-01-11 15:26:42 -0800467void ANGLETest::ignoreD3D11SDKLayersWarnings()
468{
469 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
470 mIgnoreD3D11SDKLayersWarnings = true;
471}
472
Geoff Lang0d3683c2014-10-23 11:08:16 -0400473OSWindow *ANGLETest::mOSWindow = NULL;
474
475void ANGLETestEnvironment::SetUp()
476{
477 if (!ANGLETest::InitTestWindow())
478 {
479 FAIL() << "Failed to create ANGLE test window.";
480 }
481}
482
483void ANGLETestEnvironment::TearDown()
484{
485 ANGLETest::DestroyTestWindow();
486}