xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fShaderBuiltinVarTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.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 built-in variable tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fShaderBuiltinVarTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsShaderRenderCase.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deString.h"
28*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
29*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTestCase.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker using std::string;
42*35238bceSAndroid Build Coastguard Worker using std::vector;
43*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker namespace deqp
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker namespace gles2
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker namespace Functional
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker const float builtinConstScale = 4.0f;
53*35238bceSAndroid Build Coastguard Worker 
evalBuiltinConstant(gls::ShaderEvalContext & c)54*35238bceSAndroid Build Coastguard Worker void evalBuiltinConstant(gls::ShaderEvalContext &c)
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker     bool isOk = 0 == (int)(deFloatFloor(c.coords.x() * builtinConstScale) + 0.05f);
57*35238bceSAndroid Build Coastguard Worker     c.color   = isOk ? tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f) : tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
58*35238bceSAndroid Build Coastguard Worker }
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker class ShaderBuiltinConstantCase : public gls::ShaderRenderCase
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker public:
63*35238bceSAndroid Build Coastguard Worker     ShaderBuiltinConstantCase(Context &context, const char *name, const char *desc, const char *varName,
64*35238bceSAndroid Build Coastguard Worker                               uint32_t paramName, bool isVertexCase);
65*35238bceSAndroid Build Coastguard Worker     ~ShaderBuiltinConstantCase(void);
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker     int getRefValue(void);
68*35238bceSAndroid Build Coastguard Worker     void init(void);
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker private:
71*35238bceSAndroid Build Coastguard Worker     const std::string m_varName;
72*35238bceSAndroid Build Coastguard Worker     const uint32_t m_paramName;
73*35238bceSAndroid Build Coastguard Worker };
74*35238bceSAndroid Build Coastguard Worker 
ShaderBuiltinConstantCase(Context & context,const char * name,const char * desc,const char * varName,uint32_t paramName,bool isVertexCase)75*35238bceSAndroid Build Coastguard Worker ShaderBuiltinConstantCase::ShaderBuiltinConstantCase(Context &context, const char *name, const char *desc,
76*35238bceSAndroid Build Coastguard Worker                                                      const char *varName, uint32_t paramName, bool isVertexCase)
77*35238bceSAndroid Build Coastguard Worker     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc,
78*35238bceSAndroid Build Coastguard Worker                        isVertexCase, evalBuiltinConstant)
79*35238bceSAndroid Build Coastguard Worker     , m_varName(varName)
80*35238bceSAndroid Build Coastguard Worker     , m_paramName(paramName)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker 
~ShaderBuiltinConstantCase(void)84*35238bceSAndroid Build Coastguard Worker ShaderBuiltinConstantCase::~ShaderBuiltinConstantCase(void)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker 
getRefValue(void)88*35238bceSAndroid Build Coastguard Worker int ShaderBuiltinConstantCase::getRefValue(void)
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker     if (m_varName == "gl_MaxDrawBuffers")
91*35238bceSAndroid Build Coastguard Worker     {
92*35238bceSAndroid Build Coastguard Worker         if (m_ctxInfo.isExtensionSupported("GL_EXT_draw_buffers") ||
93*35238bceSAndroid Build Coastguard Worker             m_ctxInfo.isExtensionSupported("GL_NV_draw_buffers") || m_ctxInfo.isES3Compatible())
94*35238bceSAndroid Build Coastguard Worker             return m_ctxInfo.getInt(GL_MAX_DRAW_BUFFERS);
95*35238bceSAndroid Build Coastguard Worker         else
96*35238bceSAndroid Build Coastguard Worker             return 1;
97*35238bceSAndroid Build Coastguard Worker     }
98*35238bceSAndroid Build Coastguard Worker     else
99*35238bceSAndroid Build Coastguard Worker     {
100*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_paramName != GL_NONE);
101*35238bceSAndroid Build Coastguard Worker         return m_ctxInfo.getInt(m_paramName);
102*35238bceSAndroid Build Coastguard Worker     }
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker 
init(void)105*35238bceSAndroid Build Coastguard Worker void ShaderBuiltinConstantCase::init(void)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker     const int refValue = getRefValue();
108*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << m_varName << " = " << refValue << tcu::TestLog::EndMessage;
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     static const char *defaultVertSrc = "attribute highp vec4 a_position;\n"
111*35238bceSAndroid Build Coastguard Worker                                         "attribute highp vec4 a_coords;\n"
112*35238bceSAndroid Build Coastguard Worker                                         "varying mediump vec4 v_coords;\n\n"
113*35238bceSAndroid Build Coastguard Worker                                         "void main (void)\n"
114*35238bceSAndroid Build Coastguard Worker                                         "{\n"
115*35238bceSAndroid Build Coastguard Worker                                         "    v_coords = a_coords;\n"
116*35238bceSAndroid Build Coastguard Worker                                         "    gl_Position = a_position;\n"
117*35238bceSAndroid Build Coastguard Worker                                         "}\n";
118*35238bceSAndroid Build Coastguard Worker     static const char *defaultFragSrc = "varying mediump vec4 v_color;\n\n"
119*35238bceSAndroid Build Coastguard Worker                                         "void main (void)\n"
120*35238bceSAndroid Build Coastguard Worker                                         "{\n"
121*35238bceSAndroid Build Coastguard Worker                                         "    gl_FragColor = v_color;\n"
122*35238bceSAndroid Build Coastguard Worker                                         "}\n";
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker     // Construct shader.
125*35238bceSAndroid Build Coastguard Worker     std::ostringstream src;
126*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
127*35238bceSAndroid Build Coastguard Worker     {
128*35238bceSAndroid Build Coastguard Worker         src << "attribute highp vec4 a_position;\n"
129*35238bceSAndroid Build Coastguard Worker             << "attribute highp vec4 a_coords;\n"
130*35238bceSAndroid Build Coastguard Worker             << "varying mediump vec4 v_color;\n";
131*35238bceSAndroid Build Coastguard Worker     }
132*35238bceSAndroid Build Coastguard Worker     else
133*35238bceSAndroid Build Coastguard Worker         src << "varying mediump vec4 v_coords;\n";
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     src << "void main (void)\n{\n";
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker     src << "\tbool isOk = " << m_varName << " == (" << refValue << " + int(floor("
138*35238bceSAndroid Build Coastguard Worker         << (m_isVertexCase ? "a_coords" : "v_coords") << ".x * " << de::floatToString(builtinConstScale, 1)
139*35238bceSAndroid Build Coastguard Worker         << ") + 0.05));\n";
140*35238bceSAndroid Build Coastguard Worker     src << "\t" << (m_isVertexCase ? "v_color" : "gl_FragColor")
141*35238bceSAndroid Build Coastguard Worker         << " = isOk ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);\n";
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker     if (m_isVertexCase)
144*35238bceSAndroid Build Coastguard Worker         src << "\tgl_Position = a_position;\n";
145*35238bceSAndroid Build Coastguard Worker 
146*35238bceSAndroid Build Coastguard Worker     src << "}\n";
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker     m_vertShaderSource = m_isVertexCase ? src.str() : defaultVertSrc;
149*35238bceSAndroid Build Coastguard Worker     m_fragShaderSource = m_isVertexCase ? defaultFragSrc : src.str();
150*35238bceSAndroid Build Coastguard Worker 
151*35238bceSAndroid Build Coastguard Worker     gls::ShaderRenderCase::init();
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker 
154*35238bceSAndroid Build Coastguard Worker namespace
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker struct DepthRangeParams
158*35238bceSAndroid Build Coastguard Worker {
DepthRangeParamsdeqp::gles2::Functional::__anonac2a45210111::DepthRangeParams159*35238bceSAndroid Build Coastguard Worker     DepthRangeParams(void) : zNear(0.0f), zFar(1.0f)
160*35238bceSAndroid Build Coastguard Worker     {
161*35238bceSAndroid Build Coastguard Worker     }
162*35238bceSAndroid Build Coastguard Worker 
DepthRangeParamsdeqp::gles2::Functional::__anonac2a45210111::DepthRangeParams163*35238bceSAndroid Build Coastguard Worker     DepthRangeParams(float zNear_, float zFar_) : zNear(zNear_), zFar(zFar_)
164*35238bceSAndroid Build Coastguard Worker     {
165*35238bceSAndroid Build Coastguard Worker     }
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker     float zNear;
168*35238bceSAndroid Build Coastguard Worker     float zFar;
169*35238bceSAndroid Build Coastguard Worker };
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker class DepthRangeEvaluator : public gls::ShaderEvaluator
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker public:
DepthRangeEvaluator(const DepthRangeParams & params)174*35238bceSAndroid Build Coastguard Worker     DepthRangeEvaluator(const DepthRangeParams &params) : m_params(params)
175*35238bceSAndroid Build Coastguard Worker     {
176*35238bceSAndroid Build Coastguard Worker     }
177*35238bceSAndroid Build Coastguard Worker 
evaluate(gls::ShaderEvalContext & c)178*35238bceSAndroid Build Coastguard Worker     void evaluate(gls::ShaderEvalContext &c)
179*35238bceSAndroid Build Coastguard Worker     {
180*35238bceSAndroid Build Coastguard Worker         float zNear   = deFloatClamp(m_params.zNear, 0.0f, 1.0f);
181*35238bceSAndroid Build Coastguard Worker         float zFar    = deFloatClamp(m_params.zFar, 0.0f, 1.0f);
182*35238bceSAndroid Build Coastguard Worker         float diff    = zFar - zNear;
183*35238bceSAndroid Build Coastguard Worker         c.color.xyz() = tcu::Vec3(zNear, zFar, diff * 0.5f + 0.5f);
184*35238bceSAndroid Build Coastguard Worker     }
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker private:
187*35238bceSAndroid Build Coastguard Worker     const DepthRangeParams &m_params;
188*35238bceSAndroid Build Coastguard Worker };
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker } // namespace
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker class ShaderDepthRangeTest : public gls::ShaderRenderCase
193*35238bceSAndroid Build Coastguard Worker {
194*35238bceSAndroid Build Coastguard Worker public:
ShaderDepthRangeTest(Context & context,const char * name,const char * desc,bool isVertexCase)195*35238bceSAndroid Build Coastguard Worker     ShaderDepthRangeTest(Context &context, const char *name, const char *desc, bool isVertexCase)
196*35238bceSAndroid Build Coastguard Worker         : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc,
197*35238bceSAndroid Build Coastguard Worker                            isVertexCase, m_evaluator)
198*35238bceSAndroid Build Coastguard Worker         , m_evaluator(m_depthRange)
199*35238bceSAndroid Build Coastguard Worker         , m_iterNdx(0)
200*35238bceSAndroid Build Coastguard Worker     {
201*35238bceSAndroid Build Coastguard Worker     }
202*35238bceSAndroid Build Coastguard Worker 
init(void)203*35238bceSAndroid Build Coastguard Worker     void init(void)
204*35238bceSAndroid Build Coastguard Worker     {
205*35238bceSAndroid Build Coastguard Worker         static const char *defaultVertSrc = "attribute highp vec4 a_position;\n"
206*35238bceSAndroid Build Coastguard Worker                                             "void main (void)\n"
207*35238bceSAndroid Build Coastguard Worker                                             "{\n"
208*35238bceSAndroid Build Coastguard Worker                                             "    gl_Position = a_position;\n"
209*35238bceSAndroid Build Coastguard Worker                                             "}\n";
210*35238bceSAndroid Build Coastguard Worker         static const char *defaultFragSrc = "varying mediump vec4 v_color;\n\n"
211*35238bceSAndroid Build Coastguard Worker                                             "void main (void)\n"
212*35238bceSAndroid Build Coastguard Worker                                             "{\n"
213*35238bceSAndroid Build Coastguard Worker                                             "    gl_FragColor = v_color;\n"
214*35238bceSAndroid Build Coastguard Worker                                             "}\n";
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker         // Construct shader.
217*35238bceSAndroid Build Coastguard Worker         std::ostringstream src;
218*35238bceSAndroid Build Coastguard Worker         if (m_isVertexCase)
219*35238bceSAndroid Build Coastguard Worker             src << "attribute highp vec4 a_position;\n"
220*35238bceSAndroid Build Coastguard Worker                 << "varying mediump vec4 v_color;\n";
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker         src << "void main (void)\n{\n";
223*35238bceSAndroid Build Coastguard Worker         src << "\t" << (m_isVertexCase ? "v_color" : "gl_FragColor")
224*35238bceSAndroid Build Coastguard Worker             << " = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n";
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker         if (m_isVertexCase)
227*35238bceSAndroid Build Coastguard Worker             src << "\tgl_Position = a_position;\n";
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker         src << "}\n";
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker         m_vertShaderSource = m_isVertexCase ? src.str() : defaultVertSrc;
232*35238bceSAndroid Build Coastguard Worker         m_fragShaderSource = m_isVertexCase ? defaultFragSrc : src.str();
233*35238bceSAndroid Build Coastguard Worker 
234*35238bceSAndroid Build Coastguard Worker         gls::ShaderRenderCase::init();
235*35238bceSAndroid Build Coastguard Worker     }
236*35238bceSAndroid Build Coastguard Worker 
iterate(void)237*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
238*35238bceSAndroid Build Coastguard Worker     {
239*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_renderCtx.getFunctions();
240*35238bceSAndroid Build Coastguard Worker 
241*35238bceSAndroid Build Coastguard Worker         const DepthRangeParams cases[] = {DepthRangeParams(0.0f, 1.0f), DepthRangeParams(1.5f, -1.0f),
242*35238bceSAndroid Build Coastguard Worker                                           DepthRangeParams(0.7f, 0.3f)};
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker         m_depthRange = cases[m_iterNdx];
245*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "glDepthRangef(" << m_depthRange.zNear << ", "
246*35238bceSAndroid Build Coastguard Worker                            << m_depthRange.zFar << ")" << tcu::TestLog::EndMessage;
247*35238bceSAndroid Build Coastguard Worker         gl.depthRangef(m_depthRange.zNear, m_depthRange.zFar);
248*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthRangef()");
249*35238bceSAndroid Build Coastguard Worker 
250*35238bceSAndroid Build Coastguard Worker         gls::ShaderRenderCase::iterate();
251*35238bceSAndroid Build Coastguard Worker         m_iterNdx += 1;
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker         if (m_iterNdx == DE_LENGTH_OF_ARRAY(cases) || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
254*35238bceSAndroid Build Coastguard Worker             return STOP;
255*35238bceSAndroid Build Coastguard Worker         else
256*35238bceSAndroid Build Coastguard Worker             return CONTINUE;
257*35238bceSAndroid Build Coastguard Worker     }
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker private:
260*35238bceSAndroid Build Coastguard Worker     DepthRangeParams m_depthRange;
261*35238bceSAndroid Build Coastguard Worker     DepthRangeEvaluator m_evaluator;
262*35238bceSAndroid Build Coastguard Worker     int m_iterNdx;
263*35238bceSAndroid Build Coastguard Worker };
264*35238bceSAndroid Build Coastguard Worker 
265*35238bceSAndroid Build Coastguard Worker class FragCoordXYZCase : public TestCase
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker public:
FragCoordXYZCase(Context & context)268*35238bceSAndroid Build Coastguard Worker     FragCoordXYZCase(Context &context) : TestCase(context, "fragcoord_xyz", "gl_FragCoord.xyz Test")
269*35238bceSAndroid Build Coastguard Worker     {
270*35238bceSAndroid Build Coastguard Worker     }
271*35238bceSAndroid Build Coastguard Worker 
iterate(void)272*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
273*35238bceSAndroid Build Coastguard Worker     {
274*35238bceSAndroid Build Coastguard Worker         TestLog &log             = m_testCtx.getLog();
275*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
276*35238bceSAndroid Build Coastguard Worker         const int width          = m_context.getRenderTarget().getWidth();
277*35238bceSAndroid Build Coastguard Worker         const int height         = m_context.getRenderTarget().getHeight();
278*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold =
279*35238bceSAndroid Build Coastguard Worker             tcu::RGBA(1, 1, 1, 1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
280*35238bceSAndroid Build Coastguard Worker         const tcu::Vec3 scale(1.f / float(width), 1.f / float(height), 1.0f);
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker         tcu::Surface testImg(width, height);
283*35238bceSAndroid Build Coastguard Worker         tcu::Surface refImg(width, height);
284*35238bceSAndroid Build Coastguard Worker 
285*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(
286*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(),
287*35238bceSAndroid Build Coastguard Worker             glu::makeVtxFragSources("attribute highp vec4 a_position;\n"
288*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
289*35238bceSAndroid Build Coastguard Worker                                     "{\n"
290*35238bceSAndroid Build Coastguard Worker                                     "    gl_Position = a_position;\n"
291*35238bceSAndroid Build Coastguard Worker                                     "}\n",
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker                                     "uniform mediump vec3 u_scale;\n"
294*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
295*35238bceSAndroid Build Coastguard Worker                                     "{\n"
296*35238bceSAndroid Build Coastguard Worker                                     "    gl_FragColor = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n"
297*35238bceSAndroid Build Coastguard Worker                                     "}\n"));
298*35238bceSAndroid Build Coastguard Worker 
299*35238bceSAndroid Build Coastguard Worker         log << program;
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
302*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Compile failed");
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker         // Draw with GL.
305*35238bceSAndroid Build Coastguard Worker         {
306*35238bceSAndroid Build Coastguard Worker             const float positions[]  = {-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f,
307*35238bceSAndroid Build Coastguard Worker                                         1.0f,  1.0f, 0.0f,  1.0f, 1.0f,  -1.0f, 1.0f, 1.0f};
308*35238bceSAndroid Build Coastguard Worker             const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker             const int scaleLoc                 = gl.getUniformLocation(program.getProgram(), "u_scale");
311*35238bceSAndroid Build Coastguard Worker             glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &positions[0]);
312*35238bceSAndroid Build Coastguard Worker 
313*35238bceSAndroid Build Coastguard Worker             gl.useProgram(program.getProgram());
314*35238bceSAndroid Build Coastguard Worker             gl.uniform3fv(scaleLoc, 1, scale.getPtr());
315*35238bceSAndroid Build Coastguard Worker 
316*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
317*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
320*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
321*35238bceSAndroid Build Coastguard Worker         }
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker         // Draw reference
324*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < refImg.getHeight(); y++)
325*35238bceSAndroid Build Coastguard Worker         {
326*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < refImg.getWidth(); x++)
327*35238bceSAndroid Build Coastguard Worker             {
328*35238bceSAndroid Build Coastguard Worker                 const float xf = (float(x) + .5f) / float(refImg.getWidth());
329*35238bceSAndroid Build Coastguard Worker                 const float yf = (float(refImg.getHeight() - y - 1) + .5f) / float(refImg.getHeight());
330*35238bceSAndroid Build Coastguard Worker                 const float z  = (xf + yf) / 2.0f;
331*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 fragCoord(float(x) + .5f, float(y) + .5f, z);
332*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 scaledFC = fragCoord * scale;
333*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 color(scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker                 refImg.setPixel(x, y, tcu::RGBA(color));
336*35238bceSAndroid Build Coastguard Worker             }
337*35238bceSAndroid Build Coastguard Worker         }
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker         // Compare
340*35238bceSAndroid Build Coastguard Worker         {
341*35238bceSAndroid Build Coastguard Worker             bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold,
342*35238bceSAndroid Build Coastguard Worker                                                    tcu::COMPARE_LOG_RESULT);
343*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
344*35238bceSAndroid Build Coastguard Worker                                     isOk ? "Pass" : "Image comparison failed");
345*35238bceSAndroid Build Coastguard Worker         }
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker         return STOP;
348*35238bceSAndroid Build Coastguard Worker     }
349*35238bceSAndroid Build Coastguard Worker };
350*35238bceSAndroid Build Coastguard Worker 
projectedTriInterpolate(const tcu::Vec3 & s,const tcu::Vec3 & w,float nx,float ny)351*35238bceSAndroid Build Coastguard Worker static inline float projectedTriInterpolate(const tcu::Vec3 &s, const tcu::Vec3 &w, float nx, float ny)
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker     return (s[0] * (1.0f - nx - ny) / w[0] + s[1] * ny / w[1] + s[2] * nx / w[2]) /
354*35238bceSAndroid Build Coastguard Worker            ((1.0f - nx - ny) / w[0] + ny / w[1] + nx / w[2]);
355*35238bceSAndroid Build Coastguard Worker }
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker class FragCoordWCase : public TestCase
358*35238bceSAndroid Build Coastguard Worker {
359*35238bceSAndroid Build Coastguard Worker public:
FragCoordWCase(Context & context)360*35238bceSAndroid Build Coastguard Worker     FragCoordWCase(Context &context) : TestCase(context, "fragcoord_w", "gl_FragCoord.w Test")
361*35238bceSAndroid Build Coastguard Worker     {
362*35238bceSAndroid Build Coastguard Worker     }
363*35238bceSAndroid Build Coastguard Worker 
iterate(void)364*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
365*35238bceSAndroid Build Coastguard Worker     {
366*35238bceSAndroid Build Coastguard Worker         TestLog &log             = m_testCtx.getLog();
367*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
368*35238bceSAndroid Build Coastguard Worker         const int width          = m_context.getRenderTarget().getWidth();
369*35238bceSAndroid Build Coastguard Worker         const int height         = m_context.getRenderTarget().getHeight();
370*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold =
371*35238bceSAndroid Build Coastguard Worker             tcu::RGBA(1, 1, 1, 1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker         tcu::Surface testImg(width, height);
374*35238bceSAndroid Build Coastguard Worker         tcu::Surface refImg(width, height);
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker         const float w[4] = {1.7f, 2.0f, 1.2f, 1.0f};
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(
379*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(),
380*35238bceSAndroid Build Coastguard Worker             glu::makeVtxFragSources("attribute highp vec4 a_position;\n"
381*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
382*35238bceSAndroid Build Coastguard Worker                                     "{\n"
383*35238bceSAndroid Build Coastguard Worker                                     "    gl_Position = a_position;\n"
384*35238bceSAndroid Build Coastguard Worker                                     "}\n",
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
387*35238bceSAndroid Build Coastguard Worker                                     "{\n"
388*35238bceSAndroid Build Coastguard Worker                                     "    gl_FragColor = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
389*35238bceSAndroid Build Coastguard Worker                                     "}\n"));
390*35238bceSAndroid Build Coastguard Worker 
391*35238bceSAndroid Build Coastguard Worker         log << program;
392*35238bceSAndroid Build Coastguard Worker 
393*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
394*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Compile failed");
395*35238bceSAndroid Build Coastguard Worker 
396*35238bceSAndroid Build Coastguard Worker         // Draw with GL.
397*35238bceSAndroid Build Coastguard Worker         {
398*35238bceSAndroid Build Coastguard Worker             const float positions[]  = {-w[0], w[0], 0.0f, w[0], -w[1], -w[1], 0.0f, w[1],
399*35238bceSAndroid Build Coastguard Worker                                         w[2],  w[2], 0.0f, w[2], w[3],  -w[3], 0.0f, w[3]};
400*35238bceSAndroid Build Coastguard Worker             const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
401*35238bceSAndroid Build Coastguard Worker 
402*35238bceSAndroid Build Coastguard Worker             glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &positions[0]);
403*35238bceSAndroid Build Coastguard Worker 
404*35238bceSAndroid Build Coastguard Worker             gl.useProgram(program.getProgram());
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
407*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
408*35238bceSAndroid Build Coastguard Worker 
409*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_context.getRenderContext(), 0, 0, testImg.getAccess());
410*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
411*35238bceSAndroid Build Coastguard Worker         }
412*35238bceSAndroid Build Coastguard Worker 
413*35238bceSAndroid Build Coastguard Worker         // Draw reference
414*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < refImg.getHeight(); y++)
415*35238bceSAndroid Build Coastguard Worker         {
416*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < refImg.getWidth(); x++)
417*35238bceSAndroid Build Coastguard Worker             {
418*35238bceSAndroid Build Coastguard Worker                 const float xf = (float(x) + .5f) / float(refImg.getWidth());
419*35238bceSAndroid Build Coastguard Worker                 const float yf = (float(refImg.getHeight() - y - 1) + .5f) / float(refImg.getHeight());
420*35238bceSAndroid Build Coastguard Worker                 const float oow =
421*35238bceSAndroid Build Coastguard Worker                     ((xf + yf) < 1.0f) ?
422*35238bceSAndroid Build Coastguard Worker                         projectedTriInterpolate(tcu::Vec3(w[0], w[1], w[2]), tcu::Vec3(w[0], w[1], w[2]), xf, yf) :
423*35238bceSAndroid Build Coastguard Worker                         projectedTriInterpolate(tcu::Vec3(w[3], w[2], w[1]), tcu::Vec3(w[3], w[2], w[1]), 1.0f - xf,
424*35238bceSAndroid Build Coastguard Worker                                                 1.0f - yf);
425*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 color(0.0f, oow - 1.0f, 0.0f, 1.0f);
426*35238bceSAndroid Build Coastguard Worker 
427*35238bceSAndroid Build Coastguard Worker                 refImg.setPixel(x, y, tcu::RGBA(color));
428*35238bceSAndroid Build Coastguard Worker             }
429*35238bceSAndroid Build Coastguard Worker         }
430*35238bceSAndroid Build Coastguard Worker 
431*35238bceSAndroid Build Coastguard Worker         // Compare
432*35238bceSAndroid Build Coastguard Worker         {
433*35238bceSAndroid Build Coastguard Worker             bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold,
434*35238bceSAndroid Build Coastguard Worker                                                    tcu::COMPARE_LOG_RESULT);
435*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
436*35238bceSAndroid Build Coastguard Worker                                     isOk ? "Pass" : "Image comparison failed");
437*35238bceSAndroid Build Coastguard Worker         }
438*35238bceSAndroid Build Coastguard Worker 
439*35238bceSAndroid Build Coastguard Worker         return STOP;
440*35238bceSAndroid Build Coastguard Worker     }
441*35238bceSAndroid Build Coastguard Worker };
442*35238bceSAndroid Build Coastguard Worker 
443*35238bceSAndroid Build Coastguard Worker class PointCoordCase : public TestCase
444*35238bceSAndroid Build Coastguard Worker {
445*35238bceSAndroid Build Coastguard Worker public:
PointCoordCase(Context & context)446*35238bceSAndroid Build Coastguard Worker     PointCoordCase(Context &context) : TestCase(context, "pointcoord", "gl_PointCoord Test")
447*35238bceSAndroid Build Coastguard Worker     {
448*35238bceSAndroid Build Coastguard Worker     }
449*35238bceSAndroid Build Coastguard Worker 
iterate(void)450*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
451*35238bceSAndroid Build Coastguard Worker     {
452*35238bceSAndroid Build Coastguard Worker         TestLog &log             = m_testCtx.getLog();
453*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
454*35238bceSAndroid Build Coastguard Worker         const int width          = de::min(256, m_context.getRenderTarget().getWidth());
455*35238bceSAndroid Build Coastguard Worker         const int height         = de::min(256, m_context.getRenderTarget().getHeight());
456*35238bceSAndroid Build Coastguard Worker         const float threshold    = 0.02f;
457*35238bceSAndroid Build Coastguard Worker 
458*35238bceSAndroid Build Coastguard Worker         const int numPoints = 8;
459*35238bceSAndroid Build Coastguard Worker 
460*35238bceSAndroid Build Coastguard Worker         vector<tcu::Vec3> coords(numPoints);
461*35238bceSAndroid Build Coastguard Worker         float pointSizeRange[2] = {0.0f, 0.0f};
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker         de::Random rnd(0x145fa);
464*35238bceSAndroid Build Coastguard Worker         tcu::Surface testImg(width, height);
465*35238bceSAndroid Build Coastguard Worker         tcu::Surface refImg(width, height);
466*35238bceSAndroid Build Coastguard Worker 
467*35238bceSAndroid Build Coastguard Worker         gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, &pointSizeRange[0]);
468*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE)");
469*35238bceSAndroid Build Coastguard Worker 
470*35238bceSAndroid Build Coastguard Worker         if (pointSizeRange[0] <= 0.0f || pointSizeRange[1] <= 0.0f || pointSizeRange[1] < pointSizeRange[0])
471*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Invalid GL_ALIASED_POINT_SIZE_RANGE");
472*35238bceSAndroid Build Coastguard Worker 
473*35238bceSAndroid Build Coastguard Worker         // Compute coordinates.
474*35238bceSAndroid Build Coastguard Worker         {
475*35238bceSAndroid Build Coastguard Worker 
476*35238bceSAndroid Build Coastguard Worker             for (vector<tcu::Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
477*35238bceSAndroid Build Coastguard Worker             {
478*35238bceSAndroid Build Coastguard Worker                 coord->x() = rnd.getFloat(-0.9f, 0.9f);
479*35238bceSAndroid Build Coastguard Worker                 coord->y() = rnd.getFloat(-0.9f, 0.9f);
480*35238bceSAndroid Build Coastguard Worker                 coord->z() = rnd.getFloat(pointSizeRange[0], pointSizeRange[1]);
481*35238bceSAndroid Build Coastguard Worker             }
482*35238bceSAndroid Build Coastguard Worker         }
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(
485*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(),
486*35238bceSAndroid Build Coastguard Worker             glu::makeVtxFragSources("attribute highp vec3 a_positionSize;\n"
487*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
488*35238bceSAndroid Build Coastguard Worker                                     "{\n"
489*35238bceSAndroid Build Coastguard Worker                                     "    gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n"
490*35238bceSAndroid Build Coastguard Worker                                     "    gl_PointSize = a_positionSize.z;\n"
491*35238bceSAndroid Build Coastguard Worker                                     "}\n",
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker                                     "void main (void)\n"
494*35238bceSAndroid Build Coastguard Worker                                     "{\n"
495*35238bceSAndroid Build Coastguard Worker                                     "    gl_FragColor = vec4(gl_PointCoord, 0.0, 1.0);\n"
496*35238bceSAndroid Build Coastguard Worker                                     "}\n"));
497*35238bceSAndroid Build Coastguard Worker 
498*35238bceSAndroid Build Coastguard Worker         log << program;
499*35238bceSAndroid Build Coastguard Worker 
500*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
501*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Compile failed");
502*35238bceSAndroid Build Coastguard Worker 
503*35238bceSAndroid Build Coastguard Worker         // Draw with GL.
504*35238bceSAndroid Build Coastguard Worker         {
505*35238bceSAndroid Build Coastguard Worker             glu::VertexArrayBinding posBinding =
506*35238bceSAndroid Build Coastguard Worker                 glu::va::Float("a_positionSize", 3, (int)coords.size(), 0, (const float *)&coords[0]);
507*35238bceSAndroid Build Coastguard Worker             const int viewportX = rnd.getInt(0, m_context.getRenderTarget().getWidth() - width);
508*35238bceSAndroid Build Coastguard Worker             const int viewportY = rnd.getInt(0, m_context.getRenderTarget().getHeight() - height);
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker             gl.viewport(viewportX, viewportY, width, height);
511*35238bceSAndroid Build Coastguard Worker             gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
512*35238bceSAndroid Build Coastguard Worker             gl.clear(GL_COLOR_BUFFER_BIT);
513*35238bceSAndroid Build Coastguard Worker 
514*35238bceSAndroid Build Coastguard Worker             gl.useProgram(program.getProgram());
515*35238bceSAndroid Build Coastguard Worker 
516*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
517*35238bceSAndroid Build Coastguard Worker                       glu::pr::Points((int)coords.size()));
518*35238bceSAndroid Build Coastguard Worker 
519*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
520*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
521*35238bceSAndroid Build Coastguard Worker         }
522*35238bceSAndroid Build Coastguard Worker 
523*35238bceSAndroid Build Coastguard Worker         // Draw reference
524*35238bceSAndroid Build Coastguard Worker         tcu::clear(refImg.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
525*35238bceSAndroid Build Coastguard Worker         for (vector<tcu::Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
526*35238bceSAndroid Build Coastguard Worker         {
527*35238bceSAndroid Build Coastguard Worker             const int x0 = deRoundFloatToInt32(float(width) * (pointIter->x() * 0.5f + 0.5f) - pointIter->z() * 0.5f);
528*35238bceSAndroid Build Coastguard Worker             const int y0 = deRoundFloatToInt32(float(height) * (pointIter->y() * 0.5f + 0.5f) - pointIter->z() * 0.5f);
529*35238bceSAndroid Build Coastguard Worker             const int x1 = deRoundFloatToInt32(float(width) * (pointIter->x() * 0.5f + 0.5f) + pointIter->z() * 0.5f);
530*35238bceSAndroid Build Coastguard Worker             const int y1 = deRoundFloatToInt32(float(height) * (pointIter->y() * 0.5f + 0.5f) + pointIter->z() * 0.5f);
531*35238bceSAndroid Build Coastguard Worker             const int w  = x1 - x0;
532*35238bceSAndroid Build Coastguard Worker             const int h  = y1 - y0;
533*35238bceSAndroid Build Coastguard Worker 
534*35238bceSAndroid Build Coastguard Worker             for (int yo = 0; yo < h; yo++)
535*35238bceSAndroid Build Coastguard Worker             {
536*35238bceSAndroid Build Coastguard Worker                 for (int xo = 0; xo < w; xo++)
537*35238bceSAndroid Build Coastguard Worker                 {
538*35238bceSAndroid Build Coastguard Worker                     const float xf = (float(xo) + 0.5f) / float(w);
539*35238bceSAndroid Build Coastguard Worker                     const float yf = (float(h - yo - 1) + 0.5f) / float(h);
540*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec4 color(xf, yf, 0.0f, 1.0f);
541*35238bceSAndroid Build Coastguard Worker                     const int dx = x0 + xo;
542*35238bceSAndroid Build Coastguard Worker                     const int dy = y0 + yo;
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker                     if (de::inBounds(dx, 0, refImg.getWidth()) && de::inBounds(dy, 0, refImg.getHeight()))
545*35238bceSAndroid Build Coastguard Worker                         refImg.setPixel(dx, dy, tcu::RGBA(color));
546*35238bceSAndroid Build Coastguard Worker                 }
547*35238bceSAndroid Build Coastguard Worker             }
548*35238bceSAndroid Build Coastguard Worker         }
549*35238bceSAndroid Build Coastguard Worker 
550*35238bceSAndroid Build Coastguard Worker         // Compare
551*35238bceSAndroid Build Coastguard Worker         {
552*35238bceSAndroid Build Coastguard Worker             bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", refImg, testImg, threshold,
553*35238bceSAndroid Build Coastguard Worker                                           tcu::COMPARE_LOG_RESULT);
554*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
555*35238bceSAndroid Build Coastguard Worker                                     isOk ? "Pass" : "Image comparison failed");
556*35238bceSAndroid Build Coastguard Worker         }
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker         return STOP;
559*35238bceSAndroid Build Coastguard Worker     }
560*35238bceSAndroid Build Coastguard Worker };
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker class FrontFacingCase : public TestCase
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker public:
FrontFacingCase(Context & context)565*35238bceSAndroid Build Coastguard Worker     FrontFacingCase(Context &context) : TestCase(context, "frontfacing", "gl_FrontFacing Test")
566*35238bceSAndroid Build Coastguard Worker     {
567*35238bceSAndroid Build Coastguard Worker     }
568*35238bceSAndroid Build Coastguard Worker 
iterate(void)569*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
570*35238bceSAndroid Build Coastguard Worker     {
571*35238bceSAndroid Build Coastguard Worker         // Test case renders two adjecent quads, where left is has front-facing
572*35238bceSAndroid Build Coastguard Worker         // triagles and right back-facing. Color is selected based on gl_FrontFacing
573*35238bceSAndroid Build Coastguard Worker         // value.
574*35238bceSAndroid Build Coastguard Worker 
575*35238bceSAndroid Build Coastguard Worker         TestLog &log             = m_testCtx.getLog();
576*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
577*35238bceSAndroid Build Coastguard Worker         de::Random rnd(0x89f2c);
578*35238bceSAndroid Build Coastguard Worker         const int width     = de::min(64, m_context.getRenderTarget().getWidth());
579*35238bceSAndroid Build Coastguard Worker         const int height    = de::min(64, m_context.getRenderTarget().getHeight());
580*35238bceSAndroid Build Coastguard Worker         const int viewportX = rnd.getInt(0, m_context.getRenderTarget().getWidth() - width);
581*35238bceSAndroid Build Coastguard Worker         const int viewportY = rnd.getInt(0, m_context.getRenderTarget().getHeight() - height);
582*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold =
583*35238bceSAndroid Build Coastguard Worker             tcu::RGBA(1, 1, 1, 1) + m_context.getRenderTarget().getPixelFormat().getColorThreshold();
584*35238bceSAndroid Build Coastguard Worker 
585*35238bceSAndroid Build Coastguard Worker         tcu::Surface testImg(width, height);
586*35238bceSAndroid Build Coastguard Worker         tcu::Surface refImg(width, height);
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(m_context.getRenderContext(),
589*35238bceSAndroid Build Coastguard Worker                                          glu::makeVtxFragSources("attribute highp vec4 a_position;\n"
590*35238bceSAndroid Build Coastguard Worker                                                                  "void main (void)\n"
591*35238bceSAndroid Build Coastguard Worker                                                                  "{\n"
592*35238bceSAndroid Build Coastguard Worker                                                                  "    gl_Position = a_position;\n"
593*35238bceSAndroid Build Coastguard Worker                                                                  "}\n",
594*35238bceSAndroid Build Coastguard Worker 
595*35238bceSAndroid Build Coastguard Worker                                                                  "void main (void)\n"
596*35238bceSAndroid Build Coastguard Worker                                                                  "{\n"
597*35238bceSAndroid Build Coastguard Worker                                                                  "    if (gl_FrontFacing)\n"
598*35238bceSAndroid Build Coastguard Worker                                                                  "        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
599*35238bceSAndroid Build Coastguard Worker                                                                  "    else\n"
600*35238bceSAndroid Build Coastguard Worker                                                                  "        gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n"
601*35238bceSAndroid Build Coastguard Worker                                                                  "}\n"));
602*35238bceSAndroid Build Coastguard Worker 
603*35238bceSAndroid Build Coastguard Worker         log << program;
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
606*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Compile failed");
607*35238bceSAndroid Build Coastguard Worker 
608*35238bceSAndroid Build Coastguard Worker         // Draw with GL.
609*35238bceSAndroid Build Coastguard Worker         {
610*35238bceSAndroid Build Coastguard Worker             const float positions[]     = {-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f,
611*35238bceSAndroid Build Coastguard Worker                                            1.0f,  1.0f, 0.0f, 1.0f, 1.0f,  -1.0f, 0.0f, 1.0f};
612*35238bceSAndroid Build Coastguard Worker             const uint16_t indicesCCW[] = {0, 1, 2, 2, 1, 3};
613*35238bceSAndroid Build Coastguard Worker             const uint16_t indicesCW[]  = {2, 1, 0, 3, 1, 2};
614*35238bceSAndroid Build Coastguard Worker 
615*35238bceSAndroid Build Coastguard Worker             glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 4, 4, 0, &positions[0]);
616*35238bceSAndroid Build Coastguard Worker 
617*35238bceSAndroid Build Coastguard Worker             gl.useProgram(program.getProgram());
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker             gl.frontFace(GL_CCW);
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker             gl.viewport(viewportX, viewportY, width / 2, height / 2);
622*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
623*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCCW), &indicesCCW[0]));
624*35238bceSAndroid Build Coastguard Worker 
625*35238bceSAndroid Build Coastguard Worker             gl.viewport(viewportX + width / 2, viewportY, width - width / 2, height / 2);
626*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
627*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCW), &indicesCW[0]));
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker             gl.frontFace(GL_CW);
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker             gl.viewport(viewportX, viewportY + height / 2, width / 2, height - height / 2);
632*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
633*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCCW), &indicesCCW[0]));
634*35238bceSAndroid Build Coastguard Worker 
635*35238bceSAndroid Build Coastguard Worker             gl.viewport(viewportX + width / 2, viewportY + height / 2, width - width / 2, height - height / 2);
636*35238bceSAndroid Build Coastguard Worker             glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posBinding,
637*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indicesCW), &indicesCW[0]));
638*35238bceSAndroid Build Coastguard Worker 
639*35238bceSAndroid Build Coastguard Worker             glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
640*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");
641*35238bceSAndroid Build Coastguard Worker         }
642*35238bceSAndroid Build Coastguard Worker 
643*35238bceSAndroid Build Coastguard Worker         // Draw reference
644*35238bceSAndroid Build Coastguard Worker         {
645*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < refImg.getHeight() / 2; y++)
646*35238bceSAndroid Build Coastguard Worker                 for (int x = 0; x < refImg.getWidth() / 2; x++)
647*35238bceSAndroid Build Coastguard Worker                     refImg.setPixel(x, y, tcu::RGBA::green());
648*35238bceSAndroid Build Coastguard Worker 
649*35238bceSAndroid Build Coastguard Worker             for (int y = 0; y < refImg.getHeight() / 2; y++)
650*35238bceSAndroid Build Coastguard Worker                 for (int x = refImg.getWidth() / 2; x < refImg.getWidth(); x++)
651*35238bceSAndroid Build Coastguard Worker                     refImg.setPixel(x, y, tcu::RGBA::blue());
652*35238bceSAndroid Build Coastguard Worker 
653*35238bceSAndroid Build Coastguard Worker             for (int y = refImg.getHeight() / 2; y < refImg.getHeight(); y++)
654*35238bceSAndroid Build Coastguard Worker                 for (int x = 0; x < refImg.getWidth() / 2; x++)
655*35238bceSAndroid Build Coastguard Worker                     refImg.setPixel(x, y, tcu::RGBA::blue());
656*35238bceSAndroid Build Coastguard Worker 
657*35238bceSAndroid Build Coastguard Worker             for (int y = refImg.getHeight() / 2; y < refImg.getHeight(); y++)
658*35238bceSAndroid Build Coastguard Worker                 for (int x = refImg.getWidth() / 2; x < refImg.getWidth(); x++)
659*35238bceSAndroid Build Coastguard Worker                     refImg.setPixel(x, y, tcu::RGBA::green());
660*35238bceSAndroid Build Coastguard Worker         }
661*35238bceSAndroid Build Coastguard Worker 
662*35238bceSAndroid Build Coastguard Worker         // Compare
663*35238bceSAndroid Build Coastguard Worker         {
664*35238bceSAndroid Build Coastguard Worker             bool isOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", refImg, testImg, threshold,
665*35238bceSAndroid Build Coastguard Worker                                                    tcu::COMPARE_LOG_RESULT);
666*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
667*35238bceSAndroid Build Coastguard Worker                                     isOk ? "Pass" : "Image comparison failed");
668*35238bceSAndroid Build Coastguard Worker         }
669*35238bceSAndroid Build Coastguard Worker 
670*35238bceSAndroid Build Coastguard Worker         return STOP;
671*35238bceSAndroid Build Coastguard Worker     }
672*35238bceSAndroid Build Coastguard Worker };
673*35238bceSAndroid Build Coastguard Worker 
ShaderBuiltinVarTests(Context & context)674*35238bceSAndroid Build Coastguard Worker ShaderBuiltinVarTests::ShaderBuiltinVarTests(Context &context)
675*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "builtin_variable", "Built-in Variable Tests")
676*35238bceSAndroid Build Coastguard Worker {
677*35238bceSAndroid Build Coastguard Worker }
678*35238bceSAndroid Build Coastguard Worker 
~ShaderBuiltinVarTests(void)679*35238bceSAndroid Build Coastguard Worker ShaderBuiltinVarTests::~ShaderBuiltinVarTests(void)
680*35238bceSAndroid Build Coastguard Worker {
681*35238bceSAndroid Build Coastguard Worker }
682*35238bceSAndroid Build Coastguard Worker 
init(void)683*35238bceSAndroid Build Coastguard Worker void ShaderBuiltinVarTests::init(void)
684*35238bceSAndroid Build Coastguard Worker {
685*35238bceSAndroid Build Coastguard Worker     // Builtin constants.
686*35238bceSAndroid Build Coastguard Worker 
687*35238bceSAndroid Build Coastguard Worker     static const struct
688*35238bceSAndroid Build Coastguard Worker     {
689*35238bceSAndroid Build Coastguard Worker         const char *caseName;
690*35238bceSAndroid Build Coastguard Worker         const char *varName;
691*35238bceSAndroid Build Coastguard Worker         uint32_t paramName;
692*35238bceSAndroid Build Coastguard Worker     } builtinConstants[] = {
693*35238bceSAndroid Build Coastguard Worker         {"max_vertex_attribs", "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS},
694*35238bceSAndroid Build Coastguard Worker         {"max_vertex_uniform_vectors", "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS},
695*35238bceSAndroid Build Coastguard Worker         {"max_fragment_uniform_vectors", "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS},
696*35238bceSAndroid Build Coastguard Worker         {"max_varying_vectors", "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS},
697*35238bceSAndroid Build Coastguard Worker         {"max_texture_image_units", "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS},
698*35238bceSAndroid Build Coastguard Worker         {"max_vertex_texture_image_units", "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS},
699*35238bceSAndroid Build Coastguard Worker         {"max_combined_texture_image_units", "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS},
700*35238bceSAndroid Build Coastguard Worker         {"max_draw_buffers", "gl_MaxDrawBuffers", GL_NONE}};
701*35238bceSAndroid Build Coastguard Worker 
702*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtinConstants); ndx++)
703*35238bceSAndroid Build Coastguard Worker     {
704*35238bceSAndroid Build Coastguard Worker         const char *caseName = builtinConstants[ndx].caseName;
705*35238bceSAndroid Build Coastguard Worker         const char *varName  = builtinConstants[ndx].varName;
706*35238bceSAndroid Build Coastguard Worker         uint32_t paramName   = builtinConstants[ndx].paramName;
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker         addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_vertex").c_str(), varName, varName,
709*35238bceSAndroid Build Coastguard Worker                                                paramName, true));
710*35238bceSAndroid Build Coastguard Worker         addChild(new ShaderBuiltinConstantCase(m_context, (string(caseName) + "_fragment").c_str(), varName, varName,
711*35238bceSAndroid Build Coastguard Worker                                                paramName, false));
712*35238bceSAndroid Build Coastguard Worker     }
713*35238bceSAndroid Build Coastguard Worker 
714*35238bceSAndroid Build Coastguard Worker     addChild(new ShaderDepthRangeTest(m_context, "depth_range_vertex", "gl_DepthRange", true));
715*35238bceSAndroid Build Coastguard Worker     addChild(new ShaderDepthRangeTest(m_context, "depth_range_fragment", "gl_DepthRange", false));
716*35238bceSAndroid Build Coastguard Worker 
717*35238bceSAndroid Build Coastguard Worker     // Fragment shader builtin variables.
718*35238bceSAndroid Build Coastguard Worker 
719*35238bceSAndroid Build Coastguard Worker     addChild(new FragCoordXYZCase(m_context));
720*35238bceSAndroid Build Coastguard Worker     addChild(new FragCoordWCase(m_context));
721*35238bceSAndroid Build Coastguard Worker     addChild(new PointCoordCase(m_context));
722*35238bceSAndroid Build Coastguard Worker     addChild(new FrontFacingCase(m_context));
723*35238bceSAndroid Build Coastguard Worker }
724*35238bceSAndroid Build Coastguard Worker 
725*35238bceSAndroid Build Coastguard Worker } // namespace Functional
726*35238bceSAndroid Build Coastguard Worker } // namespace gles2
727*35238bceSAndroid Build Coastguard Worker } // namespace deqp
728