blob: aebe28cdd8072280dbfe136fbd0ae607991dd2e3 [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 Madillfa05f602015-05-07 13:47:11 -040015ANGLETest::ANGLETest()
Austin Kinrossd544cc92016-01-11 15:26:42 -080016 : mEGLWindow(nullptr), mWidth(16), mHeight(16), mIgnoreD3D11SDKLayersWarnings(false)
Geoff Lang8a079e52013-10-18 16:13:33 -040017{
Geoff Lang5ade8452015-09-02 11:00:30 -040018 mEGLWindow =
19 new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
Geoff Lang0d3683c2014-10-23 11:08:16 -040020}
21
22ANGLETest::~ANGLETest()
23{
Jamie Madill77a72f62015-04-14 11:18:32 -040024 SafeDelete(mEGLWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -040025}
26
Geoff Lang8a079e52013-10-18 16:13:33 -040027void ANGLETest::SetUp()
28{
Corentin Wallezb44440d2015-07-22 17:54:20 -040029 // Resize the window before creating the context so that the first make current
30 // sets the viewport and scissor box to the right size.
31 bool needSwap = false;
32 if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
Geoff Lang7f8dc492015-07-23 21:29:33 +000033 {
Corentin Wallezb44440d2015-07-22 17:54:20 -040034 if (!mOSWindow->resize(mWidth, mHeight))
35 {
36 FAIL() << "Failed to resize ANGLE test window.";
37 }
38 needSwap = true;
Geoff Lang7f8dc492015-07-23 21:29:33 +000039 }
40
Geoff Lang8a079e52013-10-18 16:13:33 -040041 if (!createEGLContext())
42 {
43 FAIL() << "egl context creation failed.";
44 }
Corentin Wallezb828b322015-07-16 17:51:30 -040045
Corentin Wallezb44440d2015-07-22 17:54:20 -040046 if (needSwap)
47 {
48 // Swap the buffers so that the default framebuffer picks up the resize
49 // which will allow follow-up test code to assume the framebuffer covers
50 // the whole window.
51 swapBuffers();
52 }
Corentin Wallez096725b2015-07-20 16:58:57 -040053
Geoff Lang7f8dc492015-07-23 21:29:33 +000054 // This Viewport command is not strictly necessary but we add it so that programs
55 // taking OpenGL traces can guess the size of the default framebuffer and show it
56 // in their UIs
57 glViewport(0, 0, mWidth, mHeight);
Jamie Madill508a5b72015-12-08 11:26:14 -050058
59 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
60 angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
Geoff Lang8a079e52013-10-18 16:13:33 -040061}
62
63void ANGLETest::TearDown()
64{
Austin Kinrossd544cc92016-01-11 15:26:42 -080065 checkD3D11SDKLayersMessages();
66
Jamie Madill508a5b72015-12-08 11:26:14 -050067 const auto &info = testing::UnitTest::GetInstance()->current_test_info();
68 angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
69
Geoff Lang8a079e52013-10-18 16:13:33 -040070 swapBuffers();
Jamie Madill9e16d402014-09-08 17:36:33 -040071 mOSWindow->messageLoop();
72
Geoff Lang8a079e52013-10-18 16:13:33 -040073 if (!destroyEGLContext())
74 {
75 FAIL() << "egl context destruction failed.";
76 }
Jamie Madill8add0eb2014-08-26 13:16:35 -040077
78 // Check for quit message
79 Event myEvent;
80 while (mOSWindow->popEvent(&myEvent))
81 {
82 if (myEvent.Type == Event::EVENT_CLOSED)
83 {
84 exit(0);
85 }
86 }
Geoff Lang8a079e52013-10-18 16:13:33 -040087}
88
89void ANGLETest::swapBuffers()
90{
Jamie Madill77a72f62015-04-14 11:18:32 -040091 if (mEGLWindow->isGLInitialized())
92 {
93 mEGLWindow->swap();
94 }
Geoff Lang8a079e52013-10-18 16:13:33 -040095}
96
Olli Etuaho4a8329f2016-01-11 17:12:57 +020097void ANGLETest::drawQuad(GLuint program,
98 const std::string &positionAttribName,
99 GLfloat positionAttribZ)
100{
101 drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
102}
103
104void ANGLETest::drawQuad(GLuint program,
105 const std::string &positionAttribName,
106 GLfloat positionAttribZ,
107 GLfloat positionAttribXYScale)
Geoff Lang8a079e52013-10-18 16:13:33 -0400108{
109 GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
110
111 glUseProgram(program);
112
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200113 const GLfloat vertices[] = {
114 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
115 -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
116 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400117
Olli Etuaho4a8329f2016-01-11 17:12:57 +0200118 -1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
119 1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
120 1.0f * positionAttribXYScale, 1.0f * positionAttribXYScale, positionAttribZ,
Geoff Lang8a079e52013-10-18 16:13:33 -0400121 };
122
123 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
124 glEnableVertexAttribArray(positionLocation);
125
126 glDrawArrays(GL_TRIANGLES, 0, 6);
127
128 glDisableVertexAttribArray(positionLocation);
129 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
130
131 glUseProgram(0);
132}
133
Geoff Langefc551f2013-10-31 10:20:28 -0400134GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
135{
136 GLuint shader = glCreateShader(type);
137
138 const char *sourceArray[1] = { source.c_str() };
139 glShaderSource(shader, 1, sourceArray, NULL);
140 glCompileShader(shader);
141
142 GLint compileResult;
143 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
144
145 if (compileResult == 0)
146 {
147 GLint infoLogLength;
148 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
149
Jamie Madilld2c52e32015-10-14 17:07:05 -0400150 if (infoLogLength == 0)
151 {
152 std::cerr << "shader compilation failed with empty log." << std::endl;
153 }
154 else
155 {
156 std::vector<GLchar> infoLog(infoLogLength);
157 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Langefc551f2013-10-31 10:20:28 -0400158
Jamie Madilld2c52e32015-10-14 17:07:05 -0400159 std::cerr << "shader compilation failed: " << &infoLog[0];
160 }
Geoff Langefc551f2013-10-31 10:20:28 -0400161
162 glDeleteShader(shader);
163 shader = 0;
164 }
165
166 return shader;
167}
168
Austin Kinrossd544cc92016-01-11 15:26:42 -0800169void ANGLETest::checkD3D11SDKLayersMessages()
170{
171#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(NDEBUG)
172 // In debug D3D11 mode, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
173 // were outputted by the test
174 if (mIgnoreD3D11SDKLayersWarnings ||
175 mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
176 mEGLWindow->getDisplay() == EGL_NO_DISPLAY)
177 {
178 return;
179 }
180
181 const char *extensionString =
182 static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS));
183 if (!strstr(extensionString, "EGL_EXT_device_query"))
184 {
185 return;
186 }
187
188 EGLAttrib device = 0;
189 EGLAttrib angleDevice = 0;
190
191 PFNEGLQUERYDISPLAYATTRIBEXTPROC queryDisplayAttribEXT;
192 PFNEGLQUERYDEVICEATTRIBEXTPROC queryDeviceAttribEXT;
193
194 queryDisplayAttribEXT = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(
195 eglGetProcAddress("eglQueryDisplayAttribEXT"));
196 queryDeviceAttribEXT = reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(
197 eglGetProcAddress("eglQueryDeviceAttribEXT"));
198 ASSERT_NE(nullptr, queryDisplayAttribEXT);
199 ASSERT_NE(nullptr, queryDeviceAttribEXT);
200
201 ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
202 ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
203 EGL_D3D11_DEVICE_ANGLE, &device));
204 ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
205
206 ID3D11InfoQueue *infoQueue = nullptr;
207 HRESULT hr =
208 d3d11Device->QueryInterface(__uuidof(infoQueue), reinterpret_cast<void **>(&infoQueue));
209 if (SUCCEEDED(hr))
210 {
211 UINT64 numStoredD3DDebugMessages =
212 infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
213
214 if (numStoredD3DDebugMessages > 0)
215 {
216 for (UINT64 i = 0; i < numStoredD3DDebugMessages; i++)
217 {
218 SIZE_T messageLength = 0;
219 hr = infoQueue->GetMessage(i, nullptr, &messageLength);
220
221 if (SUCCEEDED(hr))
222 {
223 D3D11_MESSAGE *pMessage =
224 reinterpret_cast<D3D11_MESSAGE *>(malloc(messageLength));
225 infoQueue->GetMessage(i, pMessage, &messageLength);
226
227 std::cout << "Message " << i << ":"
228 << " " << pMessage->pDescription << "\n";
229 free(pMessage);
230 }
231 }
232
233 FAIL() << numStoredD3DDebugMessages
234 << " D3D11 SDK Layers message(s) detected! Test Failed.\n";
235 }
236 }
237
238 SafeRelease(infoQueue);
239#endif
240}
241
Geoff Lang63046e22015-07-21 12:43:50 -0400242static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
243{
244 return strstr(allExtensions, extName.c_str()) != nullptr;
245}
246
Geoff Lang8a079e52013-10-18 16:13:33 -0400247bool ANGLETest::extensionEnabled(const std::string &extName)
248{
Geoff Lang63046e22015-07-21 12:43:50 -0400249 return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
250 extName);
251}
252
253bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
254{
255 return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
256}
257
258bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
259{
260 return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
Geoff Lang8a079e52013-10-18 16:13:33 -0400261}
262
Geoff Lang8a079e52013-10-18 16:13:33 -0400263void ANGLETest::setWindowWidth(int width)
264{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400265 mWidth = width;
Geoff Lang8a079e52013-10-18 16:13:33 -0400266}
267
268void ANGLETest::setWindowHeight(int height)
269{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400270 mHeight = height;
Geoff Lang8a079e52013-10-18 16:13:33 -0400271}
272
Geoff Langefc551f2013-10-31 10:20:28 -0400273void ANGLETest::setConfigRedBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400274{
Jamie Madill62af5462014-08-26 13:16:37 -0400275 mEGLWindow->setConfigRedBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400276}
277
Geoff Langefc551f2013-10-31 10:20:28 -0400278void ANGLETest::setConfigGreenBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400279{
Jamie Madill62af5462014-08-26 13:16:37 -0400280 mEGLWindow->setConfigGreenBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400281}
282
Geoff Langefc551f2013-10-31 10:20:28 -0400283void ANGLETest::setConfigBlueBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400284{
Jamie Madill62af5462014-08-26 13:16:37 -0400285 mEGLWindow->setConfigBlueBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400286}
287
Geoff Langefc551f2013-10-31 10:20:28 -0400288void ANGLETest::setConfigAlphaBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400289{
Jamie Madill62af5462014-08-26 13:16:37 -0400290 mEGLWindow->setConfigAlphaBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400291}
292
Geoff Langefc551f2013-10-31 10:20:28 -0400293void ANGLETest::setConfigDepthBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400294{
Jamie Madill62af5462014-08-26 13:16:37 -0400295 mEGLWindow->setConfigDepthBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400296}
297
Geoff Langefc551f2013-10-31 10:20:28 -0400298void ANGLETest::setConfigStencilBits(int bits)
Geoff Lang8a079e52013-10-18 16:13:33 -0400299{
Jamie Madill62af5462014-08-26 13:16:37 -0400300 mEGLWindow->setConfigStencilBits(bits);
Geoff Lang8a079e52013-10-18 16:13:33 -0400301}
302
303void ANGLETest::setMultisampleEnabled(bool enabled)
304{
Jamie Madill62af5462014-08-26 13:16:37 -0400305 mEGLWindow->setMultisample(enabled);
Geoff Lang8a079e52013-10-18 16:13:33 -0400306}
307
Geoff Lang70d0f492015-12-10 17:45:46 -0500308void ANGLETest::setDebugEnabled(bool enabled)
309{
310 mEGLWindow->setDebugEnabled(enabled);
311}
312
Geoff Lang8a079e52013-10-18 16:13:33 -0400313int ANGLETest::getClientVersion() const
314{
Geoff Lang5ade8452015-09-02 11:00:30 -0400315 return mEGLWindow->getClientMajorVersion();
Geoff Lang8a079e52013-10-18 16:13:33 -0400316}
317
Geoff Langb9266272015-01-29 13:25:14 +0000318EGLWindow *ANGLETest::getEGLWindow() const
319{
320 return mEGLWindow;
321}
322
Geoff Lang8a079e52013-10-18 16:13:33 -0400323int ANGLETest::getWindowWidth() const
324{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400325 return mWidth;
Geoff Lang8a079e52013-10-18 16:13:33 -0400326}
327
328int ANGLETest::getWindowHeight() const
329{
Corentin Wallezf3357ee2015-07-22 14:10:19 -0400330 return mHeight;
Geoff Lang8a079e52013-10-18 16:13:33 -0400331}
332
Geoff Langefc551f2013-10-31 10:20:28 -0400333bool ANGLETest::isMultisampleEnabled() const
Geoff Lang8a079e52013-10-18 16:13:33 -0400334{
Jamie Madill62af5462014-08-26 13:16:37 -0400335 return mEGLWindow->isMultisample();
Geoff Lang8a079e52013-10-18 16:13:33 -0400336}
337
338bool ANGLETest::createEGLContext()
339{
Jamie Madill62af5462014-08-26 13:16:37 -0400340 return mEGLWindow->initializeGL(mOSWindow);
Geoff Lang8a079e52013-10-18 16:13:33 -0400341}
342
343bool ANGLETest::destroyEGLContext()
344{
Jamie Madill62af5462014-08-26 13:16:37 -0400345 mEGLWindow->destroyGL();
Geoff Lang8a079e52013-10-18 16:13:33 -0400346 return true;
347}
Geoff Langbb134672013-10-23 13:06:46 -0400348
Geoff Lang0d3683c2014-10-23 11:08:16 -0400349bool ANGLETest::InitTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400350{
351 mOSWindow = CreateOSWindow();
352 if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
353 {
354 return false;
355 }
356
Geoff Lang0d3683c2014-10-23 11:08:16 -0400357 mOSWindow->setVisible(true);
Jamie Madill8add0eb2014-08-26 13:16:35 -0400358
359 return true;
360}
361
Geoff Lang0d3683c2014-10-23 11:08:16 -0400362bool ANGLETest::DestroyTestWindow()
Jamie Madill8add0eb2014-08-26 13:16:35 -0400363{
364 if (mOSWindow)
365 {
366 mOSWindow->destroy();
367 delete mOSWindow;
368 mOSWindow = NULL;
369 }
370
371 return true;
372}
373
Geoff Lang0d3683c2014-10-23 11:08:16 -0400374void ANGLETest::SetWindowVisible(bool isVisible)
Geoff Langbb134672013-10-23 13:06:46 -0400375{
Jamie Madill4119ed32014-10-01 10:41:40 -0400376 mOSWindow->setVisible(isVisible);
Geoff Langbb134672013-10-23 13:06:46 -0400377}
Geoff Lang0d3683c2014-10-23 11:08:16 -0400378
Jamie Madillc3b9b262015-01-30 14:00:51 -0500379bool ANGLETest::isIntel() const
380{
381 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
382 return (rendererString.find("Intel") != std::string::npos);
383}
384
385bool ANGLETest::isAMD() const
386{
387 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
388 return (rendererString.find("AMD") != std::string::npos) ||
389 (rendererString.find("ATI") != std::string::npos);
390}
391
392bool ANGLETest::isNVidia() const
393{
394 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
395 return (rendererString.find("NVIDIA") != std::string::npos);
396}
397
Jamie Madilld55d2832015-10-27 13:59:19 -0400398bool ANGLETest::isD3D11() const
399{
400 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
401 return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
402}
403
Jamie Madill9fc36822015-11-18 13:08:07 -0500404bool ANGLETest::isD3D11_FL93() const
405{
406 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
407 return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
408}
409
410bool ANGLETest::isD3D9() const
411{
412 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
413 return (rendererString.find("Direct3D9") != std::string::npos);
414}
415
416bool ANGLETest::isD3DSM3() const
417{
418 std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
419 return isD3D9() || isD3D11_FL93();
420}
421
Jamie Madillc3b9b262015-01-30 14:00:51 -0500422EGLint ANGLETest::getPlatformRenderer() const
423{
Jamie Madillf6859912015-01-30 17:05:35 -0500424 assert(mEGLWindow);
425 return mEGLWindow->getPlatform().renderer;
Jamie Madillc3b9b262015-01-30 14:00:51 -0500426}
427
Austin Kinrossd544cc92016-01-11 15:26:42 -0800428void ANGLETest::ignoreD3D11SDKLayersWarnings()
429{
430 // Some tests may need to disable the D3D11 SDK Layers Warnings checks
431 mIgnoreD3D11SDKLayersWarnings = true;
432}
433
Geoff Lang0d3683c2014-10-23 11:08:16 -0400434OSWindow *ANGLETest::mOSWindow = NULL;
435
436void ANGLETestEnvironment::SetUp()
437{
438 if (!ANGLETest::InitTestWindow())
439 {
440 FAIL() << "Failed to create ANGLE test window.";
441 }
442}
443
444void ANGLETestEnvironment::TearDown()
445{
446 ANGLETest::DestroyTestWindow();
447}