1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL (ES) 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 Shader performance measurer; handles calibration and measurement
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "glsShaderPerformanceMeasurer.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluDefs.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
30*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
31*35238bceSAndroid Build Coastguard Worker
32*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
34*35238bceSAndroid Build Coastguard Worker
35*35238bceSAndroid Build Coastguard Worker #include <algorithm>
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker using std::string;
38*35238bceSAndroid Build Coastguard Worker using std::vector;
39*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
40*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
41*35238bceSAndroid Build Coastguard Worker using namespace glw; // GL types
42*35238bceSAndroid Build Coastguard Worker
43*35238bceSAndroid Build Coastguard Worker namespace deqp
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker namespace gls
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker
triangleInterpolate(float v0,float v1,float v2,float x,float y)48*35238bceSAndroid Build Coastguard Worker static inline float triangleInterpolate(float v0, float v1, float v2, float x, float y)
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker return v0 + (v2 - v0) * x + (v1 - v0) * y;
51*35238bceSAndroid Build Coastguard Worker }
52*35238bceSAndroid Build Coastguard Worker
triQuadInterpolate(float x,float y,const tcu::Vec4 & quad)53*35238bceSAndroid Build Coastguard Worker static inline float triQuadInterpolate(float x, float y, const tcu::Vec4 &quad)
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker // \note Top left fill rule.
56*35238bceSAndroid Build Coastguard Worker if (x + y < 1.0f)
57*35238bceSAndroid Build Coastguard Worker return triangleInterpolate(quad.x(), quad.y(), quad.z(), x, y);
58*35238bceSAndroid Build Coastguard Worker else
59*35238bceSAndroid Build Coastguard Worker return triangleInterpolate(quad.w(), quad.z(), quad.y(), 1.0f - x, 1.0f - y);
60*35238bceSAndroid Build Coastguard Worker }
61*35238bceSAndroid Build Coastguard Worker
getNumVertices(int gridSizeX,int gridSizeY)62*35238bceSAndroid Build Coastguard Worker static inline int getNumVertices(int gridSizeX, int gridSizeY)
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker return (gridSizeX + 1) * (gridSizeY + 1);
65*35238bceSAndroid Build Coastguard Worker }
66*35238bceSAndroid Build Coastguard Worker
getNumIndices(int gridSizeX,int gridSizeY)67*35238bceSAndroid Build Coastguard Worker static inline int getNumIndices(int gridSizeX, int gridSizeY)
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker return gridSizeX * gridSizeY * 6;
70*35238bceSAndroid Build Coastguard Worker }
71*35238bceSAndroid Build Coastguard Worker
getVtxIndex(int x,int y,int gridSizeX)72*35238bceSAndroid Build Coastguard Worker static inline uint16_t getVtxIndex(int x, int y, int gridSizeX)
73*35238bceSAndroid Build Coastguard Worker {
74*35238bceSAndroid Build Coastguard Worker return (uint16_t)(y * (gridSizeX + 1) + x);
75*35238bceSAndroid Build Coastguard Worker }
76*35238bceSAndroid Build Coastguard Worker
generateVertices(std::vector<float> & dst,int gridSizeX,int gridSizeY,const AttribSpec & spec)77*35238bceSAndroid Build Coastguard Worker static void generateVertices(std::vector<float> &dst, int gridSizeX, int gridSizeY, const AttribSpec &spec)
78*35238bceSAndroid Build Coastguard Worker {
79*35238bceSAndroid Build Coastguard Worker const int numComponents = 4;
80*35238bceSAndroid Build Coastguard Worker
81*35238bceSAndroid Build Coastguard Worker DE_ASSERT((gridSizeX + 1) * (gridSizeY + 1) <= (1 << 16)); // Must fit into 16-bit indices.
82*35238bceSAndroid Build Coastguard Worker DE_ASSERT(gridSizeX >= 1 && gridSizeY >= 1);
83*35238bceSAndroid Build Coastguard Worker dst.resize((gridSizeX + 1) * (gridSizeY + 1) * 4);
84*35238bceSAndroid Build Coastguard Worker
85*35238bceSAndroid Build Coastguard Worker for (int y = 0; y <= gridSizeY; y++)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker for (int x = 0; x <= gridSizeX; x++)
88*35238bceSAndroid Build Coastguard Worker {
89*35238bceSAndroid Build Coastguard Worker float xf = (float)x / (float)gridSizeX;
90*35238bceSAndroid Build Coastguard Worker float yf = (float)y / (float)gridSizeY;
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker for (int compNdx = 0; compNdx < numComponents; compNdx++)
93*35238bceSAndroid Build Coastguard Worker dst[getVtxIndex(x, y, gridSizeX) * numComponents + compNdx] = triQuadInterpolate(
94*35238bceSAndroid Build Coastguard Worker xf, yf, tcu::Vec4(spec.p00[compNdx], spec.p01[compNdx], spec.p10[compNdx], spec.p11[compNdx]));
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker }
98*35238bceSAndroid Build Coastguard Worker
generateIndices(std::vector<uint16_t> & dst,int gridSizeX,int gridSizeY)99*35238bceSAndroid Build Coastguard Worker static void generateIndices(std::vector<uint16_t> &dst, int gridSizeX, int gridSizeY)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker const int numIndicesPerQuad = 6;
102*35238bceSAndroid Build Coastguard Worker int numIndices = gridSizeX * gridSizeY * numIndicesPerQuad;
103*35238bceSAndroid Build Coastguard Worker dst.resize(numIndices);
104*35238bceSAndroid Build Coastguard Worker
105*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < gridSizeY; y++)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < gridSizeX; x++)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker int quadNdx = y * gridSizeX + x;
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 0] = getVtxIndex(x + 0, y + 0, gridSizeX);
112*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 1] = getVtxIndex(x + 1, y + 0, gridSizeX);
113*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 2] = getVtxIndex(x + 0, y + 1, gridSizeX);
114*35238bceSAndroid Build Coastguard Worker
115*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 3] = getVtxIndex(x + 0, y + 1, gridSizeX);
116*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 4] = getVtxIndex(x + 1, y + 0, gridSizeX);
117*35238bceSAndroid Build Coastguard Worker dst[quadNdx * numIndicesPerQuad + 5] = getVtxIndex(x + 1, y + 1, gridSizeX);
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker }
120*35238bceSAndroid Build Coastguard Worker }
121*35238bceSAndroid Build Coastguard Worker
ShaderPerformanceMeasurer(const glu::RenderContext & renderCtx,PerfCaseType measureType)122*35238bceSAndroid Build Coastguard Worker ShaderPerformanceMeasurer::ShaderPerformanceMeasurer(const glu::RenderContext &renderCtx, PerfCaseType measureType)
123*35238bceSAndroid Build Coastguard Worker : m_renderCtx(renderCtx)
124*35238bceSAndroid Build Coastguard Worker , m_gridSizeX(measureType == CASETYPE_FRAGMENT ? 1 : 255)
125*35238bceSAndroid Build Coastguard Worker , m_gridSizeY(measureType == CASETYPE_FRAGMENT ? 1 : 255)
126*35238bceSAndroid Build Coastguard Worker , m_viewportWidth(measureType == CASETYPE_VERTEX ? 32 : renderCtx.getRenderTarget().getWidth())
127*35238bceSAndroid Build Coastguard Worker , m_viewportHeight(measureType == CASETYPE_VERTEX ? 32 : renderCtx.getRenderTarget().getHeight())
128*35238bceSAndroid Build Coastguard Worker , m_state(STATE_UNINITIALIZED)
129*35238bceSAndroid Build Coastguard Worker , m_isFirstIteration(false)
130*35238bceSAndroid Build Coastguard Worker , m_prevRenderStartTime(0)
131*35238bceSAndroid Build Coastguard Worker , m_result(-1.0f, -1.0f)
132*35238bceSAndroid Build Coastguard Worker , m_indexBuffer(0)
133*35238bceSAndroid Build Coastguard Worker , m_vao(0)
134*35238bceSAndroid Build Coastguard Worker {
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker
logParameters(TestLog & log) const137*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::logParameters(TestLog &log) const
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Grid size: " << m_gridSizeX << "x" << m_gridSizeY << TestLog::EndMessage
140*35238bceSAndroid Build Coastguard Worker << TestLog::Message << "Viewport: " << m_viewportWidth << "x" << m_viewportHeight << TestLog::EndMessage;
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker
init(uint32_t program,const vector<AttribSpec> & attributes,int calibratorInitialNumCalls)143*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::init(uint32_t program, const vector<AttribSpec> &attributes,
144*35238bceSAndroid Build Coastguard Worker int calibratorInitialNumCalls)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_state == STATE_UNINITIALIZED);
147*35238bceSAndroid Build Coastguard Worker
148*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
149*35238bceSAndroid Build Coastguard Worker const bool useVAO = glu::isContextTypeGLCore(m_renderCtx.getType());
150*35238bceSAndroid Build Coastguard Worker
151*35238bceSAndroid Build Coastguard Worker if (useVAO)
152*35238bceSAndroid Build Coastguard Worker {
153*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_vao);
154*35238bceSAndroid Build Coastguard Worker gl.genVertexArrays(1, &m_vao);
155*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(m_vao);
156*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Create VAO");
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker
159*35238bceSAndroid Build Coastguard Worker // Validate that we have sane grid and viewport setup.
160*35238bceSAndroid Build Coastguard Worker
161*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(m_gridSizeX, 1, 256) && de::inBounds(m_gridSizeY, 1, 256));
162*35238bceSAndroid Build Coastguard Worker
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker bool widthTooSmall = m_renderCtx.getRenderTarget().getWidth() < m_viewportWidth;
165*35238bceSAndroid Build Coastguard Worker bool heightTooSmall = m_renderCtx.getRenderTarget().getHeight() < m_viewportHeight;
166*35238bceSAndroid Build Coastguard Worker
167*35238bceSAndroid Build Coastguard Worker if (widthTooSmall || heightTooSmall)
168*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError(
169*35238bceSAndroid Build Coastguard Worker "Render target too small (" +
170*35238bceSAndroid Build Coastguard Worker (widthTooSmall ? "width must be at least " + de::toString(m_viewportWidth) : "") +
171*35238bceSAndroid Build Coastguard Worker (heightTooSmall ?
172*35238bceSAndroid Build Coastguard Worker string(widthTooSmall ? ", " : "") + "height must be at least " + de::toString(m_viewportHeight) :
173*35238bceSAndroid Build Coastguard Worker "") +
174*35238bceSAndroid Build Coastguard Worker ")");
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker
177*35238bceSAndroid Build Coastguard Worker TCU_CHECK_INTERNAL(de::inRange(m_viewportWidth, 1, m_renderCtx.getRenderTarget().getWidth()) &&
178*35238bceSAndroid Build Coastguard Worker de::inRange(m_viewportHeight, 1, m_renderCtx.getRenderTarget().getHeight()));
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Worker // Insert a_position to attributes.
181*35238bceSAndroid Build Coastguard Worker m_attributes = attributes;
182*35238bceSAndroid Build Coastguard Worker m_attributes.push_back(AttribSpec("a_position", Vec4(-1.0f, -1.0f, 0.0f, 1.0f), Vec4(1.0f, -1.0f, 0.0f, 1.0f),
183*35238bceSAndroid Build Coastguard Worker Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(1.0f, 1.0f, 0.0f, 1.0f)));
184*35238bceSAndroid Build Coastguard Worker
185*35238bceSAndroid Build Coastguard Worker // Generate indices.
186*35238bceSAndroid Build Coastguard Worker {
187*35238bceSAndroid Build Coastguard Worker std::vector<uint16_t> indices;
188*35238bceSAndroid Build Coastguard Worker generateIndices(indices, m_gridSizeX, m_gridSizeY);
189*35238bceSAndroid Build Coastguard Worker
190*35238bceSAndroid Build Coastguard Worker gl.genBuffers(1, &m_indexBuffer);
191*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
192*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(indices.size() * sizeof(uint16_t)), &indices[0],
193*35238bceSAndroid Build Coastguard Worker GL_STATIC_DRAW);
194*35238bceSAndroid Build Coastguard Worker
195*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Upload index data");
196*35238bceSAndroid Build Coastguard Worker }
197*35238bceSAndroid Build Coastguard Worker
198*35238bceSAndroid Build Coastguard Worker // Generate vertices.
199*35238bceSAndroid Build Coastguard Worker m_attribBuffers.resize(m_attributes.size(), 0);
200*35238bceSAndroid Build Coastguard Worker gl.genBuffers((GLsizei)m_attribBuffers.size(), &m_attribBuffers[0]);
201*35238bceSAndroid Build Coastguard Worker
202*35238bceSAndroid Build Coastguard Worker for (int attribNdx = 0; attribNdx < (int)m_attributes.size(); attribNdx++)
203*35238bceSAndroid Build Coastguard Worker {
204*35238bceSAndroid Build Coastguard Worker std::vector<float> vertices;
205*35238bceSAndroid Build Coastguard Worker generateVertices(vertices, m_gridSizeX, m_gridSizeY, m_attributes[attribNdx]);
206*35238bceSAndroid Build Coastguard Worker
207*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_attribBuffers[attribNdx]);
208*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(vertices.size() * sizeof(float)), &vertices[0], GL_STATIC_DRAW);
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker
211*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Upload vertex data");
212*35238bceSAndroid Build Coastguard Worker
213*35238bceSAndroid Build Coastguard Worker // Setup attribute bindings.
214*35238bceSAndroid Build Coastguard Worker for (int attribNdx = 0; attribNdx < (int)m_attributes.size(); attribNdx++)
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker int location = gl.getAttribLocation(program, m_attributes[attribNdx].name.c_str());
217*35238bceSAndroid Build Coastguard Worker
218*35238bceSAndroid Build Coastguard Worker if (location >= 0)
219*35238bceSAndroid Build Coastguard Worker {
220*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(location);
221*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, m_attribBuffers[attribNdx]);
222*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
223*35238bceSAndroid Build Coastguard Worker }
224*35238bceSAndroid Build Coastguard Worker
225*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Setup vertex attribute state");
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker
228*35238bceSAndroid Build Coastguard Worker gl.useProgram(program);
229*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
230*35238bceSAndroid Build Coastguard Worker
231*35238bceSAndroid Build Coastguard Worker m_state = STATE_MEASURING;
232*35238bceSAndroid Build Coastguard Worker m_isFirstIteration = true;
233*35238bceSAndroid Build Coastguard Worker
234*35238bceSAndroid Build Coastguard Worker m_calibrator.clear(CalibratorParameters(calibratorInitialNumCalls, 10 /* calibrate iteration frames */,
235*35238bceSAndroid Build Coastguard Worker 2000.0f /* calibrate iteration shortcut threshold (ms) */,
236*35238bceSAndroid Build Coastguard Worker 16 /* max calibrate iterations */, 1000.0f / 30.0f /* frame time (ms) */,
237*35238bceSAndroid Build Coastguard Worker 1000.0f / 60.0f /* frame time cap (ms) */,
238*35238bceSAndroid Build Coastguard Worker 1000.0f /* target measure duration (ms) */));
239*35238bceSAndroid Build Coastguard Worker }
240*35238bceSAndroid Build Coastguard Worker
deinit(void)241*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::deinit(void)
242*35238bceSAndroid Build Coastguard Worker {
243*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
244*35238bceSAndroid Build Coastguard Worker
245*35238bceSAndroid Build Coastguard Worker if (m_indexBuffer)
246*35238bceSAndroid Build Coastguard Worker {
247*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers(1, &m_indexBuffer);
248*35238bceSAndroid Build Coastguard Worker m_indexBuffer = 0;
249*35238bceSAndroid Build Coastguard Worker }
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker if (m_vao)
252*35238bceSAndroid Build Coastguard Worker {
253*35238bceSAndroid Build Coastguard Worker gl.deleteVertexArrays(1, &m_vao);
254*35238bceSAndroid Build Coastguard Worker m_vao = 0;
255*35238bceSAndroid Build Coastguard Worker }
256*35238bceSAndroid Build Coastguard Worker
257*35238bceSAndroid Build Coastguard Worker if (!m_attribBuffers.empty())
258*35238bceSAndroid Build Coastguard Worker {
259*35238bceSAndroid Build Coastguard Worker gl.deleteBuffers((GLsizei)m_attribBuffers.size(), &m_attribBuffers[0]);
260*35238bceSAndroid Build Coastguard Worker m_attribBuffers.clear();
261*35238bceSAndroid Build Coastguard Worker }
262*35238bceSAndroid Build Coastguard Worker
263*35238bceSAndroid Build Coastguard Worker m_state = STATE_UNINITIALIZED;
264*35238bceSAndroid Build Coastguard Worker }
265*35238bceSAndroid Build Coastguard Worker
render(int numDrawCalls)266*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::render(int numDrawCalls)
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_renderCtx.getFunctions();
269*35238bceSAndroid Build Coastguard Worker GLsizei numIndices = (GLsizei)getNumIndices(m_gridSizeX, m_gridSizeY);
270*35238bceSAndroid Build Coastguard Worker
271*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, m_viewportWidth, m_viewportHeight);
272*35238bceSAndroid Build Coastguard Worker
273*35238bceSAndroid Build Coastguard Worker for (int callNdx = 0; callNdx < numDrawCalls; callNdx++)
274*35238bceSAndroid Build Coastguard Worker gl.drawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, DE_NULL);
275*35238bceSAndroid Build Coastguard Worker }
276*35238bceSAndroid Build Coastguard Worker
iterate(void)277*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::iterate(void)
278*35238bceSAndroid Build Coastguard Worker {
279*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_state == STATE_MEASURING);
280*35238bceSAndroid Build Coastguard Worker
281*35238bceSAndroid Build Coastguard Worker uint64_t renderStartTime = deGetMicroseconds();
282*35238bceSAndroid Build Coastguard Worker render(m_calibrator.getCallCount()); // Always render. This gives more stable performance behavior.
283*35238bceSAndroid Build Coastguard Worker
284*35238bceSAndroid Build Coastguard Worker TheilSenCalibrator::State calibratorState = m_calibrator.getState();
285*35238bceSAndroid Build Coastguard Worker
286*35238bceSAndroid Build Coastguard Worker if (calibratorState == TheilSenCalibrator::STATE_RECOMPUTE_PARAMS)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker m_calibrator.recomputeParameters();
289*35238bceSAndroid Build Coastguard Worker
290*35238bceSAndroid Build Coastguard Worker m_isFirstIteration = true;
291*35238bceSAndroid Build Coastguard Worker m_prevRenderStartTime = renderStartTime;
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker else if (calibratorState == TheilSenCalibrator::STATE_MEASURE)
294*35238bceSAndroid Build Coastguard Worker {
295*35238bceSAndroid Build Coastguard Worker if (!m_isFirstIteration)
296*35238bceSAndroid Build Coastguard Worker m_calibrator.recordIteration(renderStartTime - m_prevRenderStartTime);
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker m_isFirstIteration = false;
299*35238bceSAndroid Build Coastguard Worker m_prevRenderStartTime = renderStartTime;
300*35238bceSAndroid Build Coastguard Worker }
301*35238bceSAndroid Build Coastguard Worker else
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker DE_ASSERT(calibratorState == TheilSenCalibrator::STATE_FINISHED);
304*35238bceSAndroid Build Coastguard Worker
305*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(m_renderCtx.getFunctions().getError(), "End of rendering");
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker const MeasureState &measureState = m_calibrator.getMeasureState();
308*35238bceSAndroid Build Coastguard Worker
309*35238bceSAndroid Build Coastguard Worker // Compute result.
310*35238bceSAndroid Build Coastguard Worker uint64_t totalTime = measureState.getTotalTime();
311*35238bceSAndroid Build Coastguard Worker int numFrames = (int)measureState.frameTimes.size();
312*35238bceSAndroid Build Coastguard Worker int64_t numQuadGrids = measureState.numDrawCalls * numFrames;
313*35238bceSAndroid Build Coastguard Worker int64_t numPixels = (int64_t)m_viewportWidth * (int64_t)m_viewportHeight * numQuadGrids;
314*35238bceSAndroid Build Coastguard Worker int64_t numVertices = (int64_t)getNumVertices(m_gridSizeX, m_gridSizeY) * numQuadGrids;
315*35238bceSAndroid Build Coastguard Worker double mfragPerSecond = (double)numPixels / (double)totalTime;
316*35238bceSAndroid Build Coastguard Worker double mvertPerSecond = (double)numVertices / (double)totalTime;
317*35238bceSAndroid Build Coastguard Worker
318*35238bceSAndroid Build Coastguard Worker m_result = Result((float)mvertPerSecond, (float)mfragPerSecond);
319*35238bceSAndroid Build Coastguard Worker m_state = STATE_FINISHED;
320*35238bceSAndroid Build Coastguard Worker }
321*35238bceSAndroid Build Coastguard Worker }
322*35238bceSAndroid Build Coastguard Worker
logMeasurementInfo(TestLog & log) const323*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::logMeasurementInfo(TestLog &log) const
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_state == STATE_FINISHED);
326*35238bceSAndroid Build Coastguard Worker
327*35238bceSAndroid Build Coastguard Worker const MeasureState &measureState(m_calibrator.getMeasureState());
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker // Compute totals.
330*35238bceSAndroid Build Coastguard Worker uint64_t totalTime = measureState.getTotalTime();
331*35238bceSAndroid Build Coastguard Worker int numFrames = (int)measureState.frameTimes.size();
332*35238bceSAndroid Build Coastguard Worker int64_t numQuadGrids = measureState.numDrawCalls * numFrames;
333*35238bceSAndroid Build Coastguard Worker int64_t numPixels = (int64_t)m_viewportWidth * (int64_t)m_viewportHeight * numQuadGrids;
334*35238bceSAndroid Build Coastguard Worker int64_t numVertices = (int64_t)getNumVertices(m_gridSizeX, m_gridSizeY) * numQuadGrids;
335*35238bceSAndroid Build Coastguard Worker double mfragPerSecond = (double)numPixels / (double)totalTime;
336*35238bceSAndroid Build Coastguard Worker double mvertPerSecond = (double)numVertices / (double)totalTime;
337*35238bceSAndroid Build Coastguard Worker double framesPerSecond = (double)numFrames / ((double)totalTime / 1000000.0);
338*35238bceSAndroid Build Coastguard Worker
339*35238bceSAndroid Build Coastguard Worker logCalibrationInfo(log, m_calibrator);
340*35238bceSAndroid Build Coastguard Worker
341*35238bceSAndroid Build Coastguard Worker log << TestLog::Float("FramesPerSecond", "Frames per second in measurement", "Frames/s", QP_KEY_TAG_PERFORMANCE,
342*35238bceSAndroid Build Coastguard Worker (float)framesPerSecond)
343*35238bceSAndroid Build Coastguard Worker << TestLog::Float("FragmentsPerVertices", "Vertex-fragment ratio", "Fragments/Vertices", QP_KEY_TAG_NONE,
344*35238bceSAndroid Build Coastguard Worker (float)numPixels / (float)numVertices)
345*35238bceSAndroid Build Coastguard Worker << TestLog::Float("FragmentPerf", "Fragment performance", "MPix/s", QP_KEY_TAG_PERFORMANCE,
346*35238bceSAndroid Build Coastguard Worker (float)mfragPerSecond)
347*35238bceSAndroid Build Coastguard Worker << TestLog::Float("VertexPerf", "Vertex performance", "MVert/s", QP_KEY_TAG_PERFORMANCE, (float)mvertPerSecond);
348*35238bceSAndroid Build Coastguard Worker }
349*35238bceSAndroid Build Coastguard Worker
setGridSize(int gridW,int gridH)350*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::setGridSize(int gridW, int gridH)
351*35238bceSAndroid Build Coastguard Worker {
352*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_state == STATE_UNINITIALIZED);
353*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(gridW, 1, 256) && de::inBounds(gridH, 1, 256));
354*35238bceSAndroid Build Coastguard Worker m_gridSizeX = gridW;
355*35238bceSAndroid Build Coastguard Worker m_gridSizeY = gridH;
356*35238bceSAndroid Build Coastguard Worker }
357*35238bceSAndroid Build Coastguard Worker
setViewportSize(int width,int height)358*35238bceSAndroid Build Coastguard Worker void ShaderPerformanceMeasurer::setViewportSize(int width, int height)
359*35238bceSAndroid Build Coastguard Worker {
360*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_state == STATE_UNINITIALIZED);
361*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(width, 1, m_renderCtx.getRenderTarget().getWidth()) &&
362*35238bceSAndroid Build Coastguard Worker de::inRange(height, 1, m_renderCtx.getRenderTarget().getHeight()));
363*35238bceSAndroid Build Coastguard Worker m_viewportWidth = width;
364*35238bceSAndroid Build Coastguard Worker m_viewportHeight = height;
365*35238bceSAndroid Build Coastguard Worker }
366*35238bceSAndroid Build Coastguard Worker
367*35238bceSAndroid Build Coastguard Worker } // namespace gls
368*35238bceSAndroid Build Coastguard Worker } // namespace deqp
369