1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program EGL Module 3 * --------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 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 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 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. 18 * 19 *//*! 20 * \file 21 * \brief Surface query tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "teglQuerySurfaceTests.hpp" 25 26 #include "teglSimpleConfigCase.hpp" 27 28 #include "egluNativeDisplay.hpp" 29 #include "egluNativeWindow.hpp" 30 #include "egluNativePixmap.hpp" 31 #include "egluStrUtil.hpp" 32 #include "egluUtil.hpp" 33 34 #include "tcuTestLog.hpp" 35 #include "tcuTestContext.hpp" 36 #include "tcuCommandLine.hpp" 37 38 #include "deUniquePtr.hpp" 39 #include "deRandom.hpp" 40 41 #include <string> 42 #include <vector> 43 44 namespace deqp 45 { 46 namespace egl 47 { 48 49 using eglu::ConfigInfo; 50 using tcu::TestLog; 51 52 static void logSurfaceAttribute (tcu::TestLog& log, EGLint attribute, EGLint value) 53 { 54 const char* name = eglu::getSurfaceAttribName(attribute); 55 const eglu::SurfaceAttribValueFmt valueFmt (attribute, value); 56 57 log << TestLog::Message << " " << name << ": " << valueFmt << TestLog::EndMessage; 58 } 59 60 static void logSurfaceAttributes (tcu::TestLog& log, const tcu::egl::Surface& surface, const EGLint* attributes, int num) 61 { 62 for (int ndx = 0; ndx < num; ndx++) 63 { 64 const EGLint attrib = attributes[ndx]; 65 66 logSurfaceAttribute(log, attrib, surface.getAttribute(attrib)); 67 } 68 } 69 70 static void logCommonSurfaceAttributes (tcu::TestLog& log, const tcu::egl::Surface& surface) 71 { 72 static const EGLint attributes[] = 73 { 74 EGL_CONFIG_ID, 75 EGL_WIDTH, 76 EGL_HEIGHT, 77 EGL_HORIZONTAL_RESOLUTION, 78 EGL_VERTICAL_RESOLUTION, 79 EGL_MULTISAMPLE_RESOLVE, 80 EGL_PIXEL_ASPECT_RATIO, 81 EGL_RENDER_BUFFER, 82 EGL_SWAP_BEHAVIOR, 83 EGL_VG_ALPHA_FORMAT, 84 EGL_VG_COLORSPACE 85 }; 86 87 logSurfaceAttributes(log, surface, attributes, DE_LENGTH_OF_ARRAY(attributes)); 88 } 89 90 static void logPbufferSurfaceAttributes (tcu::TestLog& log, const tcu::egl::Surface& surface) 91 { 92 static const EGLint attributes[] = { 93 EGL_LARGEST_PBUFFER, 94 EGL_TEXTURE_FORMAT, 95 EGL_TEXTURE_TARGET, 96 EGL_MIPMAP_TEXTURE, 97 EGL_MIPMAP_LEVEL, 98 }; 99 100 logSurfaceAttributes(log, surface, attributes, DE_LENGTH_OF_ARRAY(attributes)); 101 } 102 103 class QuerySurfaceCase : public SimpleConfigCase 104 { 105 public: 106 QuerySurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds); 107 108 void checkCommonAttributes (const tcu::egl::Surface& surface, const ConfigInfo& info); 109 void checkNonPbufferAttributes (EGLDisplay display, const tcu::egl::Surface& surface); 110 }; 111 112 QuerySurfaceCase::QuerySurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 113 : SimpleConfigCase(eglTestCtx, name, description, configIds) 114 { 115 } 116 117 void QuerySurfaceCase::checkCommonAttributes (const tcu::egl::Surface& surface, const ConfigInfo& info) 118 { 119 tcu::TestLog& log = m_testCtx.getLog(); 120 121 // Attributes which are common to all surface types 122 123 // Config ID 124 { 125 const EGLint id = surface.getAttribute(EGL_CONFIG_ID); 126 127 if (id != info.configId) 128 { 129 log << TestLog::Message << " Fail, config ID " << id << " does not match the one used to create the surface" << TestLog::EndMessage; 130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Config ID mismatch"); 131 } 132 } 133 134 // Width and height 135 { 136 const EGLint width = surface.getWidth(); 137 const EGLint height = surface.getHeight(); 138 139 if (width <= 0 || height <= 0) 140 { 141 log << TestLog::Message << " Fail, invalid surface size " << width << "x" << height << TestLog::EndMessage; 142 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size"); 143 } 144 } 145 146 // Horizontal and vertical resolution 147 { 148 const EGLint hRes = surface.getAttribute(EGL_HORIZONTAL_RESOLUTION); 149 const EGLint vRes = surface.getAttribute(EGL_VERTICAL_RESOLUTION); 150 151 if ((hRes <= 0 || vRes <= 0) && (hRes != EGL_UNKNOWN && vRes != EGL_UNKNOWN)) 152 { 153 log << TestLog::Message << " Fail, invalid surface resolution " << hRes << "x" << vRes << TestLog::EndMessage; 154 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface resolution"); 155 } 156 } 157 158 // Pixel aspect ratio 159 { 160 const EGLint pixelRatio = surface.getAttribute(EGL_PIXEL_ASPECT_RATIO); 161 162 if (pixelRatio <= 0 && pixelRatio != EGL_UNKNOWN) 163 { 164 log << TestLog::Message << " Fail, invalid pixel aspect ratio " << surface.getAttribute(EGL_PIXEL_ASPECT_RATIO) << TestLog::EndMessage; 165 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid pixel aspect ratio"); 166 } 167 } 168 169 // Render buffer 170 { 171 const EGLint renderBuffer = surface.getAttribute(EGL_RENDER_BUFFER); 172 173 if (renderBuffer != EGL_BACK_BUFFER && renderBuffer != EGL_SINGLE_BUFFER) 174 { 175 log << TestLog::Message << " Fail, invalid render buffer value " << renderBuffer << TestLog::EndMessage; 176 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid render buffer"); 177 } 178 } 179 180 // Multisample resolve 181 { 182 const EGLint multisampleResolve = surface.getAttribute(EGL_MULTISAMPLE_RESOLVE); 183 184 if (multisampleResolve != EGL_MULTISAMPLE_RESOLVE_DEFAULT && multisampleResolve != EGL_MULTISAMPLE_RESOLVE_BOX) 185 { 186 log << TestLog::Message << " Fail, invalid multisample resolve value " << multisampleResolve << TestLog::EndMessage; 187 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid multisample resolve"); 188 } 189 190 if (multisampleResolve == EGL_MULTISAMPLE_RESOLVE_BOX && !(info.surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) 191 { 192 log << TestLog::Message << " Fail, multisample resolve is reported as box filter but configuration does not support it." << TestLog::EndMessage; 193 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid multisample resolve"); 194 } 195 } 196 197 // Swap behavior 198 { 199 const EGLint swapBehavior = surface.getAttribute(EGL_SWAP_BEHAVIOR); 200 201 if (swapBehavior != EGL_BUFFER_DESTROYED && swapBehavior != EGL_BUFFER_PRESERVED) 202 { 203 log << TestLog::Message << " Fail, invalid swap behavior value " << swapBehavior << TestLog::EndMessage; 204 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid swap behavior"); 205 } 206 207 if (swapBehavior == EGL_BUFFER_PRESERVED && !(info.surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) 208 { 209 log << TestLog::Message << " Fail, swap behavior is reported as preserve but configuration does not support it." << TestLog::EndMessage; 210 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid swap behavior"); 211 } 212 } 213 214 // OpenVG alpha format 215 { 216 const EGLint vgAlphaFormat = surface.getAttribute(EGL_VG_ALPHA_FORMAT); 217 218 if (vgAlphaFormat != EGL_VG_ALPHA_FORMAT_NONPRE && vgAlphaFormat != EGL_VG_ALPHA_FORMAT_PRE) 219 { 220 log << TestLog::Message << " Fail, invalid OpenVG alpha format value " << vgAlphaFormat << TestLog::EndMessage; 221 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid OpenVG alpha format"); 222 } 223 224 if (vgAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE && !(info.surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT)) 225 { 226 log << TestLog::Message << " Fail, OpenVG is set to use premultiplied alpha but configuration does not support it." << TestLog::EndMessage; 227 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid OpenVG alpha format"); 228 } 229 } 230 231 // OpenVG color space 232 { 233 const EGLint vgColorspace = surface.getAttribute(EGL_VG_COLORSPACE); 234 235 if (vgColorspace != EGL_VG_COLORSPACE_sRGB && vgColorspace != EGL_VG_COLORSPACE_LINEAR) 236 { 237 log << TestLog::Message << " Fail, invalid OpenVG color space value " << vgColorspace << TestLog::EndMessage; 238 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid OpenVG color space"); 239 } 240 241 if (vgColorspace == EGL_VG_COLORSPACE_LINEAR && !(info.surfaceType & EGL_VG_COLORSPACE_LINEAR_BIT)) 242 { 243 log << TestLog::Message << " Fail, OpenVG is set to use a linear color space but configuration does not support it." << TestLog::EndMessage; 244 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid OpenVG color space"); 245 } 246 } 247 } 248 249 void QuerySurfaceCase::checkNonPbufferAttributes (EGLDisplay display, const tcu::egl::Surface& surface) 250 { 251 const EGLint uninitializedMagicValue = -42; 252 tcu::TestLog& log = m_testCtx.getLog(); 253 EGLint value = uninitializedMagicValue; 254 255 static const EGLint pbufferAttribs[] = { 256 EGL_LARGEST_PBUFFER, 257 EGL_TEXTURE_FORMAT, 258 EGL_TEXTURE_TARGET, 259 EGL_MIPMAP_TEXTURE, 260 EGL_MIPMAP_LEVEL, 261 }; 262 263 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pbufferAttribs); ndx++) 264 { 265 const EGLint attribute = pbufferAttribs[ndx]; 266 const std::string name = eglu::getSurfaceAttribName(pbufferAttribs[ndx]); 267 268 eglQuerySurface(display, surface.getEGLSurface(), attribute, &value); 269 270 { 271 const EGLint error = eglGetError(); 272 273 if (error != EGL_SUCCESS) 274 { 275 log << TestLog::Message << " Fail, querying " << name << " from a non-pbuffer surface should not result in an error, received " 276 << eglu::getErrorStr(error) << TestLog::EndMessage; 277 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal error condition"); 278 } 279 280 break; 281 } 282 283 // "For a window or pixmap surface, the contents of value are not modified." 284 if (value != uninitializedMagicValue) 285 { 286 log << TestLog::Message << " Fail, return value contents were modified when querying " << name << " from a non-pbuffer surface." << TestLog::EndMessage; 287 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal modification of return value"); 288 } 289 } 290 } 291 292 class QuerySurfaceSimpleWindowCase : public QuerySurfaceCase 293 { 294 public: 295 QuerySurfaceSimpleWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 296 : QuerySurfaceCase(eglTestCtx, name, description, configIds) 297 { 298 } 299 300 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 301 { 302 tcu::TestLog& log = m_testCtx.getLog(); 303 const int width = 64; 304 const int height = 64; 305 306 ConfigInfo info; 307 display.describeConfig(config, info); 308 309 log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage; 310 TCU_CHECK_EGL(); 311 312 de::UniquePtr<eglu::NativeWindow> window(m_eglTestCtx.createNativeWindow(display.getEGLDisplay(), config, DE_NULL, width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))); 313 tcu::egl::WindowSurface surface(display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display.getEGLDisplay(), config, DE_NULL)); 314 315 logCommonSurfaceAttributes(log, surface); 316 317 checkCommonAttributes(surface, info); 318 checkNonPbufferAttributes(display.getEGLDisplay(), surface); 319 } 320 }; 321 322 class QuerySurfaceSimplePixmapCase : public QuerySurfaceCase 323 { 324 public: 325 QuerySurfaceSimplePixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 326 : QuerySurfaceCase(eglTestCtx, name, description, configIds) 327 { 328 } 329 330 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 331 { 332 tcu::TestLog& log = m_testCtx.getLog(); 333 const int width = 64; 334 const int height = 64; 335 336 ConfigInfo info; 337 display.describeConfig(config, info); 338 339 log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage; 340 TCU_CHECK_EGL(); 341 342 de::UniquePtr<eglu::NativePixmap> pixmap (m_eglTestCtx.createNativePixmap(display.getEGLDisplay(), config, DE_NULL, width, height)); 343 tcu::egl::PixmapSurface surface (display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display.getEGLDisplay(), config, DE_NULL)); 344 345 logCommonSurfaceAttributes(log, surface); 346 347 checkCommonAttributes(surface, info); 348 checkNonPbufferAttributes(display.getEGLDisplay(), surface); 349 } 350 }; 351 352 class QuerySurfaceSimplePbufferCase : public QuerySurfaceCase 353 { 354 public: 355 QuerySurfaceSimplePbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 356 : QuerySurfaceCase(eglTestCtx, name, description, configIds) 357 { 358 } 359 360 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 361 { 362 tcu::TestLog& log = m_testCtx.getLog(); 363 int width = 64; 364 int height = 64; 365 366 ConfigInfo info; 367 display.describeConfig(config, info); 368 369 log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage; 370 TCU_CHECK_EGL(); 371 372 // Clamp to maximums reported by implementation 373 width = deMin32(width, display.getConfigAttrib(config, EGL_MAX_PBUFFER_WIDTH)); 374 height = deMin32(height, display.getConfigAttrib(config, EGL_MAX_PBUFFER_HEIGHT)); 375 376 if (width == 0 || height == 0) 377 { 378 log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage; 379 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size"); 380 return; 381 } 382 383 const EGLint attribs[] = 384 { 385 EGL_WIDTH, width, 386 EGL_HEIGHT, height, 387 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE, 388 EGL_NONE 389 }; 390 391 { 392 tcu::egl::PbufferSurface surface(display, config, attribs); 393 394 logCommonSurfaceAttributes(log, surface); 395 logPbufferSurfaceAttributes(log, surface); 396 397 checkCommonAttributes(surface, info); 398 399 // Pbuffer-specific attributes 400 401 // Largest pbuffer 402 { 403 const EGLint largestPbuffer = surface.getAttribute(EGL_LARGEST_PBUFFER); 404 405 if (largestPbuffer != EGL_FALSE && largestPbuffer != EGL_TRUE) 406 { 407 log << TestLog::Message << " Fail, invalid largest pbuffer value " << largestPbuffer << TestLog::EndMessage; 408 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid largest pbuffer"); 409 } 410 } 411 412 // Texture format 413 { 414 const EGLint textureFormat = surface.getAttribute(EGL_TEXTURE_FORMAT); 415 416 if (textureFormat != EGL_NO_TEXTURE && textureFormat != EGL_TEXTURE_RGB && textureFormat != EGL_TEXTURE_RGBA) 417 { 418 log << TestLog::Message << " Fail, invalid texture format value " << textureFormat << TestLog::EndMessage; 419 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture format"); 420 } 421 } 422 423 // Texture target 424 { 425 const EGLint textureTarget = surface.getAttribute(EGL_TEXTURE_TARGET); 426 427 if (textureTarget != EGL_NO_TEXTURE && textureTarget != EGL_TEXTURE_2D) 428 { 429 log << TestLog::Message << " Fail, invalid texture target value " << textureTarget << TestLog::EndMessage; 430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture target"); 431 } 432 } 433 434 // Mipmap texture 435 { 436 const EGLint mipmapTexture = surface.getAttribute(EGL_MIPMAP_TEXTURE); 437 438 if (mipmapTexture != EGL_FALSE && mipmapTexture != EGL_TRUE) 439 { 440 log << TestLog::Message << " Fail, invalid mipmap texture value " << mipmapTexture << TestLog::EndMessage; 441 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid mipmap texture"); 442 } 443 } 444 } 445 } 446 }; 447 448 class SurfaceAttribCase : public SimpleConfigCase 449 { 450 public: 451 SurfaceAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds); 452 virtual ~SurfaceAttribCase (void) {} 453 454 void testAttributes (tcu::egl::Surface& surface, const ConfigInfo& info); 455 }; 456 457 SurfaceAttribCase::SurfaceAttribCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 458 : SimpleConfigCase(eglTestCtx, name, description, configIds) 459 { 460 } 461 462 void SurfaceAttribCase::testAttributes (tcu::egl::Surface& surface, const ConfigInfo& info) 463 { 464 const tcu::egl::Display& display = surface.getDisplay(); 465 tcu::TestLog& log = m_testCtx.getLog(); 466 const int majorVersion = display.getEGLMajorVersion(); 467 const int minorVersion = display.getEGLMinorVersion(); 468 de::Random rnd (deStringHash(m_name.c_str()) ^ 0xf215918f); 469 470 if (majorVersion == 1 && minorVersion == 0) 471 { 472 log << TestLog::Message << "No attributes can be set in EGL 1.0" << TestLog::EndMessage; 473 return; 474 } 475 476 // Mipmap level 477 if (info.renderableType & EGL_OPENGL_ES_BIT || info.renderableType & EGL_OPENGL_ES2_BIT) 478 { 479 const EGLint initialValue = 0xDEADBAAD; 480 EGLint value = initialValue; 481 482 TCU_CHECK_EGL_CALL(eglQuerySurface(surface.getDisplay().getEGLDisplay(), surface.getEGLSurface(), EGL_MIPMAP_LEVEL, &value)); 483 484 logSurfaceAttribute(log, EGL_MIPMAP_LEVEL, value); 485 486 if (dynamic_cast<tcu::egl::PbufferSurface*>(&surface)) 487 { 488 if (value != 0) 489 { 490 log << TestLog::Message << " Fail, initial mipmap level value should be 0, is " << value << TestLog::EndMessage; 491 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default mipmap level"); 492 } 493 } 494 else if (value != initialValue) 495 { 496 log << TestLog::Message << " Fail, eglQuerySurface changed value when querying EGL_MIPMAP_LEVEL for non-pbuffer surface. Result: " << value << ". Expected: " << initialValue << TestLog::EndMessage; 497 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "EGL_MIPMAP_LEVEL query modified result for non-pbuffer surface."); 498 } 499 500 eglSurfaceAttrib(display.getEGLDisplay(), surface.getEGLSurface(), EGL_MIPMAP_LEVEL, 1); 501 502 { 503 const EGLint error = eglGetError(); 504 505 if (error != EGL_SUCCESS) 506 { 507 log << TestLog::Message << " Fail, setting EGL_MIPMAP_LEVEL should not result in an error, received " << eglu::getErrorStr(error) << TestLog::EndMessage; 508 509 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Illegal error condition"); 510 } 511 } 512 } 513 514 // Only mipmap level can be set in EGL 1.3 and lower 515 if (majorVersion == 1 && minorVersion <= 3) return; 516 517 // Multisample resolve 518 { 519 const EGLint value = surface.getAttribute(EGL_MULTISAMPLE_RESOLVE); 520 521 logSurfaceAttribute(log, EGL_MULTISAMPLE_RESOLVE, value); 522 523 if (value != EGL_MULTISAMPLE_RESOLVE_DEFAULT) 524 { 525 log << TestLog::Message << " Fail, initial multisample resolve value should be EGL_MULTISAMPLE_RESOLVE_DEFAULT, is " 526 << eglu::getSurfaceAttribValueStr(EGL_MULTISAMPLE_RESOLVE, value) << TestLog::EndMessage; 527 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid default multisample resolve"); 528 } 529 530 if (info.renderableType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) 531 { 532 log << TestLog::Message << " Box filter is supported by surface, trying to set." << TestLog::EndMessage; 533 534 surface.setAttribute(EGL_MULTISAMPLE_RESOLVE, EGL_MULTISAMPLE_RESOLVE_BOX); 535 536 if (surface.getAttribute(EGL_MULTISAMPLE_RESOLVE) != EGL_MULTISAMPLE_RESOLVE_BOX) 537 { 538 log << TestLog::Message << " Fail, tried to enable box filter but value did not change."; 539 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set multisample resolve"); 540 } 541 } 542 } 543 544 // Swap behavior 545 { 546 const EGLint value = surface.getAttribute(EGL_SWAP_BEHAVIOR); 547 548 logSurfaceAttribute(log, EGL_SWAP_BEHAVIOR, value); 549 550 if (info.renderableType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) 551 { 552 const EGLint nextValue = (value == EGL_BUFFER_DESTROYED) ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED; 553 554 surface.setAttribute(EGL_SWAP_BEHAVIOR, nextValue); 555 556 if (surface.getAttribute(EGL_SWAP_BEHAVIOR) != nextValue) 557 { 558 log << TestLog::Message << " Fail, tried to set swap behavior to " << eglu::getSurfaceAttribStr(nextValue) << TestLog::EndMessage; 559 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to set swap behavior"); 560 } 561 } 562 } 563 } 564 565 class SurfaceAttribWindowCase : public SurfaceAttribCase 566 { 567 public: 568 SurfaceAttribWindowCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 569 : SurfaceAttribCase(eglTestCtx, name, description, configIds) 570 { 571 } 572 573 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 574 { 575 tcu::TestLog& log = m_testCtx.getLog(); 576 const int width = 64; 577 const int height = 64; 578 579 ConfigInfo info; 580 display.describeConfig(config, info); 581 582 log << TestLog::Message << "Creating window surface with config ID " << info.configId << TestLog::EndMessage; 583 TCU_CHECK_EGL(); 584 585 de::UniquePtr<eglu::NativeWindow> window(m_eglTestCtx.createNativeWindow(display.getEGLDisplay(), config, DE_NULL, width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))); 586 tcu::egl::WindowSurface surface(display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display.getEGLDisplay(), config, DE_NULL)); 587 588 testAttributes(surface, info); 589 } 590 }; 591 592 class SurfaceAttribPixmapCase : public SurfaceAttribCase 593 { 594 public: 595 SurfaceAttribPixmapCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 596 : SurfaceAttribCase(eglTestCtx, name, description, configIds) 597 { 598 } 599 600 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 601 { 602 tcu::TestLog& log = m_testCtx.getLog(); 603 const int width = 64; 604 const int height = 64; 605 606 ConfigInfo info; 607 display.describeConfig(config, info); 608 609 log << TestLog::Message << "Creating pixmap surface with config ID " << info.configId << TestLog::EndMessage; 610 TCU_CHECK_EGL(); 611 612 de::UniquePtr<eglu::NativePixmap> pixmap (m_eglTestCtx.createNativePixmap(display.getEGLDisplay(), config, DE_NULL, width, height)); 613 tcu::egl::PixmapSurface surface (display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, display.getEGLDisplay(), config, DE_NULL)); 614 615 testAttributes(surface, info); 616 } 617 }; 618 619 class SurfaceAttribPbufferCase : public SurfaceAttribCase 620 { 621 public: 622 SurfaceAttribPbufferCase (EglTestContext& eglTestCtx, const char* name, const char* description, const std::vector<EGLint>& configIds) 623 : SurfaceAttribCase(eglTestCtx, name, description, configIds) 624 { 625 } 626 627 void executeForConfig (tcu::egl::Display& display, EGLConfig config) 628 { 629 tcu::TestLog& log = m_testCtx.getLog(); 630 int width = 64; 631 int height = 64; 632 633 ConfigInfo info; 634 display.describeConfig(config, info); 635 636 log << TestLog::Message << "Creating pbuffer surface with config ID " << info.configId << TestLog::EndMessage; 637 TCU_CHECK_EGL(); 638 639 // Clamp to maximums reported by implementation 640 width = deMin32(width, display.getConfigAttrib(config, EGL_MAX_PBUFFER_WIDTH)); 641 height = deMin32(height, display.getConfigAttrib(config, EGL_MAX_PBUFFER_HEIGHT)); 642 643 if (width == 0 || height == 0) 644 { 645 log << TestLog::Message << " Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage; 646 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size"); 647 return; 648 } 649 650 const EGLint attribs[] = 651 { 652 EGL_WIDTH, width, 653 EGL_HEIGHT, height, 654 EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE, 655 EGL_NONE 656 }; 657 658 tcu::egl::PbufferSurface surface(display, config, attribs); 659 660 testAttributes(surface, info); 661 } 662 }; 663 664 QuerySurfaceTests::QuerySurfaceTests (EglTestContext& eglTestCtx) 665 : TestCaseGroup(eglTestCtx, "query_surface", "Surface Query Tests") 666 { 667 } 668 669 QuerySurfaceTests::~QuerySurfaceTests (void) 670 { 671 } 672 673 std::vector<EGLint> getConfigs (const tcu::egl::Display& display, EGLint surfaceType) 674 { 675 std::vector<EGLint> out; 676 677 std::vector<EGLConfig> eglConfigs; 678 display.getConfigs(eglConfigs); 679 680 for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++) 681 { 682 ConfigInfo info; 683 display.describeConfig(eglConfigs[ndx], info); 684 685 if (info.surfaceType & surfaceType) 686 out.push_back(info.configId); 687 } 688 689 return out; 690 } 691 692 void QuerySurfaceTests::init (void) 693 { 694 // Simple queries 695 { 696 tcu::TestCaseGroup* simpleGroup = new tcu::TestCaseGroup(m_testCtx, "simple", "Simple queries"); 697 addChild(simpleGroup); 698 699 // Window 700 { 701 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces"); 702 simpleGroup->addChild(windowGroup); 703 704 eglu::FilterList filters; 705 filters << (eglu::ConfigSurfaceType() & EGL_WINDOW_BIT); 706 707 std::vector<NamedConfigIdSet> configIdSets; 708 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 709 710 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 711 windowGroup->addChild(new QuerySurfaceSimpleWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 712 } 713 714 // Pixmap 715 { 716 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces"); 717 simpleGroup->addChild(pixmapGroup); 718 719 eglu::FilterList filters; 720 filters << (eglu::ConfigSurfaceType() & EGL_PIXMAP_BIT); 721 722 std::vector<NamedConfigIdSet> configIdSets; 723 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 724 725 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 726 pixmapGroup->addChild(new QuerySurfaceSimplePixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 727 } 728 729 // Pbuffer 730 { 731 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces"); 732 simpleGroup->addChild(pbufferGroup); 733 734 eglu::FilterList filters; 735 filters << (eglu::ConfigSurfaceType() & EGL_PBUFFER_BIT); 736 737 std::vector<NamedConfigIdSet> configIdSets; 738 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 739 740 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 741 pbufferGroup->addChild(new QuerySurfaceSimplePbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 742 } 743 } 744 745 // Set surface attributes 746 { 747 tcu::TestCaseGroup* setAttributeGroup = new tcu::TestCaseGroup(m_testCtx, "set_attribute", "Setting attributes"); 748 addChild(setAttributeGroup); 749 750 // Window 751 { 752 tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces"); 753 setAttributeGroup->addChild(windowGroup); 754 755 eglu::FilterList filters; 756 filters << (eglu::ConfigSurfaceType() & EGL_WINDOW_BIT); 757 758 std::vector<NamedConfigIdSet> configIdSets; 759 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 760 761 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 762 windowGroup->addChild(new SurfaceAttribWindowCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 763 } 764 765 // Pixmap 766 { 767 tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces"); 768 setAttributeGroup->addChild(pixmapGroup); 769 770 eglu::FilterList filters; 771 filters << (eglu::ConfigSurfaceType() & EGL_PIXMAP_BIT); 772 773 std::vector<NamedConfigIdSet> configIdSets; 774 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 775 776 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 777 pixmapGroup->addChild(new SurfaceAttribPixmapCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 778 } 779 780 // Pbuffer 781 { 782 tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces"); 783 setAttributeGroup->addChild(pbufferGroup); 784 785 eglu::FilterList filters; 786 filters << (eglu::ConfigSurfaceType() & EGL_PBUFFER_BIT); 787 788 std::vector<NamedConfigIdSet> configIdSets; 789 NamedConfigIdSet::getDefaultSets(configIdSets, m_eglTestCtx.getConfigs(), filters); 790 791 for (std::vector<NamedConfigIdSet>::iterator i = configIdSets.begin(); i != configIdSets.end(); i++) 792 pbufferGroup->addChild(new SurfaceAttribPbufferCase(m_eglTestCtx, i->getName(), i->getDescription(), i->getConfigIds())); 793 } 794 } 795 } 796 797 } // egl 798 } // deqp 799