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 GLES2 resource sharing performnace tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "teglGLES2SharedRenderingPerfTests.hpp" 25 26 #include "tcuTestLog.hpp" 27 28 #include "egluUtil.hpp" 29 #include "eglwLibrary.hpp" 30 #include "eglwEnums.hpp" 31 32 #include "gluDefs.hpp" 33 #include "glwDefs.hpp" 34 #include "glwEnums.hpp" 35 #include "glwFunctions.hpp" 36 37 #include "deThread.hpp" 38 #include "deClock.h" 39 #include "deStringUtil.hpp" 40 #include "deSTLUtil.hpp" 41 42 #include <vector> 43 #include <string> 44 #include <algorithm> 45 #include <cmath> 46 47 namespace deqp 48 { 49 namespace egl 50 { 51 52 using tcu::TestLog; 53 using std::vector; 54 using std::string; 55 56 using namespace glw; 57 using namespace eglw; 58 59 namespace 60 { 61 62 struct TestConfig 63 { 64 enum TextureType 65 { 66 TEXTURETYPE_TEXTURE = 0, 67 TEXTURETYPE_SHARED_TEXTURE, 68 TEXTURETYPE_IMAGE, 69 TEXTURETYPE_SHARED_IMAGE, 70 TEXTURETYPE_SHARED_IMAGE_TEXTURE 71 }; 72 73 int threadCount; 74 int perThreadContextCount; 75 76 int frameCount; 77 int drawCallCount; 78 int triangleCount; 79 80 bool sharedContexts; 81 82 bool useCoordBuffer; 83 bool sharedCoordBuffer; 84 85 bool useIndices; 86 bool useIndexBuffer; 87 bool sharedIndexBuffer; 88 89 bool useTexture; 90 TextureType textureType; 91 92 bool sharedProgram; 93 94 int textureWidth; 95 int textureHeight; 96 97 int surfaceWidth; 98 int surfaceHeight; 99 }; 100 101 class TestContext 102 { 103 public: 104 TestContext (EglTestContext& eglTestCtx, EGLDisplay display, EGLConfig eglConfig, const TestConfig& config, bool share, TestContext* parent); 105 ~TestContext (void); 106 107 void render (void); 108 109 EGLContext getEGLContext (void) { return m_eglContext; } 110 111 GLuint getCoordBuffer (void) const { return m_coordBuffer; } 112 GLuint getIndexBuffer (void) const { return m_indexBuffer; } 113 GLuint getTexture (void) const { return m_texture; } 114 GLuint getProgram (void) const { return m_program; } 115 EGLImageKHR getEGLImage (void) const { return m_eglImage; } 116 117 private: 118 TestContext* m_parent; 119 EglTestContext& m_testCtx; 120 TestConfig m_config; 121 122 EGLDisplay m_eglDisplay; 123 EGLContext m_eglContext; 124 EGLSurface m_eglSurface; 125 126 glw::Functions m_gl; 127 128 GLuint m_coordBuffer; 129 GLuint m_indexBuffer; 130 GLuint m_texture; 131 GLuint m_program; 132 133 EGLImageKHR m_eglImage; 134 135 GLuint m_coordLoc; 136 GLuint m_textureLoc; 137 138 vector<float> m_coordData; 139 vector<deUint16> m_indexData; 140 141 EGLImageKHR createEGLImage (void); 142 GLuint createTextureFromImage (EGLImageKHR image); 143 144 // Not supported 145 TestContext& operator= (const TestContext&); 146 TestContext (const TestContext&); 147 }; 148 149 namespace 150 { 151 152 void createCoordData (vector<float>& data, const TestConfig& config) 153 { 154 if (config.useIndices) 155 { 156 for (int triangleNdx = 0; triangleNdx < 2; triangleNdx++) 157 { 158 const float x1 = -1.0f; 159 const float y1 = -1.0f; 160 161 const float x2 = 1.0f; 162 const float y2 = 1.0f; 163 164 const float side = ((triangleNdx % 2) == 0 ? 1.0f : -1.0f); 165 166 data.push_back(side * x1); 167 data.push_back(side * y1); 168 169 data.push_back(side * x2); 170 data.push_back(side * y1); 171 172 data.push_back(side * x2); 173 data.push_back(side * y2); 174 } 175 } 176 else 177 { 178 data.reserve(config.triangleCount * 3 * 2); 179 180 for (int triangleNdx = 0; triangleNdx < config.triangleCount; triangleNdx++) 181 { 182 const float x1 = -1.0f; 183 const float y1 = -1.0f; 184 185 const float x2 = 1.0f; 186 const float y2 = 1.0f; 187 188 const float side = ((triangleNdx % 2) == 0 ? 1.0f : -1.0f); 189 190 data.push_back(side * x1); 191 data.push_back(side * y1); 192 193 data.push_back(side * x2); 194 data.push_back(side * y1); 195 196 data.push_back(side * x2); 197 data.push_back(side * y2); 198 } 199 } 200 } 201 202 GLuint createCoordBuffer (const glw::Functions& gl, const TestConfig& config) 203 { 204 GLuint buffer; 205 vector<float> data; 206 207 createCoordData(data, config); 208 209 gl.genBuffers(1, &buffer); 210 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers()"); 211 gl.bindBuffer(GL_ARRAY_BUFFER, buffer); 212 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()"); 213 gl.bufferData(GL_ARRAY_BUFFER, (GLsizei)(data.size() * sizeof(float)), &(data[0]), GL_STATIC_DRAW); 214 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData()"); 215 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 216 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()"); 217 218 return buffer; 219 } 220 221 void createIndexData (vector<deUint16>& data, const TestConfig& config) 222 { 223 for (int triangleNdx = 0; triangleNdx < config.triangleCount; triangleNdx++) 224 { 225 if ((triangleNdx % 2) == 0) 226 { 227 data.push_back(0); 228 data.push_back(1); 229 data.push_back(2); 230 } 231 else 232 { 233 data.push_back(2); 234 data.push_back(3); 235 data.push_back(0); 236 } 237 } 238 } 239 240 GLuint createIndexBuffer (const glw::Functions& gl, const TestConfig& config) 241 { 242 GLuint buffer; 243 vector<deUint16> data; 244 245 createIndexData(data, config); 246 247 gl.genBuffers(1, &buffer); 248 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers()"); 249 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 250 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()"); 251 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizei)(data.size() * sizeof(deUint16)), &(data[0]), GL_STATIC_DRAW); 252 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData()"); 253 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 254 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()"); 255 256 return buffer; 257 } 258 259 void createTextureData (vector<deUint8>& data, const TestConfig& config) 260 { 261 for (int x = 0; x < config.textureWidth; x++) 262 { 263 for (int y = 0; y < config.textureHeight; y++) 264 { 265 data.push_back((deUint8)((255*x)/255)); 266 data.push_back((deUint8)((255*y)/255)); 267 data.push_back((deUint8)((255*x*y)/(255*255))); 268 data.push_back(255); 269 } 270 } 271 } 272 273 GLuint createTexture (const glw::Functions& gl, const TestConfig& config) 274 { 275 GLuint texture; 276 vector<deUint8> data; 277 278 createTextureData(data, config); 279 280 gl.genTextures(1, &texture); 281 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures()"); 282 gl.bindTexture(GL_TEXTURE_2D, texture); 283 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()"); 284 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 285 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 286 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 287 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 288 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 289 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 290 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 291 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); 292 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, config.textureWidth, config.textureWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(data[0])); 293 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D()"); 294 gl.bindTexture(GL_TEXTURE_2D, 0); 295 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()"); 296 297 return texture; 298 } 299 300 GLuint createProgram (const glw::Functions& gl, const TestConfig& config) 301 { 302 GLuint vertexShader = gl.createShader(GL_VERTEX_SHADER); 303 GLuint fragmentShader = gl.createShader(GL_FRAGMENT_SHADER); 304 305 if (config.useTexture) 306 { 307 const char* vertexShaderSource = 308 "attribute mediump vec2 a_coord;\n" 309 "varying mediump vec2 v_texCoord;\n" 310 "void main(void)\n" 311 "{\n" 312 "\tv_texCoord = 0.5 * a_coord + vec2(0.5);\n" 313 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n" 314 "}\n"; 315 316 const char* fragmentShaderSource = 317 "uniform sampler2D u_sampler;\n" 318 "varying mediump vec2 v_texCoord;\n" 319 "void main(void)\n" 320 "{\n" 321 "\tgl_FragColor = texture2D(u_sampler, v_texCoord);\n" 322 "}\n"; 323 324 gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL); 325 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()"); 326 gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL); 327 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()"); 328 } 329 else 330 { 331 const char* vertexShaderSource = 332 "attribute mediump vec2 a_coord;\n" 333 "varying mediump vec4 v_color;\n" 334 "void main(void)\n" 335 "{\n" 336 "\tv_color = vec4(0.5 * a_coord + vec2(0.5), 0.5, 1.0);\n" 337 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n" 338 "}\n"; 339 340 const char* fragmentShaderSource = 341 "varying mediump vec4 v_color;\n" 342 "void main(void)\n" 343 "{\n" 344 "\tgl_FragColor = v_color;\n" 345 "}\n"; 346 347 gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL); 348 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()"); 349 gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL); 350 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()"); 351 } 352 353 gl.compileShader(vertexShader); 354 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader()"); 355 gl.compileShader(fragmentShader); 356 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader()"); 357 358 { 359 GLint status; 360 361 gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &status); 362 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 363 364 if (!status) 365 { 366 string log; 367 GLint length; 368 369 gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length); 370 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 371 log.resize(length, 0); 372 373 gl.getShaderInfoLog(vertexShader, (GLsizei)log.size(), &length, &(log[0])); 374 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog()"); 375 376 throw std::runtime_error(log.c_str()); 377 } 378 } 379 380 { 381 GLint status; 382 383 gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); 384 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 385 386 if (!status) 387 { 388 string log; 389 GLint length; 390 391 gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length); 392 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()"); 393 log.resize(length, 0); 394 395 gl.getShaderInfoLog(fragmentShader, (GLsizei)log.size(), &length, &(log[0])); 396 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog()"); 397 398 throw std::runtime_error(log.c_str()); 399 } 400 } 401 402 { 403 GLuint program = gl.createProgram(); 404 405 gl.attachShader(program, vertexShader); 406 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader()"); 407 gl.attachShader(program, fragmentShader); 408 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader()"); 409 410 gl.linkProgram(program); 411 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()"); 412 413 { 414 GLint status; 415 416 gl.getProgramiv(program, GL_LINK_STATUS, &status); 417 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()"); 418 419 if (!status) 420 { 421 string log; 422 GLsizei length; 423 424 gl.getProgramInfoLog(program, 0, &length, DE_NULL); 425 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog()"); 426 log.resize(length, 0); 427 428 gl.getProgramInfoLog(program, (GLsizei)log.size(), &length, &(log[0])); 429 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog()"); 430 431 throw std::runtime_error(log.c_str()); 432 } 433 } 434 435 gl.deleteShader(vertexShader); 436 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader()"); 437 gl.deleteShader(fragmentShader); 438 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader()"); 439 440 return program; 441 } 442 } 443 444 EGLContext createEGLContext (EglTestContext& testCtx, EGLDisplay eglDisplay, EGLConfig eglConfig, EGLContext share) 445 { 446 const Library& egl = testCtx.getLibrary(); 447 const EGLint attribList[] = 448 { 449 EGL_CONTEXT_CLIENT_VERSION, 2, 450 EGL_NONE 451 }; 452 453 EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API)); 454 455 EGLContext context = egl.createContext(eglDisplay, eglConfig, share, attribList); 456 EGLU_CHECK_MSG(egl, "eglCreateContext()"); 457 458 return context; 459 } 460 461 EGLSurface createEGLSurface (EglTestContext& testCtx, EGLDisplay display, EGLConfig eglConfig, const TestConfig& config) 462 { 463 const Library& egl = testCtx.getLibrary(); 464 const EGLint attribList[] = 465 { 466 EGL_WIDTH, config.surfaceWidth, 467 EGL_HEIGHT, config.surfaceHeight, 468 EGL_NONE 469 }; 470 471 EGLSurface surface = egl.createPbufferSurface(display, eglConfig, attribList); 472 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()"); 473 474 return surface; 475 } 476 477 } // anonymous 478 479 TestContext::TestContext (EglTestContext& testCtx, EGLDisplay eglDisplay, EGLConfig eglConfig, const TestConfig& config, bool share, TestContext* parent) 480 : m_parent (parent) 481 , m_testCtx (testCtx) 482 , m_config (config) 483 , m_eglDisplay (eglDisplay) 484 , m_eglContext (EGL_NO_CONTEXT) 485 , m_eglSurface (EGL_NO_SURFACE) 486 , m_coordBuffer (0) 487 , m_indexBuffer (0) 488 , m_texture (0) 489 , m_program (0) 490 , m_eglImage (EGL_NO_IMAGE_KHR) 491 { 492 const Library& egl = m_testCtx.getLibrary(); 493 494 if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE 495 || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE 496 || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE) 497 { 498 const vector<string> extensions = eglu::getDisplayExtensions(egl, m_eglDisplay); 499 500 if (!de::contains(extensions.begin(), extensions.end(), "EGL_KHR_image_base") || 501 !de::contains(extensions.begin(), extensions.end(), "EGL_KHR_gl_texture_2D_image")) 502 TCU_THROW(NotSupportedError, "EGL_KHR_image_base extensions not supported"); 503 } 504 505 m_eglContext = createEGLContext(m_testCtx, m_eglDisplay, eglConfig, (share && parent ? parent->getEGLContext() : EGL_NO_CONTEXT)); 506 m_eglSurface = createEGLSurface(m_testCtx, m_eglDisplay, eglConfig, config); 507 508 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)); 509 510 { 511 const char* reqExts[] = { "GL_OES_EGL_image" }; 512 m_testCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0), DE_LENGTH_OF_ARRAY(reqExts), reqExts); 513 } 514 515 if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE 516 || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE 517 || m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE) 518 { 519 vector<string> glExts = de::splitString((const char*)m_gl.getString(GL_EXTENSIONS), ' '); 520 521 if (!de::contains(glExts.begin(), glExts.end(), "GL_OES_EGL_image")) 522 TCU_THROW(NotSupportedError, "GL_OES_EGL_image extensions not supported"); 523 524 TCU_CHECK(m_gl.eglImageTargetTexture2DOES); 525 } 526 527 if (m_config.useCoordBuffer && (!m_config.sharedCoordBuffer || !parent)) 528 m_coordBuffer = createCoordBuffer(m_gl, m_config); 529 else if (m_config.useCoordBuffer && m_config.sharedCoordBuffer) 530 m_coordBuffer = parent->getCoordBuffer(); 531 else 532 createCoordData(m_coordData, m_config); 533 534 if (m_config.useIndexBuffer && (!m_config.sharedIndexBuffer || !parent)) 535 m_indexBuffer = createIndexBuffer(m_gl, m_config); 536 else if (m_config.useIndexBuffer && m_config.sharedIndexBuffer) 537 m_indexBuffer = parent->getIndexBuffer(); 538 else if (m_config.useIndices) 539 createIndexData(m_indexData, m_config); 540 541 if (m_config.useTexture) 542 { 543 if (m_config.textureType == TestConfig::TEXTURETYPE_TEXTURE) 544 m_texture = createTexture(m_gl, m_config); 545 else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_TEXTURE) 546 { 547 if (parent) 548 m_texture = parent->getTexture(); 549 else 550 m_texture = createTexture(m_gl, m_config); 551 } 552 else if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE) 553 { 554 m_eglImage = createEGLImage(); 555 m_texture = createTextureFromImage(m_eglImage); 556 } 557 else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE) 558 { 559 if (parent) 560 m_eglImage = parent->getEGLImage(); 561 else 562 m_eglImage = createEGLImage(); 563 564 m_texture = createTextureFromImage(m_eglImage); 565 } 566 else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE) 567 { 568 if (parent) 569 m_texture = parent->getTexture(); 570 else 571 { 572 m_eglImage = createEGLImage(); 573 m_texture = createTextureFromImage(m_eglImage); 574 } 575 } 576 } 577 578 if (!m_config.sharedProgram || !parent) 579 m_program = createProgram(m_gl, m_config); 580 else if (m_config.sharedProgram) 581 m_program = parent->getProgram(); 582 583 m_coordLoc = m_gl.getAttribLocation(m_program, "a_coord"); 584 585 if (m_config.useTexture) 586 m_textureLoc = m_gl.getUniformLocation(m_program, "u_sampler"); 587 588 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); 589 } 590 591 EGLImageKHR TestContext::createEGLImage (void) 592 { 593 GLuint sourceTexture = createTexture(m_gl, m_config); 594 595 try 596 { 597 const Library& egl = m_testCtx.getLibrary(); 598 const EGLint attribList[] = 599 { 600 EGL_GL_TEXTURE_LEVEL_KHR, 0, 601 EGL_NONE 602 }; 603 604 EGLImageKHR image = egl.createImageKHR(m_eglDisplay, m_eglContext, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)sourceTexture, attribList); 605 EGLU_CHECK_MSG(egl, "eglCreateImageKHR()"); 606 607 m_gl.deleteTextures(1, &sourceTexture); 608 GLU_EXPECT_NO_ERROR(m_gl.getError(), "eglCreateImageKHR()"); 609 610 return image; 611 } 612 catch (...) 613 { 614 m_gl.deleteTextures(1, &sourceTexture); 615 throw; 616 } 617 } 618 619 GLuint TestContext::createTextureFromImage (EGLImageKHR image) 620 { 621 GLuint texture = 0; 622 623 try 624 { 625 m_gl.genTextures(1, &texture); 626 m_gl.bindTexture(GL_TEXTURE_2D, texture); 627 m_gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, image); 628 m_gl.bindTexture(GL_TEXTURE_2D, 0); 629 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Creating texture from image"); 630 631 return texture; 632 } 633 catch (...) 634 { 635 m_gl.deleteTextures(1, &texture); 636 throw; 637 } 638 } 639 640 641 TestContext::~TestContext (void) 642 { 643 const Library& egl = m_testCtx.getLibrary(); 644 645 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)); 646 647 if (m_parent == DE_NULL && m_eglImage) 648 EGLU_CHECK_CALL(egl, destroyImageKHR(m_eglDisplay, m_eglImage)); 649 650 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); 651 EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext)); 652 EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface)); 653 } 654 655 void TestContext::render (void) 656 { 657 const Library& egl = m_testCtx.getLibrary(); 658 659 egl.makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); 660 661 for (int frameNdx = 0; frameNdx < m_config.frameCount; frameNdx++) 662 { 663 m_gl.clearColor(0.75f, 0.6f, 0.5f, 1.0f); 664 m_gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 665 666 for (int callNdx = 0; callNdx < m_config.drawCallCount; callNdx++) 667 { 668 m_gl.useProgram(m_program); 669 m_gl.enableVertexAttribArray(m_coordLoc); 670 671 if (m_config.useCoordBuffer) 672 { 673 m_gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffer); 674 m_gl.vertexAttribPointer(m_coordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); 675 m_gl.bindBuffer(GL_ARRAY_BUFFER, 0); 676 } 677 else 678 m_gl.vertexAttribPointer(m_coordLoc, 2, GL_FLOAT, GL_FALSE, 0, &(m_coordData[0])); 679 680 if (m_config.useTexture) 681 { 682 m_gl.bindTexture(GL_TEXTURE_2D, m_texture); 683 m_gl.uniform1i(m_textureLoc, 0); 684 } 685 686 if (m_config.useIndices) 687 { 688 if (m_config.useIndexBuffer) 689 { 690 m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); 691 m_gl.drawElements(GL_TRIANGLES, m_config.triangleCount, GL_UNSIGNED_SHORT, 0); 692 } 693 else 694 m_gl.drawElements(GL_TRIANGLES, m_config.triangleCount, GL_UNSIGNED_SHORT, &(m_indexData[0])); 695 } 696 else 697 m_gl.drawArrays(GL_TRIANGLES, 0, m_config.triangleCount); 698 699 700 if (m_config.useTexture) 701 m_gl.bindTexture(GL_TEXTURE_2D, 0); 702 703 m_gl.disableVertexAttribArray(m_coordLoc); 704 705 m_gl.useProgram(0); 706 } 707 708 709 egl.swapBuffers(m_eglDisplay, m_eglSurface); 710 } 711 712 m_gl.finish(); 713 GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFinish()"); 714 EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); 715 } 716 717 class TestThread : de::Thread 718 { 719 public: 720 TestThread (const vector<TestContext*> contexts); 721 ~TestThread (void); 722 723 void start (void); 724 void join (void); 725 void log (TestLog& log); 726 727 bool resultOk (void) { return m_isOk; } 728 729 private: 730 vector<TestContext*> m_contexts; 731 bool m_isOk; 732 string m_errorString; 733 734 deUint64 m_beginTimeUs; 735 deUint64 m_endTimeUs; 736 737 deUint64 m_joinBeginUs; 738 deUint64 m_joinEndUs; 739 740 deUint64 m_startBeginUs; 741 deUint64 m_startEndUs; 742 743 744 virtual void run (void); 745 746 TestThread& operator= (const TestThread&); 747 TestThread (const TestThread&); 748 }; 749 750 TestThread::TestThread (const vector<TestContext*> contexts) 751 : m_contexts (contexts) 752 , m_isOk (false) 753 , m_errorString ("") 754 , m_beginTimeUs (0) 755 , m_endTimeUs (0) 756 , m_joinBeginUs (0) 757 , m_joinEndUs (0) 758 , m_startBeginUs (0) 759 , m_startEndUs (0) 760 { 761 } 762 763 TestThread::~TestThread (void) 764 { 765 m_contexts.clear(); 766 } 767 768 void TestThread::log (TestLog& testLog) 769 { 770 if (!m_isOk) 771 testLog << TestLog::Message << "Thread failed: " << m_errorString << TestLog::EndMessage; 772 } 773 774 void TestThread::start (void) 775 { 776 m_startBeginUs = deGetMicroseconds(); 777 de::Thread::start(); 778 m_startEndUs = deGetMicroseconds(); 779 } 780 781 void TestThread::join (void) 782 { 783 m_joinBeginUs = deGetMicroseconds(); 784 de::Thread::join(); 785 m_joinEndUs = deGetMicroseconds(); 786 } 787 788 void TestThread::run (void) 789 { 790 try 791 { 792 m_beginTimeUs = deGetMicroseconds(); 793 794 for (int contextNdx = 0; contextNdx < (int)m_contexts.size(); contextNdx++) 795 m_contexts[contextNdx]->render(); 796 797 m_isOk = true; 798 m_endTimeUs = deGetMicroseconds(); 799 } 800 catch (const std::runtime_error& error) 801 { 802 m_isOk = false; 803 m_errorString = error.what(); 804 } 805 catch (...) 806 { 807 m_isOk = false; 808 m_errorString = "Got unknown exception"; 809 } 810 } 811 812 class SharedRenderingPerfCase : public TestCase 813 { 814 public: 815 SharedRenderingPerfCase (EglTestContext& eglTestCtx, const TestConfig& config, const char* name, const char* description); 816 ~SharedRenderingPerfCase (void); 817 818 void init (void); 819 void deinit (void); 820 IterateResult iterate (void); 821 822 private: 823 TestConfig m_config; 824 const int m_iterationCount; 825 826 EGLDisplay m_display; 827 vector<TestContext*> m_contexts; 828 vector<deUint64> m_results; 829 830 SharedRenderingPerfCase& operator= (const SharedRenderingPerfCase&); 831 SharedRenderingPerfCase (const SharedRenderingPerfCase&); 832 }; 833 834 SharedRenderingPerfCase::SharedRenderingPerfCase (EglTestContext& eglTestCtx, const TestConfig& config, const char* name, const char* description) 835 : TestCase (eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description) 836 , m_config (config) 837 , m_iterationCount (30) 838 , m_display (EGL_NO_DISPLAY) 839 { 840 } 841 842 SharedRenderingPerfCase::~SharedRenderingPerfCase (void) 843 { 844 deinit(); 845 } 846 847 void SharedRenderingPerfCase::init (void) 848 { 849 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); 850 851 { 852 const Library& egl = m_eglTestCtx.getLibrary(); 853 const EGLint attribList[] = 854 { 855 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 856 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 857 EGL_NONE 858 }; 859 EGLConfig eglConfig = eglu::chooseSingleConfig(egl, m_display, attribList); 860 861 // Create contexts and resources 862 for (int threadNdx = 0; threadNdx < m_config.threadCount * m_config.perThreadContextCount; threadNdx++) 863 m_contexts.push_back(new TestContext(m_eglTestCtx, m_display, eglConfig, m_config, m_config.sharedContexts, (threadNdx == 0 ? DE_NULL : m_contexts[threadNdx-1]))); 864 } 865 } 866 867 void SharedRenderingPerfCase::deinit (void) 868 { 869 // Destroy resources and contexts 870 for (int threadNdx = 0; threadNdx < (int)m_contexts.size(); threadNdx++) 871 { 872 delete m_contexts[threadNdx]; 873 m_contexts[threadNdx] = DE_NULL; 874 } 875 876 m_contexts.clear(); 877 m_results.clear(); 878 879 if (m_display != EGL_NO_DISPLAY) 880 { 881 m_eglTestCtx.getLibrary().terminate(m_display); 882 m_display = EGL_NO_DISPLAY; 883 } 884 } 885 886 namespace 887 { 888 889 void createThreads (vector<TestThread*>& threads, int threadCount, int perThreadContextCount, vector<TestContext*>& contexts) 890 { 891 DE_ASSERT(threadCount * perThreadContextCount == (int)contexts.size()); 892 DE_ASSERT(threads.empty()); 893 894 vector<TestContext*> threadContexts; 895 896 for (int threadNdx = 0; threadNdx < threadCount; threadNdx++) 897 { 898 for (int contextNdx = 0; contextNdx < perThreadContextCount; contextNdx++) 899 threadContexts.push_back(contexts[threadNdx * perThreadContextCount + contextNdx]); 900 901 threads.push_back(new TestThread(threadContexts)); 902 903 threadContexts.clear(); 904 } 905 } 906 907 void destroyThreads (vector<TestThread*>& threads) 908 { 909 for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++) 910 { 911 delete threads[threadNdx]; 912 threads[threadNdx] = DE_NULL; 913 } 914 915 threads.clear(); 916 } 917 918 void startThreads (vector<TestThread*>& threads) 919 { 920 for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++) 921 threads[threadNdx]->start(); 922 } 923 924 void joinThreads (vector<TestThread*>& threads) 925 { 926 for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++) 927 threads[threadNdx]->join(); 928 } 929 930 bool threadResultsOk (const vector<TestThread*>& threads) 931 { 932 for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++) 933 { 934 if (!threads[threadNdx]->resultOk()) 935 return false; 936 } 937 938 return true; 939 } 940 941 void logAndSetResults (tcu::TestContext& testCtx, const vector<deUint64>& r) 942 { 943 TestLog& log = testCtx.getLog(); 944 vector<deUint64> resultsUs = r; 945 deUint64 sum = 0; 946 deUint64 average; 947 deUint64 median; 948 double deviation; 949 950 log << TestLog::SampleList("Result", "Result") 951 << TestLog::SampleInfo << TestLog::ValueInfo("Time", "Time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE) 952 << TestLog::EndSampleInfo; 953 954 for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++) 955 log << TestLog::Sample << deInt64(resultsUs[resultNdx]) << TestLog::EndSample; 956 957 log << TestLog::EndSampleList; 958 959 std::sort(resultsUs.begin(), resultsUs.end()); 960 961 for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++) 962 sum += resultsUs[resultNdx]; 963 964 average = sum / resultsUs.size(); 965 median = resultsUs[resultsUs.size() / 2]; 966 967 deviation = 0.0; 968 for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++) 969 deviation += (double)((resultsUs[resultNdx] - average) * (resultsUs[resultNdx] - average)); 970 971 deviation = std::sqrt(deviation/(double)resultsUs.size()); 972 973 { 974 tcu::ScopedLogSection section(log, "Statistics from results", "Statistics from results"); 975 976 log << TestLog::Message 977 << "Average: " << ((double)average/1000.0) << "ms\n" 978 << "Standard deviation: " << ((double)deviation/1000.0) << "ms\n" 979 << "Standard error of mean: " << (((double)deviation/std::sqrt((double)resultsUs.size()))/1000.0) << "ms\n" 980 << "Median: " << ((double)median/1000.0) << "ms\n" 981 << TestLog::EndMessage; 982 } 983 984 testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)((double)average/1000.0), 2).c_str()); 985 } 986 987 void logTestConfig (TestLog& log, const TestConfig& config) 988 { 989 tcu::ScopedLogSection threadSection(log, "Test info", "Test information"); 990 991 log << TestLog::Message << "Total triangles rendered: : " << config.triangleCount * config.drawCallCount * config.frameCount * config.perThreadContextCount * config.threadCount << TestLog::EndMessage; 992 log << TestLog::Message << "Number of threads: " << config.threadCount << TestLog::EndMessage; 993 log << TestLog::Message << "Number of contexts used to render with each thread: " << config.perThreadContextCount << TestLog::EndMessage; 994 log << TestLog::Message << "Number of frames rendered with each context: " << config.frameCount << TestLog::EndMessage; 995 log << TestLog::Message << "Number of draw calls performed by each frame: " << config.drawCallCount << TestLog::EndMessage; 996 log << TestLog::Message << "Number of triangles rendered by each draw call: " << config.triangleCount << TestLog::EndMessage; 997 998 if (config.sharedContexts) 999 log << TestLog::Message << "Shared contexts." << TestLog::EndMessage; 1000 else 1001 log << TestLog::Message << "No shared contexts." << TestLog::EndMessage; 1002 1003 if (config.useCoordBuffer) 1004 log << TestLog::Message << (config.sharedCoordBuffer ? "Shared " : "") << "Coordinate buffer" << TestLog::EndMessage; 1005 else 1006 log << TestLog::Message << "Coordinates from pointer" << TestLog::EndMessage; 1007 1008 if (config.useIndices) 1009 log << TestLog::Message << "Using glDrawElements with indices from " << (config.sharedIndexBuffer ? "shared " : "") << (config.useIndexBuffer ? "buffer." : "pointer.") << TestLog::EndMessage; 1010 1011 if (config.useTexture) 1012 { 1013 if (config.textureType == TestConfig::TEXTURETYPE_TEXTURE) 1014 log << TestLog::Message << "Use texture." << TestLog::EndMessage; 1015 else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_TEXTURE) 1016 log << TestLog::Message << "Use shared texture." << TestLog::EndMessage; 1017 else if (config.textureType == TestConfig::TEXTURETYPE_IMAGE) 1018 log << TestLog::Message << "Use texture created from EGLImage." << TestLog::EndMessage; 1019 else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE) 1020 log << TestLog::Message << "Use texture created from shared EGLImage." << TestLog::EndMessage; 1021 else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE) 1022 log << TestLog::Message << "Use shared texture created from EGLImage." << TestLog::EndMessage; 1023 else 1024 DE_ASSERT(false); 1025 1026 log << TestLog::Message << "Texture size: " << config.textureWidth << "x" << config.textureHeight << TestLog::EndMessage; 1027 } 1028 1029 if (config.sharedProgram) 1030 log << TestLog::Message << "Shared program." << TestLog::EndMessage; 1031 1032 log << TestLog::Message << "Surface size: " << config.surfaceWidth << "x" << config.surfaceHeight << TestLog::EndMessage; 1033 } 1034 1035 } // anonymous 1036 1037 TestCase::IterateResult SharedRenderingPerfCase::iterate (void) 1038 { 1039 deUint64 beginTimeUs; 1040 deUint64 endTimeUs; 1041 vector<TestThread*> threads; 1042 1043 if (m_results.empty()) 1044 logTestConfig(m_testCtx.getLog(), m_config); 1045 1046 createThreads(threads, m_config.threadCount, m_config.perThreadContextCount, m_contexts); 1047 1048 beginTimeUs = deGetMicroseconds(); 1049 1050 startThreads(threads); 1051 joinThreads(threads); 1052 1053 endTimeUs = deGetMicroseconds(); 1054 1055 if (!threadResultsOk(threads)) 1056 { 1057 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1058 return STOP; 1059 } 1060 1061 destroyThreads(threads); 1062 1063 m_results.push_back(endTimeUs - beginTimeUs); 1064 1065 if ((int)m_results.size() == m_iterationCount) 1066 { 1067 logAndSetResults(m_testCtx, m_results); 1068 return STOP; 1069 } 1070 else 1071 return CONTINUE; 1072 } 1073 1074 string createTestName(int threads, int perThreadContextCount) 1075 { 1076 std::ostringstream stream; 1077 1078 stream << threads << (threads == 1 ? "_thread_" : "_threads_") << perThreadContextCount << (perThreadContextCount == 1 ? "_context" : "_contexts"); 1079 1080 return stream.str(); 1081 } 1082 1083 } // anonymous 1084 1085 GLES2SharedRenderingPerfTests::GLES2SharedRenderingPerfTests (EglTestContext& eglTestCtx) 1086 : TestCaseGroup(eglTestCtx, "gles2_shared_render", "") 1087 { 1088 } 1089 1090 void GLES2SharedRenderingPerfTests::init (void) 1091 { 1092 TestConfig basicConfig; 1093 1094 basicConfig.threadCount = 1; 1095 basicConfig.perThreadContextCount = 1; 1096 1097 basicConfig.sharedContexts = true; 1098 basicConfig.frameCount = 10; 1099 basicConfig.drawCallCount = 10; 1100 basicConfig.triangleCount = 100; 1101 1102 basicConfig.useCoordBuffer = true; 1103 basicConfig.sharedCoordBuffer = false; 1104 1105 basicConfig.useIndices = true; 1106 basicConfig.useIndexBuffer = true; 1107 basicConfig.sharedIndexBuffer = false; 1108 1109 basicConfig.useTexture = true; 1110 basicConfig.textureType = TestConfig::TEXTURETYPE_TEXTURE; 1111 1112 basicConfig.sharedProgram = false; 1113 1114 basicConfig.textureWidth = 128; 1115 basicConfig.textureHeight = 128; 1116 1117 basicConfig.surfaceWidth = 256; 1118 basicConfig.surfaceHeight = 256; 1119 1120 const int threadCounts[] = { 1, 2, 4 }; 1121 const int perThreadContextCounts[] = { 1, 2, 4 }; 1122 1123 // Add no sharing tests 1124 { 1125 TestCaseGroup* sharedNoneGroup = new TestCaseGroup(m_eglTestCtx, "no_shared_context", "Tests without sharing contexts."); 1126 1127 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1128 { 1129 int threadCount = threadCounts[threadCountNdx]; 1130 1131 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1132 { 1133 int contextCount = perThreadContextCounts[contextCountNdx]; 1134 1135 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1136 continue; 1137 1138 TestConfig config = basicConfig; 1139 config.threadCount = threadCount; 1140 config.perThreadContextCount = contextCount; 1141 config.sharedContexts = false; 1142 1143 { 1144 TestConfig smallConfig = config; 1145 smallConfig.triangleCount = 1; 1146 smallConfig.drawCallCount = 1000; 1147 smallConfig.frameCount = 10; 1148 1149 if (threadCount * contextCount == 1) 1150 smallConfig.frameCount *= 4; 1151 1152 sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1153 } 1154 1155 { 1156 TestConfig bigConfig = config; 1157 bigConfig.triangleCount = 1000; 1158 bigConfig.drawCallCount = 1; 1159 bigConfig.frameCount = 10; 1160 1161 if (threadCount * contextCount == 1) 1162 bigConfig.frameCount *= 4; 1163 1164 sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1165 } 1166 } 1167 } 1168 1169 addChild(sharedNoneGroup); 1170 } 1171 1172 // Add no resource sharing tests 1173 { 1174 TestCaseGroup* sharedNoneGroup = new TestCaseGroup(m_eglTestCtx, "no_shared_resource", "Tests without shared resources."); 1175 1176 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1177 { 1178 int threadCount = threadCounts[threadCountNdx]; 1179 1180 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1181 { 1182 int contextCount = perThreadContextCounts[contextCountNdx]; 1183 1184 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1185 continue; 1186 1187 TestConfig config = basicConfig; 1188 config.threadCount = threadCount; 1189 config.perThreadContextCount = contextCount; 1190 1191 { 1192 TestConfig smallConfig = config; 1193 smallConfig.triangleCount = 1; 1194 smallConfig.drawCallCount = 1000; 1195 smallConfig.frameCount = 10; 1196 1197 if (threadCount * contextCount == 1) 1198 smallConfig.frameCount *= 4; 1199 1200 sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1201 } 1202 1203 { 1204 TestConfig bigConfig = config; 1205 bigConfig.triangleCount = 1000; 1206 bigConfig.drawCallCount = 1; 1207 bigConfig.frameCount = 10; 1208 1209 if (threadCount * contextCount == 1) 1210 bigConfig.frameCount *= 4; 1211 1212 sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1213 } 1214 } 1215 } 1216 1217 addChild(sharedNoneGroup); 1218 } 1219 1220 // Add shared coord buffer tests 1221 { 1222 TestCaseGroup* sharedCoordBufferGroup = new TestCaseGroup(m_eglTestCtx, "shared_coord_buffer", "Shared coordinate bufffer"); 1223 1224 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1225 { 1226 int threadCount = threadCounts[threadCountNdx]; 1227 1228 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1229 { 1230 int contextCount = perThreadContextCounts[contextCountNdx]; 1231 1232 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1233 continue; 1234 1235 TestConfig config = basicConfig; 1236 config.sharedCoordBuffer = true; 1237 config.threadCount = threadCount; 1238 config.perThreadContextCount = contextCount; 1239 1240 { 1241 TestConfig smallConfig = config; 1242 smallConfig.triangleCount = 1; 1243 smallConfig.drawCallCount = 1000; 1244 smallConfig.frameCount = 10; 1245 1246 if (threadCount * contextCount == 1) 1247 smallConfig.frameCount *= 4; 1248 1249 sharedCoordBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1250 } 1251 1252 { 1253 TestConfig bigConfig = config; 1254 bigConfig.triangleCount = 1000; 1255 bigConfig.drawCallCount = 1; 1256 bigConfig.frameCount = 10; 1257 1258 if (threadCount * contextCount == 1) 1259 bigConfig.frameCount *= 4; 1260 1261 sharedCoordBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1262 } 1263 } 1264 } 1265 1266 addChild(sharedCoordBufferGroup); 1267 } 1268 1269 // Add shared index buffer tests 1270 { 1271 TestCaseGroup* sharedIndexBufferGroup = new TestCaseGroup(m_eglTestCtx, "shared_index_buffer", "Shared index bufffer"); 1272 1273 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1274 { 1275 int threadCount = threadCounts[threadCountNdx]; 1276 1277 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1278 { 1279 int contextCount = perThreadContextCounts[contextCountNdx]; 1280 1281 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1282 continue; 1283 1284 TestConfig config = basicConfig; 1285 config.sharedIndexBuffer = true; 1286 config.threadCount = threadCount; 1287 config.perThreadContextCount = contextCount; 1288 1289 { 1290 TestConfig smallConfig = config; 1291 smallConfig.triangleCount = 1; 1292 smallConfig.drawCallCount = 1000; 1293 smallConfig.frameCount = 10; 1294 1295 if (threadCount * contextCount == 1) 1296 smallConfig.frameCount *= 4; 1297 1298 sharedIndexBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1299 } 1300 1301 { 1302 TestConfig bigConfig = config; 1303 bigConfig.triangleCount = 1000; 1304 bigConfig.drawCallCount = 1; 1305 bigConfig.frameCount = 10; 1306 1307 if (threadCount * contextCount == 1) 1308 bigConfig.frameCount *= 4; 1309 1310 sharedIndexBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1311 } 1312 } 1313 } 1314 1315 addChild(sharedIndexBufferGroup); 1316 } 1317 1318 // Add shared texture tests 1319 { 1320 TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_texture", "Shared texture tests."); 1321 1322 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1323 { 1324 int threadCount = threadCounts[threadCountNdx]; 1325 1326 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1327 { 1328 int contextCount = perThreadContextCounts[contextCountNdx]; 1329 1330 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1331 continue; 1332 1333 TestConfig config = basicConfig; 1334 config.textureType = TestConfig::TEXTURETYPE_SHARED_TEXTURE; 1335 config.threadCount = threadCount; 1336 config.perThreadContextCount = contextCount; 1337 1338 { 1339 TestConfig smallConfig = config; 1340 smallConfig.triangleCount = 1; 1341 smallConfig.drawCallCount = 1000; 1342 smallConfig.frameCount = 10; 1343 1344 if (threadCount * contextCount == 1) 1345 smallConfig.frameCount *= 4; 1346 1347 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1348 } 1349 1350 { 1351 TestConfig bigConfig = config; 1352 bigConfig.triangleCount = 1000; 1353 bigConfig.drawCallCount = 1; 1354 bigConfig.frameCount = 10; 1355 1356 if (threadCount * contextCount == 1) 1357 bigConfig.frameCount *= 4; 1358 1359 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1360 } 1361 } 1362 } 1363 1364 addChild(sharedTextureGroup); 1365 } 1366 1367 // Add shared program tests 1368 { 1369 TestCaseGroup* sharedProgramGroup = new TestCaseGroup(m_eglTestCtx, "shared_program", "Shared program tests."); 1370 1371 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1372 { 1373 int threadCount = threadCounts[threadCountNdx]; 1374 1375 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1376 { 1377 int contextCount = perThreadContextCounts[contextCountNdx]; 1378 1379 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1380 continue; 1381 1382 TestConfig config = basicConfig; 1383 config.sharedProgram = true; 1384 config.threadCount = threadCount; 1385 config.perThreadContextCount = contextCount; 1386 1387 { 1388 TestConfig smallConfig = config; 1389 smallConfig.triangleCount = 1; 1390 smallConfig.drawCallCount = 1000; 1391 smallConfig.frameCount = 10; 1392 1393 if (threadCount * contextCount == 1) 1394 smallConfig.frameCount *= 4; 1395 1396 sharedProgramGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1397 } 1398 1399 { 1400 TestConfig bigConfig = config; 1401 bigConfig.triangleCount = 1000; 1402 bigConfig.drawCallCount = 1; 1403 bigConfig.frameCount = 10; 1404 1405 if (threadCount * contextCount == 1) 1406 bigConfig.frameCount *= 4; 1407 1408 sharedProgramGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1409 } 1410 } 1411 } 1412 1413 addChild(sharedProgramGroup); 1414 } 1415 1416 // Add shared all tests 1417 { 1418 TestCaseGroup* sharedallGroup = new TestCaseGroup(m_eglTestCtx, "shared_all", "Share all possible resources."); 1419 1420 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1421 { 1422 int threadCount = threadCounts[threadCountNdx]; 1423 1424 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1425 { 1426 int contextCount = perThreadContextCounts[contextCountNdx]; 1427 1428 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1429 continue; 1430 1431 TestConfig config = basicConfig; 1432 config.sharedCoordBuffer = true; 1433 config.sharedIndexBuffer = true; 1434 config.sharedProgram = true; 1435 config.textureType = TestConfig::TEXTURETYPE_SHARED_TEXTURE; 1436 config.threadCount = threadCount; 1437 config.perThreadContextCount = contextCount; 1438 1439 { 1440 TestConfig smallConfig = config; 1441 smallConfig.triangleCount = 1; 1442 smallConfig.drawCallCount = 1000; 1443 smallConfig.frameCount = 10; 1444 1445 if (threadCount * contextCount == 1) 1446 smallConfig.frameCount *= 4; 1447 1448 sharedallGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1449 } 1450 1451 { 1452 TestConfig bigConfig = config; 1453 bigConfig.triangleCount = 1000; 1454 bigConfig.drawCallCount = 1; 1455 bigConfig.frameCount = 10; 1456 1457 if (threadCount * contextCount == 1) 1458 bigConfig.frameCount *= 4; 1459 1460 sharedallGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1461 } 1462 } 1463 } 1464 1465 addChild(sharedallGroup); 1466 } 1467 1468 // Add EGLImage tests 1469 { 1470 TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "egl_image", "EGL image tests."); 1471 1472 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1473 { 1474 int threadCount = threadCounts[threadCountNdx]; 1475 1476 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1477 { 1478 int contextCount = perThreadContextCounts[contextCountNdx]; 1479 1480 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1481 continue; 1482 1483 TestConfig config = basicConfig; 1484 1485 config.textureType = TestConfig::TEXTURETYPE_IMAGE; 1486 config.threadCount = threadCount; 1487 config.perThreadContextCount = contextCount; 1488 config.sharedContexts = false; 1489 1490 { 1491 TestConfig smallConfig = config; 1492 smallConfig.triangleCount = 1; 1493 smallConfig.drawCallCount = 1000; 1494 smallConfig.frameCount = 10; 1495 1496 if (threadCount * contextCount == 1) 1497 smallConfig.frameCount *= 4; 1498 1499 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1500 } 1501 1502 { 1503 TestConfig bigConfig = config; 1504 bigConfig.triangleCount = 1000; 1505 bigConfig.drawCallCount = 1; 1506 bigConfig.frameCount = 10; 1507 1508 if (threadCount * contextCount == 1) 1509 bigConfig.frameCount *= 4; 1510 1511 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1512 } 1513 } 1514 } 1515 1516 addChild(sharedTextureGroup); 1517 } 1518 1519 // Add shared EGLImage tests 1520 { 1521 TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_egl_image", "Shared EGLImage tests."); 1522 1523 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1524 { 1525 int threadCount = threadCounts[threadCountNdx]; 1526 1527 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1528 { 1529 int contextCount = perThreadContextCounts[contextCountNdx]; 1530 1531 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1532 continue; 1533 1534 TestConfig config = basicConfig; 1535 1536 config.textureType = TestConfig::TEXTURETYPE_SHARED_IMAGE; 1537 config.threadCount = threadCount; 1538 config.perThreadContextCount = contextCount; 1539 config.sharedContexts = false; 1540 1541 { 1542 TestConfig smallConfig = config; 1543 smallConfig.triangleCount = 1; 1544 smallConfig.drawCallCount = 1000; 1545 smallConfig.frameCount = 10; 1546 1547 if (threadCount * contextCount == 1) 1548 smallConfig.frameCount *= 4; 1549 1550 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1551 } 1552 1553 { 1554 TestConfig bigConfig = config; 1555 bigConfig.triangleCount = 1000; 1556 bigConfig.drawCallCount = 1; 1557 bigConfig.frameCount = 10; 1558 1559 if (threadCount * contextCount == 1) 1560 bigConfig.frameCount *= 4; 1561 1562 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1563 } 1564 } 1565 } 1566 1567 addChild(sharedTextureGroup); 1568 } 1569 1570 // Shared EGLImage texture test 1571 { 1572 TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_egl_image_texture", "Shared EGLImage texture tests."); 1573 1574 for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++) 1575 { 1576 int threadCount = threadCounts[threadCountNdx]; 1577 1578 for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++) 1579 { 1580 int contextCount = perThreadContextCounts[contextCountNdx]; 1581 1582 if (threadCount * contextCount != 4 && threadCount * contextCount != 1) 1583 continue; 1584 1585 TestConfig config = basicConfig; 1586 config.textureType = TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE; 1587 config.threadCount = threadCount; 1588 config.perThreadContextCount = contextCount; 1589 1590 { 1591 TestConfig smallConfig = config; 1592 smallConfig.triangleCount = 1; 1593 smallConfig.drawCallCount = 1000; 1594 smallConfig.frameCount = 10; 1595 1596 if (threadCount * contextCount == 1) 1597 smallConfig.frameCount *= 4; 1598 1599 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), "")); 1600 } 1601 1602 { 1603 TestConfig bigConfig = config; 1604 bigConfig.triangleCount = 1000; 1605 bigConfig.drawCallCount = 1; 1606 bigConfig.frameCount = 10; 1607 1608 if (threadCount * contextCount == 1) 1609 bigConfig.frameCount *= 4; 1610 1611 sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), "")); 1612 } 1613 } 1614 } 1615 1616 addChild(sharedTextureGroup); 1617 } 1618 1619 } 1620 1621 } // egl 1622 } // deqp 1623