1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Config query tests.
22 *//*--------------------------------------------------------------------*/
24 #include "teglQueryConfigTests.hpp"
25 #include "teglSimpleConfigCase.hpp"
26 #include "tcuTestLog.hpp"
27 #include "tcuTestContext.hpp"
28 #include "tcuCommandLine.hpp"
29 #include "egluCallLogWrapper.hpp"
30 #include "egluStrUtil.hpp"
31 #include "egluUtil.hpp"
32 #include "eglwLibrary.hpp"
33 #include "eglwEnums.hpp"
34 #include "deRandom.hpp"
44 using eglu::ConfigInfo;
48 static void logConfigAttribute (TestLog& log, EGLenum attrib, EGLint value)
50 log << TestLog::Message << " " << eglu::getConfigAttribName(attrib) << ": " << eglu::getConfigAttribValueStr(attrib, value) << TestLog::EndMessage;
53 static bool isAttributePresent (const eglu::Version& version, EGLenum attribute)
58 if (version < eglu::Version(1, 3)) return false;
60 case EGL_LUMINANCE_SIZE:
61 case EGL_ALPHA_MASK_SIZE:
62 case EGL_COLOR_BUFFER_TYPE:
63 case EGL_MATCH_NATIVE_PIXMAP:
64 if (version < eglu::Version(1, 2)) return false;
66 case EGL_BIND_TO_TEXTURE_RGB:
67 case EGL_BIND_TO_TEXTURE_RGBA:
68 case EGL_MAX_SWAP_INTERVAL:
69 case EGL_MIN_SWAP_INTERVAL:
70 case EGL_RENDERABLE_TYPE:
71 if (version < eglu::Version(1, 1)) return false;
80 class GetConfigsBoundsCase : public TestCase, protected eglu::CallLogWrapper
83 GetConfigsBoundsCase (EglTestContext& eglTestCtx, const char* name, const char* description)
84 : TestCase (eglTestCtx, name, description)
85 , CallLogWrapper(eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
86 , m_display (EGL_NO_DISPLAY)
92 DE_ASSERT(m_display == EGL_NO_DISPLAY);
93 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
94 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
99 m_eglTestCtx.getLibrary().terminate(m_display);
100 m_display = EGL_NO_DISPLAY;
103 void checkGetConfigsBounds (de::Random& rnd, const int numConfigAll, const int numConfigRequested)
105 tcu::TestLog& log = m_testCtx.getLog();
106 std::vector<EGLConfig> buffer (numConfigAll + 10);
108 std::vector<deUint32> magicBuffer ((buffer.size() * sizeof(EGLConfig)) / sizeof(deUint32) + 1);
109 const EGLConfig* magicConfigs = reinterpret_cast<EGLConfig*>(&magicBuffer[0]);
111 int numConfigReturned;
113 // Fill buffers with magic
114 for (size_t ndx = 0; ndx < magicBuffer.size(); ndx++) magicBuffer[ndx] = rnd.getUint32();
115 for (size_t ndx = 0; ndx < buffer.size(); ndx++) buffer[ndx] = magicConfigs[ndx];
117 eglGetConfigs(m_display, &buffer[0], numConfigRequested, &numConfigReturned);
118 eglu::checkError(eglGetError(), DE_NULL, __FILE__, __LINE__);
120 log << TestLog::Message << numConfigReturned << " configs returned" << TestLog::EndMessage;
122 // Compare results with stored magic
124 int numOverwritten = 0;
126 for (size_t ndx = 0; ndx < buffer.size(); ndx++)
128 if (buffer[ndx] == magicConfigs[ndx])
130 numOverwritten = (int)ndx;
135 log << TestLog::Message << numOverwritten << " values actually written" << TestLog::EndMessage;
137 if (numConfigReturned > deMax32(numConfigRequested, 0))
139 log << TestLog::Message << "Fail, more configs returned than requested." << TestLog::EndMessage;
140 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Too many configs returned");
143 if (numOverwritten > deMax32(numConfigReturned, 0))
145 log << TestLog::Message << "Fail, buffer overflow detected." << TestLog::EndMessage;
146 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer overflow");
148 else if (numOverwritten != numConfigReturned)
150 log << TestLog::Message << "Fail, reported number of returned configs differs from number of values written." << TestLog::EndMessage;
151 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect size");
156 IterateResult iterate (void)
158 tcu::TestLog& log = m_testCtx.getLog();
163 eglGetConfigs(m_display, 0, 0, &numConfigAll);
165 log << TestLog::Message << numConfigAll << " configs available" << TestLog::EndMessage;
166 log << TestLog::Message << TestLog::EndMessage;
168 if (numConfigAll > 0)
170 de::Random rnd (123);
172 for (int i = 0; i < 5; i++)
174 checkGetConfigsBounds(rnd, numConfigAll, rnd.getInt(0, numConfigAll));
175 log << TestLog::Message << TestLog::EndMessage;
178 checkGetConfigsBounds(rnd, numConfigAll, -1);
182 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No configs");
185 enableLogging(false);
191 EGLDisplay m_display;
194 class GetConfigAttribCase : public TestCase, protected eglu::CallLogWrapper
197 GetConfigAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description);
201 IterateResult iterate (void);
203 EGLint getValue (EGLConfig config, EGLenum attrib, bool logValue=true);
205 virtual void executeTest (EGLConfig config) = 0;
208 EGLDisplay m_display;
211 std::vector<EGLConfig> m_configs;
212 std::vector<EGLConfig>::const_iterator m_configsIter;
215 GetConfigAttribCase::GetConfigAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description)
216 : TestCase (eglTestCtx, name, description)
217 , CallLogWrapper (eglTestCtx.getLibrary(), eglTestCtx.getTestContext().getLog())
218 , m_display (EGL_NO_DISPLAY)
222 void GetConfigAttribCase::init (void)
224 DE_ASSERT(m_display == EGL_NO_DISPLAY);
225 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
226 m_configs = eglu::getConfigs(m_eglTestCtx.getLibrary(), m_display);
227 m_configsIter = m_configs.begin();
229 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
232 void GetConfigAttribCase::deinit (void)
234 m_eglTestCtx.getLibrary().terminate(m_display);
235 m_display = EGL_NO_DISPLAY;
238 tcu::TestNode::IterateResult GetConfigAttribCase::iterate (void)
240 tcu::TestLog& log = m_testCtx.getLog();
242 if (m_configsIter == m_configs.end())
244 log << TestLog::Message << "No configs available." << TestLog::EndMessage;
249 const EGLConfig config = *m_configsIter;
252 eglGetConfigAttrib(m_display, config, EGL_CONFIG_ID, &id);
253 eglu::checkError(eglGetError(), DE_NULL, __FILE__, __LINE__);
254 log << TestLog::Message << "Config ID " << id << TestLog::EndMessage;
259 log << TestLog::Message << TestLog::EndMessage;
263 if (m_configsIter == m_configs.end())
269 EGLint GetConfigAttribCase::getValue (EGLConfig config, EGLenum attrib, bool logValue)
271 TestLog& log = m_testCtx.getLog();
274 eglGetConfigAttrib(m_display, config, attrib, &value);
275 eglu::checkError(eglGetError(), DE_NULL, __FILE__, __LINE__);
278 logConfigAttribute(log, attrib, value);
283 class GetConfigAttribSimpleCase : public GetConfigAttribCase
286 GetConfigAttribSimpleCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLenum attribute)
287 : GetConfigAttribCase(eglTestCtx, name, description)
288 , m_attrib(attribute)
292 void checkColorBufferType (EGLint value)
294 const bool isRGBBuffer = value == EGL_RGB_BUFFER;
295 const bool isLuminanceBuffer = value == EGL_LUMINANCE_BUFFER;
296 const bool isYuvBuffer = value == EGL_YUV_BUFFER_EXT;
297 const bool hasYuvSupport = eglu::hasExtension(m_eglTestCtx.getLibrary(), m_display, "EGL_EXT_yuv_surface");
299 if (!(isRGBBuffer || isLuminanceBuffer || (isYuvBuffer && hasYuvSupport)))
301 TestLog& log = m_testCtx.getLog();
303 log << TestLog::Message << "Fail, invalid EGL_COLOR_BUFFER_TYPE value" << TestLog::EndMessage;
304 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
308 void checkCaveat (EGLint value)
310 if (!(value == EGL_NONE || value == EGL_SLOW_CONFIG || value == EGL_NON_CONFORMANT_CONFIG))
312 TestLog& log = m_testCtx.getLog();
314 log << TestLog::Message << "Fail, invalid EGL_CONFIG_CAVEAT value" << TestLog::EndMessage;
315 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
319 void checkTransparentType (EGLint value)
321 if (!(value == EGL_NONE || value == EGL_TRANSPARENT_RGB))
323 TestLog& log = m_testCtx.getLog();
325 log << TestLog::Message << "Fail, invalid EGL_TRANSPARENT_TYPE value" << TestLog::EndMessage;
326 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
330 void checkBoolean (EGLenum attrib, EGLint value)
332 if (!(value == EGL_FALSE || value == EGL_TRUE))
334 TestLog& log = m_testCtx.getLog();
336 log << TestLog::Message << "Fail, " << eglu::getConfigAttribStr(attrib) << " should be a boolean value." << TestLog::EndMessage;
337 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
341 void checkInteger (EGLenum attrib, EGLint value)
343 if (attrib == EGL_NATIVE_VISUAL_ID || attrib == EGL_NATIVE_VISUAL_TYPE) // Implementation-defined
346 if (attrib == EGL_CONFIG_ID && value < 1)
348 TestLog& log = m_testCtx.getLog();
350 log << TestLog::Message << "Fail, config IDs should be positive integer values beginning from 1." << TestLog::EndMessage;
351 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
355 void checkSurfaceTypeMask (EGLint value)
357 const EGLint wantedBits = EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT;
359 if ((value & wantedBits) == 0)
361 TestLog& log = m_testCtx.getLog();
363 log << TestLog::Message << "Fail, config does not actually support creation of any surface type?" << TestLog::EndMessage;
364 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
368 void checkAttribute (EGLenum attrib, EGLint value)
372 case EGL_COLOR_BUFFER_TYPE:
373 checkColorBufferType(value);
375 case EGL_CONFIG_CAVEAT:
378 case EGL_TRANSPARENT_TYPE:
379 checkTransparentType(value);
382 case EGL_RENDERABLE_TYPE:
383 // Just print what we know
385 case EGL_SURFACE_TYPE:
386 checkSurfaceTypeMask(value);
388 case EGL_BIND_TO_TEXTURE_RGB:
389 case EGL_BIND_TO_TEXTURE_RGBA:
390 case EGL_NATIVE_RENDERABLE:
391 checkBoolean(attrib, value);
394 checkInteger(attrib, value);
398 void executeTest (EGLConfig config)
400 TestLog& log = m_testCtx.getLog();
401 eglu::Version version = eglu::getVersion(m_eglTestCtx.getLibrary(), m_display);
403 if (!isAttributePresent(version, m_attrib))
405 log << TestLog::Message << eglu::getConfigAttribStr(m_attrib) << " not supported by this EGL version";
413 eglGetConfigAttrib(m_display, config, m_attrib, &value);
414 eglu::checkError(eglGetError(), DE_NULL, __FILE__, __LINE__);
416 logConfigAttribute(log, m_attrib, value);
417 checkAttribute(m_attrib, value);
419 enableLogging(false);
427 class GetConfigAttribBufferSizeCase : public GetConfigAttribCase
430 GetConfigAttribBufferSizeCase (EglTestContext& eglTestCtx, const char* name, const char* description)
431 : GetConfigAttribCase(eglTestCtx, name, description)
435 void executeTest (EGLConfig config)
437 TestLog& log = m_testCtx.getLog();
439 const EGLint colorBufferType = getValue(config, EGL_COLOR_BUFFER_TYPE);
441 const EGLint bufferSize = getValue(config, EGL_BUFFER_SIZE);
442 const EGLint redSize = getValue(config, EGL_RED_SIZE);
443 const EGLint greenSize = getValue(config, EGL_GREEN_SIZE);
444 const EGLint blueSize = getValue(config, EGL_BLUE_SIZE);
445 const EGLint luminanceSize = getValue(config, EGL_LUMINANCE_SIZE);
446 const EGLint alphaSize = getValue(config, EGL_ALPHA_SIZE);
450 log << TestLog::Message << "Fail, alpha size must be zero or positive." << TestLog::EndMessage;
451 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid alpha size");
454 if (colorBufferType == EGL_RGB_BUFFER)
456 if (luminanceSize != 0)
458 log << TestLog::Message << "Fail, luminance size must be zero for an RGB buffer." << TestLog::EndMessage;
459 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid luminance size");
462 if (redSize <= 0 || greenSize <= 0 || blueSize <= 0)
464 log << TestLog::Message << "Fail, RGB component sizes must be positive for an RGB buffer." << TestLog::EndMessage;
465 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color component size");
468 if (bufferSize != (redSize + greenSize + blueSize + alphaSize))
470 log << TestLog::Message << "Fail, buffer size must be equal to the sum of RGB component sizes and alpha size." << TestLog::EndMessage;
471 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid buffer size");
474 else if (colorBufferType == EGL_LUMINANCE_BUFFER)
476 if (luminanceSize <= 0)
478 log << TestLog::Message << "Fail, luminance size must be positive for a luminance buffer." << TestLog::EndMessage;
479 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid luminance size");
482 if (redSize != 0 || greenSize != 0 || blueSize != 0)
484 log << TestLog::Message << "Fail, RGB component sizes must be zero for a luminance buffer." << TestLog::EndMessage;
485 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid color component size");
488 if (bufferSize != (luminanceSize + alphaSize))
490 log << TestLog::Message << "Fail, buffer size must be equal to the sum of luminance size and alpha size." << TestLog::EndMessage;
491 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid buffer size");
497 class GetConfigAttribTransparentValueCase : public GetConfigAttribCase
500 GetConfigAttribTransparentValueCase (EglTestContext& eglTestCtx, const char* name, const char* description)
501 : GetConfigAttribCase(eglTestCtx, name, description)
505 void executeTest (EGLConfig config)
507 TestLog& log = m_testCtx.getLog();
509 const EGLint transparentType = getValue(config, EGL_TRANSPARENT_TYPE);
510 const EGLint redValue = getValue(config, EGL_TRANSPARENT_RED_VALUE);
511 const EGLint greenValue = getValue(config, EGL_TRANSPARENT_GREEN_VALUE);
512 const EGLint blueValue = getValue(config, EGL_TRANSPARENT_BLUE_VALUE);
514 const EGLint redSize = getValue(config, EGL_RED_SIZE);
515 const EGLint greenSize = getValue(config, EGL_GREEN_SIZE);
516 const EGLint blueSize = getValue(config, EGL_BLUE_SIZE);
518 if (transparentType == EGL_TRANSPARENT_RGB)
520 if ( (redValue < 0 || redValue >= (1 << redSize))
521 || (greenValue < 0 || greenValue >= (1 << greenSize))
522 || (blueValue < 0 || blueValue >= (1 << blueSize)) )
524 log << TestLog::Message << "Fail, transparent color values must lie between 0 and the maximum component value." << TestLog::EndMessage;
525 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid transparent color value");
531 QueryConfigTests::QueryConfigTests (EglTestContext& eglTestCtx)
532 : TestCaseGroup(eglTestCtx, "query_config", "Surface config query tests")
536 QueryConfigTests::~QueryConfigTests (void)
540 void QueryConfigTests::init (void)
544 tcu::TestCaseGroup* getConfigsGroup = new tcu::TestCaseGroup(m_testCtx, "get_configs", "eglGetConfigs tests");
545 addChild(getConfigsGroup);
547 getConfigsGroup->addChild(new GetConfigsBoundsCase(m_eglTestCtx, "get_configs_bounds", "eglGetConfigs bounds checking test"));
550 // eglGetConfigAttrib
555 const char* testName;
558 { EGL_BUFFER_SIZE, "buffer_size" },
559 { EGL_RED_SIZE, "red_size" },
560 { EGL_GREEN_SIZE, "green_size" },
561 { EGL_BLUE_SIZE, "blue_size" },
562 { EGL_LUMINANCE_SIZE, "luminance_size" },
563 { EGL_ALPHA_SIZE, "alpha_size" },
564 { EGL_ALPHA_MASK_SIZE, "alpha_mask_size" },
565 { EGL_BIND_TO_TEXTURE_RGB, "bind_to_texture_rgb" },
566 { EGL_BIND_TO_TEXTURE_RGBA, "bind_to_texture_rgba" },
567 { EGL_COLOR_BUFFER_TYPE, "color_buffer_type" },
568 { EGL_CONFIG_CAVEAT, "config_caveat" },
569 { EGL_CONFIG_ID, "config_id" },
570 { EGL_CONFORMANT, "conformant" },
571 { EGL_DEPTH_SIZE, "depth_size" },
572 { EGL_LEVEL, "level" },
573 { EGL_MAX_SWAP_INTERVAL, "max_swap_interval" },
574 { EGL_MIN_SWAP_INTERVAL, "min_swap_interval" },
575 { EGL_NATIVE_RENDERABLE, "native_renderable" },
576 { EGL_NATIVE_VISUAL_TYPE, "native_visual_type" },
577 { EGL_RENDERABLE_TYPE, "renderable_type" },
578 { EGL_SAMPLE_BUFFERS, "sample_buffers" },
579 { EGL_SAMPLES, "samples" },
580 { EGL_STENCIL_SIZE, "stencil_size" },
581 { EGL_SURFACE_TYPE, "surface_type" },
582 { EGL_TRANSPARENT_TYPE, "transparent_type" },
583 { EGL_TRANSPARENT_RED_VALUE, "transparent_red_value" },
584 { EGL_TRANSPARENT_GREEN_VALUE, "transparent_green_value" },
585 { EGL_TRANSPARENT_BLUE_VALUE, "transparent_blue_value" }
588 tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "get_config_attrib", "eglGetConfigAttrib() tests");
589 addChild(simpleGroup);
591 for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(attributes); ndx++)
593 simpleGroup->addChild(new GetConfigAttribSimpleCase(m_eglTestCtx, attributes[ndx].testName, "Simple attribute query case", attributes[ndx].attribute));
597 // Attribute constraints
599 tcu::TestCaseGroup* constraintsGroup = new tcu::TestCaseGroup(m_testCtx, "constraints", "Attribute constraint tests");
600 addChild(constraintsGroup);
602 constraintsGroup->addChild(new GetConfigAttribBufferSizeCase(m_eglTestCtx, "color_buffer_size", "Color buffer component sizes"));
603 constraintsGroup->addChild(new GetConfigAttribTransparentValueCase(m_eglTestCtx, "transparent_value", "Transparent color value"));