1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL (ES) Module
3 * -----------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Single-program test case wrapper for ShaderPerformanceMeasurer.
22 *//*--------------------------------------------------------------------*/
24 #include "glsShaderPerformanceCase.hpp"
25 #include "tcuRenderTarget.hpp"
26 #include "deStringUtil.hpp"
29 #include "glwFunctions.hpp"
30 #include "glwEnums.hpp"
34 using namespace glw; // GL types
41 ShaderPerformanceCase::ShaderPerformanceCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, PerfCaseType caseType)
42 : tcu::TestCase (testCtx, tcu::NODETYPE_PERFORMANCE, name, description)
43 , m_renderCtx (renderCtx)
44 , m_caseType (caseType)
46 , m_measurer (renderCtx, caseType)
50 ShaderPerformanceCase::~ShaderPerformanceCase (void)
52 ShaderPerformanceCase::deinit();
55 void ShaderPerformanceCase::setGridSize (int gridW, int gridH)
57 m_measurer.setGridSize(gridW, gridH);
60 void ShaderPerformanceCase::setViewportSize (int width, int height)
62 m_measurer.setViewportSize(width, height);
65 void ShaderPerformanceCase::setVertexFragmentRatio (float fragmentsPerVertices)
67 const float eps = 0.01f;
70 int viewportW = m_renderCtx.getRenderTarget().getWidth();
71 int viewportH = m_renderCtx.getRenderTarget().getHeight();
73 for (int i = 0; i < 10; i++)
75 int numVert = (gridW+1)*(gridH+1);
76 int numFrag = viewportW*viewportH;
77 float ratio = (float)numFrag / (float)numVert;
79 if (de::abs(ratio - fragmentsPerVertices) < eps)
81 else if (ratio < fragmentsPerVertices)
83 // Not enough fragments.
84 numVert = deRoundFloatToInt32((float)numFrag / fragmentsPerVertices);
86 while ((gridW+1)*(gridH+1) > numVert)
96 // Not enough vertices.
97 numFrag = deRoundFloatToInt32((float)numVert * fragmentsPerVertices);
99 while (viewportW*viewportH > numFrag)
101 if (viewportW > viewportH)
109 float finalRatio = (float)(viewportW*viewportH) / (float)((gridW+1)*(gridH+1));
110 m_testCtx.getLog() << TestLog::Message << "Requested fragment/vertex-ratio: " << de::floatToString(fragmentsPerVertices, 2) << "\n"
111 << "Computed fragment/vertex-ratio: " << de::floatToString(finalRatio, 2)
112 << TestLog::EndMessage;
114 setGridSize(gridW, gridH);
115 setViewportSize(viewportW, viewportH);
118 static void logRenderTargetInfo (TestLog& log, const tcu::RenderTarget& renderTarget)
120 log << TestLog::Section("RenderTarget", "Render target")
121 << TestLog::Message << "size: " << renderTarget.getWidth() << "x" << renderTarget.getHeight() << TestLog::EndMessage
122 << TestLog::Message << "bits:"
123 << " R" << renderTarget.getPixelFormat().redBits
124 << " G" << renderTarget.getPixelFormat().greenBits
125 << " B" << renderTarget.getPixelFormat().blueBits
126 << " A" << renderTarget.getPixelFormat().alphaBits
127 << " D" << renderTarget.getDepthBits()
128 << " S" << renderTarget.getStencilBits()
129 << TestLog::EndMessage;
131 if (renderTarget.getNumSamples() != 0)
132 log << TestLog::Message << renderTarget.getNumSamples() << "x MSAA" << TestLog::EndMessage;
134 log << TestLog::Message << "No MSAA" << TestLog::EndMessage;
136 log << TestLog::EndSection;
139 void ShaderPerformanceCase::init (void)
141 tcu::TestLog& log = m_testCtx.getLog();
143 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(m_vertShaderSource, m_fragShaderSource));
145 if (m_program->isOk())
147 const int initialCallCount = m_initialCalibration ? m_initialCalibration->initialNumCalls : 1;
148 logRenderTargetInfo(log, m_renderCtx.getRenderTarget());
149 m_measurer.init(m_program->getProgram(), m_attributes, initialCallCount);
150 m_measurer.logParameters(log);
156 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
157 return; // Skip rest of init.
160 setupProgram(m_program->getProgram());
164 void ShaderPerformanceCase::deinit (void)
172 void ShaderPerformanceCase::setupProgram (deUint32 program)
177 void ShaderPerformanceCase::setupRenderState (void)
181 ShaderPerformanceCase::IterateResult ShaderPerformanceCase::iterate (void)
183 DE_ASSERT(m_program);
185 if (!m_program->isOk()) // This happens when compilation failed in init().
188 m_measurer.iterate();
190 if (m_measurer.isFinished())
192 m_measurer.logMeasurementInfo(m_testCtx.getLog());
194 if (m_initialCalibration)
195 m_initialCalibration->initialNumCalls = de::max(1, m_measurer.getFinalCallCount());
197 const ShaderPerformanceMeasurer::Result result = m_measurer.getResult();
198 reportResult(result.megaVertPerSec, result.megaFragPerSec);
205 void ShaderPerformanceCase::reportResult (float mvertPerSecond, float mfragPerSecond)
210 case CASETYPE_VERTEX: result = mvertPerSecond; break;
211 case CASETYPE_FRAGMENT: result = mfragPerSecond; break;
212 case CASETYPE_BALANCED: result = mfragPerSecond; break;
217 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
220 ShaderPerformanceCaseGroup::ShaderPerformanceCaseGroup (tcu::TestContext& testCtx, const char* name, const char* description)
221 : TestCaseGroup (testCtx, name, description)
222 , m_initialCalibrationStorage (new ShaderPerformanceCase::InitialCalibration)
226 void ShaderPerformanceCaseGroup::addChild (ShaderPerformanceCase* perfCase)
228 perfCase->setCalibrationInitialParamStorage(m_initialCalibrationStorage);
229 TestCaseGroup::addChild(perfCase);