Add packaging for TIZEN
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsShaderPerformanceCase.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL (ES) 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 Single-program test case wrapper for ShaderPerformanceMeasurer.
22  *//*--------------------------------------------------------------------*/
23
24 #include "glsShaderPerformanceCase.hpp"
25 #include "tcuRenderTarget.hpp"
26 #include "deStringUtil.hpp"
27 #include "deMath.h"
28
29 #include "glwFunctions.hpp"
30 #include "glwEnums.hpp"
31
32 using tcu::Vec4;
33 using tcu::TestLog;
34 using namespace glw; // GL types
35
36 namespace deqp
37 {
38 namespace gls
39 {
40
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)
45         , m_program                     (DE_NULL)
46         , m_measurer            (renderCtx, caseType)
47 {
48 }
49
50 ShaderPerformanceCase::~ShaderPerformanceCase (void)
51 {
52         ShaderPerformanceCase::deinit();
53 }
54
55 void ShaderPerformanceCase::setGridSize (int gridW, int gridH)
56 {
57         m_measurer.setGridSize(gridW, gridH);
58 }
59
60 void ShaderPerformanceCase::setViewportSize (int width, int height)
61 {
62         m_measurer.setViewportSize(width, height);
63 }
64
65 void ShaderPerformanceCase::setVertexFragmentRatio (float fragmentsPerVertices)
66 {
67         const float     eps                     = 0.01f;
68         int                     gridW           = 255;
69         int                     gridH           = 255;
70         int                     viewportW       = m_renderCtx.getRenderTarget().getWidth();
71         int                     viewportH       = m_renderCtx.getRenderTarget().getHeight();
72
73         for (int i = 0; i < 10; i++)
74         {
75                 int             numVert = (gridW+1)*(gridH+1);
76                 int             numFrag = viewportW*viewportH;
77                 float   ratio   = (float)numFrag / (float)numVert;
78
79                 if (de::abs(ratio - fragmentsPerVertices) < eps)
80                         break;
81                 else if (ratio < fragmentsPerVertices)
82                 {
83                         // Not enough fragments.
84                         numVert = deRoundFloatToInt32((float)numFrag / fragmentsPerVertices);
85
86                         while ((gridW+1)*(gridH+1) > numVert)
87                         {
88                                 if (gridW > gridH)
89                                         gridW -= 1;
90                                 else
91                                         gridH -= 1;
92                         }
93                 }
94                 else
95                 {
96                         // Not enough vertices.
97                         numFrag = deRoundFloatToInt32((float)numVert * fragmentsPerVertices);
98
99                         while (viewportW*viewportH > numFrag)
100                         {
101                                 if (viewportW > viewportH)
102                                         viewportW -= 1;
103                                 else
104                                         viewportH -= 1;
105                         }
106                 }
107         }
108
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;
113
114         setGridSize(gridW, gridH);
115         setViewportSize(viewportW, viewportH);
116 }
117
118 static void logRenderTargetInfo (TestLog& log, const tcu::RenderTarget& renderTarget)
119 {
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;
130
131         if (renderTarget.getNumSamples() != 0)
132                 log << TestLog::Message << renderTarget.getNumSamples() << "x MSAA" << TestLog::EndMessage;
133         else
134                 log << TestLog::Message << "No MSAA" << TestLog::EndMessage;
135
136         log << TestLog::EndSection;
137 }
138
139 void ShaderPerformanceCase::init (void)
140 {
141         tcu::TestLog& log = m_testCtx.getLog();
142
143         m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(m_vertShaderSource, m_fragShaderSource));
144
145         if (m_program->isOk())
146         {
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);
151                 log << *m_program;
152         }
153         else
154         {
155                 log << *m_program;
156                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
157                 return; // Skip rest of init.
158         }
159
160         setupProgram(m_program->getProgram());
161         setupRenderState();
162 }
163
164 void ShaderPerformanceCase::deinit (void)
165 {
166         delete m_program;
167         m_program = DE_NULL;
168
169         m_measurer.deinit();
170 }
171
172 void ShaderPerformanceCase::setupProgram (deUint32 program)
173 {
174         DE_UNREF(program);
175 }
176
177 void ShaderPerformanceCase::setupRenderState (void)
178 {
179 }
180
181 ShaderPerformanceCase::IterateResult ShaderPerformanceCase::iterate (void)
182 {
183         DE_ASSERT(m_program);
184
185         if (!m_program->isOk()) // This happens when compilation failed in init().
186                 return STOP;
187
188         m_measurer.iterate();
189
190         if (m_measurer.isFinished())
191         {
192                 m_measurer.logMeasurementInfo(m_testCtx.getLog());
193
194                 if (m_initialCalibration)
195                         m_initialCalibration->initialNumCalls = de::max(1, m_measurer.getFinalCallCount());
196
197                 const ShaderPerformanceMeasurer::Result result = m_measurer.getResult();
198                 reportResult(result.megaVertPerSec, result.megaFragPerSec);
199                 return STOP;
200         }
201         else
202                 return CONTINUE;
203 }
204
205 void ShaderPerformanceCase::reportResult (float mvertPerSecond, float mfragPerSecond)
206 {
207         float result = 0.0f;
208         switch (m_caseType)
209         {
210                 case CASETYPE_VERTEX:   result = mvertPerSecond;        break;
211                 case CASETYPE_FRAGMENT: result = mfragPerSecond;        break;
212                 case CASETYPE_BALANCED: result = mfragPerSecond;        break;
213                 default:
214                         DE_ASSERT(false);
215         }
216
217         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
218 }
219
220 ShaderPerformanceCaseGroup::ShaderPerformanceCaseGroup (tcu::TestContext& testCtx, const char* name, const char* description)
221         : TestCaseGroup                                 (testCtx, name, description)
222         , m_initialCalibrationStorage   (new ShaderPerformanceCase::InitialCalibration)
223 {
224 }
225
226 void ShaderPerformanceCaseGroup::addChild (ShaderPerformanceCase* perfCase)
227 {
228         perfCase->setCalibrationInitialParamStorage(m_initialCalibrationStorage);
229         TestCaseGroup::addChild(perfCase);
230 }
231
232 } // gls
233 } // deqp