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