blob: d1a3c32ebd1139b57994e1c6e23e0566a26a07c8 [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
Jamie Madille2509a32016-02-01 14:09:05 -050026GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
27{
28 memcpy(&R, &colorValue, sizeof(GLuint));
29}
30
Jamie Madill0dfa8072016-01-22 15:27:21 -050031GLColor ReadColor(GLint x, GLint y)
32{
33 GLColor actual;
34 glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R);
35 EXPECT_GL_NO_ERROR();
36 return actual;
37}
38
39bool operator==(const GLColor &a, const GLColor &b)
40{
41 return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
42}
43
44std::ostream &operator<<(std::ostream &ostream, const GLColor &color)
45{
46 ostream << "(" << static_cast<unsigned int>(color.R) << ", "
47 << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
48 << ", " << static_cast<unsigned int>(color.A) << ")";
49 return ostream;
50}
51
52} // namespace angle
53
Jamie Madillfa05f602015-05-07 13:47:11 -040054ANGLETest::ANGLETest()
Austin Kinrossd544cc92016-01-11 15:26:42 -080055 : mEGLWindow(nullptr), mWidth(16), mHeight(16), mIgnoreD3D11SDKLayersWarnings(false)
Geoff Lang8a079e52013-10-18 16:13:33 -040056{
Geoff Lang5ade8452015-09-02 11:00:30 -040057 mEGLWindow =
58 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -040059}
60
61ANGLETest::~ANGLETest()
62{
Jamie Madill77a72f62015-04-14 11:18:32 -040063 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -040064}
65
Geoff Lang8a079e52013-10-18 16:13:33 -040066void ANGLETest::SetUp()
67{
Corentin Wallezb44440d2015-07-22 17:54:20 -040068 // Resize the window before creating the context so that the first make current
69 // sets the viewport and scissor box to the right size.
70 bool needSwap = false;
71 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +000072 {
Corentin Wallezb44440d2015-07-22 17:54:20 -040073 if (!mOSWindow->resize(mWidth, mHeight))
74 {
75 FAIL() << "Failed to resize ANGLE test window.";
76 }
77 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +000078 }
79
Geoff Lang8a079e52013-10-18 16:13:33 -040080 if (!createEGLContext())
81 {
82 FAIL() << "egl context creation failed.";
83 }
Corentin Wallezb828b322015-07-16 17:51:30 -040084
Corentin Wallezb44440d2015-07-22 17:54:20 -040085 if (needSwap)
86 {
87 // Swap the buffers so that the default framebuffer picks up the resize
88 // which will allow follow-up test code to assume the framebuffer covers
89 // the whole window.
90 swapBuffers();
91 }
Corentin Wallez096725b2015-07-20 16:58:57 -040092
Geoff Lang7f8dc492015-07-23 21:29:33 +000093 // This Viewport command is not strictly necessary but we add it so that programs
94 // taking OpenGL traces can guess the size of the default framebuffer and show it
95 // in their UIs
96 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -050097
98 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
99 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -0400100}
101
102void ANGLETest::TearDown()
103{
Austin Kinrossd544cc92016-01-11 15:26:42 -0800104 checkD3D11SDKLayersMessages();
105
Jamie Madill508a5b72015-12-08 11:26:14 -0500106 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
107 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
108
Geoff Lang8a079e52013-10-18 16:13:33 -0400109 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -0400110 mOSWindow->messageLoop();
111
Geoff Lang8a079e52013-10-18 16:13:33 -0400112 if (!destroyEGLContext())
113 {
114 FAIL() << "egl context destruction failed.";
115 }
Jamie Madill8add0eb2014-08-26 13:16:35 -0400116
117 // Check for quit message
118 Event myEvent;
119 while (mOSWindow->popEvent(&myEvent))
120 {
121 if (myEvent.Type == Event::EVENT_CLOSED)
122 {
123 exit(0);
124 }
125 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400126}
127
128void ANGLETest::swapBuffers()
129{
Jamie Madill77a72f62015-04-14 11:18:32 -0400130 if (mEGLWindow->isGLInitialized())
131 {
132 mEGLWindow->swap();
133 }
Geoff Lang8a079e52013-10-18 16:13:33 -0400134}
135
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200136void ANGLETest::drawQuad(GLuint program,
137 const std::string &positionAttribName,
138 GLfloat positionAttribZ)
139{
140 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
141}
142
143void ANGLETest::drawQuad(GLuint program,
144 const std::string &positionAttribName,
145 GLfloat positionAttribZ,
146 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400147{
148 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
149
150 glUseProgram(program);
151
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200152 const GLfloat vertices[] = {
153 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
154 -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
155 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400156
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200157 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
158 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
159 1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400160 };
161
162 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
163 glEnableVertexAttribArray(positionLocation);
164
165 glDrawArrays(GL_TRIANGLES, 0, 6);
166
167 glDisableVertexAttribArray(positionLocation);
168 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
169
170 glUseProgram(0);
171}
172
Geoff Langefc551f2013-10-31 10:20:28 -0400173GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
174{
175 GLuint shader = glCreateShader(type);
176
177 const char *sourceArray[1] = { source.c_str() };
178 glShaderSource(shader, 1, sourceArray, NULL);
179 glCompileShader(shader);
180
181 GLint compileResult;
182 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
183
184 if (compileResult == 0)
185 {
186 GLint infoLogLength;
187 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
188
Jamie Madilld2c52e32015-10-14 17:07:05 -0400189 if (infoLogLength == 0)
190 {
191 std::cerr << "shader compilation failed with empty log." << std::endl;
192 }
193 else
194 {
195 std::vector<GLchar> infoLog(infoLogLength);
196 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400197
Jamie Madilld2c52e32015-10-14 17:07:05 -0400198 std::cerr << "shader compilation failed: " << &infoLog[0];
199 }
Geoff Langefc551f2013-10-31 10:20:28 -0400200
201 glDeleteShader(shader);
202 shader = 0;
203 }
204
205 return shader;
206}
207
Austin Kinrossd544cc92016-01-11 15:26:42 -0800208void ANGLETest::checkD3D11SDKLayersMessages()
209{
210#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
211 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
212 // were outputted by the test
213 if (mIgnoreD3D11SDKLayersWarnings ||
214 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
215 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
216 {
217 return;
218 }
219
220 const char *extensionString =
221 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
222 if (!strstr(extensionString, "EGL_EXT_device_query"))
223 {
224 return;
225 }
226
227 EGLAttrib device = 0;
228 EGLAttrib angleDevice = 0;
229
230 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
231 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
232
233 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
234 eglGetProcAddress("eglQueryDisplayAttribEXT"));
235 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
236 eglGetProcAddress("eglQueryDeviceAttribEXT"));
237 ASSERT_NE(nullptr, queryDisplayAttribEXT);
238 ASSERT_NE(nullptr, queryDeviceAttribEXT);
239
240 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
241 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
242 EGL_D3D11_DEVICE_ANGLE, &device));
243 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
244
245 ID3D11InfoQueue *infoQueue = nullptr;
246 HRESULT hr =
247 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
248 if (SUCCEEDED(hr))
249 {
250 UINT64 numStoredD3DDebugMessages =
251 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
252
253 if (numStoredD3DDebugMessages > 0)
254 {
255 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
256 {
257 SIZE_T messageLength = 0;
258 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
259
260 if (SUCCEEDED(hr))
261 {
262 D3D11_MESSAGE *pMessage =
263 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
264 infoQueue->GetMessage(i, pMessage, &messageLength);
265
266 std::cout << "Message " << i << ":"
267 << " " << pMessage->pDescription << "\n";
268 free(pMessage);
269 }
270 }
271
272 FAIL() << numStoredD3DDebugMessages
273 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
274 }
275 }
276
277 SafeRelease(infoQueue);
278#endif
279}
280
Geoff Lang63046e22015-07-21 12:43:50 -0400281static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
282{
283 return strstr(allExtensions, extName.c_str()) != nullptr;
284}
285
Geoff Lang8a079e52013-10-18 16:13:33 -0400286bool ANGLETest::extensionEnabled(const std::string &extName)
287{
Geoff Lang63046e22015-07-21 12:43:50 -0400288 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
289 extName);
290}
291
292bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
293{
294 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
295}
296
297bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
298{
299 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400300}
301
Geoff Lang8a079e52013-10-18 16:13:33 -0400302void ANGLETest::setWindowWidth(int width)
303{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400304 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400305}
306
307void ANGLETest::setWindowHeight(int height)
308{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400309 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400310}
311
Geoff Langefc551f2013-10-31 10:20:28 -0400312void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400313{
Jamie Madill62af5462014-08-26 13:16:37 -0400314 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400315}
316
Geoff Langefc551f2013-10-31 10:20:28 -0400317void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400318{
Jamie Madill62af5462014-08-26 13:16:37 -0400319 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400320}
321
Geoff Langefc551f2013-10-31 10:20:28 -0400322void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400323{
Jamie Madill62af5462014-08-26 13:16:37 -0400324 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400325}
326
Geoff Langefc551f2013-10-31 10:20:28 -0400327void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400328{
Jamie Madill62af5462014-08-26 13:16:37 -0400329 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400330}
331
Geoff Langefc551f2013-10-31 10:20:28 -0400332void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400333{
Jamie Madill62af5462014-08-26 13:16:37 -0400334 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400335}
336
Geoff Langefc551f2013-10-31 10:20:28 -0400337void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400338{
Jamie Madill62af5462014-08-26 13:16:37 -0400339 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400340}
341
342void ANGLETest::setMultisampleEnabled(bool enabled)
343{
Jamie Madill62af5462014-08-26 13:16:37 -0400344 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400345}
346
Geoff Lang70d0f492015-12-10 17:45:46 -0500347void ANGLETest::setDebugEnabled(bool enabled)
348{
349 mEGLWindow->setDebugEnabled(enabled);
350}
351
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500352void ANGLETest::setNoErrorEnabled(bool enabled)
353{
354 mEGLWindow->setNoErrorEnabled(enabled);
355}
356
Geoff Lang8a079e52013-10-18 16:13:33 -0400357int ANGLETest::getClientVersion() const
358{
Geoff Lang5ade8452015-09-02 11:00:30 -0400359 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400360}
361
Geoff Langb9266272015-01-29 13:25:14 +0000362EGLWindow *ANGLETest::getEGLWindow() const
363{
364 return mEGLWindow;
365}
366
Geoff Lang8a079e52013-10-18 16:13:33 -0400367int ANGLETest::getWindowWidth() const
368{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400369 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400370}
371
372int ANGLETest::getWindowHeight() const
373{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400374 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400375}
376
Geoff Langefc551f2013-10-31 10:20:28 -0400377bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400378{
Jamie Madill62af5462014-08-26 13:16:37 -0400379 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400380}
381
382bool ANGLETest::createEGLContext()
383{
Jamie Madill62af5462014-08-26 13:16:37 -0400384 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400385}
386
387bool ANGLETest::destroyEGLContext()
388{
Jamie Madill62af5462014-08-26 13:16:37 -0400389 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400390 return true;
391}
Geoff Langbb134672013-10-23 13:06:46 -0400392
Geoff Lang0d3683c2014-10-23 11:08:16 -0400393bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400394{
395 mOSWindow = CreateOSWindow();
396 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
397 {
398 return false;
399 }
400
Geoff Lang0d3683c2014-10-23 11:08:16 -0400401 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400402
403 return true;
404}
405
Geoff Lang0d3683c2014-10-23 11:08:16 -0400406bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400407{
408 if (mOSWindow)
409 {
410 mOSWindow->destroy();
411 delete mOSWindow;
412 mOSWindow = NULL;
413 }
414
415 return true;
416}
417
Geoff Lang0d3683c2014-10-23 11:08:16 -0400418void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400419{
Jamie Madill4119ed32014-10-01 10:41:40 -0400420 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400421}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400422
Jamie Madillc3b9b262015-01-30 14:00:51 -0500423bool ANGLETest::isIntel() const
424{
425 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
426 return (rendererString.find("Intel") != std::string::npos);
427}
428
429bool ANGLETest::isAMD() const
430{
431 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
432 return (rendererString.find("AMD") != std::string::npos) ||
433 (rendererString.find("ATI") != std::string::npos);
434}
435
436bool ANGLETest::isNVidia() const
437{
438 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
439 return (rendererString.find("NVIDIA") != std::string::npos);
440}
441
Jamie Madilld55d2832015-10-27 13:59:19 -0400442bool ANGLETest::isD3D11() const
443{
444 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
445 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
446}
447
Jamie Madill9fc36822015-11-18 13:08:07 -0500448bool ANGLETest::isD3D11_FL93() const
449{
450 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
451 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
452}
453
454bool ANGLETest::isD3D9() const
455{
456 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
457 return (rendererString.find("Direct3D9") != std::string::npos);
458}
459
460bool ANGLETest::isD3DSM3() const
461{
462 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
463 return isD3D9() || isD3D11_FL93();
464}
465
Jamie Madillc3b9b262015-01-30 14:00:51 -0500466EGLint ANGLETest::getPlatformRenderer() const
467{
Jamie Madillf6859912015-01-30 17:05:35 -0500468 assert(mEGLWindow);
469 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500470}
471
Austin Kinrossd544cc92016-01-11 15:26:42 -0800472void ANGLETest::ignoreD3D11SDKLayersWarnings()
473{
474 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
475 mIgnoreD3D11SDKLayersWarnings = true;
476}
477
Geoff Lang0d3683c2014-10-23 11:08:16 -0400478OSWindow *ANGLETest::mOSWindow = NULL;
479
480void ANGLETestEnvironment::SetUp()
481{
482 if (!ANGLETest::InitTestWindow())
483 {
484 FAIL() << "Failed to create ANGLE test window.";
485 }
486}
487
488void ANGLETestEnvironment::TearDown()
489{
490 ANGLETest::DestroyTestWindow();
491}