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