xref: /aosp_15_r20/external/deqp/modules/glshared/glsShaderPerformanceCase.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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::TestLog;
33 using tcu::Vec4;
34 using namespace glw; // GL types
35 
36 namespace deqp
37 {
38 namespace gls
39 {
40 
ShaderPerformanceCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,PerfCaseType caseType)41 ShaderPerformanceCase::ShaderPerformanceCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
42                                              const char *description, PerfCaseType caseType)
43     : tcu::TestCase(testCtx, tcu::NODETYPE_PERFORMANCE, name, description)
44     , m_renderCtx(renderCtx)
45     , m_caseType(caseType)
46     , m_program(DE_NULL)
47     , m_measurer(renderCtx, caseType)
48 {
49 }
50 
~ShaderPerformanceCase(void)51 ShaderPerformanceCase::~ShaderPerformanceCase(void)
52 {
53     ShaderPerformanceCase::deinit();
54 }
55 
setGridSize(int gridW,int gridH)56 void ShaderPerformanceCase::setGridSize(int gridW, int gridH)
57 {
58     m_measurer.setGridSize(gridW, gridH);
59 }
60 
setViewportSize(int width,int height)61 void ShaderPerformanceCase::setViewportSize(int width, int height)
62 {
63     m_measurer.setViewportSize(width, height);
64 }
65 
setVertexFragmentRatio(float fragmentsPerVertices)66 void ShaderPerformanceCase::setVertexFragmentRatio(float fragmentsPerVertices)
67 {
68     const float eps = 0.01f;
69     int gridW       = 255;
70     int gridH       = 255;
71     int viewportW   = m_renderCtx.getRenderTarget().getWidth();
72     int viewportH   = m_renderCtx.getRenderTarget().getHeight();
73 
74     for (int i = 0; i < 10; i++)
75     {
76         int numVert = (gridW + 1) * (gridH + 1);
77         int numFrag = viewportW * viewportH;
78         float ratio = (float)numFrag / (float)numVert;
79 
80         if (de::abs(ratio - fragmentsPerVertices) < eps)
81             break;
82         else if (ratio < fragmentsPerVertices)
83         {
84             // Not enough fragments.
85             numVert = deRoundFloatToInt32((float)numFrag / fragmentsPerVertices);
86 
87             while ((gridW + 1) * (gridH + 1) > numVert)
88             {
89                 if (gridW > gridH)
90                     gridW -= 1;
91                 else
92                     gridH -= 1;
93             }
94         }
95         else
96         {
97             // Not enough vertices.
98             numFrag = deRoundFloatToInt32((float)numVert * fragmentsPerVertices);
99 
100             while (viewportW * viewportH > numFrag)
101             {
102                 if (viewportW > viewportH)
103                     viewportW -= 1;
104                 else
105                     viewportH -= 1;
106             }
107         }
108     }
109 
110     float finalRatio = (float)(viewportW * viewportH) / (float)((gridW + 1) * (gridH + 1));
111     m_testCtx.getLog() << TestLog::Message
112                        << "Requested fragment/vertex-ratio: " << de::floatToString(fragmentsPerVertices, 2) << "\n"
113                        << "Computed fragment/vertex-ratio: " << de::floatToString(finalRatio, 2) << TestLog::EndMessage;
114 
115     setGridSize(gridW, gridH);
116     setViewportSize(viewportW, viewportH);
117 }
118 
logRenderTargetInfo(TestLog & log,const tcu::RenderTarget & renderTarget)119 static void logRenderTargetInfo(TestLog &log, const tcu::RenderTarget &renderTarget)
120 {
121     log << TestLog::Section("RenderTarget", "Render target") << TestLog::Message << "size: " << renderTarget.getWidth()
122         << "x" << renderTarget.getHeight() << TestLog::EndMessage << TestLog::Message << "bits:"
123         << " R" << renderTarget.getPixelFormat().redBits << " G" << renderTarget.getPixelFormat().greenBits << " B"
124         << renderTarget.getPixelFormat().blueBits << " A" << renderTarget.getPixelFormat().alphaBits << " D"
125         << renderTarget.getDepthBits() << " S" << renderTarget.getStencilBits() << TestLog::EndMessage;
126 
127     if (renderTarget.getNumSamples() != 0)
128         log << TestLog::Message << renderTarget.getNumSamples() << "x MSAA" << TestLog::EndMessage;
129     else
130         log << TestLog::Message << "No MSAA" << TestLog::EndMessage;
131 
132     log << TestLog::EndSection;
133 }
134 
init(void)135 void ShaderPerformanceCase::init(void)
136 {
137     tcu::TestLog &log = m_testCtx.getLog();
138 
139     m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(m_vertShaderSource, m_fragShaderSource));
140 
141     if (m_program->isOk())
142     {
143         const int initialCallCount = m_initialCalibration ? m_initialCalibration->initialNumCalls : 1;
144         logRenderTargetInfo(log, m_renderCtx.getRenderTarget());
145         m_measurer.init(m_program->getProgram(), m_attributes, initialCallCount);
146         m_measurer.logParameters(log);
147         log << *m_program;
148     }
149     else
150     {
151         log << *m_program;
152         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
153         return; // Skip rest of init.
154     }
155 
156     setupProgram(m_program->getProgram());
157     setupRenderState();
158 }
159 
deinit(void)160 void ShaderPerformanceCase::deinit(void)
161 {
162     delete m_program;
163     m_program = DE_NULL;
164 
165     m_measurer.deinit();
166 }
167 
setupProgram(uint32_t program)168 void ShaderPerformanceCase::setupProgram(uint32_t program)
169 {
170     DE_UNREF(program);
171 }
172 
setupRenderState(void)173 void ShaderPerformanceCase::setupRenderState(void)
174 {
175 }
176 
iterate(void)177 ShaderPerformanceCase::IterateResult ShaderPerformanceCase::iterate(void)
178 {
179     DE_ASSERT(m_program);
180 
181     if (!m_program->isOk()) // This happens when compilation failed in init().
182         return STOP;
183 
184     m_measurer.iterate();
185 
186     if (m_measurer.isFinished())
187     {
188         m_measurer.logMeasurementInfo(m_testCtx.getLog());
189 
190         if (m_initialCalibration)
191             m_initialCalibration->initialNumCalls = de::max(1, m_measurer.getFinalCallCount());
192 
193         const ShaderPerformanceMeasurer::Result result = m_measurer.getResult();
194         reportResult(result.megaVertPerSec, result.megaFragPerSec);
195         return STOP;
196     }
197     else
198         return CONTINUE;
199 }
200 
reportResult(float mvertPerSecond,float mfragPerSecond)201 void ShaderPerformanceCase::reportResult(float mvertPerSecond, float mfragPerSecond)
202 {
203     float result = 0.0f;
204     switch (m_caseType)
205     {
206     case CASETYPE_VERTEX:
207         result = mvertPerSecond;
208         break;
209     case CASETYPE_FRAGMENT:
210         result = mfragPerSecond;
211         break;
212     case CASETYPE_BALANCED:
213         result = mfragPerSecond;
214         break;
215     default:
216         DE_ASSERT(false);
217     }
218 
219     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
220 }
221 
ShaderPerformanceCaseGroup(tcu::TestContext & testCtx,const char * name,const char * description)222 ShaderPerformanceCaseGroup::ShaderPerformanceCaseGroup(tcu::TestContext &testCtx, const char *name,
223                                                        const char *description)
224     : TestCaseGroup(testCtx, name, description)
225     , m_initialCalibrationStorage(new ShaderPerformanceCase::InitialCalibration)
226 {
227 }
228 
addChild(ShaderPerformanceCase * perfCase)229 void ShaderPerformanceCaseGroup::addChild(ShaderPerformanceCase *perfCase)
230 {
231     perfCase->setCalibrationInitialParamStorage(m_initialCalibrationStorage);
232     TestCaseGroup::addChild(perfCase);
233 }
234 
235 } // namespace gls
236 } // namespace deqp
237