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