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