| /*------------------------------------------------------------------------- |
| * drawElements Quality Program EGL Module |
| * --------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief eglMakeCurrent performance tests. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "teglMakeCurrentPerfTests.hpp" |
| |
| #include "egluNativeWindow.hpp" |
| #include "egluNativePixmap.hpp" |
| #include "egluUtil.hpp" |
| |
| #include "eglwLibrary.hpp" |
| #include "eglwEnums.hpp" |
| |
| #include "tcuTestLog.hpp" |
| |
| #include "deRandom.hpp" |
| #include "deStringUtil.hpp" |
| |
| #include "deClock.h" |
| #include "deString.h" |
| |
| #include <algorithm> |
| #include <cmath> |
| #include <limits> |
| #include <sstream> |
| #include <string> |
| #include <vector> |
| |
| using std::ostringstream; |
| using std::string; |
| using std::vector; |
| |
| using tcu::TestLog; |
| |
| using namespace eglw; |
| |
| namespace deqp |
| { |
| namespace egl |
| { |
| |
| class MakeCurrentPerfCase : public TestCase |
| { |
| public: |
| enum SurfaceType |
| { |
| SURFACETYPE_PBUFFER = (1<<0), |
| SURFACETYPE_WINDOW = (1<<1), |
| SURFACETYPE_PIXMAP = (1<<2) |
| }; |
| |
| struct Spec |
| { |
| SurfaceType surfaceTypes; |
| int contextCount; |
| int surfaceCount; |
| |
| bool release; |
| |
| int iterationCount; |
| int sampleCount; |
| |
| string toName (void) const; |
| string toDescription (void) const; |
| }; |
| MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description); |
| ~MakeCurrentPerfCase (void); |
| |
| void init (void); |
| void deinit (void); |
| IterateResult iterate (void); |
| |
| private: |
| Spec m_spec; |
| de::Random m_rnd; |
| |
| EGLDisplay m_display; |
| EGLConfig m_config; |
| vector<EGLContext> m_contexts; |
| vector<EGLSurface> m_surfaces; |
| |
| vector<eglu::NativeWindow*> m_windows; |
| vector<eglu::NativePixmap*> m_pixmaps; |
| |
| vector<deUint64> m_samples; |
| |
| void chooseConfig (void); |
| void createSurfaces (void); |
| void createContexts (void); |
| |
| void destroySurfaces (void); |
| void destroyContexts (void); |
| |
| void createPBuffer (void); |
| void createWindow (void); |
| void createPixmap (void); |
| |
| void logTestInfo (void); |
| void logResults (void); |
| // Disabled |
| MakeCurrentPerfCase (const MakeCurrentPerfCase&); |
| MakeCurrentPerfCase& operator= (const MakeCurrentPerfCase&); |
| }; |
| |
| string MakeCurrentPerfCase::Spec::toName (void) const |
| { |
| ostringstream name; |
| |
| name << "context"; |
| |
| if (contextCount > 1) |
| name << "s_" << contextCount; |
| |
| if ((surfaceTypes & SURFACETYPE_WINDOW) != 0) |
| name << "_window" << (surfaceCount > 1 ? "s" : ""); |
| |
| if ((surfaceTypes & SURFACETYPE_PIXMAP) != 0) |
| name << "_pixmap" << (surfaceCount > 1 ? "s" : ""); |
| |
| if ((surfaceTypes & SURFACETYPE_PBUFFER) != 0) |
| name << "_pbuffer" << (surfaceCount > 1 ? "s" : ""); |
| |
| if (surfaceCount > 1) |
| name << "_" << surfaceCount; |
| |
| if (release) |
| name << "_release"; |
| |
| return name.str(); |
| } |
| |
| string MakeCurrentPerfCase::Spec::toDescription (void) const |
| { |
| // \todo [mika] Generate descrpition |
| return toName(); |
| } |
| |
| MakeCurrentPerfCase::MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description) |
| : TestCase (eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description) |
| , m_spec (spec) |
| , m_rnd (deStringHash(name)) |
| , m_display (EGL_NO_DISPLAY) |
| , m_config (DE_NULL) |
| { |
| } |
| |
| MakeCurrentPerfCase::~MakeCurrentPerfCase (void) |
| { |
| deinit(); |
| } |
| |
| void MakeCurrentPerfCase::init (void) |
| { |
| m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); |
| |
| chooseConfig(); |
| createContexts(); |
| createSurfaces(); |
| } |
| |
| void MakeCurrentPerfCase::deinit (void) |
| { |
| destroyContexts(); |
| destroySurfaces(); |
| |
| if (m_display != EGL_NO_DISPLAY) |
| { |
| m_eglTestCtx.getLibrary().terminate(m_display); |
| m_display = EGL_NO_DISPLAY; |
| } |
| } |
| |
| void MakeCurrentPerfCase::chooseConfig (void) |
| { |
| const EGLint surfaceBits = ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0 ? EGL_WINDOW_BIT : 0) |
| | ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0 ? EGL_PIXMAP_BIT : 0) |
| | ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0 ? EGL_PBUFFER_BIT : 0); |
| |
| const EGLint attribList[] = { |
| EGL_SURFACE_TYPE, surfaceBits, |
| EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| EGL_NONE |
| }; |
| |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| EGLint configCount = 0; |
| |
| EGLU_CHECK_CALL(egl, chooseConfig(m_display, attribList, &m_config, 1, &configCount)); |
| |
| if (configCount <= 0) |
| throw tcu::NotSupportedError("No compatible configs found"); |
| } |
| |
| void MakeCurrentPerfCase::createSurfaces (void) |
| { |
| vector<SurfaceType> types; |
| |
| if ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0) |
| types.push_back(SURFACETYPE_WINDOW); |
| |
| if ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0) |
| types.push_back(SURFACETYPE_PIXMAP); |
| |
| if ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0) |
| types.push_back(SURFACETYPE_PBUFFER); |
| |
| DE_ASSERT((int)types.size() <= m_spec.surfaceCount); |
| |
| // Create surfaces |
| for (int surfaceNdx = 0; surfaceNdx < m_spec.surfaceCount; surfaceNdx++) |
| { |
| SurfaceType type = types[surfaceNdx % types.size()]; |
| |
| switch (type) |
| { |
| case SURFACETYPE_PBUFFER: |
| createPBuffer(); |
| break; |
| |
| case SURFACETYPE_WINDOW: |
| createWindow(); |
| break; |
| |
| case SURFACETYPE_PIXMAP: |
| createPixmap(); |
| break; |
| |
| default: |
| DE_ASSERT(false); |
| } |
| } |
| } |
| |
| void MakeCurrentPerfCase::createPBuffer (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| const EGLint width = 256; |
| const EGLint height = 256; |
| |
| const EGLint attribList[] = { |
| EGL_WIDTH, width, |
| EGL_HEIGHT, height, |
| EGL_NONE |
| }; |
| |
| EGLSurface surface = egl.createPbufferSurface(m_display, m_config, attribList); |
| |
| EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()"); |
| |
| m_surfaces.push_back(surface); |
| } |
| |
| void MakeCurrentPerfCase::createWindow (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| const EGLint width = 256; |
| const EGLint height = 256; |
| |
| const eglu::NativeWindowFactory& windowFactory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); |
| |
| eglu::NativeWindow* window = DE_NULL; |
| EGLSurface surface = EGL_NO_SURFACE; |
| |
| try |
| { |
| window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_eglTestCtx.getTestContext().getCommandLine()))); |
| surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, m_config, DE_NULL); |
| } |
| catch (...) |
| { |
| if (surface != EGL_NO_SURFACE) |
| egl.destroySurface(m_display, surface); |
| |
| delete window; |
| throw; |
| } |
| |
| m_windows.push_back(window); |
| m_surfaces.push_back(surface); |
| } |
| |
| void MakeCurrentPerfCase::createPixmap (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| const EGLint width = 256; |
| const EGLint height = 256; |
| |
| const eglu::NativePixmapFactory& pixmapFactory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); |
| |
| eglu::NativePixmap* pixmap = DE_NULL; |
| EGLSurface surface = EGL_NO_SURFACE; |
| |
| try |
| { |
| pixmap = pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, width, height); |
| surface = eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, m_config, DE_NULL); |
| } |
| catch (...) |
| { |
| if (surface != EGL_NO_SURFACE) |
| egl.destroySurface(m_display, surface); |
| |
| delete pixmap; |
| throw; |
| } |
| |
| m_pixmaps.push_back(pixmap); |
| m_surfaces.push_back(surface); |
| } |
| |
| void MakeCurrentPerfCase::destroySurfaces (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| |
| if (m_surfaces.size() > 0) |
| { |
| EGLDisplay display = m_display; |
| |
| // Destroy surfaces |
| for (vector<EGLSurface>::iterator iter = m_surfaces.begin(); iter != m_surfaces.end(); ++iter) |
| { |
| if (*iter != EGL_NO_SURFACE) |
| EGLU_CHECK_CALL(egl, destroySurface(display, *iter)); |
| *iter = EGL_NO_SURFACE; |
| } |
| |
| m_surfaces.clear(); |
| |
| // Destroy pixmaps |
| for (vector<eglu::NativePixmap*>::iterator iter = m_pixmaps.begin(); iter != m_pixmaps.end(); ++iter) |
| { |
| delete *iter; |
| *iter = NULL; |
| } |
| |
| m_pixmaps.clear(); |
| |
| // Destroy windows |
| for (vector<eglu::NativeWindow*>::iterator iter = m_windows.begin(); iter != m_windows.end(); ++iter) |
| { |
| delete *iter; |
| *iter = NULL; |
| } |
| |
| m_windows.clear(); |
| |
| // Clear all surface handles |
| m_surfaces.clear(); |
| } |
| } |
| |
| void MakeCurrentPerfCase::createContexts (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| |
| for (int contextNdx = 0; contextNdx < m_spec.contextCount; contextNdx++) |
| { |
| const EGLint attribList[] = { |
| EGL_CONTEXT_CLIENT_VERSION, 2, |
| EGL_NONE |
| }; |
| |
| EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API)); |
| EGLContext context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList); |
| EGLU_CHECK_MSG(egl, "eglCreateContext()"); |
| |
| m_contexts.push_back(context); |
| } |
| } |
| |
| void MakeCurrentPerfCase::destroyContexts (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| if (m_contexts.size() > 0) |
| { |
| EGLDisplay display = m_display; |
| |
| for (vector<EGLContext>::iterator iter = m_contexts.begin(); iter != m_contexts.end(); ++iter) |
| { |
| if (*iter != EGL_NO_CONTEXT) |
| EGLU_CHECK_CALL(egl, destroyContext(display, *iter)); |
| *iter = EGL_NO_CONTEXT; |
| } |
| |
| m_contexts.clear(); |
| } |
| } |
| |
| void MakeCurrentPerfCase::logTestInfo (void) |
| { |
| TestLog& log = m_testCtx.getLog(); |
| |
| { |
| tcu::ScopedLogSection section(log, "Test Info", "Test case information."); |
| |
| log << TestLog::Message << "Context count: " << m_contexts.size() << TestLog::EndMessage; |
| log << TestLog::Message << "Surfaces count: " << m_surfaces.size() << TestLog::EndMessage; |
| log << TestLog::Message << "Sample count: " << m_spec.sampleCount << TestLog::EndMessage; |
| log << TestLog::Message << "Iteration count: " << m_spec.iterationCount << TestLog::EndMessage; |
| log << TestLog::Message << "Window count: " << m_windows.size() << TestLog::EndMessage; |
| log << TestLog::Message << "Pixmap count: " << m_pixmaps.size() << TestLog::EndMessage; |
| log << TestLog::Message << "PBuffer count: " << (m_surfaces.size() - m_windows.size() - m_pixmaps.size()) << TestLog::EndMessage; |
| |
| if (m_spec.release) |
| log << TestLog::Message << "Context is released after each use. Both binding and releasing context are included in result time." << TestLog::EndMessage; |
| } |
| } |
| |
| void MakeCurrentPerfCase::logResults (void) |
| { |
| TestLog& log = m_testCtx.getLog(); |
| |
| log << TestLog::SampleList("Result", "Result") |
| << TestLog::SampleInfo << TestLog::ValueInfo("Time", "Time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE) |
| << TestLog::EndSampleInfo; |
| |
| for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) |
| log << TestLog::Sample << deInt64(m_samples[sampleNdx]) << TestLog::EndSample; |
| |
| log << TestLog::EndSampleList; |
| |
| // Log stats |
| { |
| deUint64 totalTimeUs = 0; |
| deUint64 totalIterationCount = 0; |
| |
| float iterationTimeMeanUs = 0.0f; |
| float iterationTimeMedianUs = 0.0f; |
| float iterationTimeVarianceUs = 0.0f; |
| float iterationTimeSkewnessUs = 0.0f; |
| float iterationTimeMinUs = std::numeric_limits<float>::max(); |
| float iterationTimeMaxUs = 0.0f; |
| |
| std::sort(m_samples.begin(), m_samples.end()); |
| |
| // Calculate totals |
| for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) |
| { |
| totalTimeUs += m_samples[sampleNdx]; |
| totalIterationCount += m_spec.iterationCount; |
| } |
| |
| // Calculate mean and median |
| iterationTimeMeanUs = ((float)(((double)totalTimeUs) / (double)totalIterationCount)); |
| iterationTimeMedianUs = ((float)(((double)m_samples[m_samples.size() / 2]) / (double)m_spec.iterationCount)); |
| |
| // Calculate variance |
| for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) |
| { |
| float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); |
| iterationTimeVarianceUs += std::pow(iterationTimeUs - iterationTimeMedianUs, 2.0f); |
| } |
| |
| // Calculate min and max |
| for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) |
| { |
| float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); |
| iterationTimeMinUs = std::min<float>(iterationTimeMinUs, iterationTimeUs); |
| iterationTimeMaxUs = std::max<float>(iterationTimeMaxUs, iterationTimeUs); |
| } |
| |
| iterationTimeVarianceUs /= (float)m_samples.size(); |
| |
| // Calculate skewness |
| for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++) |
| { |
| float iterationTimeUs = (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount); |
| iterationTimeSkewnessUs = std::pow((iterationTimeUs - iterationTimeMedianUs) / iterationTimeVarianceUs, 2.0f); |
| } |
| |
| iterationTimeSkewnessUs /= (float)m_samples.size(); |
| |
| { |
| tcu::ScopedLogSection section(log, "Result", "Statistics from results."); |
| |
| log << TestLog::Message << "Total time: " << totalTimeUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Mean: " << iterationTimeMeanUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Median: " << iterationTimeMedianUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Variance: " << iterationTimeVarianceUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Skewness: " << iterationTimeSkewnessUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Min: " << iterationTimeMinUs << "us" << TestLog::EndMessage; |
| log << TestLog::Message << "Max: " << iterationTimeMaxUs << "us" << TestLog::EndMessage; |
| } |
| |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)(((double)totalTimeUs)/(double)totalIterationCount), 2).c_str()); |
| } |
| } |
| |
| TestCase::IterateResult MakeCurrentPerfCase::iterate (void) |
| { |
| const Library& egl = m_eglTestCtx.getLibrary(); |
| if (m_samples.size() == 0) |
| logTestInfo(); |
| |
| { |
| EGLDisplay display = m_display; |
| deUint64 beginTimeUs = deGetMicroseconds(); |
| |
| for (int iteration = 0; iteration < m_spec.iterationCount; iteration++) |
| { |
| EGLContext context = m_contexts[m_rnd.getUint32() % m_contexts.size()]; |
| EGLSurface surface = m_surfaces[m_rnd.getUint32() % m_surfaces.size()]; |
| |
| egl.makeCurrent(display, surface, surface, context); |
| |
| if (m_spec.release) |
| egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
| } |
| |
| m_samples.push_back(deGetMicroseconds() - beginTimeUs); |
| |
| egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
| EGLU_CHECK_MSG(egl, "eglMakeCurrent()"); |
| } |
| |
| if ((int)m_samples.size() == m_spec.sampleCount) |
| { |
| logResults(); |
| return STOP; |
| } |
| else |
| return CONTINUE; |
| } |
| |
| MakeCurrentPerfTests::MakeCurrentPerfTests (EglTestContext& eglTestCtx) |
| : TestCaseGroup(eglTestCtx, "make_current", "eglMakeCurrent performance tests") |
| { |
| } |
| |
| void MakeCurrentPerfTests::init (void) |
| { |
| const int iterationCount = 100; |
| const int sampleCount = 100; |
| |
| // Add simple test group |
| { |
| TestCaseGroup* simple = new TestCaseGroup(m_eglTestCtx, "simple", "Simple eglMakeCurrent performance tests using single context and surface"); |
| |
| const MakeCurrentPerfCase::SurfaceType types[] = { |
| MakeCurrentPerfCase::SURFACETYPE_PBUFFER, |
| MakeCurrentPerfCase::SURFACETYPE_PIXMAP, |
| MakeCurrentPerfCase::SURFACETYPE_WINDOW |
| }; |
| |
| for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) |
| { |
| for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) |
| { |
| MakeCurrentPerfCase::Spec spec; |
| |
| spec.surfaceTypes = types[typeNdx]; |
| spec.contextCount = 1; |
| spec.surfaceCount = 1; |
| spec.release = (releaseNdx == 1); |
| spec.iterationCount = iterationCount; |
| spec.sampleCount = sampleCount; |
| |
| simple->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); |
| } |
| } |
| |
| addChild(simple); |
| } |
| |
| // Add multi context test group |
| { |
| TestCaseGroup* multiContext = new TestCaseGroup(m_eglTestCtx, "multi_context", "eglMakeCurrent performance tests using multiple contexts and single surface"); |
| |
| const MakeCurrentPerfCase::SurfaceType types[] = { |
| MakeCurrentPerfCase::SURFACETYPE_PBUFFER, |
| MakeCurrentPerfCase::SURFACETYPE_PIXMAP, |
| MakeCurrentPerfCase::SURFACETYPE_WINDOW |
| }; |
| |
| const int contextCounts[] = { |
| 10, 100 |
| }; |
| |
| for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++) |
| { |
| for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) |
| { |
| for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) |
| { |
| MakeCurrentPerfCase::Spec spec; |
| |
| spec.surfaceTypes = types[typeNdx]; |
| spec.contextCount = contextCounts[contextCountNdx]; |
| spec.surfaceCount = 1; |
| spec.release = (releaseNdx == 1); |
| spec.iterationCount = iterationCount; |
| spec.sampleCount = sampleCount; |
| |
| multiContext->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); |
| } |
| } |
| } |
| |
| addChild(multiContext); |
| } |
| |
| // Add multi surface test group |
| { |
| TestCaseGroup* multiSurface = new TestCaseGroup(m_eglTestCtx, "multi_surface", "eglMakeCurrent performance tests using single context and multiple surfaces"); |
| |
| const MakeCurrentPerfCase::SurfaceType types[] = { |
| MakeCurrentPerfCase::SURFACETYPE_PBUFFER, |
| MakeCurrentPerfCase::SURFACETYPE_PIXMAP, |
| MakeCurrentPerfCase::SURFACETYPE_WINDOW, |
| |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_PIXMAP), |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_WINDOW), |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP |MakeCurrentPerfCase::SURFACETYPE_WINDOW), |
| |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW) |
| }; |
| |
| const int surfaceCounts[] = { |
| 10, 100 |
| }; |
| |
| for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++) |
| { |
| for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) |
| { |
| for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) |
| { |
| MakeCurrentPerfCase::Spec spec; |
| |
| spec.surfaceTypes = types[typeNdx]; |
| spec.surfaceCount = surfaceCounts[surfaceCountNdx]; |
| spec.contextCount = 1; |
| spec.release = (releaseNdx == 1); |
| spec.iterationCount = iterationCount; |
| spec.sampleCount = sampleCount; |
| |
| multiSurface->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); |
| } |
| } |
| } |
| |
| addChild(multiSurface); |
| } |
| |
| // Add Complex? test group |
| { |
| TestCaseGroup* multi = new TestCaseGroup(m_eglTestCtx, "complex", "eglMakeCurrent performance tests using multiple contexts and multiple surfaces"); |
| |
| const MakeCurrentPerfCase::SurfaceType types[] = { |
| MakeCurrentPerfCase::SURFACETYPE_PBUFFER, |
| MakeCurrentPerfCase::SURFACETYPE_PIXMAP, |
| MakeCurrentPerfCase::SURFACETYPE_WINDOW, |
| |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_PIXMAP), |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER |MakeCurrentPerfCase::SURFACETYPE_WINDOW), |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP |MakeCurrentPerfCase::SURFACETYPE_WINDOW), |
| |
| (MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW) |
| }; |
| |
| const int surfaceCounts[] = { |
| 10, 100 |
| }; |
| |
| |
| const int contextCounts[] = { |
| 10, 100 |
| }; |
| |
| for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++) |
| { |
| for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++) |
| { |
| for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++) |
| { |
| for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++) |
| { |
| MakeCurrentPerfCase::Spec spec; |
| |
| spec.surfaceTypes = types[typeNdx]; |
| spec.contextCount = contextCounts[contextCountNdx]; |
| spec.surfaceCount = surfaceCounts[surfaceCountNdx]; |
| spec.release = (releaseNdx == 1); |
| spec.iterationCount = iterationCount; |
| spec.sampleCount = sampleCount; |
| |
| multi->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str())); |
| } |
| } |
| } |
| } |
| |
| addChild(multi); |
| } |
| } |
| |
| } // egl |
| } // deqp |