xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fFlushFinishTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Flush and finish tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3fFlushFinishTests.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include "glsCalibration.hpp"
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuCPUWarmup.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuApp.hpp"
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
44*35238bceSAndroid Build Coastguard Worker #include "deThread.h"
45*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker #include <algorithm>
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker namespace deqp
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker namespace gles3
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker namespace Functional
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker 
56*35238bceSAndroid Build Coastguard Worker using deqp::gls::LineParameters;
57*35238bceSAndroid Build Coastguard Worker using deqp::gls::theilSenLinearRegression;
58*35238bceSAndroid Build Coastguard Worker using std::string;
59*35238bceSAndroid Build Coastguard Worker using std::vector;
60*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
61*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker namespace
64*35238bceSAndroid Build Coastguard Worker {
65*35238bceSAndroid Build Coastguard Worker 
66*35238bceSAndroid Build Coastguard Worker enum
67*35238bceSAndroid Build Coastguard Worker {
68*35238bceSAndroid Build Coastguard Worker     MAX_VIEWPORT_SIZE      = 256,
69*35238bceSAndroid Build Coastguard Worker     MAX_SAMPLE_DURATION_US = 150 * 1000,
70*35238bceSAndroid Build Coastguard Worker     MAX_CALIBRATE_DURATION_US =
71*35238bceSAndroid Build Coastguard Worker         tcu::WATCHDOG_INTERVAL_TIME_LIMIT_SECS / 3 * 1000 * 1000, // Abort when the watch dog gets nervous
72*35238bceSAndroid Build Coastguard Worker     WAIT_TIME_MS             = 200,
73*35238bceSAndroid Build Coastguard Worker     MIN_DRAW_CALL_COUNT      = 10,
74*35238bceSAndroid Build Coastguard Worker     MAX_DRAW_CALL_COUNT      = 1 << 20,
75*35238bceSAndroid Build Coastguard Worker     MAX_SHADER_ITER_COUNT    = 1 << 10,
76*35238bceSAndroid Build Coastguard Worker     NUM_SAMPLES              = 50,
77*35238bceSAndroid Build Coastguard Worker     NUM_VERIFICATION_SAMPLES = 3,
78*35238bceSAndroid Build Coastguard Worker     MAX_CALIBRATION_ATTEMPTS = 5
79*35238bceSAndroid Build Coastguard Worker };
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(MAX_SAMPLE_DURATION_US < 1000 * WAIT_TIME_MS);
82*35238bceSAndroid Build Coastguard Worker 
83*35238bceSAndroid Build Coastguard Worker const float NO_CORR_COEF_THRESHOLD    = 0.1f;
84*35238bceSAndroid Build Coastguard Worker const float FLUSH_COEF_THRESHOLD      = 0.2f;
85*35238bceSAndroid Build Coastguard Worker const float CORRELATED_COEF_THRESHOLD = 0.3f;
86*35238bceSAndroid Build Coastguard Worker const float CALIBRATION_VERIFICATION_THRESHOLD =
87*35238bceSAndroid Build Coastguard Worker     0.10f; // Rendering time needs to be within 10% of MAX_SAMPLE_DURATION_US
88*35238bceSAndroid Build Coastguard Worker 
busyWait(int milliseconds)89*35238bceSAndroid Build Coastguard Worker static void busyWait(int milliseconds)
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker     const uint64_t startTime = deGetMicroseconds();
92*35238bceSAndroid Build Coastguard Worker     float v                  = 2.0f;
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker     for (;;)
95*35238bceSAndroid Build Coastguard Worker     {
96*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 10; i++)
97*35238bceSAndroid Build Coastguard Worker             v = deFloatSin(v);
98*35238bceSAndroid Build Coastguard Worker 
99*35238bceSAndroid Build Coastguard Worker         if (deGetMicroseconds() - startTime >= uint64_t(1000 * milliseconds))
100*35238bceSAndroid Build Coastguard Worker             break;
101*35238bceSAndroid Build Coastguard Worker     }
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker 
104*35238bceSAndroid Build Coastguard Worker class CalibrationFailedException : public std::runtime_error
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker public:
CalibrationFailedException(const std::string & reason)107*35238bceSAndroid Build Coastguard Worker     CalibrationFailedException(const std::string &reason) : std::runtime_error(reason)
108*35238bceSAndroid Build Coastguard Worker     {
109*35238bceSAndroid Build Coastguard Worker     }
110*35238bceSAndroid Build Coastguard Worker };
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker class FlushFinishCase : public TestCase
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker public:
115*35238bceSAndroid Build Coastguard Worker     enum ExpectedBehavior
116*35238bceSAndroid Build Coastguard Worker     {
117*35238bceSAndroid Build Coastguard Worker         EXPECT_COEF_LESS_THAN = 0,
118*35238bceSAndroid Build Coastguard Worker         EXPECT_COEF_GREATER_THAN,
119*35238bceSAndroid Build Coastguard Worker     };
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker     FlushFinishCase(Context &context, const char *name, const char *description, ExpectedBehavior waitBehavior,
122*35238bceSAndroid Build Coastguard Worker                     float waitThreshold, ExpectedBehavior readBehavior, float readThreshold);
123*35238bceSAndroid Build Coastguard Worker     ~FlushFinishCase(void);
124*35238bceSAndroid Build Coastguard Worker 
125*35238bceSAndroid Build Coastguard Worker     void init(void);
126*35238bceSAndroid Build Coastguard Worker     void deinit(void);
127*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     struct Sample
130*35238bceSAndroid Build Coastguard Worker     {
131*35238bceSAndroid Build Coastguard Worker         int numDrawCalls;
132*35238bceSAndroid Build Coastguard Worker         uint64_t submitTime;
133*35238bceSAndroid Build Coastguard Worker         uint64_t waitTime;
134*35238bceSAndroid Build Coastguard Worker         uint64_t readPixelsTime;
135*35238bceSAndroid Build Coastguard Worker     };
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker     struct CalibrationParams
138*35238bceSAndroid Build Coastguard Worker     {
139*35238bceSAndroid Build Coastguard Worker         int numItersInShader;
140*35238bceSAndroid Build Coastguard Worker         int maxDrawCalls;
141*35238bceSAndroid Build Coastguard Worker     };
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker protected:
144*35238bceSAndroid Build Coastguard Worker     virtual void waitForGL(void) = 0;
145*35238bceSAndroid Build Coastguard Worker 
146*35238bceSAndroid Build Coastguard Worker private:
147*35238bceSAndroid Build Coastguard Worker     FlushFinishCase(const FlushFinishCase &);
148*35238bceSAndroid Build Coastguard Worker     FlushFinishCase &operator=(const FlushFinishCase &);
149*35238bceSAndroid Build Coastguard Worker 
150*35238bceSAndroid Build Coastguard Worker     CalibrationParams calibrate(void);
151*35238bceSAndroid Build Coastguard Worker     void verifyCalibration(const CalibrationParams &params);
152*35238bceSAndroid Build Coastguard Worker 
153*35238bceSAndroid Build Coastguard Worker     void analyzeResults(const std::vector<Sample> &samples, const CalibrationParams &calibrationParams);
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker     void setupRenderState(void);
156*35238bceSAndroid Build Coastguard Worker     void setShaderIterCount(int numIters);
157*35238bceSAndroid Build Coastguard Worker     void render(int numDrawCalls);
158*35238bceSAndroid Build Coastguard Worker     void readPixels(void);
159*35238bceSAndroid Build Coastguard Worker 
160*35238bceSAndroid Build Coastguard Worker     const ExpectedBehavior m_waitBehavior;
161*35238bceSAndroid Build Coastguard Worker     const float m_waitThreshold;
162*35238bceSAndroid Build Coastguard Worker     const ExpectedBehavior m_readBehavior;
163*35238bceSAndroid Build Coastguard Worker     const float m_readThreshold;
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_program;
166*35238bceSAndroid Build Coastguard Worker     int m_iterCountLoc;
167*35238bceSAndroid Build Coastguard Worker };
168*35238bceSAndroid Build Coastguard Worker 
FlushFinishCase(Context & context,const char * name,const char * description,ExpectedBehavior waitBehavior,float waitThreshold,ExpectedBehavior readBehavior,float readThreshold)169*35238bceSAndroid Build Coastguard Worker FlushFinishCase::FlushFinishCase(Context &context, const char *name, const char *description,
170*35238bceSAndroid Build Coastguard Worker                                  ExpectedBehavior waitBehavior, float waitThreshold, ExpectedBehavior readBehavior,
171*35238bceSAndroid Build Coastguard Worker                                  float readThreshold)
172*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
173*35238bceSAndroid Build Coastguard Worker     , m_waitBehavior(waitBehavior)
174*35238bceSAndroid Build Coastguard Worker     , m_waitThreshold(waitThreshold)
175*35238bceSAndroid Build Coastguard Worker     , m_readBehavior(readBehavior)
176*35238bceSAndroid Build Coastguard Worker     , m_readThreshold(readThreshold)
177*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
178*35238bceSAndroid Build Coastguard Worker     , m_iterCountLoc(0)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker }
181*35238bceSAndroid Build Coastguard Worker 
~FlushFinishCase(void)182*35238bceSAndroid Build Coastguard Worker FlushFinishCase::~FlushFinishCase(void)
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker     FlushFinishCase::deinit();
185*35238bceSAndroid Build Coastguard Worker }
186*35238bceSAndroid Build Coastguard Worker 
init(void)187*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::init(void)
188*35238bceSAndroid Build Coastguard Worker {
189*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_program);
190*35238bceSAndroid Build Coastguard Worker 
191*35238bceSAndroid Build Coastguard Worker     m_program =
192*35238bceSAndroid Build Coastguard Worker         new glu::ShaderProgram(m_context.getRenderContext(),
193*35238bceSAndroid Build Coastguard Worker                                glu::ProgramSources() << glu::VertexSource("#version 300 es\n"
194*35238bceSAndroid Build Coastguard Worker                                                                           "in highp vec4 a_position;\n"
195*35238bceSAndroid Build Coastguard Worker                                                                           "out highp vec4 v_coord;\n"
196*35238bceSAndroid Build Coastguard Worker                                                                           "void main (void)\n"
197*35238bceSAndroid Build Coastguard Worker                                                                           "{\n"
198*35238bceSAndroid Build Coastguard Worker                                                                           "    gl_Position = a_position;\n"
199*35238bceSAndroid Build Coastguard Worker                                                                           "    v_coord = a_position;\n"
200*35238bceSAndroid Build Coastguard Worker                                                                           "}\n")
201*35238bceSAndroid Build Coastguard Worker                                                      << glu::FragmentSource("#version 300 es\n"
202*35238bceSAndroid Build Coastguard Worker                                                                             "uniform highp int u_numIters;\n"
203*35238bceSAndroid Build Coastguard Worker                                                                             "in highp vec4 v_coord;\n"
204*35238bceSAndroid Build Coastguard Worker                                                                             "out mediump vec4 o_color;\n"
205*35238bceSAndroid Build Coastguard Worker                                                                             "void main (void)\n"
206*35238bceSAndroid Build Coastguard Worker                                                                             "{\n"
207*35238bceSAndroid Build Coastguard Worker                                                                             "    highp vec4 color = v_coord;\n"
208*35238bceSAndroid Build Coastguard Worker                                                                             "    for (int i = 0; i < u_numIters; i++)\n"
209*35238bceSAndroid Build Coastguard Worker                                                                             "        color = sin(color);\n"
210*35238bceSAndroid Build Coastguard Worker                                                                             "    o_color = color;\n"
211*35238bceSAndroid Build Coastguard Worker                                                                             "}\n"));
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
214*35238bceSAndroid Build Coastguard Worker     {
215*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_program;
216*35238bceSAndroid Build Coastguard Worker         delete m_program;
217*35238bceSAndroid Build Coastguard Worker         m_program = DE_NULL;
218*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
219*35238bceSAndroid Build Coastguard Worker     }
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker     m_iterCountLoc =
222*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().getUniformLocation(m_program->getProgram(), "u_numIters");
223*35238bceSAndroid Build Coastguard Worker     TCU_CHECK(m_iterCountLoc >= 0);
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker 
deinit(void)226*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::deinit(void)
227*35238bceSAndroid Build Coastguard Worker {
228*35238bceSAndroid Build Coastguard Worker     delete m_program;
229*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker 
operator <<(tcu::TestLog & log,const FlushFinishCase::Sample & sample)232*35238bceSAndroid Build Coastguard Worker tcu::TestLog &operator<<(tcu::TestLog &log, const FlushFinishCase::Sample &sample)
233*35238bceSAndroid Build Coastguard Worker {
234*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << sample.numDrawCalls << " calls:\t" << sample.submitTime << " us submit,\t"
235*35238bceSAndroid Build Coastguard Worker         << sample.waitTime << " us wait,\t" << sample.readPixelsTime << " us read" << TestLog::EndMessage;
236*35238bceSAndroid Build Coastguard Worker     return log;
237*35238bceSAndroid Build Coastguard Worker }
238*35238bceSAndroid Build Coastguard Worker 
setupRenderState(void)239*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::setupRenderState(void)
240*35238bceSAndroid Build Coastguard Worker {
241*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
242*35238bceSAndroid Build Coastguard Worker     const int posLoc         = gl.getAttribLocation(m_program->getProgram(), "a_position");
243*35238bceSAndroid Build Coastguard Worker     const int viewportW      = de::min<int>(m_context.getRenderTarget().getWidth(), MAX_VIEWPORT_SIZE);
244*35238bceSAndroid Build Coastguard Worker     const int viewportH      = de::min<int>(m_context.getRenderTarget().getHeight(), MAX_VIEWPORT_SIZE);
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker     static const float s_positions[] = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
247*35238bceSAndroid Build Coastguard Worker 
248*35238bceSAndroid Build Coastguard Worker     TCU_CHECK(posLoc >= 0);
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, viewportW, viewportH);
251*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_program->getProgram());
252*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(posLoc);
253*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, &s_positions[0]);
254*35238bceSAndroid Build Coastguard Worker     gl.enable(GL_BLEND);
255*35238bceSAndroid Build Coastguard Worker     gl.blendFunc(GL_ONE, GL_ONE);
256*35238bceSAndroid Build Coastguard Worker     gl.blendEquation(GL_FUNC_ADD);
257*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set up render state");
258*35238bceSAndroid Build Coastguard Worker }
259*35238bceSAndroid Build Coastguard Worker 
setShaderIterCount(int numIters)260*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::setShaderIterCount(int numIters)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
263*35238bceSAndroid Build Coastguard Worker     gl.uniform1i(m_iterCountLoc, numIters);
264*35238bceSAndroid Build Coastguard Worker }
265*35238bceSAndroid Build Coastguard Worker 
render(int numDrawCalls)266*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::render(int numDrawCalls)
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker     const uint8_t indices[] = {0, 1, 2, 2, 1, 3};
271*35238bceSAndroid Build Coastguard Worker 
272*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numDrawCalls; ndx++)
275*35238bceSAndroid Build Coastguard Worker         gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_BYTE, &indices[0]);
276*35238bceSAndroid Build Coastguard Worker }
277*35238bceSAndroid Build Coastguard Worker 
readPixels(void)278*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::readPixels(void)
279*35238bceSAndroid Build Coastguard Worker {
280*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
281*35238bceSAndroid Build Coastguard Worker     uint8_t tmp[4];
282*35238bceSAndroid Build Coastguard Worker 
283*35238bceSAndroid Build Coastguard Worker     gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &tmp);
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker 
calibrate(void)286*35238bceSAndroid Build Coastguard Worker FlushFinishCase::CalibrationParams FlushFinishCase::calibrate(void)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker     tcu::ScopedLogSection section(m_testCtx.getLog(), "CalibrationInfo", "Calibration info");
289*35238bceSAndroid Build Coastguard Worker     CalibrationParams params;
290*35238bceSAndroid Build Coastguard Worker 
291*35238bceSAndroid Build Coastguard Worker     const uint64_t calibrateStartTime = deGetMicroseconds();
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker     // Step 1: find iteration count that results in rougly 1/10th of target maximum sample duration.
294*35238bceSAndroid Build Coastguard Worker     {
295*35238bceSAndroid Build Coastguard Worker         const uint64_t targetDurationUs = MAX_SAMPLE_DURATION_US / 100;
296*35238bceSAndroid Build Coastguard Worker         uint64_t prevDuration           = 0;
297*35238bceSAndroid Build Coastguard Worker         int prevIterCount               = 1;
298*35238bceSAndroid Build Coastguard Worker         int curIterCount                = 1;
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message
301*35238bceSAndroid Build Coastguard Worker                            << "Calibrating shader iteration count, target duration = " << targetDurationUs << " us"
302*35238bceSAndroid Build Coastguard Worker                            << TestLog::EndMessage;
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker         for (;;)
305*35238bceSAndroid Build Coastguard Worker         {
306*35238bceSAndroid Build Coastguard Worker             uint64_t endTime;
307*35238bceSAndroid Build Coastguard Worker             uint64_t curDuration;
308*35238bceSAndroid Build Coastguard Worker 
309*35238bceSAndroid Build Coastguard Worker             setShaderIterCount(curIterCount);
310*35238bceSAndroid Build Coastguard Worker             render(1); // \note Submit time is ignored
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker             {
313*35238bceSAndroid Build Coastguard Worker                 const uint64_t startTime = deGetMicroseconds();
314*35238bceSAndroid Build Coastguard Worker                 readPixels();
315*35238bceSAndroid Build Coastguard Worker                 endTime     = deGetMicroseconds();
316*35238bceSAndroid Build Coastguard Worker                 curDuration = endTime - startTime;
317*35238bceSAndroid Build Coastguard Worker             }
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Duration with " << curIterCount
320*35238bceSAndroid Build Coastguard Worker                                << " iterations = " << curDuration << " us" << TestLog::EndMessage;
321*35238bceSAndroid Build Coastguard Worker 
322*35238bceSAndroid Build Coastguard Worker             if (curDuration > targetDurationUs)
323*35238bceSAndroid Build Coastguard Worker             {
324*35238bceSAndroid Build Coastguard Worker                 if (curIterCount > 1)
325*35238bceSAndroid Build Coastguard Worker                 {
326*35238bceSAndroid Build Coastguard Worker                     // Compute final count by using linear estimation.
327*35238bceSAndroid Build Coastguard Worker                     const float a   = float(curDuration - prevDuration) / float(curIterCount - prevIterCount);
328*35238bceSAndroid Build Coastguard Worker                     const float b   = float(prevDuration) - a * float(prevIterCount);
329*35238bceSAndroid Build Coastguard Worker                     const float est = (float(targetDurationUs) - b) / a;
330*35238bceSAndroid Build Coastguard Worker 
331*35238bceSAndroid Build Coastguard Worker                     curIterCount = de::clamp(deFloorFloatToInt32(est), 1, int(MAX_SHADER_ITER_COUNT));
332*35238bceSAndroid Build Coastguard Worker                 }
333*35238bceSAndroid Build Coastguard Worker                 // else: Settle on 1.
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker                 break;
336*35238bceSAndroid Build Coastguard Worker             }
337*35238bceSAndroid Build Coastguard Worker             else if (curIterCount >= MAX_SHADER_ITER_COUNT)
338*35238bceSAndroid Build Coastguard Worker                 break; // Settle on maximum.
339*35238bceSAndroid Build Coastguard Worker             else if (endTime - calibrateStartTime > MAX_CALIBRATE_DURATION_US)
340*35238bceSAndroid Build Coastguard Worker             {
341*35238bceSAndroid Build Coastguard Worker                 // Calibration is taking longer than expected. This can be due to eager draw call execution.
342*35238bceSAndroid Build Coastguard Worker                 throw CalibrationFailedException(
343*35238bceSAndroid Build Coastguard Worker                     "Calibration failed, target duration not reached within expected time");
344*35238bceSAndroid Build Coastguard Worker             }
345*35238bceSAndroid Build Coastguard Worker             else
346*35238bceSAndroid Build Coastguard Worker             {
347*35238bceSAndroid Build Coastguard Worker                 prevIterCount = curIterCount;
348*35238bceSAndroid Build Coastguard Worker                 prevDuration  = curDuration;
349*35238bceSAndroid Build Coastguard Worker                 curIterCount  = curIterCount * 2;
350*35238bceSAndroid Build Coastguard Worker             }
351*35238bceSAndroid Build Coastguard Worker         }
352*35238bceSAndroid Build Coastguard Worker 
353*35238bceSAndroid Build Coastguard Worker         params.numItersInShader = curIterCount;
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Integer("ShaderIterCount", "Shader iteration count", "", QP_KEY_TAG_NONE,
356*35238bceSAndroid Build Coastguard Worker                                                params.numItersInShader);
357*35238bceSAndroid Build Coastguard Worker     }
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker     // Step 2: Find draw call count that results in desired maximum time.
360*35238bceSAndroid Build Coastguard Worker     {
361*35238bceSAndroid Build Coastguard Worker         uint64_t prevDuration = 0;
362*35238bceSAndroid Build Coastguard Worker         int prevDrawCount     = 1;
363*35238bceSAndroid Build Coastguard Worker         int curDrawCount      = 1;
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message
366*35238bceSAndroid Build Coastguard Worker                            << "Calibrating maximum draw call count, target duration = " << int(MAX_SAMPLE_DURATION_US)
367*35238bceSAndroid Build Coastguard Worker                            << " us" << TestLog::EndMessage;
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker         setShaderIterCount(params.numItersInShader);
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker         for (;;)
372*35238bceSAndroid Build Coastguard Worker         {
373*35238bceSAndroid Build Coastguard Worker             uint64_t endTime;
374*35238bceSAndroid Build Coastguard Worker             uint64_t curDuration;
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker             render(curDrawCount); // \note Submit time is ignored
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker             {
379*35238bceSAndroid Build Coastguard Worker                 const uint64_t startTime = deGetMicroseconds();
380*35238bceSAndroid Build Coastguard Worker                 readPixels();
381*35238bceSAndroid Build Coastguard Worker                 endTime     = deGetMicroseconds();
382*35238bceSAndroid Build Coastguard Worker                 curDuration = endTime - startTime;
383*35238bceSAndroid Build Coastguard Worker             }
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Duration with " << curDrawCount
386*35238bceSAndroid Build Coastguard Worker                                << " draw calls = " << curDuration << " us" << TestLog::EndMessage;
387*35238bceSAndroid Build Coastguard Worker 
388*35238bceSAndroid Build Coastguard Worker             if (curDuration > MAX_SAMPLE_DURATION_US)
389*35238bceSAndroid Build Coastguard Worker             {
390*35238bceSAndroid Build Coastguard Worker                 if (curDrawCount > 1)
391*35238bceSAndroid Build Coastguard Worker                 {
392*35238bceSAndroid Build Coastguard Worker                     // Compute final count by using linear estimation.
393*35238bceSAndroid Build Coastguard Worker                     const float a   = float(curDuration - prevDuration) / float(curDrawCount - prevDrawCount);
394*35238bceSAndroid Build Coastguard Worker                     const float b   = float(prevDuration) - a * float(prevDrawCount);
395*35238bceSAndroid Build Coastguard Worker                     const float est = (float(MAX_SAMPLE_DURATION_US) - b) / a;
396*35238bceSAndroid Build Coastguard Worker 
397*35238bceSAndroid Build Coastguard Worker                     curDrawCount = de::clamp(deFloorFloatToInt32(est), 1, int(MAX_DRAW_CALL_COUNT));
398*35238bceSAndroid Build Coastguard Worker                 }
399*35238bceSAndroid Build Coastguard Worker                 // else: Settle on 1.
400*35238bceSAndroid Build Coastguard Worker 
401*35238bceSAndroid Build Coastguard Worker                 break;
402*35238bceSAndroid Build Coastguard Worker             }
403*35238bceSAndroid Build Coastguard Worker             else if (curDrawCount >= MAX_DRAW_CALL_COUNT)
404*35238bceSAndroid Build Coastguard Worker                 break; // Settle on maximum.
405*35238bceSAndroid Build Coastguard Worker             else if (endTime - calibrateStartTime > MAX_CALIBRATE_DURATION_US)
406*35238bceSAndroid Build Coastguard Worker             {
407*35238bceSAndroid Build Coastguard Worker                 // Calibration is taking longer than expected. This can be due to eager draw call execution.
408*35238bceSAndroid Build Coastguard Worker                 throw CalibrationFailedException(
409*35238bceSAndroid Build Coastguard Worker                     "Calibration failed, target duration not reached within expected time");
410*35238bceSAndroid Build Coastguard Worker             }
411*35238bceSAndroid Build Coastguard Worker             else
412*35238bceSAndroid Build Coastguard Worker             {
413*35238bceSAndroid Build Coastguard Worker                 prevDrawCount = curDrawCount;
414*35238bceSAndroid Build Coastguard Worker                 prevDuration  = curDuration;
415*35238bceSAndroid Build Coastguard Worker                 curDrawCount  = curDrawCount * 2;
416*35238bceSAndroid Build Coastguard Worker             }
417*35238bceSAndroid Build Coastguard Worker         }
418*35238bceSAndroid Build Coastguard Worker 
419*35238bceSAndroid Build Coastguard Worker         params.maxDrawCalls = curDrawCount;
420*35238bceSAndroid Build Coastguard Worker 
421*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Integer("MaxDrawCalls", "Maximum number of draw calls", "", QP_KEY_TAG_NONE,
422*35238bceSAndroid Build Coastguard Worker                                                params.maxDrawCalls);
423*35238bceSAndroid Build Coastguard Worker     }
424*35238bceSAndroid Build Coastguard Worker 
425*35238bceSAndroid Build Coastguard Worker     // Quick check.
426*35238bceSAndroid Build Coastguard Worker     if (params.maxDrawCalls < MIN_DRAW_CALL_COUNT)
427*35238bceSAndroid Build Coastguard Worker         throw CalibrationFailedException("Calibration failed, maximum draw call count is too low");
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker     return params;
430*35238bceSAndroid Build Coastguard Worker }
431*35238bceSAndroid Build Coastguard Worker 
verifyCalibration(const CalibrationParams & params)432*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::verifyCalibration(const CalibrationParams &params)
433*35238bceSAndroid Build Coastguard Worker {
434*35238bceSAndroid Build Coastguard Worker     setShaderIterCount(params.numItersInShader);
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker     for (int sampleNdx = 0; sampleNdx < NUM_VERIFICATION_SAMPLES; sampleNdx++)
437*35238bceSAndroid Build Coastguard Worker     {
438*35238bceSAndroid Build Coastguard Worker         uint64_t readStartTime;
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker         render(params.maxDrawCalls);
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker         readStartTime = deGetMicroseconds();
443*35238bceSAndroid Build Coastguard Worker         readPixels();
444*35238bceSAndroid Build Coastguard Worker 
445*35238bceSAndroid Build Coastguard Worker         {
446*35238bceSAndroid Build Coastguard Worker             const uint64_t renderDuration = deGetMicroseconds() - readStartTime;
447*35238bceSAndroid Build Coastguard Worker             const float relativeDelta     = float(double(renderDuration) / double(MAX_SAMPLE_DURATION_US)) - 1.0f;
448*35238bceSAndroid Build Coastguard Worker 
449*35238bceSAndroid Build Coastguard Worker             if (!de::inBounds(relativeDelta, -CALIBRATION_VERIFICATION_THRESHOLD, CALIBRATION_VERIFICATION_THRESHOLD))
450*35238bceSAndroid Build Coastguard Worker             {
451*35238bceSAndroid Build Coastguard Worker                 std::ostringstream msg;
452*35238bceSAndroid Build Coastguard Worker                 msg << "ERROR: Unstable performance, got " << renderDuration << " us read time, "
453*35238bceSAndroid Build Coastguard Worker                     << de::floatToString(relativeDelta * 100.0f, 1) << "% diff to estimated "
454*35238bceSAndroid Build Coastguard Worker                     << (int)MAX_SAMPLE_DURATION_US << " us";
455*35238bceSAndroid Build Coastguard Worker                 throw CalibrationFailedException(msg.str());
456*35238bceSAndroid Build Coastguard Worker             }
457*35238bceSAndroid Build Coastguard Worker         }
458*35238bceSAndroid Build Coastguard Worker     }
459*35238bceSAndroid Build Coastguard Worker }
460*35238bceSAndroid Build Coastguard Worker 
461*35238bceSAndroid Build Coastguard Worker struct CompareSampleDrawCount
462*35238bceSAndroid Build Coastguard Worker {
operator ()deqp::gles3::Functional::__anone65d782f0111::CompareSampleDrawCount463*35238bceSAndroid Build Coastguard Worker     bool operator()(const FlushFinishCase::Sample &a, const FlushFinishCase::Sample &b) const
464*35238bceSAndroid Build Coastguard Worker     {
465*35238bceSAndroid Build Coastguard Worker         return a.numDrawCalls < b.numDrawCalls;
466*35238bceSAndroid Build Coastguard Worker     }
467*35238bceSAndroid Build Coastguard Worker };
468*35238bceSAndroid Build Coastguard Worker 
getPointsFromSamples(const std::vector<FlushFinishCase::Sample> & samples,const uint64_t FlushFinishCase::Sample::* field)469*35238bceSAndroid Build Coastguard Worker std::vector<Vec2> getPointsFromSamples(const std::vector<FlushFinishCase::Sample> &samples,
470*35238bceSAndroid Build Coastguard Worker                                        const uint64_t FlushFinishCase::Sample::*field)
471*35238bceSAndroid Build Coastguard Worker {
472*35238bceSAndroid Build Coastguard Worker     vector<Vec2> points(samples.size());
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 0; ndx < samples.size(); ndx++)
475*35238bceSAndroid Build Coastguard Worker         points[ndx] = Vec2(float(samples[ndx].numDrawCalls), float(samples[ndx].*field));
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker     return points;
478*35238bceSAndroid Build Coastguard Worker }
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker template <typename T>
getMaximumValue(const std::vector<FlushFinishCase::Sample> & samples,const T FlushFinishCase::Sample::* field)481*35238bceSAndroid Build Coastguard Worker T getMaximumValue(const std::vector<FlushFinishCase::Sample> &samples, const T FlushFinishCase::Sample::*field)
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!samples.empty());
484*35238bceSAndroid Build Coastguard Worker 
485*35238bceSAndroid Build Coastguard Worker     T maxVal = samples[0].*field;
486*35238bceSAndroid Build Coastguard Worker 
487*35238bceSAndroid Build Coastguard Worker     for (size_t ndx = 1; ndx < samples.size(); ndx++)
488*35238bceSAndroid Build Coastguard Worker         maxVal = de::max(maxVal, samples[ndx].*field);
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker     return maxVal;
491*35238bceSAndroid Build Coastguard Worker }
492*35238bceSAndroid Build Coastguard Worker 
analyzeResults(const std::vector<Sample> & samples,const CalibrationParams & calibrationParams)493*35238bceSAndroid Build Coastguard Worker void FlushFinishCase::analyzeResults(const std::vector<Sample> &samples, const CalibrationParams &calibrationParams)
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker     const vector<Vec2> waitTimes  = getPointsFromSamples(samples, &Sample::waitTime);
496*35238bceSAndroid Build Coastguard Worker     const vector<Vec2> readTimes  = getPointsFromSamples(samples, &Sample::readPixelsTime);
497*35238bceSAndroid Build Coastguard Worker     const LineParameters waitLine = theilSenLinearRegression(waitTimes);
498*35238bceSAndroid Build Coastguard Worker     const LineParameters readLine = theilSenLinearRegression(readTimes);
499*35238bceSAndroid Build Coastguard Worker     const float normWaitCoef =
500*35238bceSAndroid Build Coastguard Worker         waitLine.coefficient * float(calibrationParams.maxDrawCalls) / float(MAX_SAMPLE_DURATION_US);
501*35238bceSAndroid Build Coastguard Worker     const float normReadCoef =
502*35238bceSAndroid Build Coastguard Worker         readLine.coefficient * float(calibrationParams.maxDrawCalls) / float(MAX_SAMPLE_DURATION_US);
503*35238bceSAndroid Build Coastguard Worker     bool allOk = true;
504*35238bceSAndroid Build Coastguard Worker 
505*35238bceSAndroid Build Coastguard Worker     {
506*35238bceSAndroid Build Coastguard Worker         tcu::ScopedLogSection section(m_testCtx.getLog(), "Samples", "Samples");
507*35238bceSAndroid Build Coastguard Worker         vector<Sample> sortedSamples(samples.begin(), samples.end());
508*35238bceSAndroid Build Coastguard Worker 
509*35238bceSAndroid Build Coastguard Worker         std::sort(sortedSamples.begin(), sortedSamples.end(), CompareSampleDrawCount());
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker         for (vector<Sample>::const_iterator iter = sortedSamples.begin(); iter != sortedSamples.end(); ++iter)
512*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << *iter;
513*35238bceSAndroid Build Coastguard Worker     }
514*35238bceSAndroid Build Coastguard Worker 
515*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::Float("WaitCoefficient", "Wait coefficient", "", QP_KEY_TAG_NONE,
516*35238bceSAndroid Build Coastguard Worker                                          waitLine.coefficient)
517*35238bceSAndroid Build Coastguard Worker                        << TestLog::Float("ReadCoefficient", "Read coefficient", "", QP_KEY_TAG_NONE,
518*35238bceSAndroid Build Coastguard Worker                                          readLine.coefficient)
519*35238bceSAndroid Build Coastguard Worker                        << TestLog::Float("NormalizedWaitCoefficient", "Normalized wait coefficient", "",
520*35238bceSAndroid Build Coastguard Worker                                          QP_KEY_TAG_NONE, normWaitCoef)
521*35238bceSAndroid Build Coastguard Worker                        << TestLog::Float("NormalizedReadCoefficient", "Normalized read coefficient", "",
522*35238bceSAndroid Build Coastguard Worker                                          QP_KEY_TAG_NONE, normReadCoef);
523*35238bceSAndroid Build Coastguard Worker 
524*35238bceSAndroid Build Coastguard Worker     {
525*35238bceSAndroid Build Coastguard Worker         const bool waitCorrelated = normWaitCoef > CORRELATED_COEF_THRESHOLD;
526*35238bceSAndroid Build Coastguard Worker         const bool readCorrelated = normReadCoef > CORRELATED_COEF_THRESHOLD;
527*35238bceSAndroid Build Coastguard Worker         const bool waitNotCorr    = normWaitCoef < NO_CORR_COEF_THRESHOLD;
528*35238bceSAndroid Build Coastguard Worker         const bool readNotCorr    = normReadCoef < NO_CORR_COEF_THRESHOLD;
529*35238bceSAndroid Build Coastguard Worker 
530*35238bceSAndroid Build Coastguard Worker         if (waitCorrelated || waitNotCorr)
531*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Wait time is" << (waitCorrelated ? "" : " NOT")
532*35238bceSAndroid Build Coastguard Worker                                << " correlated to rendering workload size." << TestLog::EndMessage;
533*35238bceSAndroid Build Coastguard Worker         else
534*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message
535*35238bceSAndroid Build Coastguard Worker                                << "Warning: Wait time correlation to rendering workload size is unclear."
536*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker         if (readCorrelated || readNotCorr)
539*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Read time is" << (readCorrelated ? "" : " NOT")
540*35238bceSAndroid Build Coastguard Worker                                << " correlated to rendering workload size." << TestLog::EndMessage;
541*35238bceSAndroid Build Coastguard Worker         else
542*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message
543*35238bceSAndroid Build Coastguard Worker                                << "Warning: Read time correlation to rendering workload size is unclear."
544*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
545*35238bceSAndroid Build Coastguard Worker     }
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < 2; ndx++)
548*35238bceSAndroid Build Coastguard Worker     {
549*35238bceSAndroid Build Coastguard Worker         const float coef                = ndx == 0 ? normWaitCoef : normReadCoef;
550*35238bceSAndroid Build Coastguard Worker         const char *name                = ndx == 0 ? "wait" : "read";
551*35238bceSAndroid Build Coastguard Worker         const ExpectedBehavior behavior = ndx == 0 ? m_waitBehavior : m_readBehavior;
552*35238bceSAndroid Build Coastguard Worker         const float threshold           = ndx == 0 ? m_waitThreshold : m_readThreshold;
553*35238bceSAndroid Build Coastguard Worker         const bool isOk                 = behavior == EXPECT_COEF_GREATER_THAN ? coef > threshold :
554*35238bceSAndroid Build Coastguard Worker                                           behavior == EXPECT_COEF_LESS_THAN    ? coef < threshold :
555*35238bceSAndroid Build Coastguard Worker                                                                                  false;
556*35238bceSAndroid Build Coastguard Worker         const char *cmpName             = behavior == EXPECT_COEF_GREATER_THAN ? "greater than" :
557*35238bceSAndroid Build Coastguard Worker                                           behavior == EXPECT_COEF_LESS_THAN    ? "less than" :
558*35238bceSAndroid Build Coastguard Worker                                                                                  DE_NULL;
559*35238bceSAndroid Build Coastguard Worker 
560*35238bceSAndroid Build Coastguard Worker         if (!isOk)
561*35238bceSAndroid Build Coastguard Worker         {
562*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "ERROR: Expected " << name << " coefficient to be " << cmpName
563*35238bceSAndroid Build Coastguard Worker                                << " " << threshold << TestLog::EndMessage;
564*35238bceSAndroid Build Coastguard Worker             allOk = false;
565*35238bceSAndroid Build Coastguard Worker         }
566*35238bceSAndroid Build Coastguard Worker     }
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(allOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_COMPATIBILITY_WARNING,
569*35238bceSAndroid Build Coastguard Worker                             allOk ? "Pass" : "Suspicious performance behavior");
570*35238bceSAndroid Build Coastguard Worker }
571*35238bceSAndroid Build Coastguard Worker 
iterate(void)572*35238bceSAndroid Build Coastguard Worker FlushFinishCase::IterateResult FlushFinishCase::iterate(void)
573*35238bceSAndroid Build Coastguard Worker {
574*35238bceSAndroid Build Coastguard Worker     vector<Sample> samples(NUM_SAMPLES);
575*35238bceSAndroid Build Coastguard Worker     CalibrationParams params;
576*35238bceSAndroid Build Coastguard Worker 
577*35238bceSAndroid Build Coastguard Worker     tcu::warmupCPU();
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker     setupRenderState();
580*35238bceSAndroid Build Coastguard Worker 
581*35238bceSAndroid Build Coastguard Worker     // Do one full render cycle.
582*35238bceSAndroid Build Coastguard Worker     {
583*35238bceSAndroid Build Coastguard Worker         setShaderIterCount(1);
584*35238bceSAndroid Build Coastguard Worker         render(1);
585*35238bceSAndroid Build Coastguard Worker         readPixels();
586*35238bceSAndroid Build Coastguard Worker     }
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker     // Calibrate.
589*35238bceSAndroid Build Coastguard Worker     for (int calibrationRoundNdx = 0; /* until done */; calibrationRoundNdx++)
590*35238bceSAndroid Build Coastguard Worker     {
591*35238bceSAndroid Build Coastguard Worker         try
592*35238bceSAndroid Build Coastguard Worker         {
593*35238bceSAndroid Build Coastguard Worker             m_testCtx.touchWatchdog();
594*35238bceSAndroid Build Coastguard Worker             params = calibrate();
595*35238bceSAndroid Build Coastguard Worker             verifyCalibration(params);
596*35238bceSAndroid Build Coastguard Worker             break;
597*35238bceSAndroid Build Coastguard Worker         }
598*35238bceSAndroid Build Coastguard Worker         catch (const CalibrationFailedException &e)
599*35238bceSAndroid Build Coastguard Worker         {
600*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << e;
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker             if (calibrationRoundNdx < MAX_CALIBRATION_ATTEMPTS)
603*35238bceSAndroid Build Coastguard Worker             {
604*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << TestLog::Message << "Retrying calibration (" << (calibrationRoundNdx + 1) << " / "
605*35238bceSAndroid Build Coastguard Worker                                    << (int)MAX_CALIBRATION_ATTEMPTS << ")" << TestLog::EndMessage;
606*35238bceSAndroid Build Coastguard Worker             }
607*35238bceSAndroid Build Coastguard Worker             else
608*35238bceSAndroid Build Coastguard Worker             {
609*35238bceSAndroid Build Coastguard Worker                 m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, e.what());
610*35238bceSAndroid Build Coastguard Worker                 return STOP;
611*35238bceSAndroid Build Coastguard Worker             }
612*35238bceSAndroid Build Coastguard Worker         }
613*35238bceSAndroid Build Coastguard Worker     }
614*35238bceSAndroid Build Coastguard Worker 
615*35238bceSAndroid Build Coastguard Worker     // Do measurement.
616*35238bceSAndroid Build Coastguard Worker     {
617*35238bceSAndroid Build Coastguard Worker         de::Random rnd(123);
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker         setShaderIterCount(params.numItersInShader);
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker         for (size_t ndx = 0; ndx < samples.size(); ndx++)
622*35238bceSAndroid Build Coastguard Worker         {
623*35238bceSAndroid Build Coastguard Worker             const int drawCallCount        = rnd.getInt(1, params.maxDrawCalls);
624*35238bceSAndroid Build Coastguard Worker             const uint64_t submitStartTime = deGetMicroseconds();
625*35238bceSAndroid Build Coastguard Worker             uint64_t waitStartTime;
626*35238bceSAndroid Build Coastguard Worker             uint64_t readStartTime;
627*35238bceSAndroid Build Coastguard Worker             uint64_t readFinishTime;
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker             render(drawCallCount);
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker             waitStartTime = deGetMicroseconds();
632*35238bceSAndroid Build Coastguard Worker             waitForGL();
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker             readStartTime = deGetMicroseconds();
635*35238bceSAndroid Build Coastguard Worker             readPixels();
636*35238bceSAndroid Build Coastguard Worker             readFinishTime = deGetMicroseconds();
637*35238bceSAndroid Build Coastguard Worker 
638*35238bceSAndroid Build Coastguard Worker             samples[ndx].numDrawCalls   = drawCallCount;
639*35238bceSAndroid Build Coastguard Worker             samples[ndx].submitTime     = waitStartTime - submitStartTime;
640*35238bceSAndroid Build Coastguard Worker             samples[ndx].waitTime       = readStartTime - waitStartTime;
641*35238bceSAndroid Build Coastguard Worker             samples[ndx].readPixelsTime = readFinishTime - readStartTime;
642*35238bceSAndroid Build Coastguard Worker 
643*35238bceSAndroid Build Coastguard Worker             m_testCtx.touchWatchdog();
644*35238bceSAndroid Build Coastguard Worker         }
645*35238bceSAndroid Build Coastguard Worker     }
646*35238bceSAndroid Build Coastguard Worker 
647*35238bceSAndroid Build Coastguard Worker     // Analyze - sets test case result.
648*35238bceSAndroid Build Coastguard Worker     analyzeResults(samples, params);
649*35238bceSAndroid Build Coastguard Worker 
650*35238bceSAndroid Build Coastguard Worker     return STOP;
651*35238bceSAndroid Build Coastguard Worker }
652*35238bceSAndroid Build Coastguard Worker 
653*35238bceSAndroid Build Coastguard Worker class WaitOnlyCase : public FlushFinishCase
654*35238bceSAndroid Build Coastguard Worker {
655*35238bceSAndroid Build Coastguard Worker public:
WaitOnlyCase(Context & context)656*35238bceSAndroid Build Coastguard Worker     WaitOnlyCase(Context &context)
657*35238bceSAndroid Build Coastguard Worker         : FlushFinishCase(context, "wait", "Wait only", EXPECT_COEF_LESS_THAN, NO_CORR_COEF_THRESHOLD,
658*35238bceSAndroid Build Coastguard Worker                           EXPECT_COEF_GREATER_THAN, -1000.0f /* practically nothing is expected */)
659*35238bceSAndroid Build Coastguard Worker     {
660*35238bceSAndroid Build Coastguard Worker     }
661*35238bceSAndroid Build Coastguard Worker 
init(void)662*35238bceSAndroid Build Coastguard Worker     void init(void)
663*35238bceSAndroid Build Coastguard Worker     {
664*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << int(WAIT_TIME_MS) << " ms busy wait" << TestLog::EndMessage;
665*35238bceSAndroid Build Coastguard Worker         FlushFinishCase::init();
666*35238bceSAndroid Build Coastguard Worker     }
667*35238bceSAndroid Build Coastguard Worker 
668*35238bceSAndroid Build Coastguard Worker protected:
waitForGL(void)669*35238bceSAndroid Build Coastguard Worker     void waitForGL(void)
670*35238bceSAndroid Build Coastguard Worker     {
671*35238bceSAndroid Build Coastguard Worker         busyWait(WAIT_TIME_MS);
672*35238bceSAndroid Build Coastguard Worker     }
673*35238bceSAndroid Build Coastguard Worker };
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker class FlushOnlyCase : public FlushFinishCase
676*35238bceSAndroid Build Coastguard Worker {
677*35238bceSAndroid Build Coastguard Worker public:
FlushOnlyCase(Context & context)678*35238bceSAndroid Build Coastguard Worker     FlushOnlyCase(Context &context)
679*35238bceSAndroid Build Coastguard Worker         : FlushFinishCase(context, "flush", "Flush only", EXPECT_COEF_LESS_THAN, FLUSH_COEF_THRESHOLD,
680*35238bceSAndroid Build Coastguard Worker                           EXPECT_COEF_GREATER_THAN, CORRELATED_COEF_THRESHOLD)
681*35238bceSAndroid Build Coastguard Worker     {
682*35238bceSAndroid Build Coastguard Worker     }
683*35238bceSAndroid Build Coastguard Worker 
init(void)684*35238bceSAndroid Build Coastguard Worker     void init(void)
685*35238bceSAndroid Build Coastguard Worker     {
686*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Single call to glFlush()" << TestLog::EndMessage;
687*35238bceSAndroid Build Coastguard Worker         FlushFinishCase::init();
688*35238bceSAndroid Build Coastguard Worker     }
689*35238bceSAndroid Build Coastguard Worker 
690*35238bceSAndroid Build Coastguard Worker protected:
waitForGL(void)691*35238bceSAndroid Build Coastguard Worker     void waitForGL(void)
692*35238bceSAndroid Build Coastguard Worker     {
693*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().flush();
694*35238bceSAndroid Build Coastguard Worker     }
695*35238bceSAndroid Build Coastguard Worker };
696*35238bceSAndroid Build Coastguard Worker 
697*35238bceSAndroid Build Coastguard Worker class FlushWaitCase : public FlushFinishCase
698*35238bceSAndroid Build Coastguard Worker {
699*35238bceSAndroid Build Coastguard Worker public:
FlushWaitCase(Context & context)700*35238bceSAndroid Build Coastguard Worker     FlushWaitCase(Context &context)
701*35238bceSAndroid Build Coastguard Worker         : FlushFinishCase(context, "flush_wait", "Wait after flushing", EXPECT_COEF_LESS_THAN, FLUSH_COEF_THRESHOLD,
702*35238bceSAndroid Build Coastguard Worker                           EXPECT_COEF_LESS_THAN, NO_CORR_COEF_THRESHOLD)
703*35238bceSAndroid Build Coastguard Worker     {
704*35238bceSAndroid Build Coastguard Worker     }
705*35238bceSAndroid Build Coastguard Worker 
init(void)706*35238bceSAndroid Build Coastguard Worker     void init(void)
707*35238bceSAndroid Build Coastguard Worker     {
708*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "glFlush() followed by " << int(WAIT_TIME_MS) << " ms busy wait"
709*35238bceSAndroid Build Coastguard Worker                            << TestLog::EndMessage;
710*35238bceSAndroid Build Coastguard Worker         FlushFinishCase::init();
711*35238bceSAndroid Build Coastguard Worker     }
712*35238bceSAndroid Build Coastguard Worker 
713*35238bceSAndroid Build Coastguard Worker protected:
waitForGL(void)714*35238bceSAndroid Build Coastguard Worker     void waitForGL(void)
715*35238bceSAndroid Build Coastguard Worker     {
716*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().flush();
717*35238bceSAndroid Build Coastguard Worker         busyWait(WAIT_TIME_MS);
718*35238bceSAndroid Build Coastguard Worker     }
719*35238bceSAndroid Build Coastguard Worker };
720*35238bceSAndroid Build Coastguard Worker 
721*35238bceSAndroid Build Coastguard Worker class FinishOnlyCase : public FlushFinishCase
722*35238bceSAndroid Build Coastguard Worker {
723*35238bceSAndroid Build Coastguard Worker public:
FinishOnlyCase(Context & context)724*35238bceSAndroid Build Coastguard Worker     FinishOnlyCase(Context &context)
725*35238bceSAndroid Build Coastguard Worker         : FlushFinishCase(context, "finish", "Finish only", EXPECT_COEF_GREATER_THAN, CORRELATED_COEF_THRESHOLD,
726*35238bceSAndroid Build Coastguard Worker                           EXPECT_COEF_LESS_THAN, NO_CORR_COEF_THRESHOLD)
727*35238bceSAndroid Build Coastguard Worker     {
728*35238bceSAndroid Build Coastguard Worker     }
729*35238bceSAndroid Build Coastguard Worker 
init(void)730*35238bceSAndroid Build Coastguard Worker     void init(void)
731*35238bceSAndroid Build Coastguard Worker     {
732*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Single call to glFinish()" << TestLog::EndMessage;
733*35238bceSAndroid Build Coastguard Worker         FlushFinishCase::init();
734*35238bceSAndroid Build Coastguard Worker     }
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker protected:
waitForGL(void)737*35238bceSAndroid Build Coastguard Worker     void waitForGL(void)
738*35238bceSAndroid Build Coastguard Worker     {
739*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().finish();
740*35238bceSAndroid Build Coastguard Worker     }
741*35238bceSAndroid Build Coastguard Worker };
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker class FinishWaitCase : public FlushFinishCase
744*35238bceSAndroid Build Coastguard Worker {
745*35238bceSAndroid Build Coastguard Worker public:
FinishWaitCase(Context & context)746*35238bceSAndroid Build Coastguard Worker     FinishWaitCase(Context &context)
747*35238bceSAndroid Build Coastguard Worker         : FlushFinishCase(context, "finish_wait", "Finish and wait", EXPECT_COEF_GREATER_THAN,
748*35238bceSAndroid Build Coastguard Worker                           CORRELATED_COEF_THRESHOLD, EXPECT_COEF_LESS_THAN, NO_CORR_COEF_THRESHOLD)
749*35238bceSAndroid Build Coastguard Worker     {
750*35238bceSAndroid Build Coastguard Worker     }
751*35238bceSAndroid Build Coastguard Worker 
init(void)752*35238bceSAndroid Build Coastguard Worker     void init(void)
753*35238bceSAndroid Build Coastguard Worker     {
754*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "glFinish() followed by " << int(WAIT_TIME_MS) << " ms busy wait"
755*35238bceSAndroid Build Coastguard Worker                            << TestLog::EndMessage;
756*35238bceSAndroid Build Coastguard Worker         FlushFinishCase::init();
757*35238bceSAndroid Build Coastguard Worker     }
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker protected:
waitForGL(void)760*35238bceSAndroid Build Coastguard Worker     void waitForGL(void)
761*35238bceSAndroid Build Coastguard Worker     {
762*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().finish();
763*35238bceSAndroid Build Coastguard Worker         busyWait(WAIT_TIME_MS);
764*35238bceSAndroid Build Coastguard Worker     }
765*35238bceSAndroid Build Coastguard Worker };
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker } // namespace
768*35238bceSAndroid Build Coastguard Worker 
FlushFinishTests(Context & context)769*35238bceSAndroid Build Coastguard Worker FlushFinishTests::FlushFinishTests(Context &context) : TestCaseGroup(context, "flush_finish", "Flush and Finish tests")
770*35238bceSAndroid Build Coastguard Worker {
771*35238bceSAndroid Build Coastguard Worker }
772*35238bceSAndroid Build Coastguard Worker 
~FlushFinishTests(void)773*35238bceSAndroid Build Coastguard Worker FlushFinishTests::~FlushFinishTests(void)
774*35238bceSAndroid Build Coastguard Worker {
775*35238bceSAndroid Build Coastguard Worker }
776*35238bceSAndroid Build Coastguard Worker 
init(void)777*35238bceSAndroid Build Coastguard Worker void FlushFinishTests::init(void)
778*35238bceSAndroid Build Coastguard Worker {
779*35238bceSAndroid Build Coastguard Worker     addChild(new WaitOnlyCase(m_context));
780*35238bceSAndroid Build Coastguard Worker     addChild(new FlushOnlyCase(m_context));
781*35238bceSAndroid Build Coastguard Worker     addChild(new FlushWaitCase(m_context));
782*35238bceSAndroid Build Coastguard Worker     addChild(new FinishOnlyCase(m_context));
783*35238bceSAndroid Build Coastguard Worker     addChild(new FinishWaitCase(m_context));
784*35238bceSAndroid Build Coastguard Worker }
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker } // namespace Functional
787*35238bceSAndroid Build Coastguard Worker } // namespace gles3
788*35238bceSAndroid Build Coastguard Worker } // namespace deqp
789