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 derivate function tests.
22*35238bceSAndroid Build Coastguard Worker *
23*35238bceSAndroid Build Coastguard Worker * \todo [2013-06-25 pyry] Missing features:
24*35238bceSAndroid Build Coastguard Worker * - lines and points
25*35238bceSAndroid Build Coastguard Worker * - projected coordinates
26*35238bceSAndroid Build Coastguard Worker * - continous non-trivial functions (sin, exp)
27*35238bceSAndroid Build Coastguard Worker * - non-continous functions (step)
28*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
29*35238bceSAndroid Build Coastguard Worker
30*35238bceSAndroid Build Coastguard Worker #include "es3fShaderDerivateTests.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluShaderUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "gluTexture.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "tcuRGBA.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "tcuFloat.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "tcuInterval.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
49*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
50*35238bceSAndroid Build Coastguard Worker #include "deString.h"
51*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
52*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
53*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp" // gls::setupDefaultUniforms()
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker #include <sstream>
56*35238bceSAndroid Build Coastguard Worker
57*35238bceSAndroid Build Coastguard Worker namespace deqp
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker namespace gles3
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker namespace Functional
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker using std::map;
65*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
66*35238bceSAndroid Build Coastguard Worker using std::string;
67*35238bceSAndroid Build Coastguard Worker using std::vector;
68*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker enum
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker VIEWPORT_WIDTH = 167,
73*35238bceSAndroid Build Coastguard Worker VIEWPORT_HEIGHT = 103,
74*35238bceSAndroid Build Coastguard Worker FBO_WIDTH = 99,
75*35238bceSAndroid Build Coastguard Worker FBO_HEIGHT = 133,
76*35238bceSAndroid Build Coastguard Worker MAX_FAILED_MESSAGES = 10
77*35238bceSAndroid Build Coastguard Worker };
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker enum DerivateFunc
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker DERIVATE_DFDX = 0,
82*35238bceSAndroid Build Coastguard Worker DERIVATE_DFDY,
83*35238bceSAndroid Build Coastguard Worker DERIVATE_FWIDTH,
84*35238bceSAndroid Build Coastguard Worker
85*35238bceSAndroid Build Coastguard Worker DERIVATE_LAST
86*35238bceSAndroid Build Coastguard Worker };
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker enum SurfaceType
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker SURFACETYPE_DEFAULT_FRAMEBUFFER = 0,
91*35238bceSAndroid Build Coastguard Worker SURFACETYPE_UNORM_FBO,
92*35238bceSAndroid Build Coastguard Worker SURFACETYPE_FLOAT_FBO, // \note Uses RGBA32UI fbo actually, since FP rendertargets are not in core spec.
93*35238bceSAndroid Build Coastguard Worker
94*35238bceSAndroid Build Coastguard Worker SURFACETYPE_LAST
95*35238bceSAndroid Build Coastguard Worker };
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker // Utilities
98*35238bceSAndroid Build Coastguard Worker
99*35238bceSAndroid Build Coastguard Worker namespace
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker class AutoFbo
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker public:
AutoFbo(const glw::Functions & gl)105*35238bceSAndroid Build Coastguard Worker AutoFbo(const glw::Functions &gl) : m_gl(gl), m_fbo(0)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker }
108*35238bceSAndroid Build Coastguard Worker
~AutoFbo(void)109*35238bceSAndroid Build Coastguard Worker ~AutoFbo(void)
110*35238bceSAndroid Build Coastguard Worker {
111*35238bceSAndroid Build Coastguard Worker if (m_fbo)
112*35238bceSAndroid Build Coastguard Worker m_gl.deleteFramebuffers(1, &m_fbo);
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker
gen(void)115*35238bceSAndroid Build Coastguard Worker void gen(void)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_fbo);
118*35238bceSAndroid Build Coastguard Worker m_gl.genFramebuffers(1, &m_fbo);
119*35238bceSAndroid Build Coastguard Worker }
120*35238bceSAndroid Build Coastguard Worker
operator *(void) const121*35238bceSAndroid Build Coastguard Worker uint32_t operator*(void) const
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker return m_fbo;
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
126*35238bceSAndroid Build Coastguard Worker private:
127*35238bceSAndroid Build Coastguard Worker const glw::Functions &m_gl;
128*35238bceSAndroid Build Coastguard Worker uint32_t m_fbo;
129*35238bceSAndroid Build Coastguard Worker };
130*35238bceSAndroid Build Coastguard Worker
131*35238bceSAndroid Build Coastguard Worker class AutoRbo
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker public:
AutoRbo(const glw::Functions & gl)134*35238bceSAndroid Build Coastguard Worker AutoRbo(const glw::Functions &gl) : m_gl(gl), m_rbo(0)
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker }
137*35238bceSAndroid Build Coastguard Worker
~AutoRbo(void)138*35238bceSAndroid Build Coastguard Worker ~AutoRbo(void)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker if (m_rbo)
141*35238bceSAndroid Build Coastguard Worker m_gl.deleteRenderbuffers(1, &m_rbo);
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
gen(void)144*35238bceSAndroid Build Coastguard Worker void gen(void)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_rbo);
147*35238bceSAndroid Build Coastguard Worker m_gl.genRenderbuffers(1, &m_rbo);
148*35238bceSAndroid Build Coastguard Worker }
149*35238bceSAndroid Build Coastguard Worker
operator *(void) const150*35238bceSAndroid Build Coastguard Worker uint32_t operator*(void) const
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker return m_rbo;
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker
155*35238bceSAndroid Build Coastguard Worker private:
156*35238bceSAndroid Build Coastguard Worker const glw::Functions &m_gl;
157*35238bceSAndroid Build Coastguard Worker uint32_t m_rbo;
158*35238bceSAndroid Build Coastguard Worker };
159*35238bceSAndroid Build Coastguard Worker
160*35238bceSAndroid Build Coastguard Worker } // namespace
161*35238bceSAndroid Build Coastguard Worker
getDerivateFuncName(DerivateFunc func)162*35238bceSAndroid Build Coastguard Worker static const char *getDerivateFuncName(DerivateFunc func)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker switch (func)
165*35238bceSAndroid Build Coastguard Worker {
166*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDX:
167*35238bceSAndroid Build Coastguard Worker return "dFdx";
168*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDY:
169*35238bceSAndroid Build Coastguard Worker return "dFdy";
170*35238bceSAndroid Build Coastguard Worker case DERIVATE_FWIDTH:
171*35238bceSAndroid Build Coastguard Worker return "fwidth";
172*35238bceSAndroid Build Coastguard Worker default:
173*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
174*35238bceSAndroid Build Coastguard Worker return DE_NULL;
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker
getDerivateFuncCaseName(DerivateFunc func)178*35238bceSAndroid Build Coastguard Worker static const char *getDerivateFuncCaseName(DerivateFunc func)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker switch (func)
181*35238bceSAndroid Build Coastguard Worker {
182*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDX:
183*35238bceSAndroid Build Coastguard Worker return "dfdx";
184*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDY:
185*35238bceSAndroid Build Coastguard Worker return "dfdy";
186*35238bceSAndroid Build Coastguard Worker case DERIVATE_FWIDTH:
187*35238bceSAndroid Build Coastguard Worker return "fwidth";
188*35238bceSAndroid Build Coastguard Worker default:
189*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
190*35238bceSAndroid Build Coastguard Worker return DE_NULL;
191*35238bceSAndroid Build Coastguard Worker }
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker
getDerivateMask(glu::DataType type)194*35238bceSAndroid Build Coastguard Worker static inline tcu::BVec4 getDerivateMask(glu::DataType type)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker switch (type)
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
199*35238bceSAndroid Build Coastguard Worker return tcu::BVec4(true, false, false, false);
200*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC2:
201*35238bceSAndroid Build Coastguard Worker return tcu::BVec4(true, true, false, false);
202*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC3:
203*35238bceSAndroid Build Coastguard Worker return tcu::BVec4(true, true, true, false);
204*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC4:
205*35238bceSAndroid Build Coastguard Worker return tcu::BVec4(true, true, true, true);
206*35238bceSAndroid Build Coastguard Worker default:
207*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
208*35238bceSAndroid Build Coastguard Worker return tcu::BVec4(true);
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker }
211*35238bceSAndroid Build Coastguard Worker
readDerivate(const tcu::ConstPixelBufferAccess & surface,const tcu::Vec4 & derivScale,const tcu::Vec4 & derivBias,int x,int y)212*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 readDerivate(const tcu::ConstPixelBufferAccess &surface, const tcu::Vec4 &derivScale,
213*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &derivBias, int x, int y)
214*35238bceSAndroid Build Coastguard Worker {
215*35238bceSAndroid Build Coastguard Worker return (surface.getPixel(x, y) - derivBias) / derivScale;
216*35238bceSAndroid Build Coastguard Worker }
217*35238bceSAndroid Build Coastguard Worker
getCompExpBits(const tcu::Vec4 & v)218*35238bceSAndroid Build Coastguard Worker static inline tcu::UVec4 getCompExpBits(const tcu::Vec4 &v)
219*35238bceSAndroid Build Coastguard Worker {
220*35238bceSAndroid Build Coastguard Worker return tcu::UVec4(tcu::Float32(v[0]).exponentBits(), tcu::Float32(v[1]).exponentBits(),
221*35238bceSAndroid Build Coastguard Worker tcu::Float32(v[2]).exponentBits(), tcu::Float32(v[3]).exponentBits());
222*35238bceSAndroid Build Coastguard Worker }
223*35238bceSAndroid Build Coastguard Worker
computeFloatingPointError(const float value,const int numAccurateBits)224*35238bceSAndroid Build Coastguard Worker float computeFloatingPointError(const float value, const int numAccurateBits)
225*35238bceSAndroid Build Coastguard Worker {
226*35238bceSAndroid Build Coastguard Worker const int numGarbageBits = 23 - numAccurateBits;
227*35238bceSAndroid Build Coastguard Worker const uint32_t mask = (1u << numGarbageBits) - 1u;
228*35238bceSAndroid Build Coastguard Worker const int exp = (tcu::Float32(value).exponent() < -3) ? -3 : tcu::Float32(value).exponent();
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker return tcu::Float32::construct(+1, exp, (1u << 23) | mask).asFloat() -
231*35238bceSAndroid Build Coastguard Worker tcu::Float32::construct(+1, exp, 1u << 23).asFloat();
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker
getNumMantissaBits(const glu::Precision precision)234*35238bceSAndroid Build Coastguard Worker static int getNumMantissaBits(const glu::Precision precision)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker switch (precision)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
239*35238bceSAndroid Build Coastguard Worker return 23;
240*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
241*35238bceSAndroid Build Coastguard Worker return 10;
242*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
243*35238bceSAndroid Build Coastguard Worker return 6;
244*35238bceSAndroid Build Coastguard Worker default:
245*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
246*35238bceSAndroid Build Coastguard Worker return 0;
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker }
249*35238bceSAndroid Build Coastguard Worker
getMinExponent(const glu::Precision precision)250*35238bceSAndroid Build Coastguard Worker static int getMinExponent(const glu::Precision precision)
251*35238bceSAndroid Build Coastguard Worker {
252*35238bceSAndroid Build Coastguard Worker switch (precision)
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
255*35238bceSAndroid Build Coastguard Worker return -126;
256*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
257*35238bceSAndroid Build Coastguard Worker return -14;
258*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
259*35238bceSAndroid Build Coastguard Worker return -8;
260*35238bceSAndroid Build Coastguard Worker default:
261*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
262*35238bceSAndroid Build Coastguard Worker return 0;
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker }
265*35238bceSAndroid Build Coastguard Worker
getSingleULPForExponent(int exp,int numMantissaBits)266*35238bceSAndroid Build Coastguard Worker static float getSingleULPForExponent(int exp, int numMantissaBits)
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker if (numMantissaBits > 0)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numMantissaBits <= 23);
271*35238bceSAndroid Build Coastguard Worker
272*35238bceSAndroid Build Coastguard Worker const int ulpBitNdx = 23 - numMantissaBits;
273*35238bceSAndroid Build Coastguard Worker return tcu::Float32::construct(+1, exp, (1 << 23) | (1 << ulpBitNdx)).asFloat() -
274*35238bceSAndroid Build Coastguard Worker tcu::Float32::construct(+1, exp, (1 << 23)).asFloat();
275*35238bceSAndroid Build Coastguard Worker }
276*35238bceSAndroid Build Coastguard Worker else
277*35238bceSAndroid Build Coastguard Worker {
278*35238bceSAndroid Build Coastguard Worker DE_ASSERT(numMantissaBits == 0);
279*35238bceSAndroid Build Coastguard Worker return tcu::Float32::construct(+1, exp, (1 << 23)).asFloat();
280*35238bceSAndroid Build Coastguard Worker }
281*35238bceSAndroid Build Coastguard Worker }
282*35238bceSAndroid Build Coastguard Worker
getSingleULPForValue(float value,int numMantissaBits)283*35238bceSAndroid Build Coastguard Worker static float getSingleULPForValue(float value, int numMantissaBits)
284*35238bceSAndroid Build Coastguard Worker {
285*35238bceSAndroid Build Coastguard Worker const int exp = tcu::Float32(value).exponent();
286*35238bceSAndroid Build Coastguard Worker return getSingleULPForExponent(exp, numMantissaBits);
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker
convertFloatFlushToZeroRtn(float value,int minExponent,int numAccurateBits)289*35238bceSAndroid Build Coastguard Worker static float convertFloatFlushToZeroRtn(float value, int minExponent, int numAccurateBits)
290*35238bceSAndroid Build Coastguard Worker {
291*35238bceSAndroid Build Coastguard Worker if (value == 0.0f)
292*35238bceSAndroid Build Coastguard Worker {
293*35238bceSAndroid Build Coastguard Worker return 0.0f;
294*35238bceSAndroid Build Coastguard Worker }
295*35238bceSAndroid Build Coastguard Worker else
296*35238bceSAndroid Build Coastguard Worker {
297*35238bceSAndroid Build Coastguard Worker const tcu::Float32 inputFloat = tcu::Float32(value);
298*35238bceSAndroid Build Coastguard Worker const int numTruncatedBits = 23 - numAccurateBits;
299*35238bceSAndroid Build Coastguard Worker const uint32_t truncMask = (1u << numTruncatedBits) - 1u;
300*35238bceSAndroid Build Coastguard Worker
301*35238bceSAndroid Build Coastguard Worker if (value > 0.0f)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker if (value > 0.0f && tcu::Float32(value).exponent() < minExponent)
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker // flush to zero if possible
306*35238bceSAndroid Build Coastguard Worker return 0.0f;
307*35238bceSAndroid Build Coastguard Worker }
308*35238bceSAndroid Build Coastguard Worker else
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker // just mask away non-representable bits
311*35238bceSAndroid Build Coastguard Worker return tcu::Float32::construct(+1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask).asFloat();
312*35238bceSAndroid Build Coastguard Worker }
313*35238bceSAndroid Build Coastguard Worker }
314*35238bceSAndroid Build Coastguard Worker else
315*35238bceSAndroid Build Coastguard Worker {
316*35238bceSAndroid Build Coastguard Worker if (inputFloat.mantissa() & truncMask)
317*35238bceSAndroid Build Coastguard Worker {
318*35238bceSAndroid Build Coastguard Worker // decrement one ulp if truncated bits are non-zero (i.e. if value is not representable)
319*35238bceSAndroid Build Coastguard Worker return tcu::Float32::construct(-1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask)
320*35238bceSAndroid Build Coastguard Worker .asFloat() -
321*35238bceSAndroid Build Coastguard Worker getSingleULPForExponent(inputFloat.exponent(), numAccurateBits);
322*35238bceSAndroid Build Coastguard Worker }
323*35238bceSAndroid Build Coastguard Worker else
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker // value is representable, no need to do anything
326*35238bceSAndroid Build Coastguard Worker return value;
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker }
329*35238bceSAndroid Build Coastguard Worker }
330*35238bceSAndroid Build Coastguard Worker }
331*35238bceSAndroid Build Coastguard Worker
convertFloatFlushToZeroRtp(float value,int minExponent,int numAccurateBits)332*35238bceSAndroid Build Coastguard Worker static float convertFloatFlushToZeroRtp(float value, int minExponent, int numAccurateBits)
333*35238bceSAndroid Build Coastguard Worker {
334*35238bceSAndroid Build Coastguard Worker return -convertFloatFlushToZeroRtn(-value, minExponent, numAccurateBits);
335*35238bceSAndroid Build Coastguard Worker }
336*35238bceSAndroid Build Coastguard Worker
addErrorUlp(float value,float numUlps,int numMantissaBits)337*35238bceSAndroid Build Coastguard Worker static float addErrorUlp(float value, float numUlps, int numMantissaBits)
338*35238bceSAndroid Build Coastguard Worker {
339*35238bceSAndroid Build Coastguard Worker return value + numUlps * getSingleULPForValue(value, numMantissaBits);
340*35238bceSAndroid Build Coastguard Worker }
341*35238bceSAndroid Build Coastguard Worker
342*35238bceSAndroid Build Coastguard Worker enum
343*35238bceSAndroid Build Coastguard Worker {
344*35238bceSAndroid Build Coastguard Worker INTERPOLATION_LOST_BITS = 3, // number mantissa of bits allowed to be lost in varying interpolation
345*35238bceSAndroid Build Coastguard Worker };
346*35238bceSAndroid Build Coastguard Worker
getInterpolationLostBitsWarning(const glu::Precision precision)347*35238bceSAndroid Build Coastguard Worker static int getInterpolationLostBitsWarning(const glu::Precision precision)
348*35238bceSAndroid Build Coastguard Worker {
349*35238bceSAndroid Build Coastguard Worker // number mantissa of bits allowed to be lost in varying interpolation
350*35238bceSAndroid Build Coastguard Worker switch (precision)
351*35238bceSAndroid Build Coastguard Worker {
352*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
353*35238bceSAndroid Build Coastguard Worker return 9;
354*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
355*35238bceSAndroid Build Coastguard Worker return 3;
356*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
357*35238bceSAndroid Build Coastguard Worker return 3;
358*35238bceSAndroid Build Coastguard Worker default:
359*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
360*35238bceSAndroid Build Coastguard Worker return 0;
361*35238bceSAndroid Build Coastguard Worker }
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker
getDerivateThreshold(const glu::Precision precision,const tcu::Vec4 & valueMin,const tcu::Vec4 & valueMax,const tcu::Vec4 & expectedDerivate)364*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 getDerivateThreshold(const glu::Precision precision, const tcu::Vec4 &valueMin,
365*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &valueMax, const tcu::Vec4 &expectedDerivate)
366*35238bceSAndroid Build Coastguard Worker {
367*35238bceSAndroid Build Coastguard Worker const int baseBits = getNumMantissaBits(precision);
368*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 derivExp = getCompExpBits(expectedDerivate);
369*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 maxValueExp = max(getCompExpBits(valueMin), getCompExpBits(valueMax));
370*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 numBitsLost = maxValueExp - min(maxValueExp, derivExp);
371*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 numAccurateBits =
372*35238bceSAndroid Build Coastguard Worker max(baseBits - numBitsLost.asInt() - (int)INTERPOLATION_LOST_BITS, tcu::IVec4(0));
373*35238bceSAndroid Build Coastguard Worker
374*35238bceSAndroid Build Coastguard Worker return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
375*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
376*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
377*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
378*35238bceSAndroid Build Coastguard Worker }
379*35238bceSAndroid Build Coastguard Worker
getDerivateThresholdWarning(const glu::Precision precision,const tcu::Vec4 & valueMin,const tcu::Vec4 & valueMax,const tcu::Vec4 & expectedDerivate)380*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 getDerivateThresholdWarning(const glu::Precision precision, const tcu::Vec4 &valueMin,
381*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &valueMax, const tcu::Vec4 &expectedDerivate)
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker const int baseBits = getNumMantissaBits(precision);
384*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 derivExp = getCompExpBits(expectedDerivate);
385*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 maxValueExp = max(getCompExpBits(valueMin), getCompExpBits(valueMax));
386*35238bceSAndroid Build Coastguard Worker const tcu::UVec4 numBitsLost = maxValueExp - min(maxValueExp, derivExp);
387*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 numAccurateBits =
388*35238bceSAndroid Build Coastguard Worker max(baseBits - numBitsLost.asInt() - getInterpolationLostBitsWarning(precision), tcu::IVec4(0));
389*35238bceSAndroid Build Coastguard Worker
390*35238bceSAndroid Build Coastguard Worker return tcu::Vec4(computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
391*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
392*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
393*35238bceSAndroid Build Coastguard Worker computeFloatingPointError(expectedDerivate[3], numAccurateBits[3]));
394*35238bceSAndroid Build Coastguard Worker }
395*35238bceSAndroid Build Coastguard Worker
396*35238bceSAndroid Build Coastguard Worker namespace
397*35238bceSAndroid Build Coastguard Worker {
398*35238bceSAndroid Build Coastguard Worker
399*35238bceSAndroid Build Coastguard Worker struct LogVecComps
400*35238bceSAndroid Build Coastguard Worker {
401*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &v;
402*35238bceSAndroid Build Coastguard Worker int numComps;
403*35238bceSAndroid Build Coastguard Worker
LogVecCompsdeqp::gles3::Functional::__anonf22f2d770411::LogVecComps404*35238bceSAndroid Build Coastguard Worker LogVecComps(const tcu::Vec4 &v_, int numComps_) : v(v_), numComps(numComps_)
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker }
407*35238bceSAndroid Build Coastguard Worker };
408*35238bceSAndroid Build Coastguard Worker
operator <<(std::ostream & str,const LogVecComps & v)409*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &str, const LogVecComps &v)
410*35238bceSAndroid Build Coastguard Worker {
411*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(v.numComps, 1, 4));
412*35238bceSAndroid Build Coastguard Worker if (v.numComps == 1)
413*35238bceSAndroid Build Coastguard Worker return str << v.v[0];
414*35238bceSAndroid Build Coastguard Worker else if (v.numComps == 2)
415*35238bceSAndroid Build Coastguard Worker return str << v.v.toWidth<2>();
416*35238bceSAndroid Build Coastguard Worker else if (v.numComps == 3)
417*35238bceSAndroid Build Coastguard Worker return str << v.v.toWidth<3>();
418*35238bceSAndroid Build Coastguard Worker else
419*35238bceSAndroid Build Coastguard Worker return str << v.v;
420*35238bceSAndroid Build Coastguard Worker }
421*35238bceSAndroid Build Coastguard Worker
422*35238bceSAndroid Build Coastguard Worker } // namespace
423*35238bceSAndroid Build Coastguard Worker
424*35238bceSAndroid Build Coastguard Worker enum VerificationLogging
425*35238bceSAndroid Build Coastguard Worker {
426*35238bceSAndroid Build Coastguard Worker LOG_ALL = 0,
427*35238bceSAndroid Build Coastguard Worker LOG_NOTHING
428*35238bceSAndroid Build Coastguard Worker };
429*35238bceSAndroid Build Coastguard Worker
verifyConstantDerivate(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,glu::DataType dataType,const tcu::Vec4 & reference,const tcu::Vec4 & threshold,const tcu::Vec4 & scale,const tcu::Vec4 & bias,VerificationLogging logPolicy=LOG_ALL)430*35238bceSAndroid Build Coastguard Worker static qpTestResult verifyConstantDerivate(tcu::TestLog &log, const tcu::ConstPixelBufferAccess &result,
431*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess &errorMask, glu::DataType dataType,
432*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &reference, const tcu::Vec4 &threshold,
433*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &scale, const tcu::Vec4 &bias,
434*35238bceSAndroid Build Coastguard Worker VerificationLogging logPolicy = LOG_ALL)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker const int numComps = glu::getDataTypeFloatScalars(dataType);
437*35238bceSAndroid Build Coastguard Worker const tcu::BVec4 mask = tcu::logicalNot(getDerivateMask(dataType));
438*35238bceSAndroid Build Coastguard Worker int numFailedPixels = 0;
439*35238bceSAndroid Build Coastguard Worker
440*35238bceSAndroid Build Coastguard Worker if (logPolicy == LOG_ALL)
441*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Expecting " << LogVecComps(reference, numComps) << " with threshold "
442*35238bceSAndroid Build Coastguard Worker << LogVecComps(threshold, numComps) << TestLog::EndMessage;
443*35238bceSAndroid Build Coastguard Worker
444*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < result.getHeight(); y++)
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < result.getWidth(); x++)
447*35238bceSAndroid Build Coastguard Worker {
448*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 resDerivate = readDerivate(result, scale, bias, x, y);
449*35238bceSAndroid Build Coastguard Worker const bool isOk =
450*35238bceSAndroid Build Coastguard Worker tcu::allEqual(tcu::logicalOr(tcu::lessThanEqual(tcu::abs(reference - resDerivate), threshold), mask),
451*35238bceSAndroid Build Coastguard Worker tcu::BVec4(true));
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker if (!isOk)
454*35238bceSAndroid Build Coastguard Worker {
455*35238bceSAndroid Build Coastguard Worker if (numFailedPixels < MAX_FAILED_MESSAGES && logPolicy == LOG_ALL)
456*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "FAIL: got " << LogVecComps(resDerivate, numComps)
457*35238bceSAndroid Build Coastguard Worker << ", diff = " << LogVecComps(tcu::abs(reference - resDerivate), numComps) << ", at x = " << x
458*35238bceSAndroid Build Coastguard Worker << ", y = " << y << TestLog::EndMessage;
459*35238bceSAndroid Build Coastguard Worker numFailedPixels += 1;
460*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(tcu::RGBA::red().toVec(), x, y);
461*35238bceSAndroid Build Coastguard Worker }
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker }
464*35238bceSAndroid Build Coastguard Worker
465*35238bceSAndroid Build Coastguard Worker if (numFailedPixels >= MAX_FAILED_MESSAGES && logPolicy == LOG_ALL)
466*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "..." << TestLog::EndMessage;
467*35238bceSAndroid Build Coastguard Worker
468*35238bceSAndroid Build Coastguard Worker if (numFailedPixels > 0 && logPolicy == LOG_ALL)
469*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;
470*35238bceSAndroid Build Coastguard Worker
471*35238bceSAndroid Build Coastguard Worker return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
472*35238bceSAndroid Build Coastguard Worker }
473*35238bceSAndroid Build Coastguard Worker
474*35238bceSAndroid Build Coastguard Worker struct Linear2DFunctionEvaluator
475*35238bceSAndroid Build Coastguard Worker {
476*35238bceSAndroid Build Coastguard Worker tcu::Matrix<float, 4, 3> matrix;
477*35238bceSAndroid Build Coastguard Worker
478*35238bceSAndroid Build Coastguard Worker // .-----.
479*35238bceSAndroid Build Coastguard Worker // | s_x |
480*35238bceSAndroid Build Coastguard Worker // M x | s_y |
481*35238bceSAndroid Build Coastguard Worker // | 1.0 |
482*35238bceSAndroid Build Coastguard Worker // '-----'
483*35238bceSAndroid Build Coastguard Worker tcu::Vec4 evaluateAt(float screenX, float screenY) const;
484*35238bceSAndroid Build Coastguard Worker };
485*35238bceSAndroid Build Coastguard Worker
evaluateAt(float screenX,float screenY) const486*35238bceSAndroid Build Coastguard Worker tcu::Vec4 Linear2DFunctionEvaluator::evaluateAt(float screenX, float screenY) const
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker const tcu::Vec3 position(screenX, screenY, 1.0f);
489*35238bceSAndroid Build Coastguard Worker return matrix * position;
490*35238bceSAndroid Build Coastguard Worker }
491*35238bceSAndroid Build Coastguard Worker
reverifyConstantDerivateWithFlushRelaxations(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,glu::DataType dataType,glu::Precision precision,const tcu::Vec4 & derivScale,const tcu::Vec4 & derivBias,const tcu::Vec4 & surfaceThreshold,DerivateFunc derivateFunc,const Linear2DFunctionEvaluator & function)492*35238bceSAndroid Build Coastguard Worker static qpTestResult reverifyConstantDerivateWithFlushRelaxations(
493*35238bceSAndroid Build Coastguard Worker tcu::TestLog &log, const tcu::ConstPixelBufferAccess &result, const tcu::PixelBufferAccess &errorMask,
494*35238bceSAndroid Build Coastguard Worker glu::DataType dataType, glu::Precision precision, const tcu::Vec4 &derivScale, const tcu::Vec4 &derivBias,
495*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &surfaceThreshold, DerivateFunc derivateFunc, const Linear2DFunctionEvaluator &function)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker DE_ASSERT(result.getWidth() == errorMask.getWidth());
498*35238bceSAndroid Build Coastguard Worker DE_ASSERT(result.getHeight() == errorMask.getHeight());
499*35238bceSAndroid Build Coastguard Worker DE_ASSERT(derivateFunc == DERIVATE_DFDX || derivateFunc == DERIVATE_DFDY);
500*35238bceSAndroid Build Coastguard Worker
501*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 red(255, 0, 0, 255);
502*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 green(0, 255, 0, 255);
503*35238bceSAndroid Build Coastguard Worker const float divisionErrorUlps = 2.5f;
504*35238bceSAndroid Build Coastguard Worker
505*35238bceSAndroid Build Coastguard Worker const int numComponents = glu::getDataTypeFloatScalars(dataType);
506*35238bceSAndroid Build Coastguard Worker const int numBits = getNumMantissaBits(precision);
507*35238bceSAndroid Build Coastguard Worker const int minExponent = getMinExponent(precision);
508*35238bceSAndroid Build Coastguard Worker
509*35238bceSAndroid Build Coastguard Worker const int numVaryingSampleBits = numBits - INTERPOLATION_LOST_BITS;
510*35238bceSAndroid Build Coastguard Worker int numFailedPixels = 0;
511*35238bceSAndroid Build Coastguard Worker
512*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask, green);
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker // search for failed pixels
515*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < result.getHeight(); ++y)
516*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < result.getWidth(); ++x)
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker // flushToZero?(f2z?(functionValueCurrent) - f2z?(functionValueBefore))
519*35238bceSAndroid Build Coastguard Worker // flushToZero? ( ------------------------------------------------------------------------ +- 2.5 ULP )
520*35238bceSAndroid Build Coastguard Worker // dx
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 resultDerivative = readDerivate(result, derivScale, derivBias, x, y);
523*35238bceSAndroid Build Coastguard Worker
524*35238bceSAndroid Build Coastguard Worker // sample at the front of the back pixel and the back of the front pixel to cover the whole area of
525*35238bceSAndroid Build Coastguard Worker // legal sample positions. In general case this is NOT OK, but we know that the target function is
526*35238bceSAndroid Build Coastguard Worker // (mostly*) linear which allows us to take the sample points at arbitrary points. This gets us the
527*35238bceSAndroid Build Coastguard Worker // maximum difference possible in exponents which are used in error bound calculations.
528*35238bceSAndroid Build Coastguard Worker // * non-linearity may happen around zero or with very high function values due to subnorms not
529*35238bceSAndroid Build Coastguard Worker // behaving well.
530*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 functionValueForward = (derivateFunc == DERIVATE_DFDX) ?
531*35238bceSAndroid Build Coastguard Worker (function.evaluateAt((float)x + 2.0f, (float)y + 0.5f)) :
532*35238bceSAndroid Build Coastguard Worker (function.evaluateAt((float)x + 0.5f, (float)y + 2.0f));
533*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 functionValueBackward = (derivateFunc == DERIVATE_DFDX) ?
534*35238bceSAndroid Build Coastguard Worker (function.evaluateAt((float)x - 1.0f, (float)y + 0.5f)) :
535*35238bceSAndroid Build Coastguard Worker (function.evaluateAt((float)x + 0.5f, (float)y - 1.0f));
536*35238bceSAndroid Build Coastguard Worker
537*35238bceSAndroid Build Coastguard Worker bool anyComponentFailed = false;
538*35238bceSAndroid Build Coastguard Worker
539*35238bceSAndroid Build Coastguard Worker // check components separately
540*35238bceSAndroid Build Coastguard Worker for (int c = 0; c < numComponents; ++c)
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker // Simulate interpolation. Add allowed interpolation error and round to target precision. Allow one half ULP (i.e. correct rounding)
543*35238bceSAndroid Build Coastguard Worker const tcu::Interval forwardComponent(
544*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtn(addErrorUlp((float)functionValueForward[c], -0.5f, numVaryingSampleBits),
545*35238bceSAndroid Build Coastguard Worker minExponent, numBits),
546*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtp(addErrorUlp((float)functionValueForward[c], +0.5f, numVaryingSampleBits),
547*35238bceSAndroid Build Coastguard Worker minExponent, numBits));
548*35238bceSAndroid Build Coastguard Worker const tcu::Interval backwardComponent(
549*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtn(
550*35238bceSAndroid Build Coastguard Worker addErrorUlp((float)functionValueBackward[c], -0.5f, numVaryingSampleBits), minExponent,
551*35238bceSAndroid Build Coastguard Worker numBits),
552*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtp(
553*35238bceSAndroid Build Coastguard Worker addErrorUlp((float)functionValueBackward[c], +0.5f, numVaryingSampleBits), minExponent,
554*35238bceSAndroid Build Coastguard Worker numBits));
555*35238bceSAndroid Build Coastguard Worker const int maxValueExp = de::max(de::max(tcu::Float32(forwardComponent.lo()).exponent(),
556*35238bceSAndroid Build Coastguard Worker tcu::Float32(forwardComponent.hi()).exponent()),
557*35238bceSAndroid Build Coastguard Worker de::max(tcu::Float32(backwardComponent.lo()).exponent(),
558*35238bceSAndroid Build Coastguard Worker tcu::Float32(backwardComponent.hi()).exponent()));
559*35238bceSAndroid Build Coastguard Worker
560*35238bceSAndroid Build Coastguard Worker // subtraction in numerator will likely cause a cancellation of the most
561*35238bceSAndroid Build Coastguard Worker // significant bits. Apply error bounds.
562*35238bceSAndroid Build Coastguard Worker
563*35238bceSAndroid Build Coastguard Worker const tcu::Interval numerator(forwardComponent - backwardComponent);
564*35238bceSAndroid Build Coastguard Worker const int numeratorLoExp = tcu::Float32(numerator.lo()).exponent();
565*35238bceSAndroid Build Coastguard Worker const int numeratorHiExp = tcu::Float32(numerator.hi()).exponent();
566*35238bceSAndroid Build Coastguard Worker const int numeratorLoBitsLost = de::max(
567*35238bceSAndroid Build Coastguard Worker 0,
568*35238bceSAndroid Build Coastguard Worker maxValueExp -
569*35238bceSAndroid Build Coastguard Worker numeratorLoExp); //!< must clamp to zero since if forward and backward components have different
570*35238bceSAndroid Build Coastguard Worker const int numeratorHiBitsLost = de::max(
571*35238bceSAndroid Build Coastguard Worker 0, maxValueExp - numeratorHiExp); //!< sign, numerator might have larger exponent than its operands.
572*35238bceSAndroid Build Coastguard Worker const int numeratorLoBits = de::max(0, numBits - numeratorLoBitsLost);
573*35238bceSAndroid Build Coastguard Worker const int numeratorHiBits = de::max(0, numBits - numeratorHiBitsLost);
574*35238bceSAndroid Build Coastguard Worker
575*35238bceSAndroid Build Coastguard Worker const tcu::Interval numeratorRange(
576*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtn((float)numerator.lo(), minExponent, numeratorLoBits),
577*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtp((float)numerator.hi(), minExponent, numeratorHiBits));
578*35238bceSAndroid Build Coastguard Worker
579*35238bceSAndroid Build Coastguard Worker const tcu::Interval divisionRange =
580*35238bceSAndroid Build Coastguard Worker numeratorRange /
581*35238bceSAndroid Build Coastguard Worker 3.0f; // legal sample area is anywhere within this and neighboring pixels (i.e. size = 3)
582*35238bceSAndroid Build Coastguard Worker const tcu::Interval divisionResultRange(
583*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtn(addErrorUlp((float)divisionRange.lo(), -divisionErrorUlps, numBits),
584*35238bceSAndroid Build Coastguard Worker minExponent, numBits),
585*35238bceSAndroid Build Coastguard Worker convertFloatFlushToZeroRtp(addErrorUlp((float)divisionRange.hi(), +divisionErrorUlps, numBits),
586*35238bceSAndroid Build Coastguard Worker minExponent, numBits));
587*35238bceSAndroid Build Coastguard Worker const tcu::Interval finalResultRange(divisionResultRange.lo() - surfaceThreshold[c],
588*35238bceSAndroid Build Coastguard Worker divisionResultRange.hi() + surfaceThreshold[c]);
589*35238bceSAndroid Build Coastguard Worker
590*35238bceSAndroid Build Coastguard Worker if (resultDerivative[c] >= finalResultRange.lo() && resultDerivative[c] <= finalResultRange.hi())
591*35238bceSAndroid Build Coastguard Worker {
592*35238bceSAndroid Build Coastguard Worker // value ok
593*35238bceSAndroid Build Coastguard Worker }
594*35238bceSAndroid Build Coastguard Worker else
595*35238bceSAndroid Build Coastguard Worker {
596*35238bceSAndroid Build Coastguard Worker if (numFailedPixels < MAX_FAILED_MESSAGES)
597*35238bceSAndroid Build Coastguard Worker log << tcu::TestLog::Message << "Error in pixel at " << x << ", " << y << " with component "
598*35238bceSAndroid Build Coastguard Worker << c << " (channel " << ("rgba"[c]) << ")\n"
599*35238bceSAndroid Build Coastguard Worker << "\tGot pixel value " << result.getPixelInt(x, y) << "\n"
600*35238bceSAndroid Build Coastguard Worker << "\t\tdFd" << ((derivateFunc == DERIVATE_DFDX) ? ('x') : ('y'))
601*35238bceSAndroid Build Coastguard Worker << " ~= " << resultDerivative[c] << "\n"
602*35238bceSAndroid Build Coastguard Worker << "\t\tdifference to a valid range: "
603*35238bceSAndroid Build Coastguard Worker << ((resultDerivative[c] < finalResultRange.lo()) ? ("-") : ("+"))
604*35238bceSAndroid Build Coastguard Worker << ((resultDerivative[c] < finalResultRange.lo()) ?
605*35238bceSAndroid Build Coastguard Worker (finalResultRange.lo() - resultDerivative[c]) :
606*35238bceSAndroid Build Coastguard Worker (resultDerivative[c] - finalResultRange.hi()))
607*35238bceSAndroid Build Coastguard Worker << "\n"
608*35238bceSAndroid Build Coastguard Worker << "\tDerivative value range:\n"
609*35238bceSAndroid Build Coastguard Worker << "\t\tMin: " << finalResultRange.lo() << "\n"
610*35238bceSAndroid Build Coastguard Worker << "\t\tMax: " << finalResultRange.hi() << "\n"
611*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
612*35238bceSAndroid Build Coastguard Worker
613*35238bceSAndroid Build Coastguard Worker ++numFailedPixels;
614*35238bceSAndroid Build Coastguard Worker anyComponentFailed = true;
615*35238bceSAndroid Build Coastguard Worker }
616*35238bceSAndroid Build Coastguard Worker }
617*35238bceSAndroid Build Coastguard Worker
618*35238bceSAndroid Build Coastguard Worker if (anyComponentFailed)
619*35238bceSAndroid Build Coastguard Worker errorMask.setPixel(red, x, y);
620*35238bceSAndroid Build Coastguard Worker }
621*35238bceSAndroid Build Coastguard Worker
622*35238bceSAndroid Build Coastguard Worker if (numFailedPixels >= MAX_FAILED_MESSAGES)
623*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "..." << TestLog::EndMessage;
624*35238bceSAndroid Build Coastguard Worker
625*35238bceSAndroid Build Coastguard Worker if (numFailedPixels > 0)
626*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "FAIL: found " << numFailedPixels << " failed pixels" << TestLog::EndMessage;
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker return (numFailedPixels == 0) ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
629*35238bceSAndroid Build Coastguard Worker }
630*35238bceSAndroid Build Coastguard Worker
631*35238bceSAndroid Build Coastguard Worker // TriangleDerivateCase
632*35238bceSAndroid Build Coastguard Worker
633*35238bceSAndroid Build Coastguard Worker class TriangleDerivateCase : public TestCase
634*35238bceSAndroid Build Coastguard Worker {
635*35238bceSAndroid Build Coastguard Worker public:
636*35238bceSAndroid Build Coastguard Worker TriangleDerivateCase(Context &context, const char *name, const char *description);
637*35238bceSAndroid Build Coastguard Worker ~TriangleDerivateCase(void);
638*35238bceSAndroid Build Coastguard Worker
639*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void);
640*35238bceSAndroid Build Coastguard Worker
641*35238bceSAndroid Build Coastguard Worker protected:
setupRenderState(uint32_t program)642*35238bceSAndroid Build Coastguard Worker virtual void setupRenderState(uint32_t program)
643*35238bceSAndroid Build Coastguard Worker {
644*35238bceSAndroid Build Coastguard Worker DE_UNREF(program);
645*35238bceSAndroid Build Coastguard Worker }
646*35238bceSAndroid Build Coastguard Worker virtual qpTestResult verify(const tcu::ConstPixelBufferAccess &result,
647*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess &errorMask) = DE_NULL;
648*35238bceSAndroid Build Coastguard Worker
649*35238bceSAndroid Build Coastguard Worker tcu::IVec2 getViewportSize(void) const;
650*35238bceSAndroid Build Coastguard Worker tcu::Vec4 getSurfaceThreshold(void) const;
651*35238bceSAndroid Build Coastguard Worker
652*35238bceSAndroid Build Coastguard Worker glu::DataType m_dataType;
653*35238bceSAndroid Build Coastguard Worker glu::Precision m_precision;
654*35238bceSAndroid Build Coastguard Worker
655*35238bceSAndroid Build Coastguard Worker glu::DataType m_coordDataType;
656*35238bceSAndroid Build Coastguard Worker glu::Precision m_coordPrecision;
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker std::string m_fragmentSrc;
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_coordMin;
661*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_coordMax;
662*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_derivScale;
663*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_derivBias;
664*35238bceSAndroid Build Coastguard Worker
665*35238bceSAndroid Build Coastguard Worker SurfaceType m_surfaceType;
666*35238bceSAndroid Build Coastguard Worker int m_numSamples;
667*35238bceSAndroid Build Coastguard Worker uint32_t m_hint;
668*35238bceSAndroid Build Coastguard Worker
669*35238bceSAndroid Build Coastguard Worker bool m_useAsymmetricCoords;
670*35238bceSAndroid Build Coastguard Worker };
671*35238bceSAndroid Build Coastguard Worker
TriangleDerivateCase(Context & context,const char * name,const char * description)672*35238bceSAndroid Build Coastguard Worker TriangleDerivateCase::TriangleDerivateCase(Context &context, const char *name, const char *description)
673*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
674*35238bceSAndroid Build Coastguard Worker , m_dataType(glu::TYPE_LAST)
675*35238bceSAndroid Build Coastguard Worker , m_precision(glu::PRECISION_LAST)
676*35238bceSAndroid Build Coastguard Worker , m_coordDataType(glu::TYPE_LAST)
677*35238bceSAndroid Build Coastguard Worker , m_coordPrecision(glu::PRECISION_LAST)
678*35238bceSAndroid Build Coastguard Worker , m_surfaceType(SURFACETYPE_DEFAULT_FRAMEBUFFER)
679*35238bceSAndroid Build Coastguard Worker , m_numSamples(0)
680*35238bceSAndroid Build Coastguard Worker , m_hint(GL_DONT_CARE)
681*35238bceSAndroid Build Coastguard Worker , m_useAsymmetricCoords(false)
682*35238bceSAndroid Build Coastguard Worker {
683*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER || m_numSamples == 0);
684*35238bceSAndroid Build Coastguard Worker }
685*35238bceSAndroid Build Coastguard Worker
~TriangleDerivateCase(void)686*35238bceSAndroid Build Coastguard Worker TriangleDerivateCase::~TriangleDerivateCase(void)
687*35238bceSAndroid Build Coastguard Worker {
688*35238bceSAndroid Build Coastguard Worker TriangleDerivateCase::deinit();
689*35238bceSAndroid Build Coastguard Worker }
690*35238bceSAndroid Build Coastguard Worker
genVertexSource(glu::DataType coordType,glu::Precision precision)691*35238bceSAndroid Build Coastguard Worker static std::string genVertexSource(glu::DataType coordType, glu::Precision precision)
692*35238bceSAndroid Build Coastguard Worker {
693*35238bceSAndroid Build Coastguard Worker DE_ASSERT(glu::isDataTypeFloatOrVec(coordType));
694*35238bceSAndroid Build Coastguard Worker
695*35238bceSAndroid Build Coastguard Worker const char *vertexTmpl = "#version 300 es\n"
696*35238bceSAndroid Build Coastguard Worker "in highp vec4 a_position;\n"
697*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} a_coord;\n"
698*35238bceSAndroid Build Coastguard Worker "out ${PRECISION} ${DATATYPE} v_coord;\n"
699*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
700*35238bceSAndroid Build Coastguard Worker "{\n"
701*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
702*35238bceSAndroid Build Coastguard Worker " v_coord = a_coord;\n"
703*35238bceSAndroid Build Coastguard Worker "}\n";
704*35238bceSAndroid Build Coastguard Worker
705*35238bceSAndroid Build Coastguard Worker map<string, string> vertexParams;
706*35238bceSAndroid Build Coastguard Worker
707*35238bceSAndroid Build Coastguard Worker vertexParams["PRECISION"] = glu::getPrecisionName(precision);
708*35238bceSAndroid Build Coastguard Worker vertexParams["DATATYPE"] = glu::getDataTypeName(coordType);
709*35238bceSAndroid Build Coastguard Worker
710*35238bceSAndroid Build Coastguard Worker return tcu::StringTemplate(vertexTmpl).specialize(vertexParams);
711*35238bceSAndroid Build Coastguard Worker }
712*35238bceSAndroid Build Coastguard Worker
getViewportSize(void) const713*35238bceSAndroid Build Coastguard Worker inline tcu::IVec2 TriangleDerivateCase::getViewportSize(void) const
714*35238bceSAndroid Build Coastguard Worker {
715*35238bceSAndroid Build Coastguard Worker if (m_surfaceType == SURFACETYPE_DEFAULT_FRAMEBUFFER)
716*35238bceSAndroid Build Coastguard Worker {
717*35238bceSAndroid Build Coastguard Worker const int width = de::min<int>(m_context.getRenderTarget().getWidth(), VIEWPORT_WIDTH);
718*35238bceSAndroid Build Coastguard Worker const int height = de::min<int>(m_context.getRenderTarget().getHeight(), VIEWPORT_HEIGHT);
719*35238bceSAndroid Build Coastguard Worker return tcu::IVec2(width, height);
720*35238bceSAndroid Build Coastguard Worker }
721*35238bceSAndroid Build Coastguard Worker else
722*35238bceSAndroid Build Coastguard Worker return tcu::IVec2(FBO_WIDTH, FBO_HEIGHT);
723*35238bceSAndroid Build Coastguard Worker }
724*35238bceSAndroid Build Coastguard Worker
iterate(void)725*35238bceSAndroid Build Coastguard Worker TriangleDerivateCase::IterateResult TriangleDerivateCase::iterate(void)
726*35238bceSAndroid Build Coastguard Worker {
727*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
728*35238bceSAndroid Build Coastguard Worker const glu::ShaderProgram program(
729*35238bceSAndroid Build Coastguard Worker m_context.getRenderContext(),
730*35238bceSAndroid Build Coastguard Worker glu::makeVtxFragSources(genVertexSource(m_coordDataType, m_coordPrecision), m_fragmentSrc));
731*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()) ^ 0xbbc24);
732*35238bceSAndroid Build Coastguard Worker const bool useFbo = m_surfaceType != SURFACETYPE_DEFAULT_FRAMEBUFFER;
733*35238bceSAndroid Build Coastguard Worker const uint32_t fboFormat = m_surfaceType == SURFACETYPE_FLOAT_FBO ? GL_RGBA32UI : GL_RGBA8;
734*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize = getViewportSize();
735*35238bceSAndroid Build Coastguard Worker const int viewportX = useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getWidth() - viewportSize.x());
736*35238bceSAndroid Build Coastguard Worker const int viewportY = useFbo ? 0 : rnd.getInt(0, m_context.getRenderTarget().getHeight() - viewportSize.y());
737*35238bceSAndroid Build Coastguard Worker AutoFbo fbo(gl);
738*35238bceSAndroid Build Coastguard Worker AutoRbo rbo(gl);
739*35238bceSAndroid Build Coastguard Worker tcu::TextureLevel result;
740*35238bceSAndroid Build Coastguard Worker
741*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << program;
742*35238bceSAndroid Build Coastguard Worker
743*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
744*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Compile failed");
745*35238bceSAndroid Build Coastguard Worker
746*35238bceSAndroid Build Coastguard Worker if (useFbo)
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "Rendering to FBO, format = " << glu::getTextureFormatStr(fboFormat)
749*35238bceSAndroid Build Coastguard Worker << ", samples = " << m_numSamples << TestLog::EndMessage;
750*35238bceSAndroid Build Coastguard Worker
751*35238bceSAndroid Build Coastguard Worker fbo.gen();
752*35238bceSAndroid Build Coastguard Worker rbo.gen();
753*35238bceSAndroid Build Coastguard Worker
754*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, *rbo);
755*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_numSamples, fboFormat, viewportSize.x(), viewportSize.y());
756*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
757*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
758*35238bceSAndroid Build Coastguard Worker TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
759*35238bceSAndroid Build Coastguard Worker }
760*35238bceSAndroid Build Coastguard Worker else
761*35238bceSAndroid Build Coastguard Worker {
762*35238bceSAndroid Build Coastguard Worker const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
763*35238bceSAndroid Build Coastguard Worker
764*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "Rendering to default framebuffer\n"
765*35238bceSAndroid Build Coastguard Worker << "\tColor depth: R=" << pixelFormat.redBits << ", G=" << pixelFormat.greenBits
766*35238bceSAndroid Build Coastguard Worker << ", B=" << pixelFormat.blueBits << ", A=" << pixelFormat.alphaBits << TestLog::EndMessage;
767*35238bceSAndroid Build Coastguard Worker }
768*35238bceSAndroid Build Coastguard Worker
769*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Message << "in: " << m_coordMin << " -> " << m_coordMax << "\n"
770*35238bceSAndroid Build Coastguard Worker << (m_useAsymmetricCoords ? "v_coord.x = in.x * (x+y)/2\n" : "v_coord.x = in.x * x\n")
771*35238bceSAndroid Build Coastguard Worker << (m_useAsymmetricCoords ? "v_coord.y = in.y * (x+y)/2\n" : "v_coord.y = in.y * y\n")
772*35238bceSAndroid Build Coastguard Worker << "v_coord.z = in.z * (x+y)/2\n"
773*35238bceSAndroid Build Coastguard Worker << "v_coord.w = in.w * (1 - (x+y)/2)\n"
774*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage << TestLog::Message << "u_scale: " << m_derivScale
775*35238bceSAndroid Build Coastguard Worker << ", u_bias: " << m_derivBias << " (displayed values have scale/bias removed)"
776*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage << TestLog::Message << "Viewport: " << viewportSize.x() << "x"
777*35238bceSAndroid Build Coastguard Worker << viewportSize.y() << TestLog::EndMessage << TestLog::Message
778*35238bceSAndroid Build Coastguard Worker << "GL_FRAGMENT_SHADER_DERIVATE_HINT: " << glu::getHintModeStr(m_hint) << TestLog::EndMessage;
779*35238bceSAndroid Build Coastguard Worker
780*35238bceSAndroid Build Coastguard Worker // Draw
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker const float positions[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
783*35238bceSAndroid Build Coastguard Worker 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
784*35238bceSAndroid Build Coastguard Worker float coords[] = {m_coordMin.x(),
785*35238bceSAndroid Build Coastguard Worker m_coordMin.y(),
786*35238bceSAndroid Build Coastguard Worker m_coordMin.z(),
787*35238bceSAndroid Build Coastguard Worker m_coordMax.w(),
788*35238bceSAndroid Build Coastguard Worker m_coordMin.x(),
789*35238bceSAndroid Build Coastguard Worker m_coordMax.y(),
790*35238bceSAndroid Build Coastguard Worker (m_coordMin.z() + m_coordMax.z()) * 0.5f,
791*35238bceSAndroid Build Coastguard Worker (m_coordMin.w() + m_coordMax.w()) * 0.5f,
792*35238bceSAndroid Build Coastguard Worker m_coordMax.x(),
793*35238bceSAndroid Build Coastguard Worker m_coordMin.y(),
794*35238bceSAndroid Build Coastguard Worker (m_coordMin.z() + m_coordMax.z()) * 0.5f,
795*35238bceSAndroid Build Coastguard Worker (m_coordMin.w() + m_coordMax.w()) * 0.5f,
796*35238bceSAndroid Build Coastguard Worker m_coordMax.x(),
797*35238bceSAndroid Build Coastguard Worker m_coordMax.y(),
798*35238bceSAndroid Build Coastguard Worker m_coordMax.z(),
799*35238bceSAndroid Build Coastguard Worker m_coordMin.w()};
800*35238bceSAndroid Build Coastguard Worker
801*35238bceSAndroid Build Coastguard Worker // For linear tests we want varying data x and y to vary along both axes
802*35238bceSAndroid Build Coastguard Worker // to get nonzero x for dfdy and nonzero y for dfdx. To make the gradient
803*35238bceSAndroid Build Coastguard Worker // the same for both triangles we set vertices 2 and 3 to middle values.
804*35238bceSAndroid Build Coastguard Worker // This way the values go from min -> (max+min) / 2 or (max+min) / 2 -> max
805*35238bceSAndroid Build Coastguard Worker // depending on the triangle, but the derivative is the same for both.
806*35238bceSAndroid Build Coastguard Worker if (m_useAsymmetricCoords)
807*35238bceSAndroid Build Coastguard Worker {
808*35238bceSAndroid Build Coastguard Worker coords[4] = coords[8] = (m_coordMin.x() + m_coordMax.x()) * 0.5f;
809*35238bceSAndroid Build Coastguard Worker coords[5] = coords[9] = (m_coordMin.y() + m_coordMax.y()) * 0.5f;
810*35238bceSAndroid Build Coastguard Worker }
811*35238bceSAndroid Build Coastguard Worker
812*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 4, 4, 0, &positions[0]),
813*35238bceSAndroid Build Coastguard Worker glu::va::Float("a_coord", 4, 4, 0, &coords[0])};
814*35238bceSAndroid Build Coastguard Worker const uint16_t indices[] = {0, 2, 1, 2, 3, 1};
815*35238bceSAndroid Build Coastguard Worker
816*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
817*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
818*35238bceSAndroid Build Coastguard Worker gl.disable(GL_DITHER);
819*35238bceSAndroid Build Coastguard Worker
820*35238bceSAndroid Build Coastguard Worker gl.useProgram(program.getProgram());
821*35238bceSAndroid Build Coastguard Worker
822*35238bceSAndroid Build Coastguard Worker {
823*35238bceSAndroid Build Coastguard Worker const int scaleLoc = gl.getUniformLocation(program.getProgram(), "u_scale");
824*35238bceSAndroid Build Coastguard Worker const int biasLoc = gl.getUniformLocation(program.getProgram(), "u_bias");
825*35238bceSAndroid Build Coastguard Worker
826*35238bceSAndroid Build Coastguard Worker switch (m_dataType)
827*35238bceSAndroid Build Coastguard Worker {
828*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT:
829*35238bceSAndroid Build Coastguard Worker gl.uniform1f(scaleLoc, m_derivScale.x());
830*35238bceSAndroid Build Coastguard Worker gl.uniform1f(biasLoc, m_derivBias.x());
831*35238bceSAndroid Build Coastguard Worker break;
832*35238bceSAndroid Build Coastguard Worker
833*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC2:
834*35238bceSAndroid Build Coastguard Worker gl.uniform2fv(scaleLoc, 1, m_derivScale.getPtr());
835*35238bceSAndroid Build Coastguard Worker gl.uniform2fv(biasLoc, 1, m_derivBias.getPtr());
836*35238bceSAndroid Build Coastguard Worker break;
837*35238bceSAndroid Build Coastguard Worker
838*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC3:
839*35238bceSAndroid Build Coastguard Worker gl.uniform3fv(scaleLoc, 1, m_derivScale.getPtr());
840*35238bceSAndroid Build Coastguard Worker gl.uniform3fv(biasLoc, 1, m_derivBias.getPtr());
841*35238bceSAndroid Build Coastguard Worker break;
842*35238bceSAndroid Build Coastguard Worker
843*35238bceSAndroid Build Coastguard Worker case glu::TYPE_FLOAT_VEC4:
844*35238bceSAndroid Build Coastguard Worker gl.uniform4fv(scaleLoc, 1, m_derivScale.getPtr());
845*35238bceSAndroid Build Coastguard Worker gl.uniform4fv(biasLoc, 1, m_derivBias.getPtr());
846*35238bceSAndroid Build Coastguard Worker break;
847*35238bceSAndroid Build Coastguard Worker
848*35238bceSAndroid Build Coastguard Worker default:
849*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
850*35238bceSAndroid Build Coastguard Worker }
851*35238bceSAndroid Build Coastguard Worker }
852*35238bceSAndroid Build Coastguard Worker
853*35238bceSAndroid Build Coastguard Worker gls::setupDefaultUniforms(m_context.getRenderContext(), program.getProgram());
854*35238bceSAndroid Build Coastguard Worker setupRenderState(program.getProgram());
855*35238bceSAndroid Build Coastguard Worker
856*35238bceSAndroid Build Coastguard Worker gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, m_hint);
857*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Setup program state");
858*35238bceSAndroid Build Coastguard Worker
859*35238bceSAndroid Build Coastguard Worker gl.viewport(viewportX, viewportY, viewportSize.x(), viewportSize.y());
860*35238bceSAndroid Build Coastguard Worker glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays),
861*35238bceSAndroid Build Coastguard Worker &vertexArrays[0], glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
862*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
863*35238bceSAndroid Build Coastguard Worker }
864*35238bceSAndroid Build Coastguard Worker
865*35238bceSAndroid Build Coastguard Worker // Read back results
866*35238bceSAndroid Build Coastguard Worker {
867*35238bceSAndroid Build Coastguard Worker const bool isMSAA = useFbo && m_numSamples > 0;
868*35238bceSAndroid Build Coastguard Worker AutoFbo resFbo(gl);
869*35238bceSAndroid Build Coastguard Worker AutoRbo resRbo(gl);
870*35238bceSAndroid Build Coastguard Worker
871*35238bceSAndroid Build Coastguard Worker // Resolve if necessary
872*35238bceSAndroid Build Coastguard Worker if (isMSAA)
873*35238bceSAndroid Build Coastguard Worker {
874*35238bceSAndroid Build Coastguard Worker resFbo.gen();
875*35238bceSAndroid Build Coastguard Worker resRbo.gen();
876*35238bceSAndroid Build Coastguard Worker
877*35238bceSAndroid Build Coastguard Worker gl.bindRenderbuffer(GL_RENDERBUFFER, *resRbo);
878*35238bceSAndroid Build Coastguard Worker gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, fboFormat, viewportSize.x(), viewportSize.y());
879*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, *resFbo);
880*35238bceSAndroid Build Coastguard Worker gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *resRbo);
881*35238bceSAndroid Build Coastguard Worker TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
882*35238bceSAndroid Build Coastguard Worker
883*35238bceSAndroid Build Coastguard Worker gl.blitFramebuffer(0, 0, viewportSize.x(), viewportSize.y(), 0, 0, viewportSize.x(), viewportSize.y(),
884*35238bceSAndroid Build Coastguard Worker GL_COLOR_BUFFER_BIT, GL_NEAREST);
885*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Resolve blit");
886*35238bceSAndroid Build Coastguard Worker
887*35238bceSAndroid Build Coastguard Worker gl.bindFramebuffer(GL_READ_FRAMEBUFFER, *resFbo);
888*35238bceSAndroid Build Coastguard Worker }
889*35238bceSAndroid Build Coastguard Worker
890*35238bceSAndroid Build Coastguard Worker switch (m_surfaceType)
891*35238bceSAndroid Build Coastguard Worker {
892*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_DEFAULT_FRAMEBUFFER:
893*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_UNORM_FBO:
894*35238bceSAndroid Build Coastguard Worker result.setStorage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
895*35238bceSAndroid Build Coastguard Worker viewportSize.x(), viewportSize.y());
896*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, result);
897*35238bceSAndroid Build Coastguard Worker break;
898*35238bceSAndroid Build Coastguard Worker
899*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_FLOAT_FBO:
900*35238bceSAndroid Build Coastguard Worker {
901*35238bceSAndroid Build Coastguard Worker const tcu::TextureFormat dataFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
902*35238bceSAndroid Build Coastguard Worker const tcu::TextureFormat transferFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
903*35238bceSAndroid Build Coastguard Worker
904*35238bceSAndroid Build Coastguard Worker result.setStorage(dataFormat, viewportSize.x(), viewportSize.y());
905*35238bceSAndroid Build Coastguard Worker glu::readPixels(m_context.getRenderContext(), viewportX, viewportY,
906*35238bceSAndroid Build Coastguard Worker tcu::PixelBufferAccess(transferFormat, result.getWidth(), result.getHeight(),
907*35238bceSAndroid Build Coastguard Worker result.getDepth(), result.getAccess().getDataPtr()));
908*35238bceSAndroid Build Coastguard Worker break;
909*35238bceSAndroid Build Coastguard Worker }
910*35238bceSAndroid Build Coastguard Worker
911*35238bceSAndroid Build Coastguard Worker default:
912*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
913*35238bceSAndroid Build Coastguard Worker }
914*35238bceSAndroid Build Coastguard Worker
915*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");
916*35238bceSAndroid Build Coastguard Worker }
917*35238bceSAndroid Build Coastguard Worker
918*35238bceSAndroid Build Coastguard Worker // Verify
919*35238bceSAndroid Build Coastguard Worker {
920*35238bceSAndroid Build Coastguard Worker tcu::Surface errorMask(result.getWidth(), result.getHeight());
921*35238bceSAndroid Build Coastguard Worker tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
922*35238bceSAndroid Build Coastguard Worker
923*35238bceSAndroid Build Coastguard Worker const qpTestResult testResult = verify(result.getAccess(), errorMask.getAccess());
924*35238bceSAndroid Build Coastguard Worker const char *failStr = "Fail";
925*35238bceSAndroid Build Coastguard Worker
926*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::ImageSet("Result", "Result images")
927*35238bceSAndroid Build Coastguard Worker << TestLog::Image("Rendered", "Rendered image", result);
928*35238bceSAndroid Build Coastguard Worker
929*35238bceSAndroid Build Coastguard Worker if (testResult != QP_TEST_RESULT_PASS)
930*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::Image("ErrorMask", "Error mask", errorMask);
931*35238bceSAndroid Build Coastguard Worker
932*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << TestLog::EndImageSet;
933*35238bceSAndroid Build Coastguard Worker
934*35238bceSAndroid Build Coastguard Worker if (testResult == QP_TEST_RESULT_PASS)
935*35238bceSAndroid Build Coastguard Worker failStr = "Pass";
936*35238bceSAndroid Build Coastguard Worker else if (testResult == QP_TEST_RESULT_QUALITY_WARNING)
937*35238bceSAndroid Build Coastguard Worker failStr = "QualityWarning";
938*35238bceSAndroid Build Coastguard Worker
939*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(testResult, failStr);
940*35238bceSAndroid Build Coastguard Worker }
941*35238bceSAndroid Build Coastguard Worker
942*35238bceSAndroid Build Coastguard Worker return STOP;
943*35238bceSAndroid Build Coastguard Worker }
944*35238bceSAndroid Build Coastguard Worker
getSurfaceThreshold(void) const945*35238bceSAndroid Build Coastguard Worker tcu::Vec4 TriangleDerivateCase::getSurfaceThreshold(void) const
946*35238bceSAndroid Build Coastguard Worker {
947*35238bceSAndroid Build Coastguard Worker switch (m_surfaceType)
948*35238bceSAndroid Build Coastguard Worker {
949*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_DEFAULT_FRAMEBUFFER:
950*35238bceSAndroid Build Coastguard Worker {
951*35238bceSAndroid Build Coastguard Worker const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
952*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 channelBits(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits,
953*35238bceSAndroid Build Coastguard Worker pixelFormat.alphaBits);
954*35238bceSAndroid Build Coastguard Worker const tcu::IVec4 intThreshold = tcu::IVec4(1) << (8 - channelBits);
955*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 normThreshold = intThreshold.asFloat() / 255.0f;
956*35238bceSAndroid Build Coastguard Worker
957*35238bceSAndroid Build Coastguard Worker return normThreshold;
958*35238bceSAndroid Build Coastguard Worker }
959*35238bceSAndroid Build Coastguard Worker
960*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_UNORM_FBO:
961*35238bceSAndroid Build Coastguard Worker return tcu::IVec4(1).asFloat() / 255.0f;
962*35238bceSAndroid Build Coastguard Worker case SURFACETYPE_FLOAT_FBO:
963*35238bceSAndroid Build Coastguard Worker return tcu::Vec4(0.0f);
964*35238bceSAndroid Build Coastguard Worker default:
965*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
966*35238bceSAndroid Build Coastguard Worker return tcu::Vec4(0.0f);
967*35238bceSAndroid Build Coastguard Worker }
968*35238bceSAndroid Build Coastguard Worker }
969*35238bceSAndroid Build Coastguard Worker
970*35238bceSAndroid Build Coastguard Worker // ConstantDerivateCase
971*35238bceSAndroid Build Coastguard Worker
972*35238bceSAndroid Build Coastguard Worker class ConstantDerivateCase : public TriangleDerivateCase
973*35238bceSAndroid Build Coastguard Worker {
974*35238bceSAndroid Build Coastguard Worker public:
975*35238bceSAndroid Build Coastguard Worker ConstantDerivateCase(Context &context, const char *name, const char *description, DerivateFunc func,
976*35238bceSAndroid Build Coastguard Worker glu::DataType type);
~ConstantDerivateCase(void)977*35238bceSAndroid Build Coastguard Worker ~ConstantDerivateCase(void)
978*35238bceSAndroid Build Coastguard Worker {
979*35238bceSAndroid Build Coastguard Worker }
980*35238bceSAndroid Build Coastguard Worker
981*35238bceSAndroid Build Coastguard Worker void init(void);
982*35238bceSAndroid Build Coastguard Worker
983*35238bceSAndroid Build Coastguard Worker protected:
984*35238bceSAndroid Build Coastguard Worker qpTestResult verify(const tcu::ConstPixelBufferAccess &result, const tcu::PixelBufferAccess &errorMask);
985*35238bceSAndroid Build Coastguard Worker
986*35238bceSAndroid Build Coastguard Worker private:
987*35238bceSAndroid Build Coastguard Worker DerivateFunc m_func;
988*35238bceSAndroid Build Coastguard Worker };
989*35238bceSAndroid Build Coastguard Worker
ConstantDerivateCase(Context & context,const char * name,const char * description,DerivateFunc func,glu::DataType type)990*35238bceSAndroid Build Coastguard Worker ConstantDerivateCase::ConstantDerivateCase(Context &context, const char *name, const char *description,
991*35238bceSAndroid Build Coastguard Worker DerivateFunc func, glu::DataType type)
992*35238bceSAndroid Build Coastguard Worker : TriangleDerivateCase(context, name, description)
993*35238bceSAndroid Build Coastguard Worker , m_func(func)
994*35238bceSAndroid Build Coastguard Worker {
995*35238bceSAndroid Build Coastguard Worker m_dataType = type;
996*35238bceSAndroid Build Coastguard Worker m_precision = glu::PRECISION_HIGHP;
997*35238bceSAndroid Build Coastguard Worker m_coordDataType = m_dataType;
998*35238bceSAndroid Build Coastguard Worker m_coordPrecision = m_precision;
999*35238bceSAndroid Build Coastguard Worker }
1000*35238bceSAndroid Build Coastguard Worker
init(void)1001*35238bceSAndroid Build Coastguard Worker void ConstantDerivateCase::init(void)
1002*35238bceSAndroid Build Coastguard Worker {
1003*35238bceSAndroid Build Coastguard Worker const char *fragmentTmpl = "#version 300 es\n"
1004*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out mediump vec4 o_color;\n"
1005*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1006*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1007*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1008*35238bceSAndroid Build Coastguard Worker "{\n"
1009*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = ${FUNC}(${VALUE}) * u_scale + u_bias;\n"
1010*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1011*35238bceSAndroid Build Coastguard Worker "}\n";
1012*35238bceSAndroid Build Coastguard Worker map<string, string> fragmentParams;
1013*35238bceSAndroid Build Coastguard Worker fragmentParams["PRECISION"] = glu::getPrecisionName(m_precision);
1014*35238bceSAndroid Build Coastguard Worker fragmentParams["DATATYPE"] = glu::getDataTypeName(m_dataType);
1015*35238bceSAndroid Build Coastguard Worker fragmentParams["FUNC"] = getDerivateFuncName(m_func);
1016*35238bceSAndroid Build Coastguard Worker fragmentParams["VALUE"] = m_dataType == glu::TYPE_FLOAT_VEC4 ? "vec4(1.0, 7.2, -1e5, 0.0)" :
1017*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec3(1e2, 8.0, 0.01)" :
1018*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec2(-0.0, 2.7)" :
1019*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "7.7";
1020*35238bceSAndroid Build Coastguard Worker fragmentParams["CAST_TO_OUTPUT"] = m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
1021*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
1022*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
1023*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "vec4(res, 0.0, 0.0, 1.0)";
1024*35238bceSAndroid Build Coastguard Worker
1025*35238bceSAndroid Build Coastguard Worker m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
1026*35238bceSAndroid Build Coastguard Worker
1027*35238bceSAndroid Build Coastguard Worker m_derivScale = tcu::Vec4(1e3f, 1e3f, 1e3f, 1e3f);
1028*35238bceSAndroid Build Coastguard Worker m_derivBias = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
1029*35238bceSAndroid Build Coastguard Worker }
1030*35238bceSAndroid Build Coastguard Worker
verify(const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask)1031*35238bceSAndroid Build Coastguard Worker qpTestResult ConstantDerivateCase::verify(const tcu::ConstPixelBufferAccess &result,
1032*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess &errorMask)
1033*35238bceSAndroid Build Coastguard Worker {
1034*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 reference(0.0f); // Derivate of constant argument should always be 0
1035*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 threshold = getSurfaceThreshold() / abs(m_derivScale);
1036*35238bceSAndroid Build Coastguard Worker
1037*35238bceSAndroid Build Coastguard Worker return verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType, reference, threshold, m_derivScale,
1038*35238bceSAndroid Build Coastguard Worker m_derivBias);
1039*35238bceSAndroid Build Coastguard Worker }
1040*35238bceSAndroid Build Coastguard Worker
1041*35238bceSAndroid Build Coastguard Worker // LinearDerivateCase
1042*35238bceSAndroid Build Coastguard Worker
1043*35238bceSAndroid Build Coastguard Worker class LinearDerivateCase : public TriangleDerivateCase
1044*35238bceSAndroid Build Coastguard Worker {
1045*35238bceSAndroid Build Coastguard Worker public:
1046*35238bceSAndroid Build Coastguard Worker LinearDerivateCase(Context &context, const char *name, const char *description, DerivateFunc func,
1047*35238bceSAndroid Build Coastguard Worker glu::DataType type, glu::Precision precision, uint32_t hint, SurfaceType surfaceType,
1048*35238bceSAndroid Build Coastguard Worker int numSamples, const char *fragmentSrcTmpl);
~LinearDerivateCase(void)1049*35238bceSAndroid Build Coastguard Worker ~LinearDerivateCase(void)
1050*35238bceSAndroid Build Coastguard Worker {
1051*35238bceSAndroid Build Coastguard Worker }
1052*35238bceSAndroid Build Coastguard Worker
1053*35238bceSAndroid Build Coastguard Worker void init(void);
1054*35238bceSAndroid Build Coastguard Worker
1055*35238bceSAndroid Build Coastguard Worker protected:
1056*35238bceSAndroid Build Coastguard Worker qpTestResult verify(const tcu::ConstPixelBufferAccess &result, const tcu::PixelBufferAccess &errorMask);
1057*35238bceSAndroid Build Coastguard Worker
1058*35238bceSAndroid Build Coastguard Worker private:
1059*35238bceSAndroid Build Coastguard Worker DerivateFunc m_func;
1060*35238bceSAndroid Build Coastguard Worker std::string m_fragmentTmpl;
1061*35238bceSAndroid Build Coastguard Worker };
1062*35238bceSAndroid Build Coastguard Worker
LinearDerivateCase(Context & context,const char * name,const char * description,DerivateFunc func,glu::DataType type,glu::Precision precision,uint32_t hint,SurfaceType surfaceType,int numSamples,const char * fragmentSrcTmpl)1063*35238bceSAndroid Build Coastguard Worker LinearDerivateCase::LinearDerivateCase(Context &context, const char *name, const char *description, DerivateFunc func,
1064*35238bceSAndroid Build Coastguard Worker glu::DataType type, glu::Precision precision, uint32_t hint,
1065*35238bceSAndroid Build Coastguard Worker SurfaceType surfaceType, int numSamples, const char *fragmentSrcTmpl)
1066*35238bceSAndroid Build Coastguard Worker : TriangleDerivateCase(context, name, description)
1067*35238bceSAndroid Build Coastguard Worker , m_func(func)
1068*35238bceSAndroid Build Coastguard Worker , m_fragmentTmpl(fragmentSrcTmpl)
1069*35238bceSAndroid Build Coastguard Worker {
1070*35238bceSAndroid Build Coastguard Worker m_dataType = type;
1071*35238bceSAndroid Build Coastguard Worker m_precision = precision;
1072*35238bceSAndroid Build Coastguard Worker m_coordDataType = m_dataType;
1073*35238bceSAndroid Build Coastguard Worker m_coordPrecision = m_precision;
1074*35238bceSAndroid Build Coastguard Worker m_hint = hint;
1075*35238bceSAndroid Build Coastguard Worker m_surfaceType = surfaceType;
1076*35238bceSAndroid Build Coastguard Worker m_numSamples = numSamples;
1077*35238bceSAndroid Build Coastguard Worker m_useAsymmetricCoords = true;
1078*35238bceSAndroid Build Coastguard Worker }
1079*35238bceSAndroid Build Coastguard Worker
init(void)1080*35238bceSAndroid Build Coastguard Worker void LinearDerivateCase::init(void)
1081*35238bceSAndroid Build Coastguard Worker {
1082*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize = getViewportSize();
1083*35238bceSAndroid Build Coastguard Worker const float w = float(viewportSize.x());
1084*35238bceSAndroid Build Coastguard Worker const float h = float(viewportSize.y());
1085*35238bceSAndroid Build Coastguard Worker const bool packToInt = m_surfaceType == SURFACETYPE_FLOAT_FBO;
1086*35238bceSAndroid Build Coastguard Worker map<string, string> fragmentParams;
1087*35238bceSAndroid Build Coastguard Worker
1088*35238bceSAndroid Build Coastguard Worker fragmentParams["OUTPUT_TYPE"] = glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
1089*35238bceSAndroid Build Coastguard Worker fragmentParams["OUTPUT_PREC"] = glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
1090*35238bceSAndroid Build Coastguard Worker fragmentParams["PRECISION"] = glu::getPrecisionName(m_precision);
1091*35238bceSAndroid Build Coastguard Worker fragmentParams["DATATYPE"] = glu::getDataTypeName(m_dataType);
1092*35238bceSAndroid Build Coastguard Worker fragmentParams["FUNC"] = getDerivateFuncName(m_func);
1093*35238bceSAndroid Build Coastguard Worker
1094*35238bceSAndroid Build Coastguard Worker if (packToInt)
1095*35238bceSAndroid Build Coastguard Worker {
1096*35238bceSAndroid Build Coastguard Worker fragmentParams["CAST_TO_OUTPUT"] =
1097*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
1098*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
1099*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
1100*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
1101*35238bceSAndroid Build Coastguard Worker }
1102*35238bceSAndroid Build Coastguard Worker else
1103*35238bceSAndroid Build Coastguard Worker {
1104*35238bceSAndroid Build Coastguard Worker fragmentParams["CAST_TO_OUTPUT"] =
1105*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
1106*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
1107*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
1108*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "vec4(res, 0.0, 0.0, 1.0)";
1109*35238bceSAndroid Build Coastguard Worker }
1110*35238bceSAndroid Build Coastguard Worker
1111*35238bceSAndroid Build Coastguard Worker m_fragmentSrc = tcu::StringTemplate(m_fragmentTmpl.c_str()).specialize(fragmentParams);
1112*35238bceSAndroid Build Coastguard Worker
1113*35238bceSAndroid Build Coastguard Worker switch (m_precision)
1114*35238bceSAndroid Build Coastguard Worker {
1115*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
1116*35238bceSAndroid Build Coastguard Worker m_coordMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
1117*35238bceSAndroid Build Coastguard Worker m_coordMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
1118*35238bceSAndroid Build Coastguard Worker break;
1119*35238bceSAndroid Build Coastguard Worker
1120*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
1121*35238bceSAndroid Build Coastguard Worker m_coordMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
1122*35238bceSAndroid Build Coastguard Worker m_coordMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
1123*35238bceSAndroid Build Coastguard Worker break;
1124*35238bceSAndroid Build Coastguard Worker
1125*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
1126*35238bceSAndroid Build Coastguard Worker m_coordMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
1127*35238bceSAndroid Build Coastguard Worker m_coordMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
1128*35238bceSAndroid Build Coastguard Worker break;
1129*35238bceSAndroid Build Coastguard Worker
1130*35238bceSAndroid Build Coastguard Worker default:
1131*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1132*35238bceSAndroid Build Coastguard Worker }
1133*35238bceSAndroid Build Coastguard Worker
1134*35238bceSAndroid Build Coastguard Worker if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
1135*35238bceSAndroid Build Coastguard Worker {
1136*35238bceSAndroid Build Coastguard Worker // No scale or bias used for accuracy.
1137*35238bceSAndroid Build Coastguard Worker m_derivScale = tcu::Vec4(1.0f);
1138*35238bceSAndroid Build Coastguard Worker m_derivBias = tcu::Vec4(0.0f);
1139*35238bceSAndroid Build Coastguard Worker }
1140*35238bceSAndroid Build Coastguard Worker else
1141*35238bceSAndroid Build Coastguard Worker {
1142*35238bceSAndroid Build Coastguard Worker // Compute scale - bias that normalizes to 0..1 range.
1143*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dx = (m_coordMax - m_coordMin) / tcu::Vec4(w, w, w * 0.5f, -w * 0.5f);
1144*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dy = (m_coordMax - m_coordMin) / tcu::Vec4(h, h, h * 0.5f, -h * 0.5f);
1145*35238bceSAndroid Build Coastguard Worker
1146*35238bceSAndroid Build Coastguard Worker switch (m_func)
1147*35238bceSAndroid Build Coastguard Worker {
1148*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDX:
1149*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / dx;
1150*35238bceSAndroid Build Coastguard Worker break;
1151*35238bceSAndroid Build Coastguard Worker
1152*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDY:
1153*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / dy;
1154*35238bceSAndroid Build Coastguard Worker break;
1155*35238bceSAndroid Build Coastguard Worker
1156*35238bceSAndroid Build Coastguard Worker case DERIVATE_FWIDTH:
1157*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
1158*35238bceSAndroid Build Coastguard Worker break;
1159*35238bceSAndroid Build Coastguard Worker
1160*35238bceSAndroid Build Coastguard Worker default:
1161*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1162*35238bceSAndroid Build Coastguard Worker }
1163*35238bceSAndroid Build Coastguard Worker
1164*35238bceSAndroid Build Coastguard Worker m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1165*35238bceSAndroid Build Coastguard Worker }
1166*35238bceSAndroid Build Coastguard Worker }
1167*35238bceSAndroid Build Coastguard Worker
verify(const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask)1168*35238bceSAndroid Build Coastguard Worker qpTestResult LinearDerivateCase::verify(const tcu::ConstPixelBufferAccess &result,
1169*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess &errorMask)
1170*35238bceSAndroid Build Coastguard Worker {
1171*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 xScale = tcu::Vec4(0.5f, 0.5f, 0.5f, -0.5f);
1172*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 yScale = tcu::Vec4(0.5f, 0.5f, 0.5f, -0.5f);
1173*35238bceSAndroid Build Coastguard Worker
1174*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 surfaceThreshold = getSurfaceThreshold() / abs(m_derivScale);
1175*35238bceSAndroid Build Coastguard Worker
1176*35238bceSAndroid Build Coastguard Worker if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
1177*35238bceSAndroid Build Coastguard Worker {
1178*35238bceSAndroid Build Coastguard Worker const bool isX = m_func == DERIVATE_DFDX;
1179*35238bceSAndroid Build Coastguard Worker const float div = isX ? float(result.getWidth()) : float(result.getHeight());
1180*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 scale = isX ? xScale : yScale;
1181*35238bceSAndroid Build Coastguard Worker tcu::Vec4 reference = ((m_coordMax - m_coordMin) / div);
1182*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 opThreshold = getDerivateThreshold(m_precision, m_coordMin, m_coordMax, reference);
1183*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 opThresholdW = getDerivateThresholdWarning(m_precision, m_coordMin, m_coordMax, reference);
1184*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 threshold = max(surfaceThreshold, opThreshold);
1185*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 thresholdW = max(surfaceThreshold, opThresholdW);
1186*35238bceSAndroid Build Coastguard Worker const int numComps = glu::getDataTypeFloatScalars(m_dataType);
1187*35238bceSAndroid Build Coastguard Worker
1188*35238bceSAndroid Build Coastguard Worker /* adjust the reference value for the correct dfdx or dfdy sample adjacency */
1189*35238bceSAndroid Build Coastguard Worker reference = reference * scale;
1190*35238bceSAndroid Build Coastguard Worker
1191*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result image.\n"
1192*35238bceSAndroid Build Coastguard Worker << "\tValid derivative is " << LogVecComps(reference, numComps) << " with threshold "
1193*35238bceSAndroid Build Coastguard Worker << LogVecComps(threshold, numComps) << tcu::TestLog::EndMessage;
1194*35238bceSAndroid Build Coastguard Worker
1195*35238bceSAndroid Build Coastguard Worker // short circuit if result is strictly within the normal value error bounds.
1196*35238bceSAndroid Build Coastguard Worker // This improves performance significantly.
1197*35238bceSAndroid Build Coastguard Worker if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType, reference, threshold,
1198*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias, LOG_NOTHING) == QP_TEST_RESULT_PASS)
1199*35238bceSAndroid Build Coastguard Worker {
1200*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "No incorrect derivatives found, result valid."
1201*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1202*35238bceSAndroid Build Coastguard Worker
1203*35238bceSAndroid Build Coastguard Worker return QP_TEST_RESULT_PASS;
1204*35238bceSAndroid Build Coastguard Worker }
1205*35238bceSAndroid Build Coastguard Worker
1206*35238bceSAndroid Build Coastguard Worker // Check with relaxed threshold value
1207*35238bceSAndroid Build Coastguard Worker if (verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType, reference, thresholdW,
1208*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias, LOG_NOTHING) == QP_TEST_RESULT_PASS)
1209*35238bceSAndroid Build Coastguard Worker {
1210*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1211*35238bceSAndroid Build Coastguard Worker << "No incorrect derivatives found, result valid with quality warning."
1212*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1213*35238bceSAndroid Build Coastguard Worker
1214*35238bceSAndroid Build Coastguard Worker return QP_TEST_RESULT_QUALITY_WARNING;
1215*35238bceSAndroid Build Coastguard Worker }
1216*35238bceSAndroid Build Coastguard Worker
1217*35238bceSAndroid Build Coastguard Worker // some pixels exceed error bounds calculated for normal values. Verify that these
1218*35238bceSAndroid Build Coastguard Worker // potentially invalid pixels are in fact valid due to (for example) subnorm flushing.
1219*35238bceSAndroid Build Coastguard Worker
1220*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1221*35238bceSAndroid Build Coastguard Worker << "Initial verification failed, verifying image by calculating accurate error bounds for "
1222*35238bceSAndroid Build Coastguard Worker "each result pixel.\n"
1223*35238bceSAndroid Build Coastguard Worker << "\tVerifying each result derivative is within its range of legal result values."
1224*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1225*35238bceSAndroid Build Coastguard Worker
1226*35238bceSAndroid Build Coastguard Worker {
1227*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize = getViewportSize();
1228*35238bceSAndroid Build Coastguard Worker const float w = float(viewportSize.x());
1229*35238bceSAndroid Build Coastguard Worker const float h = float(viewportSize.y());
1230*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 valueRamp = (m_coordMax - m_coordMin);
1231*35238bceSAndroid Build Coastguard Worker Linear2DFunctionEvaluator function;
1232*35238bceSAndroid Build Coastguard Worker
1233*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(0,
1234*35238bceSAndroid Build Coastguard Worker tcu::Vec3((valueRamp.x() / w) / 2.0f, (valueRamp.x() / h) / 2.0f, m_coordMin.x()));
1235*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(1,
1236*35238bceSAndroid Build Coastguard Worker tcu::Vec3((valueRamp.y() / w) / 2.0f, (valueRamp.y() / h) / 2.0f, m_coordMin.y()));
1237*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(2, tcu::Vec3(valueRamp.z() / w, valueRamp.z() / h, m_coordMin.z() + m_coordMin.z()) /
1238*35238bceSAndroid Build Coastguard Worker 2.0f);
1239*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(
1240*35238bceSAndroid Build Coastguard Worker 3, tcu::Vec3(-valueRamp.w() / w, -valueRamp.w() / h, m_coordMax.w() + m_coordMax.w()) / 2.0f);
1241*35238bceSAndroid Build Coastguard Worker
1242*35238bceSAndroid Build Coastguard Worker return reverifyConstantDerivateWithFlushRelaxations(m_testCtx.getLog(), result, errorMask, m_dataType,
1243*35238bceSAndroid Build Coastguard Worker m_precision, m_derivScale, m_derivBias,
1244*35238bceSAndroid Build Coastguard Worker surfaceThreshold, m_func, function);
1245*35238bceSAndroid Build Coastguard Worker }
1246*35238bceSAndroid Build Coastguard Worker }
1247*35238bceSAndroid Build Coastguard Worker else
1248*35238bceSAndroid Build Coastguard Worker {
1249*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_func == DERIVATE_FWIDTH);
1250*35238bceSAndroid Build Coastguard Worker const float w = float(result.getWidth());
1251*35238bceSAndroid Build Coastguard Worker const float h = float(result.getHeight());
1252*35238bceSAndroid Build Coastguard Worker
1253*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dx = ((m_coordMax - m_coordMin) / w) * xScale;
1254*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dy = ((m_coordMax - m_coordMin) / h) * yScale;
1255*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 reference = tcu::abs(dx) + tcu::abs(dy);
1256*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dxThreshold = getDerivateThreshold(m_precision, m_coordMin * xScale, m_coordMax * xScale, dx);
1257*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dyThreshold = getDerivateThreshold(m_precision, m_coordMin * yScale, m_coordMax * yScale, dy);
1258*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dxThresholdW =
1259*35238bceSAndroid Build Coastguard Worker getDerivateThresholdWarning(m_precision, m_coordMin * xScale, m_coordMax * xScale, dx);
1260*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dyThresholdW =
1261*35238bceSAndroid Build Coastguard Worker getDerivateThresholdWarning(m_precision, m_coordMin * yScale, m_coordMax * yScale, dy);
1262*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 threshold = max(surfaceThreshold, max(dxThreshold, dyThreshold));
1263*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 thresholdW = max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
1264*35238bceSAndroid Build Coastguard Worker qpTestResult testResult = QP_TEST_RESULT_FAIL;
1265*35238bceSAndroid Build Coastguard Worker
1266*35238bceSAndroid Build Coastguard Worker testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType, reference, threshold,
1267*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias);
1268*35238bceSAndroid Build Coastguard Worker
1269*35238bceSAndroid Build Coastguard Worker // return if result is pass
1270*35238bceSAndroid Build Coastguard Worker if (testResult == QP_TEST_RESULT_PASS)
1271*35238bceSAndroid Build Coastguard Worker return testResult;
1272*35238bceSAndroid Build Coastguard Worker
1273*35238bceSAndroid Build Coastguard Worker // re-check with relaxed threshold
1274*35238bceSAndroid Build Coastguard Worker testResult = verifyConstantDerivate(m_testCtx.getLog(), result, errorMask, m_dataType, reference, thresholdW,
1275*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias);
1276*35238bceSAndroid Build Coastguard Worker
1277*35238bceSAndroid Build Coastguard Worker // if with relaxed threshold test is passing then mark the result with quality warning.
1278*35238bceSAndroid Build Coastguard Worker if (testResult == QP_TEST_RESULT_PASS)
1279*35238bceSAndroid Build Coastguard Worker testResult = QP_TEST_RESULT_QUALITY_WARNING;
1280*35238bceSAndroid Build Coastguard Worker
1281*35238bceSAndroid Build Coastguard Worker return testResult;
1282*35238bceSAndroid Build Coastguard Worker }
1283*35238bceSAndroid Build Coastguard Worker }
1284*35238bceSAndroid Build Coastguard Worker
1285*35238bceSAndroid Build Coastguard Worker // TextureDerivateCase
1286*35238bceSAndroid Build Coastguard Worker
1287*35238bceSAndroid Build Coastguard Worker class TextureDerivateCase : public TriangleDerivateCase
1288*35238bceSAndroid Build Coastguard Worker {
1289*35238bceSAndroid Build Coastguard Worker public:
1290*35238bceSAndroid Build Coastguard Worker TextureDerivateCase(Context &context, const char *name, const char *description, DerivateFunc func,
1291*35238bceSAndroid Build Coastguard Worker glu::DataType type, glu::Precision precision, uint32_t hint, SurfaceType surfaceType,
1292*35238bceSAndroid Build Coastguard Worker int numSamples);
1293*35238bceSAndroid Build Coastguard Worker ~TextureDerivateCase(void);
1294*35238bceSAndroid Build Coastguard Worker
1295*35238bceSAndroid Build Coastguard Worker void init(void);
1296*35238bceSAndroid Build Coastguard Worker void deinit(void);
1297*35238bceSAndroid Build Coastguard Worker
1298*35238bceSAndroid Build Coastguard Worker protected:
1299*35238bceSAndroid Build Coastguard Worker void setupRenderState(uint32_t program);
1300*35238bceSAndroid Build Coastguard Worker qpTestResult verify(const tcu::ConstPixelBufferAccess &result, const tcu::PixelBufferAccess &errorMask);
1301*35238bceSAndroid Build Coastguard Worker
1302*35238bceSAndroid Build Coastguard Worker private:
1303*35238bceSAndroid Build Coastguard Worker DerivateFunc m_func;
1304*35238bceSAndroid Build Coastguard Worker
1305*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_texValueMin;
1306*35238bceSAndroid Build Coastguard Worker tcu::Vec4 m_texValueMax;
1307*35238bceSAndroid Build Coastguard Worker glu::Texture2D *m_texture;
1308*35238bceSAndroid Build Coastguard Worker };
1309*35238bceSAndroid Build Coastguard Worker
TextureDerivateCase(Context & context,const char * name,const char * description,DerivateFunc func,glu::DataType type,glu::Precision precision,uint32_t hint,SurfaceType surfaceType,int numSamples)1310*35238bceSAndroid Build Coastguard Worker TextureDerivateCase::TextureDerivateCase(Context &context, const char *name, const char *description, DerivateFunc func,
1311*35238bceSAndroid Build Coastguard Worker glu::DataType type, glu::Precision precision, uint32_t hint,
1312*35238bceSAndroid Build Coastguard Worker SurfaceType surfaceType, int numSamples)
1313*35238bceSAndroid Build Coastguard Worker : TriangleDerivateCase(context, name, description)
1314*35238bceSAndroid Build Coastguard Worker , m_func(func)
1315*35238bceSAndroid Build Coastguard Worker , m_texture(DE_NULL)
1316*35238bceSAndroid Build Coastguard Worker {
1317*35238bceSAndroid Build Coastguard Worker m_dataType = type;
1318*35238bceSAndroid Build Coastguard Worker m_precision = precision;
1319*35238bceSAndroid Build Coastguard Worker m_coordDataType = glu::TYPE_FLOAT_VEC2;
1320*35238bceSAndroid Build Coastguard Worker m_coordPrecision = glu::PRECISION_HIGHP;
1321*35238bceSAndroid Build Coastguard Worker m_hint = hint;
1322*35238bceSAndroid Build Coastguard Worker m_surfaceType = surfaceType;
1323*35238bceSAndroid Build Coastguard Worker m_numSamples = numSamples;
1324*35238bceSAndroid Build Coastguard Worker }
1325*35238bceSAndroid Build Coastguard Worker
~TextureDerivateCase(void)1326*35238bceSAndroid Build Coastguard Worker TextureDerivateCase::~TextureDerivateCase(void)
1327*35238bceSAndroid Build Coastguard Worker {
1328*35238bceSAndroid Build Coastguard Worker delete m_texture;
1329*35238bceSAndroid Build Coastguard Worker }
1330*35238bceSAndroid Build Coastguard Worker
init(void)1331*35238bceSAndroid Build Coastguard Worker void TextureDerivateCase::init(void)
1332*35238bceSAndroid Build Coastguard Worker {
1333*35238bceSAndroid Build Coastguard Worker // Generate shader
1334*35238bceSAndroid Build Coastguard Worker {
1335*35238bceSAndroid Build Coastguard Worker const char *fragmentTmpl = "#version 300 es\n"
1336*35238bceSAndroid Build Coastguard Worker "in highp vec2 v_coord;\n"
1337*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1338*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} sampler2D u_sampler;\n"
1339*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1340*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1341*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1342*35238bceSAndroid Build Coastguard Worker "{\n"
1343*35238bceSAndroid Build Coastguard Worker " ${PRECISION} vec4 tex = texture(u_sampler, v_coord);\n"
1344*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = ${FUNC}(tex${SWIZZLE}) * u_scale + u_bias;\n"
1345*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1346*35238bceSAndroid Build Coastguard Worker "}\n";
1347*35238bceSAndroid Build Coastguard Worker
1348*35238bceSAndroid Build Coastguard Worker const bool packToInt = m_surfaceType == SURFACETYPE_FLOAT_FBO;
1349*35238bceSAndroid Build Coastguard Worker map<string, string> fragmentParams;
1350*35238bceSAndroid Build Coastguard Worker
1351*35238bceSAndroid Build Coastguard Worker fragmentParams["OUTPUT_TYPE"] = glu::getDataTypeName(packToInt ? glu::TYPE_UINT_VEC4 : glu::TYPE_FLOAT_VEC4);
1352*35238bceSAndroid Build Coastguard Worker fragmentParams["OUTPUT_PREC"] = glu::getPrecisionName(packToInt ? glu::PRECISION_HIGHP : m_precision);
1353*35238bceSAndroid Build Coastguard Worker fragmentParams["PRECISION"] = glu::getPrecisionName(m_precision);
1354*35238bceSAndroid Build Coastguard Worker fragmentParams["DATATYPE"] = glu::getDataTypeName(m_dataType);
1355*35238bceSAndroid Build Coastguard Worker fragmentParams["FUNC"] = getDerivateFuncName(m_func);
1356*35238bceSAndroid Build Coastguard Worker fragmentParams["SWIZZLE"] = m_dataType == glu::TYPE_FLOAT_VEC4 ? "" :
1357*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? ".xyz" :
1358*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? ".xy" :
1359*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ ".x";
1360*35238bceSAndroid Build Coastguard Worker
1361*35238bceSAndroid Build Coastguard Worker if (packToInt)
1362*35238bceSAndroid Build Coastguard Worker {
1363*35238bceSAndroid Build Coastguard Worker fragmentParams["CAST_TO_OUTPUT"] =
1364*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC4 ? "floatBitsToUint(res)" :
1365*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "floatBitsToUint(vec4(res, 1.0))" :
1366*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "floatBitsToUint(vec4(res, 0.0, 1.0))" :
1367*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))";
1368*35238bceSAndroid Build Coastguard Worker }
1369*35238bceSAndroid Build Coastguard Worker else
1370*35238bceSAndroid Build Coastguard Worker {
1371*35238bceSAndroid Build Coastguard Worker fragmentParams["CAST_TO_OUTPUT"] =
1372*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC4 ? "res" :
1373*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC3 ? "vec4(res, 1.0)" :
1374*35238bceSAndroid Build Coastguard Worker m_dataType == glu::TYPE_FLOAT_VEC2 ? "vec4(res, 0.0, 1.0)" :
1375*35238bceSAndroid Build Coastguard Worker /* TYPE_FLOAT */ "vec4(res, 0.0, 0.0, 1.0)";
1376*35238bceSAndroid Build Coastguard Worker }
1377*35238bceSAndroid Build Coastguard Worker
1378*35238bceSAndroid Build Coastguard Worker m_fragmentSrc = tcu::StringTemplate(fragmentTmpl).specialize(fragmentParams);
1379*35238bceSAndroid Build Coastguard Worker }
1380*35238bceSAndroid Build Coastguard Worker
1381*35238bceSAndroid Build Coastguard Worker // Texture size matches viewport and nearest sampling is used. Thus texture sampling
1382*35238bceSAndroid Build Coastguard Worker // is equal to just interpolating the texture value range.
1383*35238bceSAndroid Build Coastguard Worker
1384*35238bceSAndroid Build Coastguard Worker // Determine value range for texture.
1385*35238bceSAndroid Build Coastguard Worker
1386*35238bceSAndroid Build Coastguard Worker switch (m_precision)
1387*35238bceSAndroid Build Coastguard Worker {
1388*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_HIGHP:
1389*35238bceSAndroid Build Coastguard Worker m_texValueMin = tcu::Vec4(-97.f, 0.2f, 71.f, 74.f);
1390*35238bceSAndroid Build Coastguard Worker m_texValueMax = tcu::Vec4(-13.2f, -77.f, 44.f, 76.f);
1391*35238bceSAndroid Build Coastguard Worker break;
1392*35238bceSAndroid Build Coastguard Worker
1393*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_MEDIUMP:
1394*35238bceSAndroid Build Coastguard Worker m_texValueMin = tcu::Vec4(-37.0f, 47.f, -7.f, 0.0f);
1395*35238bceSAndroid Build Coastguard Worker m_texValueMax = tcu::Vec4(-1.0f, 12.f, 7.f, 19.f);
1396*35238bceSAndroid Build Coastguard Worker break;
1397*35238bceSAndroid Build Coastguard Worker
1398*35238bceSAndroid Build Coastguard Worker case glu::PRECISION_LOWP:
1399*35238bceSAndroid Build Coastguard Worker m_texValueMin = tcu::Vec4(0.0f, -1.0f, 0.0f, 1.0f);
1400*35238bceSAndroid Build Coastguard Worker m_texValueMax = tcu::Vec4(1.0f, 1.0f, -1.0f, -1.0f);
1401*35238bceSAndroid Build Coastguard Worker break;
1402*35238bceSAndroid Build Coastguard Worker
1403*35238bceSAndroid Build Coastguard Worker default:
1404*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1405*35238bceSAndroid Build Coastguard Worker }
1406*35238bceSAndroid Build Coastguard Worker
1407*35238bceSAndroid Build Coastguard Worker // Lowp and mediump cases use RGBA16F format, while highp uses RGBA32F.
1408*35238bceSAndroid Build Coastguard Worker {
1409*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize = getViewportSize();
1410*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_texture);
1411*35238bceSAndroid Build Coastguard Worker m_texture = new glu::Texture2D(m_context.getRenderContext(),
1412*35238bceSAndroid Build Coastguard Worker m_precision == glu::PRECISION_HIGHP ? GL_RGBA32F : GL_RGBA16F, viewportSize.x(),
1413*35238bceSAndroid Build Coastguard Worker viewportSize.y());
1414*35238bceSAndroid Build Coastguard Worker m_texture->getRefTexture().allocLevel(0);
1415*35238bceSAndroid Build Coastguard Worker }
1416*35238bceSAndroid Build Coastguard Worker
1417*35238bceSAndroid Build Coastguard Worker // Texture coordinates
1418*35238bceSAndroid Build Coastguard Worker m_coordMin = tcu::Vec4(0.0f);
1419*35238bceSAndroid Build Coastguard Worker m_coordMax = tcu::Vec4(1.0f);
1420*35238bceSAndroid Build Coastguard Worker
1421*35238bceSAndroid Build Coastguard Worker // Fill with gradients.
1422*35238bceSAndroid Build Coastguard Worker {
1423*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess level0 = m_texture->getRefTexture().getLevel(0);
1424*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < level0.getHeight(); y++)
1425*35238bceSAndroid Build Coastguard Worker {
1426*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < level0.getWidth(); x++)
1427*35238bceSAndroid Build Coastguard Worker {
1428*35238bceSAndroid Build Coastguard Worker const float xf = (float(x) + 0.5f) / float(level0.getWidth());
1429*35238bceSAndroid Build Coastguard Worker const float yf = (float(y) + 0.5f) / float(level0.getHeight());
1430*35238bceSAndroid Build Coastguard Worker // Make x and y data to have dependency to both axes so that dfdx(tex).y and dfdy(tex).x are nonzero.
1431*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 s =
1432*35238bceSAndroid Build Coastguard Worker tcu::Vec4(xf + yf / 2.0f, yf + xf / 2.0f, (xf + yf) / 2.0f, 1.0f - (xf + yf) / 2.0f);
1433*35238bceSAndroid Build Coastguard Worker
1434*35238bceSAndroid Build Coastguard Worker level0.setPixel(m_texValueMin + (m_texValueMax - m_texValueMin) * s, x, y);
1435*35238bceSAndroid Build Coastguard Worker }
1436*35238bceSAndroid Build Coastguard Worker }
1437*35238bceSAndroid Build Coastguard Worker }
1438*35238bceSAndroid Build Coastguard Worker
1439*35238bceSAndroid Build Coastguard Worker m_texture->upload();
1440*35238bceSAndroid Build Coastguard Worker
1441*35238bceSAndroid Build Coastguard Worker if (m_surfaceType == SURFACETYPE_FLOAT_FBO)
1442*35238bceSAndroid Build Coastguard Worker {
1443*35238bceSAndroid Build Coastguard Worker // No scale or bias used for accuracy.
1444*35238bceSAndroid Build Coastguard Worker m_derivScale = tcu::Vec4(1.0f);
1445*35238bceSAndroid Build Coastguard Worker m_derivBias = tcu::Vec4(0.0f);
1446*35238bceSAndroid Build Coastguard Worker }
1447*35238bceSAndroid Build Coastguard Worker else
1448*35238bceSAndroid Build Coastguard Worker {
1449*35238bceSAndroid Build Coastguard Worker // Compute scale - bias that normalizes to 0..1 range.
1450*35238bceSAndroid Build Coastguard Worker const tcu::IVec2 viewportSize = getViewportSize();
1451*35238bceSAndroid Build Coastguard Worker const float w = float(viewportSize.x());
1452*35238bceSAndroid Build Coastguard Worker const float h = float(viewportSize.y());
1453*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dx = (m_texValueMax - m_texValueMin) / tcu::Vec4(w, w, w * 0.5f, -w * 0.5f);
1454*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dy = (m_texValueMax - m_texValueMin) / tcu::Vec4(h, h, h * 0.5f, -h * 0.5f);
1455*35238bceSAndroid Build Coastguard Worker
1456*35238bceSAndroid Build Coastguard Worker switch (m_func)
1457*35238bceSAndroid Build Coastguard Worker {
1458*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDX:
1459*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / dx;
1460*35238bceSAndroid Build Coastguard Worker break;
1461*35238bceSAndroid Build Coastguard Worker
1462*35238bceSAndroid Build Coastguard Worker case DERIVATE_DFDY:
1463*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / dy;
1464*35238bceSAndroid Build Coastguard Worker break;
1465*35238bceSAndroid Build Coastguard Worker
1466*35238bceSAndroid Build Coastguard Worker case DERIVATE_FWIDTH:
1467*35238bceSAndroid Build Coastguard Worker m_derivScale = 0.5f / (tcu::abs(dx) + tcu::abs(dy));
1468*35238bceSAndroid Build Coastguard Worker break;
1469*35238bceSAndroid Build Coastguard Worker
1470*35238bceSAndroid Build Coastguard Worker default:
1471*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
1472*35238bceSAndroid Build Coastguard Worker }
1473*35238bceSAndroid Build Coastguard Worker
1474*35238bceSAndroid Build Coastguard Worker m_derivBias = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1475*35238bceSAndroid Build Coastguard Worker }
1476*35238bceSAndroid Build Coastguard Worker }
1477*35238bceSAndroid Build Coastguard Worker
deinit(void)1478*35238bceSAndroid Build Coastguard Worker void TextureDerivateCase::deinit(void)
1479*35238bceSAndroid Build Coastguard Worker {
1480*35238bceSAndroid Build Coastguard Worker delete m_texture;
1481*35238bceSAndroid Build Coastguard Worker m_texture = DE_NULL;
1482*35238bceSAndroid Build Coastguard Worker }
1483*35238bceSAndroid Build Coastguard Worker
setupRenderState(uint32_t program)1484*35238bceSAndroid Build Coastguard Worker void TextureDerivateCase::setupRenderState(uint32_t program)
1485*35238bceSAndroid Build Coastguard Worker {
1486*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1487*35238bceSAndroid Build Coastguard Worker const int texUnit = 1;
1488*35238bceSAndroid Build Coastguard Worker
1489*35238bceSAndroid Build Coastguard Worker gl.activeTexture(GL_TEXTURE0 + texUnit);
1490*35238bceSAndroid Build Coastguard Worker gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
1491*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1492*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1493*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1494*35238bceSAndroid Build Coastguard Worker gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1495*35238bceSAndroid Build Coastguard Worker
1496*35238bceSAndroid Build Coastguard Worker gl.uniform1i(gl.getUniformLocation(program, "u_sampler"), texUnit);
1497*35238bceSAndroid Build Coastguard Worker }
1498*35238bceSAndroid Build Coastguard Worker
verify(const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask)1499*35238bceSAndroid Build Coastguard Worker qpTestResult TextureDerivateCase::verify(const tcu::ConstPixelBufferAccess &result,
1500*35238bceSAndroid Build Coastguard Worker const tcu::PixelBufferAccess &errorMask)
1501*35238bceSAndroid Build Coastguard Worker {
1502*35238bceSAndroid Build Coastguard Worker // \note Edges are ignored in comparison
1503*35238bceSAndroid Build Coastguard Worker if (result.getWidth() < 2 || result.getHeight() < 2)
1504*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Too small viewport");
1505*35238bceSAndroid Build Coastguard Worker
1506*35238bceSAndroid Build Coastguard Worker tcu::ConstPixelBufferAccess compareArea =
1507*35238bceSAndroid Build Coastguard Worker tcu::getSubregion(result, 1, 1, result.getWidth() - 2, result.getHeight() - 2);
1508*35238bceSAndroid Build Coastguard Worker tcu::PixelBufferAccess maskArea =
1509*35238bceSAndroid Build Coastguard Worker tcu::getSubregion(errorMask, 1, 1, errorMask.getWidth() - 2, errorMask.getHeight() - 2);
1510*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 xScale = tcu::Vec4(1.0f, 0.5f, 0.5f, -0.5f);
1511*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 yScale = tcu::Vec4(0.5f, 1.0f, 0.5f, -0.5f);
1512*35238bceSAndroid Build Coastguard Worker const float w = float(result.getWidth());
1513*35238bceSAndroid Build Coastguard Worker const float h = float(result.getHeight());
1514*35238bceSAndroid Build Coastguard Worker
1515*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 surfaceThreshold = getSurfaceThreshold() / abs(m_derivScale);
1516*35238bceSAndroid Build Coastguard Worker
1517*35238bceSAndroid Build Coastguard Worker if (m_func == DERIVATE_DFDX || m_func == DERIVATE_DFDY)
1518*35238bceSAndroid Build Coastguard Worker {
1519*35238bceSAndroid Build Coastguard Worker const bool isX = m_func == DERIVATE_DFDX;
1520*35238bceSAndroid Build Coastguard Worker const float div = isX ? w : h;
1521*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 scale = isX ? xScale : yScale;
1522*35238bceSAndroid Build Coastguard Worker tcu::Vec4 reference = ((m_texValueMax - m_texValueMin) / div);
1523*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 opThreshold = getDerivateThreshold(m_precision, m_texValueMin, m_texValueMax, reference);
1524*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 opThresholdW =
1525*35238bceSAndroid Build Coastguard Worker getDerivateThresholdWarning(m_precision, m_texValueMin, m_texValueMax, reference);
1526*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 threshold = max(surfaceThreshold, opThreshold);
1527*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 thresholdW = max(surfaceThreshold, opThresholdW);
1528*35238bceSAndroid Build Coastguard Worker const int numComps = glu::getDataTypeFloatScalars(m_dataType);
1529*35238bceSAndroid Build Coastguard Worker
1530*35238bceSAndroid Build Coastguard Worker /* adjust the reference value for the correct dfdx or dfdy sample adjacency */
1531*35238bceSAndroid Build Coastguard Worker reference = reference * scale;
1532*35238bceSAndroid Build Coastguard Worker
1533*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result image.\n"
1534*35238bceSAndroid Build Coastguard Worker << "\tValid derivative is " << LogVecComps(reference, numComps) << " with threshold "
1535*35238bceSAndroid Build Coastguard Worker << LogVecComps(threshold, numComps) << tcu::TestLog::EndMessage;
1536*35238bceSAndroid Build Coastguard Worker
1537*35238bceSAndroid Build Coastguard Worker // short circuit if result is strictly within the normal value error bounds.
1538*35238bceSAndroid Build Coastguard Worker // This improves performance significantly.
1539*35238bceSAndroid Build Coastguard Worker if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType, reference, threshold,
1540*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias, LOG_NOTHING) == QP_TEST_RESULT_PASS)
1541*35238bceSAndroid Build Coastguard Worker {
1542*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "No incorrect derivatives found, result valid."
1543*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1544*35238bceSAndroid Build Coastguard Worker
1545*35238bceSAndroid Build Coastguard Worker return QP_TEST_RESULT_PASS;
1546*35238bceSAndroid Build Coastguard Worker }
1547*35238bceSAndroid Build Coastguard Worker
1548*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result image.\n"
1549*35238bceSAndroid Build Coastguard Worker << "\tValid derivative is " << LogVecComps(reference, numComps) << " with Warning threshold "
1550*35238bceSAndroid Build Coastguard Worker << LogVecComps(thresholdW, numComps) << tcu::TestLog::EndMessage;
1551*35238bceSAndroid Build Coastguard Worker
1552*35238bceSAndroid Build Coastguard Worker // Re-check with relaxed threshold
1553*35238bceSAndroid Build Coastguard Worker if (verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType, reference, thresholdW,
1554*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias, LOG_NOTHING) == QP_TEST_RESULT_PASS)
1555*35238bceSAndroid Build Coastguard Worker {
1556*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1557*35238bceSAndroid Build Coastguard Worker << "No incorrect derivatives found, result valid with quality warning."
1558*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1559*35238bceSAndroid Build Coastguard Worker
1560*35238bceSAndroid Build Coastguard Worker return QP_TEST_RESULT_QUALITY_WARNING;
1561*35238bceSAndroid Build Coastguard Worker }
1562*35238bceSAndroid Build Coastguard Worker
1563*35238bceSAndroid Build Coastguard Worker // some pixels exceed error bounds calculated for normal values. Verify that these
1564*35238bceSAndroid Build Coastguard Worker // potentially invalid pixels are in fact valid due to (for example) subnorm flushing.
1565*35238bceSAndroid Build Coastguard Worker
1566*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << tcu::TestLog::Message
1567*35238bceSAndroid Build Coastguard Worker << "Initial verification failed, verifying image by calculating accurate error bounds for "
1568*35238bceSAndroid Build Coastguard Worker "each result pixel.\n"
1569*35238bceSAndroid Build Coastguard Worker << "\tVerifying each result derivative is within its range of legal result values."
1570*35238bceSAndroid Build Coastguard Worker << tcu::TestLog::EndMessage;
1571*35238bceSAndroid Build Coastguard Worker
1572*35238bceSAndroid Build Coastguard Worker {
1573*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 valueRamp = (m_texValueMax - m_texValueMin);
1574*35238bceSAndroid Build Coastguard Worker Linear2DFunctionEvaluator function;
1575*35238bceSAndroid Build Coastguard Worker
1576*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(0, tcu::Vec3(valueRamp.x() / w, (valueRamp.x() / h) / 2.0f, m_texValueMin.x()));
1577*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(1, tcu::Vec3((valueRamp.y() / w) / 2.0f, valueRamp.y() / h, m_texValueMin.y()));
1578*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(
1579*35238bceSAndroid Build Coastguard Worker 2, tcu::Vec3(valueRamp.z() / w, valueRamp.z() / h, m_texValueMin.z() + m_texValueMin.z()) / 2.0f);
1580*35238bceSAndroid Build Coastguard Worker function.matrix.setRow(
1581*35238bceSAndroid Build Coastguard Worker 3, tcu::Vec3(-valueRamp.w() / w, -valueRamp.w() / h, m_texValueMax.w() + m_texValueMax.w()) / 2.0f);
1582*35238bceSAndroid Build Coastguard Worker
1583*35238bceSAndroid Build Coastguard Worker return reverifyConstantDerivateWithFlushRelaxations(m_testCtx.getLog(), compareArea, maskArea, m_dataType,
1584*35238bceSAndroid Build Coastguard Worker m_precision, m_derivScale, m_derivBias,
1585*35238bceSAndroid Build Coastguard Worker surfaceThreshold, m_func, function);
1586*35238bceSAndroid Build Coastguard Worker }
1587*35238bceSAndroid Build Coastguard Worker }
1588*35238bceSAndroid Build Coastguard Worker else
1589*35238bceSAndroid Build Coastguard Worker {
1590*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_func == DERIVATE_FWIDTH);
1591*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dx = ((m_texValueMax - m_texValueMin) / w) * xScale;
1592*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dy = ((m_texValueMax - m_texValueMin) / h) * yScale;
1593*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 reference = tcu::abs(dx) + tcu::abs(dy);
1594*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dxThreshold =
1595*35238bceSAndroid Build Coastguard Worker getDerivateThreshold(m_precision, m_texValueMin * xScale, m_texValueMax * xScale, dx);
1596*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dyThreshold =
1597*35238bceSAndroid Build Coastguard Worker getDerivateThreshold(m_precision, m_texValueMin * yScale, m_texValueMax * yScale, dy);
1598*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dxThresholdW =
1599*35238bceSAndroid Build Coastguard Worker getDerivateThresholdWarning(m_precision, m_texValueMin * xScale, m_texValueMax * xScale, dx);
1600*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 dyThresholdW =
1601*35238bceSAndroid Build Coastguard Worker getDerivateThresholdWarning(m_precision, m_texValueMin * yScale, m_texValueMax * yScale, dy);
1602*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 threshold = max(surfaceThreshold, max(dxThreshold, dyThreshold));
1603*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 thresholdW = max(surfaceThreshold, max(dxThresholdW, dyThresholdW));
1604*35238bceSAndroid Build Coastguard Worker qpTestResult testResult = QP_TEST_RESULT_FAIL;
1605*35238bceSAndroid Build Coastguard Worker
1606*35238bceSAndroid Build Coastguard Worker testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType, reference, threshold,
1607*35238bceSAndroid Build Coastguard Worker m_derivScale, m_derivBias);
1608*35238bceSAndroid Build Coastguard Worker
1609*35238bceSAndroid Build Coastguard Worker if (testResult == QP_TEST_RESULT_PASS)
1610*35238bceSAndroid Build Coastguard Worker return testResult;
1611*35238bceSAndroid Build Coastguard Worker
1612*35238bceSAndroid Build Coastguard Worker // Re-Check with relaxed threshold
1613*35238bceSAndroid Build Coastguard Worker testResult = verifyConstantDerivate(m_testCtx.getLog(), compareArea, maskArea, m_dataType, reference,
1614*35238bceSAndroid Build Coastguard Worker thresholdW, m_derivScale, m_derivBias);
1615*35238bceSAndroid Build Coastguard Worker
1616*35238bceSAndroid Build Coastguard Worker // If test is passing with relaxed threshold then mark quality warning
1617*35238bceSAndroid Build Coastguard Worker if (testResult == QP_TEST_RESULT_PASS)
1618*35238bceSAndroid Build Coastguard Worker testResult = QP_TEST_RESULT_QUALITY_WARNING;
1619*35238bceSAndroid Build Coastguard Worker
1620*35238bceSAndroid Build Coastguard Worker return testResult;
1621*35238bceSAndroid Build Coastguard Worker }
1622*35238bceSAndroid Build Coastguard Worker }
1623*35238bceSAndroid Build Coastguard Worker
ShaderDerivateTests(Context & context)1624*35238bceSAndroid Build Coastguard Worker ShaderDerivateTests::ShaderDerivateTests(Context &context)
1625*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(context, "derivate", "Derivate Function Tests")
1626*35238bceSAndroid Build Coastguard Worker {
1627*35238bceSAndroid Build Coastguard Worker }
1628*35238bceSAndroid Build Coastguard Worker
~ShaderDerivateTests(void)1629*35238bceSAndroid Build Coastguard Worker ShaderDerivateTests::~ShaderDerivateTests(void)
1630*35238bceSAndroid Build Coastguard Worker {
1631*35238bceSAndroid Build Coastguard Worker }
1632*35238bceSAndroid Build Coastguard Worker
1633*35238bceSAndroid Build Coastguard Worker struct FunctionSpec
1634*35238bceSAndroid Build Coastguard Worker {
1635*35238bceSAndroid Build Coastguard Worker std::string name;
1636*35238bceSAndroid Build Coastguard Worker DerivateFunc function;
1637*35238bceSAndroid Build Coastguard Worker glu::DataType dataType;
1638*35238bceSAndroid Build Coastguard Worker glu::Precision precision;
1639*35238bceSAndroid Build Coastguard Worker
FunctionSpecdeqp::gles3::Functional::FunctionSpec1640*35238bceSAndroid Build Coastguard Worker FunctionSpec(const std::string &name_, DerivateFunc function_, glu::DataType dataType_, glu::Precision precision_)
1641*35238bceSAndroid Build Coastguard Worker : name(name_)
1642*35238bceSAndroid Build Coastguard Worker , function(function_)
1643*35238bceSAndroid Build Coastguard Worker , dataType(dataType_)
1644*35238bceSAndroid Build Coastguard Worker , precision(precision_)
1645*35238bceSAndroid Build Coastguard Worker {
1646*35238bceSAndroid Build Coastguard Worker }
1647*35238bceSAndroid Build Coastguard Worker };
1648*35238bceSAndroid Build Coastguard Worker
init(void)1649*35238bceSAndroid Build Coastguard Worker void ShaderDerivateTests::init(void)
1650*35238bceSAndroid Build Coastguard Worker {
1651*35238bceSAndroid Build Coastguard Worker static const struct
1652*35238bceSAndroid Build Coastguard Worker {
1653*35238bceSAndroid Build Coastguard Worker const char *name;
1654*35238bceSAndroid Build Coastguard Worker const char *description;
1655*35238bceSAndroid Build Coastguard Worker const char *source;
1656*35238bceSAndroid Build Coastguard Worker } s_linearDerivateCases[] = {
1657*35238bceSAndroid Build Coastguard Worker {"linear", "Basic derivate of linearly interpolated argument",
1658*35238bceSAndroid Build Coastguard Worker
1659*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1660*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1661*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1662*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1663*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1664*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1665*35238bceSAndroid Build Coastguard Worker "{\n"
1666*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
1667*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1668*35238bceSAndroid Build Coastguard Worker "}\n"},
1669*35238bceSAndroid Build Coastguard Worker {"in_function", "Derivate of linear function argument",
1670*35238bceSAndroid Build Coastguard Worker
1671*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1672*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1673*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1674*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1675*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1676*35238bceSAndroid Build Coastguard Worker "\n"
1677*35238bceSAndroid Build Coastguard Worker "${PRECISION} ${DATATYPE} computeRes (${PRECISION} ${DATATYPE} value)\n"
1678*35238bceSAndroid Build Coastguard Worker "{\n"
1679*35238bceSAndroid Build Coastguard Worker " return ${FUNC}(v_coord) * u_scale + u_bias;\n"
1680*35238bceSAndroid Build Coastguard Worker "}\n"
1681*35238bceSAndroid Build Coastguard Worker "\n"
1682*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1683*35238bceSAndroid Build Coastguard Worker "{\n"
1684*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = computeRes(v_coord);\n"
1685*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1686*35238bceSAndroid Build Coastguard Worker "}\n"},
1687*35238bceSAndroid Build Coastguard Worker {"static_if", "Derivate of linearly interpolated value in static if",
1688*35238bceSAndroid Build Coastguard Worker
1689*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1690*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1691*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1692*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1693*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1694*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1695*35238bceSAndroid Build Coastguard Worker "{\n"
1696*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res;\n"
1697*35238bceSAndroid Build Coastguard Worker " if (false)\n"
1698*35238bceSAndroid Build Coastguard Worker " res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
1699*35238bceSAndroid Build Coastguard Worker " else\n"
1700*35238bceSAndroid Build Coastguard Worker " res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
1701*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1702*35238bceSAndroid Build Coastguard Worker "}\n"},
1703*35238bceSAndroid Build Coastguard Worker {"static_loop", "Derivate of linearly interpolated value in static loop",
1704*35238bceSAndroid Build Coastguard Worker
1705*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1706*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1707*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1708*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1709*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1710*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1711*35238bceSAndroid Build Coastguard Worker "{\n"
1712*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
1713*35238bceSAndroid Build Coastguard Worker " for (int i = 0; i < 2; i++)\n"
1714*35238bceSAndroid Build Coastguard Worker " res += ${FUNC}(v_coord * float(i));\n"
1715*35238bceSAndroid Build Coastguard Worker " res = res * u_scale + u_bias;\n"
1716*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1717*35238bceSAndroid Build Coastguard Worker "}\n"},
1718*35238bceSAndroid Build Coastguard Worker {"static_switch", "Derivate of linearly interpolated value in static switch",
1719*35238bceSAndroid Build Coastguard Worker
1720*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1721*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1722*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1723*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1724*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1725*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1726*35238bceSAndroid Build Coastguard Worker "{\n"
1727*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res;\n"
1728*35238bceSAndroid Build Coastguard Worker " switch (1)\n"
1729*35238bceSAndroid Build Coastguard Worker " {\n"
1730*35238bceSAndroid Build Coastguard Worker " case 0: res = ${FUNC}(-v_coord) * u_scale + u_bias; break;\n"
1731*35238bceSAndroid Build Coastguard Worker " case 1: res = ${FUNC}(v_coord) * u_scale + u_bias; break;\n"
1732*35238bceSAndroid Build Coastguard Worker " }\n"
1733*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1734*35238bceSAndroid Build Coastguard Worker "}\n"},
1735*35238bceSAndroid Build Coastguard Worker {"uniform_if", "Derivate of linearly interpolated value in uniform if",
1736*35238bceSAndroid Build Coastguard Worker
1737*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1738*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1739*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1740*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1741*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1742*35238bceSAndroid Build Coastguard Worker "uniform bool ub_true;\n"
1743*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1744*35238bceSAndroid Build Coastguard Worker "{\n"
1745*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res;\n"
1746*35238bceSAndroid Build Coastguard Worker " if (ub_true)"
1747*35238bceSAndroid Build Coastguard Worker " res = ${FUNC}(v_coord) * u_scale + u_bias;\n"
1748*35238bceSAndroid Build Coastguard Worker " else\n"
1749*35238bceSAndroid Build Coastguard Worker " res = ${FUNC}(-v_coord) * u_scale + u_bias;\n"
1750*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1751*35238bceSAndroid Build Coastguard Worker "}\n"},
1752*35238bceSAndroid Build Coastguard Worker {"uniform_loop", "Derivate of linearly interpolated value in uniform loop",
1753*35238bceSAndroid Build Coastguard Worker
1754*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1755*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1756*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1757*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1758*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1759*35238bceSAndroid Build Coastguard Worker "uniform int ui_two;\n"
1760*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1761*35238bceSAndroid Build Coastguard Worker "{\n"
1762*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n"
1763*35238bceSAndroid Build Coastguard Worker " for (int i = 0; i < ui_two; i++)\n"
1764*35238bceSAndroid Build Coastguard Worker " res += ${FUNC}(v_coord * float(i));\n"
1765*35238bceSAndroid Build Coastguard Worker " res = res * u_scale + u_bias;\n"
1766*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1767*35238bceSAndroid Build Coastguard Worker "}\n"},
1768*35238bceSAndroid Build Coastguard Worker {"uniform_switch", "Derivate of linearly interpolated value in uniform switch",
1769*35238bceSAndroid Build Coastguard Worker
1770*35238bceSAndroid Build Coastguard Worker "#version 300 es\n"
1771*35238bceSAndroid Build Coastguard Worker "in ${PRECISION} ${DATATYPE} v_coord;\n"
1772*35238bceSAndroid Build Coastguard Worker "layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n"
1773*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_scale;\n"
1774*35238bceSAndroid Build Coastguard Worker "uniform ${PRECISION} ${DATATYPE} u_bias;\n"
1775*35238bceSAndroid Build Coastguard Worker "uniform int ui_one;\n"
1776*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
1777*35238bceSAndroid Build Coastguard Worker "{\n"
1778*35238bceSAndroid Build Coastguard Worker " ${PRECISION} ${DATATYPE} res;\n"
1779*35238bceSAndroid Build Coastguard Worker " switch (ui_one)\n"
1780*35238bceSAndroid Build Coastguard Worker " {\n"
1781*35238bceSAndroid Build Coastguard Worker " case 0: res = ${FUNC}(-v_coord) * u_scale + u_bias; break;\n"
1782*35238bceSAndroid Build Coastguard Worker " case 1: res = ${FUNC}(v_coord) * u_scale + u_bias; break;\n"
1783*35238bceSAndroid Build Coastguard Worker " }\n"
1784*35238bceSAndroid Build Coastguard Worker " o_color = ${CAST_TO_OUTPUT};\n"
1785*35238bceSAndroid Build Coastguard Worker "}\n"},
1786*35238bceSAndroid Build Coastguard Worker };
1787*35238bceSAndroid Build Coastguard Worker
1788*35238bceSAndroid Build Coastguard Worker static const struct
1789*35238bceSAndroid Build Coastguard Worker {
1790*35238bceSAndroid Build Coastguard Worker const char *name;
1791*35238bceSAndroid Build Coastguard Worker SurfaceType surfaceType;
1792*35238bceSAndroid Build Coastguard Worker int numSamples;
1793*35238bceSAndroid Build Coastguard Worker } s_fboConfigs[] = {
1794*35238bceSAndroid Build Coastguard Worker {"fbo", SURFACETYPE_DEFAULT_FRAMEBUFFER, 0},
1795*35238bceSAndroid Build Coastguard Worker {"fbo_msaa2", SURFACETYPE_UNORM_FBO, 2},
1796*35238bceSAndroid Build Coastguard Worker {"fbo_msaa4", SURFACETYPE_UNORM_FBO, 4},
1797*35238bceSAndroid Build Coastguard Worker {"fbo_float", SURFACETYPE_FLOAT_FBO, 0},
1798*35238bceSAndroid Build Coastguard Worker };
1799*35238bceSAndroid Build Coastguard Worker
1800*35238bceSAndroid Build Coastguard Worker static const struct
1801*35238bceSAndroid Build Coastguard Worker {
1802*35238bceSAndroid Build Coastguard Worker const char *name;
1803*35238bceSAndroid Build Coastguard Worker uint32_t hint;
1804*35238bceSAndroid Build Coastguard Worker } s_hints[] = {
1805*35238bceSAndroid Build Coastguard Worker {"fastest", GL_FASTEST},
1806*35238bceSAndroid Build Coastguard Worker {"nicest", GL_NICEST},
1807*35238bceSAndroid Build Coastguard Worker };
1808*35238bceSAndroid Build Coastguard Worker
1809*35238bceSAndroid Build Coastguard Worker static const struct
1810*35238bceSAndroid Build Coastguard Worker {
1811*35238bceSAndroid Build Coastguard Worker const char *name;
1812*35238bceSAndroid Build Coastguard Worker SurfaceType surfaceType;
1813*35238bceSAndroid Build Coastguard Worker int numSamples;
1814*35238bceSAndroid Build Coastguard Worker } s_hintFboConfigs[] = {{"default", SURFACETYPE_DEFAULT_FRAMEBUFFER, 0},
1815*35238bceSAndroid Build Coastguard Worker {"fbo_msaa4", SURFACETYPE_UNORM_FBO, 4},
1816*35238bceSAndroid Build Coastguard Worker {"fbo_float", SURFACETYPE_FLOAT_FBO, 0}};
1817*35238bceSAndroid Build Coastguard Worker
1818*35238bceSAndroid Build Coastguard Worker static const struct
1819*35238bceSAndroid Build Coastguard Worker {
1820*35238bceSAndroid Build Coastguard Worker const char *name;
1821*35238bceSAndroid Build Coastguard Worker SurfaceType surfaceType;
1822*35238bceSAndroid Build Coastguard Worker int numSamples;
1823*35238bceSAndroid Build Coastguard Worker uint32_t hint;
1824*35238bceSAndroid Build Coastguard Worker } s_textureConfigs[] = {
1825*35238bceSAndroid Build Coastguard Worker {"basic", SURFACETYPE_DEFAULT_FRAMEBUFFER, 0, GL_DONT_CARE},
1826*35238bceSAndroid Build Coastguard Worker {"msaa4", SURFACETYPE_UNORM_FBO, 4, GL_DONT_CARE},
1827*35238bceSAndroid Build Coastguard Worker {"float_fastest", SURFACETYPE_FLOAT_FBO, 0, GL_FASTEST},
1828*35238bceSAndroid Build Coastguard Worker {"float_nicest", SURFACETYPE_FLOAT_FBO, 0, GL_NICEST},
1829*35238bceSAndroid Build Coastguard Worker };
1830*35238bceSAndroid Build Coastguard Worker
1831*35238bceSAndroid Build Coastguard Worker // .dfdx, .dfdy, .fwidth
1832*35238bceSAndroid Build Coastguard Worker for (int funcNdx = 0; funcNdx < DERIVATE_LAST; funcNdx++)
1833*35238bceSAndroid Build Coastguard Worker {
1834*35238bceSAndroid Build Coastguard Worker const DerivateFunc function = DerivateFunc(funcNdx);
1835*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const functionGroup =
1836*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, getDerivateFuncCaseName(function), getDerivateFuncName(function));
1837*35238bceSAndroid Build Coastguard Worker addChild(functionGroup);
1838*35238bceSAndroid Build Coastguard Worker
1839*35238bceSAndroid Build Coastguard Worker // .constant - no precision variants, checks that derivate of constant arguments is 0
1840*35238bceSAndroid Build Coastguard Worker {
1841*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const constantGroup =
1842*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "constant", "Derivate of constant argument");
1843*35238bceSAndroid Build Coastguard Worker functionGroup->addChild(constantGroup);
1844*35238bceSAndroid Build Coastguard Worker
1845*35238bceSAndroid Build Coastguard Worker for (int vecSize = 1; vecSize <= 4; vecSize++)
1846*35238bceSAndroid Build Coastguard Worker {
1847*35238bceSAndroid Build Coastguard Worker const glu::DataType dataType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
1848*35238bceSAndroid Build Coastguard Worker constantGroup->addChild(
1849*35238bceSAndroid Build Coastguard Worker new ConstantDerivateCase(m_context, glu::getDataTypeName(dataType), "", function, dataType));
1850*35238bceSAndroid Build Coastguard Worker }
1851*35238bceSAndroid Build Coastguard Worker }
1852*35238bceSAndroid Build Coastguard Worker
1853*35238bceSAndroid Build Coastguard Worker // Cases based on LinearDerivateCase
1854*35238bceSAndroid Build Coastguard Worker for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_linearDerivateCases); caseNdx++)
1855*35238bceSAndroid Build Coastguard Worker {
1856*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const linearCaseGroup = new tcu::TestCaseGroup(
1857*35238bceSAndroid Build Coastguard Worker m_testCtx, s_linearDerivateCases[caseNdx].name, s_linearDerivateCases[caseNdx].description);
1858*35238bceSAndroid Build Coastguard Worker const char *source = s_linearDerivateCases[caseNdx].source;
1859*35238bceSAndroid Build Coastguard Worker functionGroup->addChild(linearCaseGroup);
1860*35238bceSAndroid Build Coastguard Worker
1861*35238bceSAndroid Build Coastguard Worker for (int vecSize = 1; vecSize <= 4; vecSize++)
1862*35238bceSAndroid Build Coastguard Worker {
1863*35238bceSAndroid Build Coastguard Worker for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
1864*35238bceSAndroid Build Coastguard Worker {
1865*35238bceSAndroid Build Coastguard Worker const glu::DataType dataType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
1866*35238bceSAndroid Build Coastguard Worker const glu::Precision precision = glu::Precision(precNdx);
1867*35238bceSAndroid Build Coastguard Worker const SurfaceType surfaceType = SURFACETYPE_DEFAULT_FRAMEBUFFER;
1868*35238bceSAndroid Build Coastguard Worker const int numSamples = 0;
1869*35238bceSAndroid Build Coastguard Worker const uint32_t hint = GL_DONT_CARE;
1870*35238bceSAndroid Build Coastguard Worker ostringstream caseName;
1871*35238bceSAndroid Build Coastguard Worker
1872*35238bceSAndroid Build Coastguard Worker if (caseNdx != 0 && precision == glu::PRECISION_LOWP)
1873*35238bceSAndroid Build Coastguard Worker continue; // Skip as lowp doesn't actually produce any bits when rendered to default FB.
1874*35238bceSAndroid Build Coastguard Worker
1875*35238bceSAndroid Build Coastguard Worker caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
1876*35238bceSAndroid Build Coastguard Worker
1877*35238bceSAndroid Build Coastguard Worker linearCaseGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function,
1878*35238bceSAndroid Build Coastguard Worker dataType, precision, hint, surfaceType, numSamples,
1879*35238bceSAndroid Build Coastguard Worker source));
1880*35238bceSAndroid Build Coastguard Worker }
1881*35238bceSAndroid Build Coastguard Worker }
1882*35238bceSAndroid Build Coastguard Worker }
1883*35238bceSAndroid Build Coastguard Worker
1884*35238bceSAndroid Build Coastguard Worker // Fbo cases
1885*35238bceSAndroid Build Coastguard Worker for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_fboConfigs); caseNdx++)
1886*35238bceSAndroid Build Coastguard Worker {
1887*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const fboGroup =
1888*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, s_fboConfigs[caseNdx].name, "Derivate usage when rendering into FBO");
1889*35238bceSAndroid Build Coastguard Worker const char *source = s_linearDerivateCases[0].source; // use source from .linear group
1890*35238bceSAndroid Build Coastguard Worker const SurfaceType surfaceType = s_fboConfigs[caseNdx].surfaceType;
1891*35238bceSAndroid Build Coastguard Worker const int numSamples = s_fboConfigs[caseNdx].numSamples;
1892*35238bceSAndroid Build Coastguard Worker functionGroup->addChild(fboGroup);
1893*35238bceSAndroid Build Coastguard Worker
1894*35238bceSAndroid Build Coastguard Worker for (int vecSize = 1; vecSize <= 4; vecSize++)
1895*35238bceSAndroid Build Coastguard Worker {
1896*35238bceSAndroid Build Coastguard Worker for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
1897*35238bceSAndroid Build Coastguard Worker {
1898*35238bceSAndroid Build Coastguard Worker const glu::DataType dataType = vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
1899*35238bceSAndroid Build Coastguard Worker const glu::Precision precision = glu::Precision(precNdx);
1900*35238bceSAndroid Build Coastguard Worker const uint32_t hint = GL_DONT_CARE;
1901*35238bceSAndroid Build Coastguard Worker ostringstream caseName;
1902*35238bceSAndroid Build Coastguard Worker
1903*35238bceSAndroid Build Coastguard Worker if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
1904*35238bceSAndroid Build Coastguard Worker continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
1905*35238bceSAndroid Build Coastguard Worker
1906*35238bceSAndroid Build Coastguard Worker caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
1907*35238bceSAndroid Build Coastguard Worker
1908*35238bceSAndroid Build Coastguard Worker fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function, dataType,
1909*35238bceSAndroid Build Coastguard Worker precision, hint, surfaceType, numSamples, source));
1910*35238bceSAndroid Build Coastguard Worker }
1911*35238bceSAndroid Build Coastguard Worker }
1912*35238bceSAndroid Build Coastguard Worker }
1913*35238bceSAndroid Build Coastguard Worker
1914*35238bceSAndroid Build Coastguard Worker // .fastest, .nicest
1915*35238bceSAndroid Build Coastguard Worker for (int hintCaseNdx = 0; hintCaseNdx < DE_LENGTH_OF_ARRAY(s_hints); hintCaseNdx++)
1916*35238bceSAndroid Build Coastguard Worker {
1917*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const hintGroup =
1918*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, s_hints[hintCaseNdx].name, "Shader derivate hints");
1919*35238bceSAndroid Build Coastguard Worker const char *source = s_linearDerivateCases[0].source; // use source from .linear group
1920*35238bceSAndroid Build Coastguard Worker const uint32_t hint = s_hints[hintCaseNdx].hint;
1921*35238bceSAndroid Build Coastguard Worker functionGroup->addChild(hintGroup);
1922*35238bceSAndroid Build Coastguard Worker
1923*35238bceSAndroid Build Coastguard Worker for (int fboCaseNdx = 0; fboCaseNdx < DE_LENGTH_OF_ARRAY(s_hintFboConfigs); fboCaseNdx++)
1924*35238bceSAndroid Build Coastguard Worker {
1925*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const fboGroup =
1926*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, s_hintFboConfigs[fboCaseNdx].name, "");
1927*35238bceSAndroid Build Coastguard Worker const SurfaceType surfaceType = s_hintFboConfigs[fboCaseNdx].surfaceType;
1928*35238bceSAndroid Build Coastguard Worker const int numSamples = s_hintFboConfigs[fboCaseNdx].numSamples;
1929*35238bceSAndroid Build Coastguard Worker hintGroup->addChild(fboGroup);
1930*35238bceSAndroid Build Coastguard Worker
1931*35238bceSAndroid Build Coastguard Worker for (int vecSize = 1; vecSize <= 4; vecSize++)
1932*35238bceSAndroid Build Coastguard Worker {
1933*35238bceSAndroid Build Coastguard Worker for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
1934*35238bceSAndroid Build Coastguard Worker {
1935*35238bceSAndroid Build Coastguard Worker const glu::DataType dataType =
1936*35238bceSAndroid Build Coastguard Worker vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
1937*35238bceSAndroid Build Coastguard Worker const glu::Precision precision = glu::Precision(precNdx);
1938*35238bceSAndroid Build Coastguard Worker ostringstream caseName;
1939*35238bceSAndroid Build Coastguard Worker
1940*35238bceSAndroid Build Coastguard Worker if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
1941*35238bceSAndroid Build Coastguard Worker continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
1942*35238bceSAndroid Build Coastguard Worker
1943*35238bceSAndroid Build Coastguard Worker caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
1944*35238bceSAndroid Build Coastguard Worker
1945*35238bceSAndroid Build Coastguard Worker fboGroup->addChild(new LinearDerivateCase(m_context, caseName.str().c_str(), "", function,
1946*35238bceSAndroid Build Coastguard Worker dataType, precision, hint, surfaceType, numSamples,
1947*35238bceSAndroid Build Coastguard Worker source));
1948*35238bceSAndroid Build Coastguard Worker }
1949*35238bceSAndroid Build Coastguard Worker }
1950*35238bceSAndroid Build Coastguard Worker }
1951*35238bceSAndroid Build Coastguard Worker }
1952*35238bceSAndroid Build Coastguard Worker
1953*35238bceSAndroid Build Coastguard Worker // .texture
1954*35238bceSAndroid Build Coastguard Worker {
1955*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const textureGroup =
1956*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "texture", "Derivate of texture lookup result");
1957*35238bceSAndroid Build Coastguard Worker functionGroup->addChild(textureGroup);
1958*35238bceSAndroid Build Coastguard Worker
1959*35238bceSAndroid Build Coastguard Worker for (int texCaseNdx = 0; texCaseNdx < DE_LENGTH_OF_ARRAY(s_textureConfigs); texCaseNdx++)
1960*35238bceSAndroid Build Coastguard Worker {
1961*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *const caseGroup =
1962*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, s_textureConfigs[texCaseNdx].name, "");
1963*35238bceSAndroid Build Coastguard Worker const SurfaceType surfaceType = s_textureConfigs[texCaseNdx].surfaceType;
1964*35238bceSAndroid Build Coastguard Worker const int numSamples = s_textureConfigs[texCaseNdx].numSamples;
1965*35238bceSAndroid Build Coastguard Worker const uint32_t hint = s_textureConfigs[texCaseNdx].hint;
1966*35238bceSAndroid Build Coastguard Worker textureGroup->addChild(caseGroup);
1967*35238bceSAndroid Build Coastguard Worker
1968*35238bceSAndroid Build Coastguard Worker for (int vecSize = 1; vecSize <= 4; vecSize++)
1969*35238bceSAndroid Build Coastguard Worker {
1970*35238bceSAndroid Build Coastguard Worker for (int precNdx = 0; precNdx < glu::PRECISION_LAST; precNdx++)
1971*35238bceSAndroid Build Coastguard Worker {
1972*35238bceSAndroid Build Coastguard Worker const glu::DataType dataType =
1973*35238bceSAndroid Build Coastguard Worker vecSize > 1 ? glu::getDataTypeFloatVec(vecSize) : glu::TYPE_FLOAT;
1974*35238bceSAndroid Build Coastguard Worker const glu::Precision precision = glu::Precision(precNdx);
1975*35238bceSAndroid Build Coastguard Worker ostringstream caseName;
1976*35238bceSAndroid Build Coastguard Worker
1977*35238bceSAndroid Build Coastguard Worker if (surfaceType != SURFACETYPE_FLOAT_FBO && precision == glu::PRECISION_LOWP)
1978*35238bceSAndroid Build Coastguard Worker continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
1979*35238bceSAndroid Build Coastguard Worker
1980*35238bceSAndroid Build Coastguard Worker caseName << glu::getDataTypeName(dataType) << "_" << glu::getPrecisionName(precision);
1981*35238bceSAndroid Build Coastguard Worker
1982*35238bceSAndroid Build Coastguard Worker caseGroup->addChild(new TextureDerivateCase(m_context, caseName.str().c_str(), "", function,
1983*35238bceSAndroid Build Coastguard Worker dataType, precision, hint, surfaceType,
1984*35238bceSAndroid Build Coastguard Worker numSamples));
1985*35238bceSAndroid Build Coastguard Worker }
1986*35238bceSAndroid Build Coastguard Worker }
1987*35238bceSAndroid Build Coastguard Worker }
1988*35238bceSAndroid Build Coastguard Worker }
1989*35238bceSAndroid Build Coastguard Worker }
1990*35238bceSAndroid Build Coastguard Worker }
1991*35238bceSAndroid Build Coastguard Worker
1992*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1993*35238bceSAndroid Build Coastguard Worker } // namespace gles3
1994*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1995