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 Shader precision tests.
22*35238bceSAndroid Build Coastguard Worker *
23*35238bceSAndroid Build Coastguard Worker * \note Floating-point case uses R32UI render target and uses
24*35238bceSAndroid Build Coastguard Worker * floatBitsToUint() in shader to write out floating-point value bits.
25*35238bceSAndroid Build Coastguard Worker * This is done since ES3 core doesn't support FP render targets.
26*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "es3fShaderPrecisionTests.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuFloat.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuFormatUtil.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "deString.h"
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
43*35238bceSAndroid Build Coastguard Worker
44*35238bceSAndroid Build Coastguard Worker #include <algorithm>
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker namespace deqp
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace gles3
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker namespace Functional
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
54*35238bceSAndroid Build Coastguard Worker using std::string;
55*35238bceSAndroid Build Coastguard Worker using std::vector;
56*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker enum
59*35238bceSAndroid Build Coastguard Worker {
60*35238bceSAndroid Build Coastguard Worker FRAMEBUFFER_WIDTH = 32,
61*35238bceSAndroid Build Coastguard Worker FRAMEBUFFER_HEIGHT = 32
62*35238bceSAndroid Build Coastguard Worker };
63*35238bceSAndroid Build Coastguard Worker
createFloatPrecisionEvalProgram(const glu::RenderContext & context,glu::Precision precision,const char * evalOp,bool isVertexCase)64*35238bceSAndroid Build Coastguard Worker static glu::ShaderProgram *createFloatPrecisionEvalProgram(const glu::RenderContext &context, glu::Precision precision,
65*35238bceSAndroid Build Coastguard Worker const char *evalOp, bool isVertexCase)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker glu::DataType type = glu::TYPE_FLOAT;
68*35238bceSAndroid Build Coastguard Worker glu::DataType outType = glu::TYPE_UINT;
69*35238bceSAndroid Build Coastguard Worker const char *typeName = glu::getDataTypeName(type);
70*35238bceSAndroid Build Coastguard Worker const char *outTypeName = glu::getDataTypeName(outType);
71*35238bceSAndroid Build Coastguard Worker const char *precName = glu::getPrecisionName(precision);
72*35238bceSAndroid Build Coastguard Worker ostringstream vtx;
73*35238bceSAndroid Build Coastguard Worker ostringstream frag;
74*35238bceSAndroid Build Coastguard Worker ostringstream &op = isVertexCase ? vtx : frag;
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker vtx << "#version 300 es\n"
77*35238bceSAndroid Build Coastguard Worker << "in highp vec4 a_position;\n"
78*35238bceSAndroid Build Coastguard Worker << "in " << precName << " " << typeName << " a_in0;\n"
79*35238bceSAndroid Build Coastguard Worker << "in " << precName << " " << typeName << " a_in1;\n";
80*35238bceSAndroid Build Coastguard Worker frag << "#version 300 es\n"
81*35238bceSAndroid Build Coastguard Worker << "layout(location = 0) out highp " << outTypeName << " o_out;\n";
82*35238bceSAndroid Build Coastguard Worker
83*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker vtx << "flat out " << precName << " " << typeName << " v_out;\n";
86*35238bceSAndroid Build Coastguard Worker frag << "flat in " << precName << " " << typeName << " v_out;\n";
87*35238bceSAndroid Build Coastguard Worker }
88*35238bceSAndroid Build Coastguard Worker else
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker vtx << "flat out " << precName << " " << typeName << " v_in0;\n"
91*35238bceSAndroid Build Coastguard Worker << "flat out " << precName << " " << typeName << " v_in1;\n";
92*35238bceSAndroid Build Coastguard Worker frag << "flat in " << precName << " " << typeName << " v_in0;\n"
93*35238bceSAndroid Build Coastguard Worker << "flat in " << precName << " " << typeName << " v_in1;\n";
94*35238bceSAndroid Build Coastguard Worker }
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker vtx << "\nvoid main (void)\n{\n"
97*35238bceSAndroid Build Coastguard Worker << " gl_Position = a_position;\n";
98*35238bceSAndroid Build Coastguard Worker frag << "\nvoid main (void)\n{\n";
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker op << "\t" << precName << " " << typeName << " in0 = " << (isVertexCase ? "a_" : "v_") << "in0;\n"
101*35238bceSAndroid Build Coastguard Worker << "\t" << precName << " " << typeName << " in1 = " << (isVertexCase ? "a_" : "v_") << "in1;\n";
102*35238bceSAndroid Build Coastguard Worker
103*35238bceSAndroid Build Coastguard Worker if (!isVertexCase)
104*35238bceSAndroid Build Coastguard Worker op << "\t" << precName << " " << typeName << " res;\n";
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker op << "\t" << (isVertexCase ? "v_out" : "res") << " = " << evalOp << ";\n";
107*35238bceSAndroid Build Coastguard Worker
108*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker frag << " o_out = floatBitsToUint(v_out);\n";
111*35238bceSAndroid Build Coastguard Worker }
112*35238bceSAndroid Build Coastguard Worker else
113*35238bceSAndroid Build Coastguard Worker {
114*35238bceSAndroid Build Coastguard Worker vtx << " v_in0 = a_in0;\n"
115*35238bceSAndroid Build Coastguard Worker << " v_in1 = a_in1;\n";
116*35238bceSAndroid Build Coastguard Worker frag << " o_out = floatBitsToUint(res);\n";
117*35238bceSAndroid Build Coastguard Worker }
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
120*35238bceSAndroid Build Coastguard Worker frag << "}\n";
121*35238bceSAndroid Build Coastguard Worker
122*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(context, glu::makeVtxFragSources(vtx.str(), frag.str()));
123*35238bceSAndroid Build Coastguard Worker }
124*35238bceSAndroid Build Coastguard Worker
createIntUintPrecisionEvalProgram(const glu::RenderContext & context,glu::DataType type,glu::Precision precision,const char * evalOp,bool isVertexCase)125*35238bceSAndroid Build Coastguard Worker static glu::ShaderProgram *createIntUintPrecisionEvalProgram(const glu::RenderContext &context, glu::DataType type,
126*35238bceSAndroid Build Coastguard Worker glu::Precision precision, const char *evalOp,
127*35238bceSAndroid Build Coastguard Worker bool isVertexCase)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker const char *typeName = glu::getDataTypeName(type);
130*35238bceSAndroid Build Coastguard Worker const char *precName = glu::getPrecisionName(precision);
131*35238bceSAndroid Build Coastguard Worker ostringstream vtx;
132*35238bceSAndroid Build Coastguard Worker ostringstream frag;
133*35238bceSAndroid Build Coastguard Worker ostringstream &op = isVertexCase ? vtx : frag;
134*35238bceSAndroid Build Coastguard Worker
135*35238bceSAndroid Build Coastguard Worker vtx << "#version 300 es\n"
136*35238bceSAndroid Build Coastguard Worker << "in highp vec4 a_position;\n"
137*35238bceSAndroid Build Coastguard Worker << "in " << precName << " " << typeName << " a_in0;\n"
138*35238bceSAndroid Build Coastguard Worker << "in " << precName << " " << typeName << " a_in1;\n";
139*35238bceSAndroid Build Coastguard Worker frag << "#version 300 es\n"
140*35238bceSAndroid Build Coastguard Worker << "layout(location = 0) out " << precName << " " << typeName << " o_out;\n";
141*35238bceSAndroid Build Coastguard Worker
142*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
143*35238bceSAndroid Build Coastguard Worker {
144*35238bceSAndroid Build Coastguard Worker vtx << "flat out " << precName << " " << typeName << " v_out;\n";
145*35238bceSAndroid Build Coastguard Worker frag << "flat in " << precName << " " << typeName << " v_out;\n";
146*35238bceSAndroid Build Coastguard Worker }
147*35238bceSAndroid Build Coastguard Worker else
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker vtx << "flat out " << precName << " " << typeName << " v_in0;\n"
150*35238bceSAndroid Build Coastguard Worker << "flat out " << precName << " " << typeName << " v_in1;\n";
151*35238bceSAndroid Build Coastguard Worker frag << "flat in " << precName << " " << typeName << " v_in0;\n"
152*35238bceSAndroid Build Coastguard Worker << "flat in " << precName << " " << typeName << " v_in1;\n";
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker
155*35238bceSAndroid Build Coastguard Worker vtx << "\nvoid main (void)\n{\n"
156*35238bceSAndroid Build Coastguard Worker << " gl_Position = a_position;\n";
157*35238bceSAndroid Build Coastguard Worker frag << "\nvoid main (void)\n{\n";
158*35238bceSAndroid Build Coastguard Worker
159*35238bceSAndroid Build Coastguard Worker op << "\t" << precName << " " << typeName << " in0 = " << (isVertexCase ? "a_" : "v_") << "in0;\n"
160*35238bceSAndroid Build Coastguard Worker << "\t" << precName << " " << typeName << " in1 = " << (isVertexCase ? "a_" : "v_") << "in1;\n";
161*35238bceSAndroid Build Coastguard Worker
162*35238bceSAndroid Build Coastguard Worker op << "\t" << (isVertexCase ? "v_" : "o_") << "out = " << evalOp << ";\n";
163*35238bceSAndroid Build Coastguard Worker
164*35238bceSAndroid Build Coastguard Worker if (isVertexCase)
165*35238bceSAndroid Build Coastguard Worker {
166*35238bceSAndroid Build Coastguard Worker frag << " o_out = v_out;\n";
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker else
169*35238bceSAndroid Build Coastguard Worker {
170*35238bceSAndroid Build Coastguard Worker vtx << " v_in0 = a_in0;\n"
171*35238bceSAndroid Build Coastguard Worker << " v_in1 = a_in1;\n";
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker
174*35238bceSAndroid Build Coastguard Worker vtx << "}\n";
175*35238bceSAndroid Build Coastguard Worker frag << "}\n";
176*35238bceSAndroid Build Coastguard Worker
177*35238bceSAndroid Build Coastguard Worker return new glu::ShaderProgram(context, glu::makeVtxFragSources(vtx.str(), frag.str()));
178*35238bceSAndroid Build Coastguard Worker }
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Worker class ShaderFloatPrecisionCase : public TestCase
181*35238bceSAndroid Build Coastguard Worker {
182*35238bceSAndroid Build Coastguard Worker public:
183*35238bceSAndroid Build Coastguard Worker typedef double (*EvalFunc)(double in0, double in1);
184*35238bceSAndroid Build Coastguard Worker
185*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase(Context &context, const char *name, const char *desc, const char *op, EvalFunc evalFunc,
186*35238bceSAndroid Build Coastguard Worker glu::Precision precision, const tcu::Vec2 &rangeA, const tcu::Vec2 &rangeB,
187*35238bceSAndroid Build Coastguard Worker bool isVertexCase);
188*35238bceSAndroid Build Coastguard Worker ~ShaderFloatPrecisionCase(void);
189*35238bceSAndroid Build Coastguard Worker
190*35238bceSAndroid Build Coastguard Worker void init(void);
191*35238bceSAndroid Build Coastguard Worker void deinit(void);
192*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
193*35238bceSAndroid Build Coastguard Worker
194*35238bceSAndroid Build Coastguard Worker protected:
195*35238bceSAndroid Build Coastguard Worker bool compare(float in0, float in1, double reference, float result);
196*35238bceSAndroid Build Coastguard Worker
197*35238bceSAndroid Build Coastguard Worker private:
198*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase(const ShaderFloatPrecisionCase &other);
199*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase &operator=(const ShaderFloatPrecisionCase &other);
200*35238bceSAndroid Build Coastguard Worker
201*35238bceSAndroid Build Coastguard Worker // Case parameters.
202*35238bceSAndroid Build Coastguard Worker std::string m_op;
203*35238bceSAndroid Build Coastguard Worker EvalFunc m_evalFunc;
204*35238bceSAndroid Build Coastguard Worker glu::Precision m_precision;
205*35238bceSAndroid Build Coastguard Worker tcu::Vec2 m_rangeA;
206*35238bceSAndroid Build Coastguard Worker tcu::Vec2 m_rangeB;
207*35238bceSAndroid Build Coastguard Worker bool m_isVertexCase;
208*35238bceSAndroid Build Coastguard Worker
209*35238bceSAndroid Build Coastguard Worker int m_numTestsPerIter;
210*35238bceSAndroid Build Coastguard Worker int m_numIters;
211*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
212*35238bceSAndroid Build Coastguard Worker
213*35238bceSAndroid Build Coastguard Worker // Iteration state.
214*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
215*35238bceSAndroid Build Coastguard Worker uint32_t m_framebuffer;
216*35238bceSAndroid Build Coastguard Worker uint32_t m_renderbuffer;
217*35238bceSAndroid Build Coastguard Worker int m_iterNdx;
218*35238bceSAndroid Build Coastguard Worker };
219*35238bceSAndroid Build Coastguard Worker
ShaderFloatPrecisionCase(Context & context,const char * name,const char * desc,const char * op,EvalFunc evalFunc,glu::Precision precision,const tcu::Vec2 & rangeA,const tcu::Vec2 & rangeB,bool isVertexCase)220*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase::ShaderFloatPrecisionCase(Context &context, const char *name, const char *desc, const char *op,
221*35238bceSAndroid Build Coastguard Worker EvalFunc evalFunc, glu::Precision precision, const tcu::Vec2 &rangeA,
222*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 &rangeB, bool isVertexCase)
223*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
224*35238bceSAndroid Build Coastguard Worker , m_op(op)
225*35238bceSAndroid Build Coastguard Worker , m_evalFunc(evalFunc)
226*35238bceSAndroid Build Coastguard Worker , m_precision(precision)
227*35238bceSAndroid Build Coastguard Worker , m_rangeA(rangeA)
228*35238bceSAndroid Build Coastguard Worker , m_rangeB(rangeB)
229*35238bceSAndroid Build Coastguard Worker , m_isVertexCase(isVertexCase)
230*35238bceSAndroid Build Coastguard Worker , m_numTestsPerIter(32)
231*35238bceSAndroid Build Coastguard Worker , m_numIters(4)
232*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(name))
233*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
234*35238bceSAndroid Build Coastguard Worker , m_framebuffer(0)
235*35238bceSAndroid Build Coastguard Worker , m_renderbuffer(0)
236*35238bceSAndroid Build Coastguard Worker , m_iterNdx(0)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker }
239*35238bceSAndroid Build Coastguard Worker
~ShaderFloatPrecisionCase(void)240*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase::~ShaderFloatPrecisionCase(void)
241*35238bceSAndroid Build Coastguard Worker {
242*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase::deinit();
243*35238bceSAndroid Build Coastguard Worker }
244*35238bceSAndroid Build Coastguard Worker
init(void)245*35238bceSAndroid Build Coastguard Worker void ShaderFloatPrecisionCase::init(void)
246*35238bceSAndroid Build Coastguard Worker {
247*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
248*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
249*35238bceSAndroid Build Coastguard Worker
250*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer);
251*35238bceSAndroid Build Coastguard Worker
252*35238bceSAndroid Build Coastguard Worker // Create program.
253*35238bceSAndroid Build Coastguard Worker m_program =
254*35238bceSAndroid Build Coastguard Worker createFloatPrecisionEvalProgram(m_context.getRenderContext(), m_precision, m_op.c_str(), m_isVertexCase);
255*35238bceSAndroid Build Coastguard Worker log << *m_program;
256*35238bceSAndroid Build Coastguard Worker
257*35238bceSAndroid Build Coastguard Worker TCU_CHECK(m_program->isOk());
258*35238bceSAndroid Build Coastguard Worker
259*35238bceSAndroid Build Coastguard Worker // Create framebuffer.
260*35238bceSAndroid Build Coastguard Worker gl.genFramebuffers(1, &m_framebuffer);
261*35238bceSAndroid Build Coastguard Worker gl.genRenderbuffers(1, &m_renderbuffer);
262*35238bceSAndroid Build Coastguard Worker
263*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
264*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
265*35238bceSAndroid Build Coastguard Worker
266*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
267*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
268*35238bceSAndroid Build Coastguard Worker
269*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup");
270*35238bceSAndroid Build Coastguard Worker TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
273*35238bceSAndroid Build Coastguard Worker
274*35238bceSAndroid Build Coastguard Worker // Initialize test result to pass.
275*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
276*35238bceSAndroid Build Coastguard Worker m_iterNdx = 0;
277*35238bceSAndroid Build Coastguard Worker }
278*35238bceSAndroid Build Coastguard Worker
deinit(void)279*35238bceSAndroid Build Coastguard Worker void ShaderFloatPrecisionCase::deinit(void)
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker delete m_program;
282*35238bceSAndroid Build Coastguard Worker
283*35238bceSAndroid Build Coastguard Worker if (m_framebuffer)
284*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer);
285*35238bceSAndroid Build Coastguard Worker
286*35238bceSAndroid Build Coastguard Worker if (m_renderbuffer)
287*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer);
288*35238bceSAndroid Build Coastguard Worker
289*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
290*35238bceSAndroid Build Coastguard Worker m_framebuffer = 0;
291*35238bceSAndroid Build Coastguard Worker m_renderbuffer = 0;
292*35238bceSAndroid Build Coastguard Worker }
293*35238bceSAndroid Build Coastguard Worker
compare(float in0,float in1,double reference,float result)294*35238bceSAndroid Build Coastguard Worker bool ShaderFloatPrecisionCase::compare(float in0, float in1, double reference, float result)
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker // Comparison is done using 64-bit reference value to accurately evaluate rounding mode error.
297*35238bceSAndroid Build Coastguard Worker // If 32-bit reference value is used, 2 bits of rounding error must be allowed.
298*35238bceSAndroid Build Coastguard Worker
299*35238bceSAndroid Build Coastguard Worker // For mediump and lowp types the comparison currently allows 3 bits of rounding error:
300*35238bceSAndroid Build Coastguard Worker // two bits from conversions and one from actual operation.
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker // \todo [2013-09-30 pyry] Make this more strict: determine if rounding can actually happen.
303*35238bceSAndroid Build Coastguard Worker
304*35238bceSAndroid Build Coastguard Worker const int mantissaBits = m_precision == glu::PRECISION_HIGHP ? 23 : 10;
305*35238bceSAndroid Build Coastguard Worker const int numPrecBits = 52 - mantissaBits;
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker const int in0Exp = tcu::Float32(in0).exponent();
308*35238bceSAndroid Build Coastguard Worker const int in1Exp = tcu::Float32(in1).exponent();
309*35238bceSAndroid Build Coastguard Worker const int resExp = tcu::Float32(result).exponent();
310*35238bceSAndroid Build Coastguard Worker const int numLostBits = de::max(de::max(in0Exp - resExp, in1Exp - resExp), 0); // Lost due to mantissa shift.
311*35238bceSAndroid Build Coastguard Worker
312*35238bceSAndroid Build Coastguard Worker const int roundingUlpError = m_precision == glu::PRECISION_HIGHP ? 1 : 3;
313*35238bceSAndroid Build Coastguard Worker const int maskBits = numLostBits + numPrecBits;
314*35238bceSAndroid Build Coastguard Worker
315*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "Assuming " << mantissaBits << " mantissa bits, " << numLostBits
316*35238bceSAndroid Build Coastguard Worker << " bits lost in operation, and " << roundingUlpError << " ULP rounding error."
317*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker {
320*35238bceSAndroid Build Coastguard Worker const uint64_t refBits = tcu::Float64(reference).bits();
321*35238bceSAndroid Build Coastguard Worker const uint64_t resBits = tcu::Float64(result).bits();
322*35238bceSAndroid Build Coastguard Worker const uint64_t accurateRefBits = maskBits < 64 ? refBits >> (uint64_t)maskBits : 0u;
323*35238bceSAndroid Build Coastguard Worker const uint64_t accurateResBits = maskBits < 64 ? resBits >> (uint64_t)maskBits : 0u;
324*35238bceSAndroid Build Coastguard Worker const uint64_t ulpDiff = (uint64_t)de::abs((int64_t)accurateRefBits - (int64_t)accurateResBits);
325*35238bceSAndroid Build Coastguard Worker
326*35238bceSAndroid Build Coastguard Worker if (ulpDiff > (uint64_t)roundingUlpError)
327*35238bceSAndroid Build Coastguard Worker {
328*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message
329*35238bceSAndroid Build Coastguard Worker << "ERROR: comparison failed! ULP diff (ignoring lost/undefined bits) = " << ulpDiff
330*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
331*35238bceSAndroid Build Coastguard Worker return false;
332*35238bceSAndroid Build Coastguard Worker }
333*35238bceSAndroid Build Coastguard Worker else
334*35238bceSAndroid Build Coastguard Worker return true;
335*35238bceSAndroid Build Coastguard Worker }
336*35238bceSAndroid Build Coastguard Worker }
337*35238bceSAndroid Build Coastguard Worker
iterate(void)338*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase::IterateResult ShaderFloatPrecisionCase::iterate(void)
339*35238bceSAndroid Build Coastguard Worker {
340*35238bceSAndroid Build Coastguard Worker // Constant data.
341*35238bceSAndroid Build Coastguard Worker const float position[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
342*35238bceSAndroid Build Coastguard Worker 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
343*35238bceSAndroid Build Coastguard Worker const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
344*35238bceSAndroid Build Coastguard Worker
345*35238bceSAndroid Build Coastguard Worker const int numVertices = 4;
346*35238bceSAndroid Build Coastguard Worker float in0Arr[4] = {0.0f};
347*35238bceSAndroid Build Coastguard Worker float in1Arr[4] = {0.0f};
348*35238bceSAndroid Build Coastguard Worker
349*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
350*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
351*35238bceSAndroid Build Coastguard Worker vector<glu::VertexArrayBinding> vertexArrays;
352*35238bceSAndroid Build Coastguard Worker
353*35238bceSAndroid Build Coastguard Worker // Image read from GL.
354*35238bceSAndroid Build Coastguard Worker std::vector<float> pixels(FRAMEBUFFER_WIDTH * FRAMEBUFFER_HEIGHT * 4);
355*35238bceSAndroid Build Coastguard Worker
356*35238bceSAndroid Build Coastguard Worker // \todo [2012-05-03 pyry] Could be cached.
357*35238bceSAndroid Build Coastguard Worker uint32_t prog = m_program->getProgram();
358*35238bceSAndroid Build Coastguard Worker
359*35238bceSAndroid Build Coastguard Worker gl.useProgram(prog);
360*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
361*35238bceSAndroid Build Coastguard Worker
362*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0]));
363*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Float("a_in0", 1, numVertices, 0, &in0Arr[0]));
364*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Float("a_in1", 1, numVertices, 0, &in1Arr[0]));
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup");
367*35238bceSAndroid Build Coastguard Worker
368*35238bceSAndroid Build Coastguard Worker // Compute values and reference.
369*35238bceSAndroid Build Coastguard Worker for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++)
370*35238bceSAndroid Build Coastguard Worker {
371*35238bceSAndroid Build Coastguard Worker const float in0 = m_rnd.getFloat(m_rangeA.x(), m_rangeA.y());
372*35238bceSAndroid Build Coastguard Worker const float in1 = m_rnd.getFloat(m_rangeB.x(), m_rangeB.y());
373*35238bceSAndroid Build Coastguard Worker const double refD = m_evalFunc((double)in0, (double)in1);
374*35238bceSAndroid Build Coastguard Worker const float refF = tcu::Float64(refD).asFloat(); // Uses RTE rounding mode.
375*35238bceSAndroid Build Coastguard Worker
376*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": "
377*35238bceSAndroid Build Coastguard Worker << "in0 = " << in0 << " / " << tcu::toHex(tcu::Float32(in0).bits()) << ", in1 = " << in1 << " / "
378*35238bceSAndroid Build Coastguard Worker << tcu::toHex(tcu::Float32(in1).bits()) << TestLog::EndMessage << TestLog::Message
379*35238bceSAndroid Build Coastguard Worker << " reference = " << refF << " / " << tcu::toHex(tcu::Float32(refF).bits()) << TestLog::EndMessage;
380*35238bceSAndroid Build Coastguard Worker
381*35238bceSAndroid Build Coastguard Worker std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0);
382*35238bceSAndroid Build Coastguard Worker std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1);
383*35238bceSAndroid Build Coastguard Worker
384*35238bceSAndroid Build Coastguard Worker glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0],
385*35238bceSAndroid Build Coastguard Worker glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
386*35238bceSAndroid Build Coastguard Worker gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
387*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After render");
388*35238bceSAndroid Build Coastguard Worker
389*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << " result = " << pixels[0] << " / " << tcu::toHex(tcu::Float32(pixels[0]).bits())
390*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
391*35238bceSAndroid Build Coastguard Worker
392*35238bceSAndroid Build Coastguard Worker // Verify results
393*35238bceSAndroid Build Coastguard Worker {
394*35238bceSAndroid Build Coastguard Worker const bool firstPixelOk = compare(in0, in1, refD, pixels[0]);
395*35238bceSAndroid Build Coastguard Worker
396*35238bceSAndroid Build Coastguard Worker if (firstPixelOk)
397*35238bceSAndroid Build Coastguard Worker {
398*35238bceSAndroid Build Coastguard Worker // Check that rest of pixels match to first one.
399*35238bceSAndroid Build Coastguard Worker const uint32_t firstPixelBits = tcu::Float32(pixels[0]).bits();
400*35238bceSAndroid Build Coastguard Worker bool allPixelsOk = true;
401*35238bceSAndroid Build Coastguard Worker
402*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++)
403*35238bceSAndroid Build Coastguard Worker {
404*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < FRAMEBUFFER_WIDTH; x++)
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker const uint32_t pixelBits = tcu::Float32(pixels[(y * FRAMEBUFFER_WIDTH + x) * 4]).bits();
407*35238bceSAndroid Build Coastguard Worker
408*35238bceSAndroid Build Coastguard Worker if (pixelBits != firstPixelBits)
409*35238bceSAndroid Build Coastguard Worker {
410*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "ERROR: Inconsistent results, got " << tcu::toHex(pixelBits)
411*35238bceSAndroid Build Coastguard Worker << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
412*35238bceSAndroid Build Coastguard Worker allPixelsOk = false;
413*35238bceSAndroid Build Coastguard Worker }
414*35238bceSAndroid Build Coastguard Worker }
415*35238bceSAndroid Build Coastguard Worker
416*35238bceSAndroid Build Coastguard Worker if (!allPixelsOk)
417*35238bceSAndroid Build Coastguard Worker break;
418*35238bceSAndroid Build Coastguard Worker }
419*35238bceSAndroid Build Coastguard Worker
420*35238bceSAndroid Build Coastguard Worker if (!allPixelsOk)
421*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsistent values in framebuffer");
422*35238bceSAndroid Build Coastguard Worker }
423*35238bceSAndroid Build Coastguard Worker else
424*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
425*35238bceSAndroid Build Coastguard Worker }
426*35238bceSAndroid Build Coastguard Worker
427*35238bceSAndroid Build Coastguard Worker if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
428*35238bceSAndroid Build Coastguard Worker break;
429*35238bceSAndroid Build Coastguard Worker }
430*35238bceSAndroid Build Coastguard Worker
431*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
432*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration");
433*35238bceSAndroid Build Coastguard Worker
434*35238bceSAndroid Build Coastguard Worker m_iterNdx += 1;
435*35238bceSAndroid Build Coastguard Worker return (m_iterNdx < m_numIters && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) ? CONTINUE : STOP;
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker
438*35238bceSAndroid Build Coastguard Worker class ShaderIntPrecisionCase : public TestCase
439*35238bceSAndroid Build Coastguard Worker {
440*35238bceSAndroid Build Coastguard Worker public:
441*35238bceSAndroid Build Coastguard Worker typedef int64_t (*EvalFunc)(int64_t a, int64_t b);
442*35238bceSAndroid Build Coastguard Worker
443*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase(Context &context, const char *name, const char *desc, const char *op, EvalFunc evalFunc,
444*35238bceSAndroid Build Coastguard Worker glu::Precision precision, int bits, const tcu::IVec2 &rangeA, const tcu::IVec2 &rangeB,
445*35238bceSAndroid Build Coastguard Worker bool isVertexCase);
446*35238bceSAndroid Build Coastguard Worker ~ShaderIntPrecisionCase(void);
447*35238bceSAndroid Build Coastguard Worker
448*35238bceSAndroid Build Coastguard Worker void init(void);
449*35238bceSAndroid Build Coastguard Worker void deinit(void);
450*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
451*35238bceSAndroid Build Coastguard Worker
452*35238bceSAndroid Build Coastguard Worker private:
453*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase(const ShaderIntPrecisionCase &other);
454*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase &operator=(const ShaderIntPrecisionCase &other);
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker // Case parameters.
457*35238bceSAndroid Build Coastguard Worker std::string m_op;
458*35238bceSAndroid Build Coastguard Worker EvalFunc m_evalFunc;
459*35238bceSAndroid Build Coastguard Worker glu::Precision m_precision;
460*35238bceSAndroid Build Coastguard Worker int m_bits;
461*35238bceSAndroid Build Coastguard Worker tcu::IVec2 m_rangeA;
462*35238bceSAndroid Build Coastguard Worker tcu::IVec2 m_rangeB;
463*35238bceSAndroid Build Coastguard Worker bool m_isVertexCase;
464*35238bceSAndroid Build Coastguard Worker
465*35238bceSAndroid Build Coastguard Worker int m_numTestsPerIter;
466*35238bceSAndroid Build Coastguard Worker int m_numIters;
467*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker // Iteration state.
470*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
471*35238bceSAndroid Build Coastguard Worker uint32_t m_framebuffer;
472*35238bceSAndroid Build Coastguard Worker uint32_t m_renderbuffer;
473*35238bceSAndroid Build Coastguard Worker int m_iterNdx;
474*35238bceSAndroid Build Coastguard Worker };
475*35238bceSAndroid Build Coastguard Worker
ShaderIntPrecisionCase(Context & context,const char * name,const char * desc,const char * op,EvalFunc evalFunc,glu::Precision precision,int bits,const tcu::IVec2 & rangeA,const tcu::IVec2 & rangeB,bool isVertexCase)476*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase::ShaderIntPrecisionCase(Context &context, const char *name, const char *desc, const char *op,
477*35238bceSAndroid Build Coastguard Worker EvalFunc evalFunc, glu::Precision precision, int bits,
478*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 &rangeA, const tcu::IVec2 &rangeB, bool isVertexCase)
479*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
480*35238bceSAndroid Build Coastguard Worker , m_op(op)
481*35238bceSAndroid Build Coastguard Worker , m_evalFunc(evalFunc)
482*35238bceSAndroid Build Coastguard Worker , m_precision(precision)
483*35238bceSAndroid Build Coastguard Worker , m_bits(bits)
484*35238bceSAndroid Build Coastguard Worker , m_rangeA(rangeA)
485*35238bceSAndroid Build Coastguard Worker , m_rangeB(rangeB)
486*35238bceSAndroid Build Coastguard Worker , m_isVertexCase(isVertexCase)
487*35238bceSAndroid Build Coastguard Worker , m_numTestsPerIter(32)
488*35238bceSAndroid Build Coastguard Worker , m_numIters(4)
489*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(name))
490*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
491*35238bceSAndroid Build Coastguard Worker , m_framebuffer(0)
492*35238bceSAndroid Build Coastguard Worker , m_renderbuffer(0)
493*35238bceSAndroid Build Coastguard Worker , m_iterNdx(0)
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker }
496*35238bceSAndroid Build Coastguard Worker
~ShaderIntPrecisionCase(void)497*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase::~ShaderIntPrecisionCase(void)
498*35238bceSAndroid Build Coastguard Worker {
499*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase::deinit();
500*35238bceSAndroid Build Coastguard Worker }
501*35238bceSAndroid Build Coastguard Worker
init(void)502*35238bceSAndroid Build Coastguard Worker void ShaderIntPrecisionCase::init(void)
503*35238bceSAndroid Build Coastguard Worker {
504*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
505*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
506*35238bceSAndroid Build Coastguard Worker
507*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer);
508*35238bceSAndroid Build Coastguard Worker
509*35238bceSAndroid Build Coastguard Worker // Create program.
510*35238bceSAndroid Build Coastguard Worker m_program = createIntUintPrecisionEvalProgram(m_context.getRenderContext(), glu::TYPE_INT, m_precision,
511*35238bceSAndroid Build Coastguard Worker m_op.c_str(), m_isVertexCase);
512*35238bceSAndroid Build Coastguard Worker log << *m_program;
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker TCU_CHECK(m_program->isOk());
515*35238bceSAndroid Build Coastguard Worker
516*35238bceSAndroid Build Coastguard Worker // Create framebuffer.
517*35238bceSAndroid Build Coastguard Worker gl.genFramebuffers(1, &m_framebuffer);
518*35238bceSAndroid Build Coastguard Worker gl.genRenderbuffers(1, &m_renderbuffer);
519*35238bceSAndroid Build Coastguard Worker
520*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
521*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32I, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
522*35238bceSAndroid Build Coastguard Worker
523*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
524*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
525*35238bceSAndroid Build Coastguard Worker
526*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup");
527*35238bceSAndroid Build Coastguard Worker TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
528*35238bceSAndroid Build Coastguard Worker
529*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
530*35238bceSAndroid Build Coastguard Worker
531*35238bceSAndroid Build Coastguard Worker // Initialize test result to pass.
532*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
533*35238bceSAndroid Build Coastguard Worker m_iterNdx = 0;
534*35238bceSAndroid Build Coastguard Worker
535*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Number of accurate bits assumed = " << m_bits << TestLog::EndMessage;
536*35238bceSAndroid Build Coastguard Worker }
537*35238bceSAndroid Build Coastguard Worker
deinit(void)538*35238bceSAndroid Build Coastguard Worker void ShaderIntPrecisionCase::deinit(void)
539*35238bceSAndroid Build Coastguard Worker {
540*35238bceSAndroid Build Coastguard Worker delete m_program;
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker if (m_framebuffer)
543*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer);
544*35238bceSAndroid Build Coastguard Worker
545*35238bceSAndroid Build Coastguard Worker if (m_renderbuffer)
546*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer);
547*35238bceSAndroid Build Coastguard Worker
548*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
549*35238bceSAndroid Build Coastguard Worker m_framebuffer = 0;
550*35238bceSAndroid Build Coastguard Worker m_renderbuffer = 0;
551*35238bceSAndroid Build Coastguard Worker }
552*35238bceSAndroid Build Coastguard Worker
iterate(void)553*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase::IterateResult ShaderIntPrecisionCase::iterate(void)
554*35238bceSAndroid Build Coastguard Worker {
555*35238bceSAndroid Build Coastguard Worker // Constant data.
556*35238bceSAndroid Build Coastguard Worker const float position[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
557*35238bceSAndroid Build Coastguard Worker 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
558*35238bceSAndroid Build Coastguard Worker const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
559*35238bceSAndroid Build Coastguard Worker
560*35238bceSAndroid Build Coastguard Worker const int numVertices = 4;
561*35238bceSAndroid Build Coastguard Worker int in0Arr[4] = {0};
562*35238bceSAndroid Build Coastguard Worker int in1Arr[4] = {0};
563*35238bceSAndroid Build Coastguard Worker
564*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
565*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
566*35238bceSAndroid Build Coastguard Worker uint32_t mask = m_bits == 32 ? 0xffffffffu : ((1u << m_bits) - 1);
567*35238bceSAndroid Build Coastguard Worker vector<int> pixels(FRAMEBUFFER_WIDTH * FRAMEBUFFER_HEIGHT * 4);
568*35238bceSAndroid Build Coastguard Worker vector<glu::VertexArrayBinding> vertexArrays;
569*35238bceSAndroid Build Coastguard Worker
570*35238bceSAndroid Build Coastguard Worker uint32_t prog = m_program->getProgram();
571*35238bceSAndroid Build Coastguard Worker
572*35238bceSAndroid Build Coastguard Worker // \todo [2012-05-03 pyry] A bit hacky. getInt() should work fine with ranges like this.
573*35238bceSAndroid Build Coastguard Worker bool isMaxRangeA = m_rangeA.x() == (int)0x80000000 && m_rangeA.y() == (int)0x7fffffff;
574*35238bceSAndroid Build Coastguard Worker bool isMaxRangeB = m_rangeB.x() == (int)0x80000000 && m_rangeB.y() == (int)0x7fffffff;
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker gl.useProgram(prog);
577*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
578*35238bceSAndroid Build Coastguard Worker
579*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0]));
580*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Int32("a_in0", 1, numVertices, 0, &in0Arr[0]));
581*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Int32("a_in1", 1, numVertices, 0, &in1Arr[0]));
582*35238bceSAndroid Build Coastguard Worker
583*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup");
584*35238bceSAndroid Build Coastguard Worker
585*35238bceSAndroid Build Coastguard Worker // Compute values and reference.
586*35238bceSAndroid Build Coastguard Worker for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker int in0 = deSignExtendTo32(
589*35238bceSAndroid Build Coastguard Worker ((isMaxRangeA ? (int)m_rnd.getUint32() : m_rnd.getInt(m_rangeA.x(), m_rangeA.y())) & mask), m_bits);
590*35238bceSAndroid Build Coastguard Worker int in1 = deSignExtendTo32(
591*35238bceSAndroid Build Coastguard Worker ((isMaxRangeB ? (int)m_rnd.getUint32() : m_rnd.getInt(m_rangeB.x(), m_rangeB.y())) & mask), m_bits);
592*35238bceSAndroid Build Coastguard Worker int refMasked = static_cast<int>(m_evalFunc(in0, in1) & static_cast<uint64_t>(mask));
593*35238bceSAndroid Build Coastguard Worker int refOut = deSignExtendTo32(refMasked, m_bits);
594*35238bceSAndroid Build Coastguard Worker
595*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": "
596*35238bceSAndroid Build Coastguard Worker << "in0 = " << in0 << ", in1 = " << in1 << ", ref out = " << refOut << " / " << tcu::toHex(refMasked)
597*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
598*35238bceSAndroid Build Coastguard Worker
599*35238bceSAndroid Build Coastguard Worker std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0);
600*35238bceSAndroid Build Coastguard Worker std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1);
601*35238bceSAndroid Build Coastguard Worker
602*35238bceSAndroid Build Coastguard Worker glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0],
603*35238bceSAndroid Build Coastguard Worker glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
604*35238bceSAndroid Build Coastguard Worker gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_INT, &pixels[0]);
605*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After render");
606*35238bceSAndroid Build Coastguard Worker
607*35238bceSAndroid Build Coastguard Worker // Compare pixels.
608*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++)
609*35238bceSAndroid Build Coastguard Worker {
610*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < FRAMEBUFFER_WIDTH; x++)
611*35238bceSAndroid Build Coastguard Worker {
612*35238bceSAndroid Build Coastguard Worker int cmpOut = pixels[(y * FRAMEBUFFER_WIDTH + x) * 4];
613*35238bceSAndroid Build Coastguard Worker int cmpMasked = cmpOut & mask;
614*35238bceSAndroid Build Coastguard Worker
615*35238bceSAndroid Build Coastguard Worker if (cmpMasked != refMasked)
616*35238bceSAndroid Build Coastguard Worker {
617*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Comparison failed (at " << x << ", " << y << "): "
618*35238bceSAndroid Build Coastguard Worker << "got " << cmpOut << " / " << tcu::toHex(cmpOut) << TestLog::EndMessage;
619*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
620*35238bceSAndroid Build Coastguard Worker return STOP;
621*35238bceSAndroid Build Coastguard Worker }
622*35238bceSAndroid Build Coastguard Worker }
623*35238bceSAndroid Build Coastguard Worker }
624*35238bceSAndroid Build Coastguard Worker }
625*35238bceSAndroid Build Coastguard Worker
626*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
627*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration");
628*35238bceSAndroid Build Coastguard Worker
629*35238bceSAndroid Build Coastguard Worker m_iterNdx += 1;
630*35238bceSAndroid Build Coastguard Worker return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
631*35238bceSAndroid Build Coastguard Worker }
632*35238bceSAndroid Build Coastguard Worker
633*35238bceSAndroid Build Coastguard Worker class ShaderUintPrecisionCase : public TestCase
634*35238bceSAndroid Build Coastguard Worker {
635*35238bceSAndroid Build Coastguard Worker public:
636*35238bceSAndroid Build Coastguard Worker typedef uint32_t (*EvalFunc)(uint32_t a, uint32_t b);
637*35238bceSAndroid Build Coastguard Worker
638*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase(Context &context, const char *name, const char *desc, const char *op, EvalFunc evalFunc,
639*35238bceSAndroid Build Coastguard Worker glu::Precision precision, int bits, const tcu::UVec2 &rangeA, const tcu::UVec2 &rangeB,
640*35238bceSAndroid Build Coastguard Worker bool isVertexCase);
641*35238bceSAndroid Build Coastguard Worker ~ShaderUintPrecisionCase(void);
642*35238bceSAndroid Build Coastguard Worker
643*35238bceSAndroid Build Coastguard Worker void init(void);
644*35238bceSAndroid Build Coastguard Worker void deinit(void);
645*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
646*35238bceSAndroid Build Coastguard Worker
647*35238bceSAndroid Build Coastguard Worker private:
648*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase(const ShaderUintPrecisionCase &other);
649*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase &operator=(const ShaderUintPrecisionCase &other);
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker // Case parameters.
652*35238bceSAndroid Build Coastguard Worker std::string m_op;
653*35238bceSAndroid Build Coastguard Worker EvalFunc m_evalFunc;
654*35238bceSAndroid Build Coastguard Worker glu::Precision m_precision;
655*35238bceSAndroid Build Coastguard Worker int m_bits;
656*35238bceSAndroid Build Coastguard Worker tcu::UVec2 m_rangeA;
657*35238bceSAndroid Build Coastguard Worker tcu::UVec2 m_rangeB;
658*35238bceSAndroid Build Coastguard Worker bool m_isVertexCase;
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker int m_numTestsPerIter;
661*35238bceSAndroid Build Coastguard Worker int m_numIters;
662*35238bceSAndroid Build Coastguard Worker de::Random m_rnd;
663*35238bceSAndroid Build Coastguard Worker
664*35238bceSAndroid Build Coastguard Worker // Iteration state.
665*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram *m_program;
666*35238bceSAndroid Build Coastguard Worker uint32_t m_framebuffer;
667*35238bceSAndroid Build Coastguard Worker uint32_t m_renderbuffer;
668*35238bceSAndroid Build Coastguard Worker int m_iterNdx;
669*35238bceSAndroid Build Coastguard Worker };
670*35238bceSAndroid Build Coastguard Worker
ShaderUintPrecisionCase(Context & context,const char * name,const char * desc,const char * op,EvalFunc evalFunc,glu::Precision precision,int bits,const tcu::UVec2 & rangeA,const tcu::UVec2 & rangeB,bool isVertexCase)671*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase::ShaderUintPrecisionCase(Context &context, const char *name, const char *desc, const char *op,
672*35238bceSAndroid Build Coastguard Worker EvalFunc evalFunc, glu::Precision precision, int bits,
673*35238bceSAndroid Build Coastguard Worker const tcu::UVec2 &rangeA, const tcu::UVec2 &rangeB, bool isVertexCase)
674*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, desc)
675*35238bceSAndroid Build Coastguard Worker , m_op(op)
676*35238bceSAndroid Build Coastguard Worker , m_evalFunc(evalFunc)
677*35238bceSAndroid Build Coastguard Worker , m_precision(precision)
678*35238bceSAndroid Build Coastguard Worker , m_bits(bits)
679*35238bceSAndroid Build Coastguard Worker , m_rangeA(rangeA)
680*35238bceSAndroid Build Coastguard Worker , m_rangeB(rangeB)
681*35238bceSAndroid Build Coastguard Worker , m_isVertexCase(isVertexCase)
682*35238bceSAndroid Build Coastguard Worker , m_numTestsPerIter(32)
683*35238bceSAndroid Build Coastguard Worker , m_numIters(4)
684*35238bceSAndroid Build Coastguard Worker , m_rnd(deStringHash(name))
685*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
686*35238bceSAndroid Build Coastguard Worker , m_framebuffer(0)
687*35238bceSAndroid Build Coastguard Worker , m_renderbuffer(0)
688*35238bceSAndroid Build Coastguard Worker , m_iterNdx(0)
689*35238bceSAndroid Build Coastguard Worker {
690*35238bceSAndroid Build Coastguard Worker }
691*35238bceSAndroid Build Coastguard Worker
~ShaderUintPrecisionCase(void)692*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase::~ShaderUintPrecisionCase(void)
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase::deinit();
695*35238bceSAndroid Build Coastguard Worker }
696*35238bceSAndroid Build Coastguard Worker
init(void)697*35238bceSAndroid Build Coastguard Worker void ShaderUintPrecisionCase::init(void)
698*35238bceSAndroid Build Coastguard Worker {
699*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
700*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
701*35238bceSAndroid Build Coastguard Worker
702*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer);
703*35238bceSAndroid Build Coastguard Worker
704*35238bceSAndroid Build Coastguard Worker // Create program.
705*35238bceSAndroid Build Coastguard Worker m_program = createIntUintPrecisionEvalProgram(m_context.getRenderContext(), glu::TYPE_UINT, m_precision,
706*35238bceSAndroid Build Coastguard Worker m_op.c_str(), m_isVertexCase);
707*35238bceSAndroid Build Coastguard Worker log << *m_program;
708*35238bceSAndroid Build Coastguard Worker
709*35238bceSAndroid Build Coastguard Worker TCU_CHECK(m_program->isOk());
710*35238bceSAndroid Build Coastguard Worker
711*35238bceSAndroid Build Coastguard Worker // Create framebuffer.
712*35238bceSAndroid Build Coastguard Worker gl.genFramebuffers(1, &m_framebuffer);
713*35238bceSAndroid Build Coastguard Worker gl.genRenderbuffers(1, &m_renderbuffer);
714*35238bceSAndroid Build Coastguard Worker
715*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);
716*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
717*35238bceSAndroid Build Coastguard Worker
718*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
719*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);
720*35238bceSAndroid Build Coastguard Worker
721*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup");
722*35238bceSAndroid Build Coastguard Worker TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
723*35238bceSAndroid Build Coastguard Worker
724*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker // Initialize test result to pass.
727*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
728*35238bceSAndroid Build Coastguard Worker m_iterNdx = 0;
729*35238bceSAndroid Build Coastguard Worker
730*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Number of accurate bits assumed = " << m_bits << TestLog::EndMessage;
731*35238bceSAndroid Build Coastguard Worker }
732*35238bceSAndroid Build Coastguard Worker
deinit(void)733*35238bceSAndroid Build Coastguard Worker void ShaderUintPrecisionCase::deinit(void)
734*35238bceSAndroid Build Coastguard Worker {
735*35238bceSAndroid Build Coastguard Worker delete m_program;
736*35238bceSAndroid Build Coastguard Worker
737*35238bceSAndroid Build Coastguard Worker if (m_framebuffer)
738*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer);
739*35238bceSAndroid Build Coastguard Worker
740*35238bceSAndroid Build Coastguard Worker if (m_renderbuffer)
741*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer);
742*35238bceSAndroid Build Coastguard Worker
743*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
744*35238bceSAndroid Build Coastguard Worker m_framebuffer = 0;
745*35238bceSAndroid Build Coastguard Worker m_renderbuffer = 0;
746*35238bceSAndroid Build Coastguard Worker }
747*35238bceSAndroid Build Coastguard Worker
iterate(void)748*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase::IterateResult ShaderUintPrecisionCase::iterate(void)
749*35238bceSAndroid Build Coastguard Worker {
750*35238bceSAndroid Build Coastguard Worker // Constant data.
751*35238bceSAndroid Build Coastguard Worker const float position[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
752*35238bceSAndroid Build Coastguard Worker 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
753*35238bceSAndroid Build Coastguard Worker const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
754*35238bceSAndroid Build Coastguard Worker
755*35238bceSAndroid Build Coastguard Worker const int numVertices = 4;
756*35238bceSAndroid Build Coastguard Worker uint32_t in0Arr[4] = {0};
757*35238bceSAndroid Build Coastguard Worker uint32_t in1Arr[4] = {0};
758*35238bceSAndroid Build Coastguard Worker
759*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
760*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
761*35238bceSAndroid Build Coastguard Worker uint32_t mask = m_bits == 32 ? 0xffffffffu : ((1u << m_bits) - 1);
762*35238bceSAndroid Build Coastguard Worker vector<uint32_t> pixels(FRAMEBUFFER_WIDTH * FRAMEBUFFER_HEIGHT * 4);
763*35238bceSAndroid Build Coastguard Worker vector<glu::VertexArrayBinding> vertexArrays;
764*35238bceSAndroid Build Coastguard Worker
765*35238bceSAndroid Build Coastguard Worker uint32_t prog = m_program->getProgram();
766*35238bceSAndroid Build Coastguard Worker
767*35238bceSAndroid Build Coastguard Worker // \todo [2012-05-03 pyry] A bit hacky.
768*35238bceSAndroid Build Coastguard Worker bool isMaxRangeA = m_rangeA.x() == 0 && m_rangeA.y() == 0xffffffff;
769*35238bceSAndroid Build Coastguard Worker bool isMaxRangeB = m_rangeB.x() == 0 && m_rangeB.y() == 0xffffffff;
770*35238bceSAndroid Build Coastguard Worker
771*35238bceSAndroid Build Coastguard Worker gl.useProgram(prog);
772*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
773*35238bceSAndroid Build Coastguard Worker
774*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0]));
775*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Uint32("a_in0", 1, numVertices, 0, &in0Arr[0]));
776*35238bceSAndroid Build Coastguard Worker vertexArrays.push_back(glu::va::Uint32("a_in1", 1, numVertices, 0, &in1Arr[0]));
777*35238bceSAndroid Build Coastguard Worker
778*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup");
779*35238bceSAndroid Build Coastguard Worker
780*35238bceSAndroid Build Coastguard Worker // Compute values and reference.
781*35238bceSAndroid Build Coastguard Worker for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++)
782*35238bceSAndroid Build Coastguard Worker {
783*35238bceSAndroid Build Coastguard Worker uint32_t in0 =
784*35238bceSAndroid Build Coastguard Worker (isMaxRangeA ? m_rnd.getUint32() : (m_rangeA.x() + m_rnd.getUint32() % (m_rangeA.y() - m_rangeA.x() + 1))) &
785*35238bceSAndroid Build Coastguard Worker mask;
786*35238bceSAndroid Build Coastguard Worker uint32_t in1 =
787*35238bceSAndroid Build Coastguard Worker (isMaxRangeB ? m_rnd.getUint32() : (m_rangeB.x() + m_rnd.getUint32() % (m_rangeB.y() - m_rangeB.x() + 1))) &
788*35238bceSAndroid Build Coastguard Worker mask;
789*35238bceSAndroid Build Coastguard Worker uint32_t refOut = m_evalFunc(in0, in1) & mask;
790*35238bceSAndroid Build Coastguard Worker
791*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": "
792*35238bceSAndroid Build Coastguard Worker << "in0 = " << tcu::toHex(in0) << ", in1 = " << tcu::toHex(in1) << ", ref out = " << tcu::toHex(refOut)
793*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
794*35238bceSAndroid Build Coastguard Worker
795*35238bceSAndroid Build Coastguard Worker std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0);
796*35238bceSAndroid Build Coastguard Worker std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1);
797*35238bceSAndroid Build Coastguard Worker
798*35238bceSAndroid Build Coastguard Worker glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0],
799*35238bceSAndroid Build Coastguard Worker glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
800*35238bceSAndroid Build Coastguard Worker gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
801*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After render");
802*35238bceSAndroid Build Coastguard Worker
803*35238bceSAndroid Build Coastguard Worker // Compare pixels.
804*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++)
805*35238bceSAndroid Build Coastguard Worker {
806*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < FRAMEBUFFER_WIDTH; x++)
807*35238bceSAndroid Build Coastguard Worker {
808*35238bceSAndroid Build Coastguard Worker uint32_t cmpOut = pixels[(y * FRAMEBUFFER_WIDTH + x) * 4];
809*35238bceSAndroid Build Coastguard Worker uint32_t cmpMasked = cmpOut & mask;
810*35238bceSAndroid Build Coastguard Worker
811*35238bceSAndroid Build Coastguard Worker if (cmpMasked != refOut)
812*35238bceSAndroid Build Coastguard Worker {
813*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Comparison failed (at " << x << ", " << y << "): "
814*35238bceSAndroid Build Coastguard Worker << "got " << tcu::toHex(cmpOut) << TestLog::EndMessage;
815*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
816*35238bceSAndroid Build Coastguard Worker return STOP;
817*35238bceSAndroid Build Coastguard Worker }
818*35238bceSAndroid Build Coastguard Worker }
819*35238bceSAndroid Build Coastguard Worker }
820*35238bceSAndroid Build Coastguard Worker }
821*35238bceSAndroid Build Coastguard Worker
822*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
823*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration");
824*35238bceSAndroid Build Coastguard Worker
825*35238bceSAndroid Build Coastguard Worker m_iterNdx += 1;
826*35238bceSAndroid Build Coastguard Worker return (m_iterNdx < m_numIters) ? CONTINUE : STOP;
827*35238bceSAndroid Build Coastguard Worker }
828*35238bceSAndroid Build Coastguard Worker
ShaderPrecisionTests(Context & context)829*35238bceSAndroid Build Coastguard Worker ShaderPrecisionTests::ShaderPrecisionTests(Context &context)
830*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "precision", "Shader precision requirements validation tests")
831*35238bceSAndroid Build Coastguard Worker {
832*35238bceSAndroid Build Coastguard Worker }
833*35238bceSAndroid Build Coastguard Worker
~ShaderPrecisionTests(void)834*35238bceSAndroid Build Coastguard Worker ShaderPrecisionTests::~ShaderPrecisionTests(void)
835*35238bceSAndroid Build Coastguard Worker {
836*35238bceSAndroid Build Coastguard Worker }
837*35238bceSAndroid Build Coastguard Worker
init(void)838*35238bceSAndroid Build Coastguard Worker void ShaderPrecisionTests::init(void)
839*35238bceSAndroid Build Coastguard Worker {
840*35238bceSAndroid Build Coastguard Worker using tcu::add;
841*35238bceSAndroid Build Coastguard Worker using tcu::div;
842*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
843*35238bceSAndroid Build Coastguard Worker using tcu::mul;
844*35238bceSAndroid Build Coastguard Worker using tcu::sub;
845*35238bceSAndroid Build Coastguard Worker using tcu::UVec2;
846*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
847*35238bceSAndroid Build Coastguard Worker
848*35238bceSAndroid Build Coastguard Worker // Exp = Emax-2, Mantissa = 0
849*35238bceSAndroid Build Coastguard Worker float minF32 = tcu::Float32((1u << 31) | (0xfdu << 23) | 0x0u).asFloat();
850*35238bceSAndroid Build Coastguard Worker float maxF32 = tcu::Float32((0u << 31) | (0xfdu << 23) | 0x0u).asFloat();
851*35238bceSAndroid Build Coastguard Worker float minF16 = tcu::Float16((uint16_t)((1u << 15) | (0x1du << 10) | 0x0u)).asFloat();
852*35238bceSAndroid Build Coastguard Worker float maxF16 = tcu::Float16((uint16_t)((0u << 15) | (0x1du << 10) | 0x0u)).asFloat();
853*35238bceSAndroid Build Coastguard Worker tcu::Vec2 fullRange32F(minF32, maxF32);
854*35238bceSAndroid Build Coastguard Worker tcu::Vec2 fullRange16F(minF16, maxF16);
855*35238bceSAndroid Build Coastguard Worker tcu::IVec2 fullRange32I(0x80000000, 0x7fffffff);
856*35238bceSAndroid Build Coastguard Worker tcu::IVec2 fullRange16I(-(1 << 15), (1 << 15) - 1);
857*35238bceSAndroid Build Coastguard Worker tcu::IVec2 fullRange8I(-(1 << 7), (1 << 7) - 1);
858*35238bceSAndroid Build Coastguard Worker tcu::UVec2 fullRange32U(0u, 0xffffffffu);
859*35238bceSAndroid Build Coastguard Worker tcu::UVec2 fullRange16U(0u, 0xffffu);
860*35238bceSAndroid Build Coastguard Worker tcu::UVec2 fullRange8U(0u, 0xffu);
861*35238bceSAndroid Build Coastguard Worker
862*35238bceSAndroid Build Coastguard Worker // \note Right now it is not programmatically verified that the results shouldn't end up being inf/nan but
863*35238bceSAndroid Build Coastguard Worker // actual values used are ok.
864*35238bceSAndroid Build Coastguard Worker
865*35238bceSAndroid Build Coastguard Worker static const struct
866*35238bceSAndroid Build Coastguard Worker {
867*35238bceSAndroid Build Coastguard Worker const char *name;
868*35238bceSAndroid Build Coastguard Worker const char *op;
869*35238bceSAndroid Build Coastguard Worker ShaderFloatPrecisionCase::EvalFunc evalFunc;
870*35238bceSAndroid Build Coastguard Worker glu::Precision precision;
871*35238bceSAndroid Build Coastguard Worker tcu::Vec2 rangeA;
872*35238bceSAndroid Build Coastguard Worker tcu::Vec2 rangeB;
873*35238bceSAndroid Build Coastguard Worker } floatCases[] = {
874*35238bceSAndroid Build Coastguard Worker // Name Op Eval Precision RangeA RangeB
875*35238bceSAndroid Build Coastguard Worker {"highp_add", "in0 + in1", add<double>, glu::PRECISION_HIGHP, fullRange32F, fullRange32F},
876*35238bceSAndroid Build Coastguard Worker {"highp_sub", "in0 - in1", sub<double>, glu::PRECISION_HIGHP, fullRange32F, fullRange32F},
877*35238bceSAndroid Build Coastguard Worker {"highp_mul", "in0 * in1", mul<double>, glu::PRECISION_HIGHP, Vec2(-1e5f, 1e5f), Vec2(-1e5f, 1e5f)},
878*35238bceSAndroid Build Coastguard Worker {"highp_div", "in0 / in1", div<double>, glu::PRECISION_HIGHP, Vec2(-1e5f, 1e5f), Vec2(-1e5f, 1e5f)},
879*35238bceSAndroid Build Coastguard Worker {"mediump_add", "in0 + in1", add<double>, glu::PRECISION_MEDIUMP, fullRange16F, fullRange16F},
880*35238bceSAndroid Build Coastguard Worker {"mediump_sub", "in0 - in1", sub<double>, glu::PRECISION_MEDIUMP, fullRange16F, fullRange16F},
881*35238bceSAndroid Build Coastguard Worker {"mediump_mul", "in0 * in1", mul<double>, glu::PRECISION_MEDIUMP, Vec2(-1e2f, 1e2f), Vec2(-1e2f, 1e2f)},
882*35238bceSAndroid Build Coastguard Worker {"mediump_div", "in0 / in1", div<double>, glu::PRECISION_MEDIUMP, Vec2(-1e2f, 1e2f), Vec2(-1e2f, 1e2f)}};
883*35238bceSAndroid Build Coastguard Worker
884*35238bceSAndroid Build Coastguard Worker static const struct
885*35238bceSAndroid Build Coastguard Worker {
886*35238bceSAndroid Build Coastguard Worker const char *name;
887*35238bceSAndroid Build Coastguard Worker const char *op;
888*35238bceSAndroid Build Coastguard Worker ShaderIntPrecisionCase::EvalFunc evalFunc;
889*35238bceSAndroid Build Coastguard Worker glu::Precision precision;
890*35238bceSAndroid Build Coastguard Worker int bits;
891*35238bceSAndroid Build Coastguard Worker tcu::IVec2 rangeA;
892*35238bceSAndroid Build Coastguard Worker tcu::IVec2 rangeB;
893*35238bceSAndroid Build Coastguard Worker } intCases[] = {
894*35238bceSAndroid Build Coastguard Worker // Name Op Eval Precision Bits RangeA RangeB
895*35238bceSAndroid Build Coastguard Worker {"highp_add", "in0 + in1", add<int64_t>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I},
896*35238bceSAndroid Build Coastguard Worker {"highp_sub", "in0 - in1", sub<int64_t>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I},
897*35238bceSAndroid Build Coastguard Worker {"highp_mul", "in0 * in1", mul<int64_t>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I},
898*35238bceSAndroid Build Coastguard Worker {"highp_div", "in0 / in1", div<int64_t>, glu::PRECISION_HIGHP, 32, fullRange32I, IVec2(-10000, -1)},
899*35238bceSAndroid Build Coastguard Worker {"mediump_add", "in0 + in1", add<int64_t>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I},
900*35238bceSAndroid Build Coastguard Worker {"mediump_sub", "in0 - in1", sub<int64_t>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I},
901*35238bceSAndroid Build Coastguard Worker {"mediump_mul", "in0 * in1", mul<int64_t>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I},
902*35238bceSAndroid Build Coastguard Worker {"mediump_div", "in0 / in1", div<int64_t>, glu::PRECISION_MEDIUMP, 16, fullRange16I, IVec2(1, 1000)},
903*35238bceSAndroid Build Coastguard Worker {"lowp_add", "in0 + in1", add<int64_t>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I},
904*35238bceSAndroid Build Coastguard Worker {"lowp_sub", "in0 - in1", sub<int64_t>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I},
905*35238bceSAndroid Build Coastguard Worker {"lowp_mul", "in0 * in1", mul<int64_t>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I},
906*35238bceSAndroid Build Coastguard Worker {"lowp_div", "in0 / in1", div<int64_t>, glu::PRECISION_LOWP, 8, fullRange8I, IVec2(-50, -1)}};
907*35238bceSAndroid Build Coastguard Worker
908*35238bceSAndroid Build Coastguard Worker static const struct
909*35238bceSAndroid Build Coastguard Worker {
910*35238bceSAndroid Build Coastguard Worker const char *name;
911*35238bceSAndroid Build Coastguard Worker const char *op;
912*35238bceSAndroid Build Coastguard Worker ShaderUintPrecisionCase::EvalFunc evalFunc;
913*35238bceSAndroid Build Coastguard Worker glu::Precision precision;
914*35238bceSAndroid Build Coastguard Worker int bits;
915*35238bceSAndroid Build Coastguard Worker tcu::UVec2 rangeA;
916*35238bceSAndroid Build Coastguard Worker tcu::UVec2 rangeB;
917*35238bceSAndroid Build Coastguard Worker } uintCases[] = {
918*35238bceSAndroid Build Coastguard Worker // Name Op Eval Precision Bits RangeA RangeB
919*35238bceSAndroid Build Coastguard Worker {"highp_add", "in0 + in1", add<uint32_t>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U},
920*35238bceSAndroid Build Coastguard Worker {"highp_sub", "in0 - in1", sub<uint32_t>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U},
921*35238bceSAndroid Build Coastguard Worker {"highp_mul", "in0 * in1", mul<uint32_t>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U},
922*35238bceSAndroid Build Coastguard Worker {"highp_div", "in0 / in1", div<uint32_t>, glu::PRECISION_HIGHP, 32, fullRange32U, UVec2(1u, 10000u)},
923*35238bceSAndroid Build Coastguard Worker {"mediump_add", "in0 + in1", add<uint32_t>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U},
924*35238bceSAndroid Build Coastguard Worker {"mediump_sub", "in0 - in1", sub<uint32_t>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U},
925*35238bceSAndroid Build Coastguard Worker {"mediump_mul", "in0 * in1", mul<uint32_t>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U},
926*35238bceSAndroid Build Coastguard Worker {"mediump_div", "in0 / in1", div<uint32_t>, glu::PRECISION_MEDIUMP, 16, fullRange16U, UVec2(1, 1000u)},
927*35238bceSAndroid Build Coastguard Worker {"lowp_add", "in0 + in1", add<uint32_t>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U},
928*35238bceSAndroid Build Coastguard Worker {"lowp_sub", "in0 - in1", sub<uint32_t>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U},
929*35238bceSAndroid Build Coastguard Worker {"lowp_mul", "in0 * in1", mul<uint32_t>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U},
930*35238bceSAndroid Build Coastguard Worker {"lowp_div", "in0 / in1", div<uint32_t>, glu::PRECISION_LOWP, 8, fullRange8U, UVec2(1, 50u)}};
931*35238bceSAndroid Build Coastguard Worker
932*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *floatGroup = new tcu::TestCaseGroup(m_testCtx, "float", "Floating-point precision tests");
933*35238bceSAndroid Build Coastguard Worker addChild(floatGroup);
934*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(floatCases); ndx++)
935*35238bceSAndroid Build Coastguard Worker {
936*35238bceSAndroid Build Coastguard Worker floatGroup->addChild(new ShaderFloatPrecisionCase(
937*35238bceSAndroid Build Coastguard Worker m_context, (string(floatCases[ndx].name) + "_vertex").c_str(), "", floatCases[ndx].op,
938*35238bceSAndroid Build Coastguard Worker floatCases[ndx].evalFunc, floatCases[ndx].precision, floatCases[ndx].rangeA, floatCases[ndx].rangeB, true));
939*35238bceSAndroid Build Coastguard Worker floatGroup->addChild(
940*35238bceSAndroid Build Coastguard Worker new ShaderFloatPrecisionCase(m_context, (string(floatCases[ndx].name) + "_fragment").c_str(), "",
941*35238bceSAndroid Build Coastguard Worker floatCases[ndx].op, floatCases[ndx].evalFunc, floatCases[ndx].precision,
942*35238bceSAndroid Build Coastguard Worker floatCases[ndx].rangeA, floatCases[ndx].rangeB, false));
943*35238bceSAndroid Build Coastguard Worker }
944*35238bceSAndroid Build Coastguard Worker
945*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *intGroup = new tcu::TestCaseGroup(m_testCtx, "int", "Integer precision tests");
946*35238bceSAndroid Build Coastguard Worker addChild(intGroup);
947*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(intCases); ndx++)
948*35238bceSAndroid Build Coastguard Worker {
949*35238bceSAndroid Build Coastguard Worker intGroup->addChild(new ShaderIntPrecisionCase(
950*35238bceSAndroid Build Coastguard Worker m_context, (string(intCases[ndx].name) + "_vertex").c_str(), "", intCases[ndx].op, intCases[ndx].evalFunc,
951*35238bceSAndroid Build Coastguard Worker intCases[ndx].precision, intCases[ndx].bits, intCases[ndx].rangeA, intCases[ndx].rangeB, true));
952*35238bceSAndroid Build Coastguard Worker intGroup->addChild(new ShaderIntPrecisionCase(
953*35238bceSAndroid Build Coastguard Worker m_context, (string(intCases[ndx].name) + "_fragment").c_str(), "", intCases[ndx].op, intCases[ndx].evalFunc,
954*35238bceSAndroid Build Coastguard Worker intCases[ndx].precision, intCases[ndx].bits, intCases[ndx].rangeA, intCases[ndx].rangeB, false));
955*35238bceSAndroid Build Coastguard Worker }
956*35238bceSAndroid Build Coastguard Worker
957*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *uintGroup = new tcu::TestCaseGroup(m_testCtx, "uint", "Unsigned integer precision tests");
958*35238bceSAndroid Build Coastguard Worker addChild(uintGroup);
959*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uintCases); ndx++)
960*35238bceSAndroid Build Coastguard Worker {
961*35238bceSAndroid Build Coastguard Worker uintGroup->addChild(new ShaderUintPrecisionCase(m_context, (string(uintCases[ndx].name) + "_vertex").c_str(),
962*35238bceSAndroid Build Coastguard Worker "", uintCases[ndx].op, uintCases[ndx].evalFunc,
963*35238bceSAndroid Build Coastguard Worker uintCases[ndx].precision, uintCases[ndx].bits,
964*35238bceSAndroid Build Coastguard Worker uintCases[ndx].rangeA, uintCases[ndx].rangeB, true));
965*35238bceSAndroid Build Coastguard Worker uintGroup->addChild(new ShaderUintPrecisionCase(m_context, (string(uintCases[ndx].name) + "_fragment").c_str(),
966*35238bceSAndroid Build Coastguard Worker "", uintCases[ndx].op, uintCases[ndx].evalFunc,
967*35238bceSAndroid Build Coastguard Worker uintCases[ndx].precision, uintCases[ndx].bits,
968*35238bceSAndroid Build Coastguard Worker uintCases[ndx].rangeA, uintCases[ndx].rangeB, false));
969*35238bceSAndroid Build Coastguard Worker }
970*35238bceSAndroid Build Coastguard Worker }
971*35238bceSAndroid Build Coastguard Worker
972*35238bceSAndroid Build Coastguard Worker } // namespace Functional
973*35238bceSAndroid Build Coastguard Worker } // namespace gles3
974*35238bceSAndroid Build Coastguard Worker } // namespace deqp
975