xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fDepthRangeTests.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 glDepthRangef() tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fDepthRangeTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
35*35238bceSAndroid Build Coastguard Worker #include "deString.h"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker #include "glw.h"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker namespace deqp
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace gles2
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace Functional
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker enum
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker     VISUALIZE_DEPTH_STEPS = 32 //!< Number of depth steps in visualization
49*35238bceSAndroid Build Coastguard Worker };
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker using std::string;
52*35238bceSAndroid Build Coastguard Worker using std::vector;
53*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
54*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
55*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
56*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
57*35238bceSAndroid Build Coastguard Worker 
58*35238bceSAndroid Build Coastguard Worker static const char *s_vertexShaderSrc   = "attribute highp vec4 a_position;\n"
59*35238bceSAndroid Build Coastguard Worker                                          "attribute highp vec2 a_coord;\n"
60*35238bceSAndroid Build Coastguard Worker                                          "void main (void)\n"
61*35238bceSAndroid Build Coastguard Worker                                          "{\n"
62*35238bceSAndroid Build Coastguard Worker                                          "    gl_Position = a_position;\n"
63*35238bceSAndroid Build Coastguard Worker                                          "}\n";
64*35238bceSAndroid Build Coastguard Worker static const char *s_fragmentShaderSrc = "uniform mediump vec4 u_color;\n"
65*35238bceSAndroid Build Coastguard Worker                                          "void main (void)\n"
66*35238bceSAndroid Build Coastguard Worker                                          "{\n"
67*35238bceSAndroid Build Coastguard Worker                                          "    gl_FragColor = u_color;\n"
68*35238bceSAndroid Build Coastguard Worker                                          "}\n";
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker template <typename T>
compare(uint32_t func,T a,T b)71*35238bceSAndroid Build Coastguard Worker static inline bool compare(uint32_t func, T a, T b)
72*35238bceSAndroid Build Coastguard Worker {
73*35238bceSAndroid Build Coastguard Worker     switch (func)
74*35238bceSAndroid Build Coastguard Worker     {
75*35238bceSAndroid Build Coastguard Worker     case GL_NEVER:
76*35238bceSAndroid Build Coastguard Worker         return false;
77*35238bceSAndroid Build Coastguard Worker     case GL_ALWAYS:
78*35238bceSAndroid Build Coastguard Worker         return true;
79*35238bceSAndroid Build Coastguard Worker     case GL_LESS:
80*35238bceSAndroid Build Coastguard Worker         return a < b;
81*35238bceSAndroid Build Coastguard Worker     case GL_LEQUAL:
82*35238bceSAndroid Build Coastguard Worker         return a <= b;
83*35238bceSAndroid Build Coastguard Worker     case GL_EQUAL:
84*35238bceSAndroid Build Coastguard Worker         return a == b;
85*35238bceSAndroid Build Coastguard Worker     case GL_NOTEQUAL:
86*35238bceSAndroid Build Coastguard Worker         return a != b;
87*35238bceSAndroid Build Coastguard Worker     case GL_GEQUAL:
88*35238bceSAndroid Build Coastguard Worker         return a >= b;
89*35238bceSAndroid Build Coastguard Worker     case GL_GREATER:
90*35238bceSAndroid Build Coastguard Worker         return a > b;
91*35238bceSAndroid Build Coastguard Worker     default:
92*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
93*35238bceSAndroid Build Coastguard Worker         return false;
94*35238bceSAndroid Build Coastguard Worker     }
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker 
triangleInterpolate(const float v0,const float v1,const float v2,const float x,const float y)97*35238bceSAndroid Build Coastguard Worker inline float triangleInterpolate(const float v0, const float v1, const float v2, const float x, const float y)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker     return v0 + (v2 - v0) * x + (v1 - v0) * y;
100*35238bceSAndroid Build Coastguard Worker }
101*35238bceSAndroid Build Coastguard Worker 
triQuadInterpolate(const float x,const float y,const tcu::Vec4 & quad)102*35238bceSAndroid Build Coastguard Worker inline float triQuadInterpolate(const float x, const float y, const tcu::Vec4 &quad)
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker     // \note Top left fill rule.
105*35238bceSAndroid Build Coastguard Worker     if (x + y < 1.0f)
106*35238bceSAndroid Build Coastguard Worker         return triangleInterpolate(quad.x(), quad.y(), quad.z(), x, y);
107*35238bceSAndroid Build Coastguard Worker     else
108*35238bceSAndroid Build Coastguard Worker         return triangleInterpolate(quad.w(), quad.z(), quad.y(), 1.0f - x, 1.0f - y);
109*35238bceSAndroid Build Coastguard Worker }
110*35238bceSAndroid Build Coastguard Worker 
depthRangeTransform(const float zd,const float zNear,const float zFar)111*35238bceSAndroid Build Coastguard Worker inline float depthRangeTransform(const float zd, const float zNear, const float zFar)
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker     const float cNear = de::clamp(zNear, 0.0f, 1.0f);
114*35238bceSAndroid Build Coastguard Worker     const float cFar  = de::clamp(zFar, 0.0f, 1.0f);
115*35238bceSAndroid Build Coastguard Worker     return ((cFar - cNear) / 2.0f) * zd + (cNear + cFar) / 2.0f;
116*35238bceSAndroid Build Coastguard Worker }
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker class DepthRangeCompareCase : public TestCase
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker public:
121*35238bceSAndroid Build Coastguard Worker     DepthRangeCompareCase(Context &context, const char *name, const char *desc, const tcu::Vec4 &depthCoord,
122*35238bceSAndroid Build Coastguard Worker                           const float zNear, const float zFar, const uint32_t compareFunc);
123*35238bceSAndroid Build Coastguard Worker     ~DepthRangeCompareCase(void);
124*35238bceSAndroid Build Coastguard Worker 
125*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker private:
128*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 m_depthCoord;
129*35238bceSAndroid Build Coastguard Worker     const float m_zNear;
130*35238bceSAndroid Build Coastguard Worker     const float m_zFar;
131*35238bceSAndroid Build Coastguard Worker     const uint32_t m_compareFunc;
132*35238bceSAndroid Build Coastguard Worker };
133*35238bceSAndroid Build Coastguard Worker 
DepthRangeCompareCase(Context & context,const char * name,const char * desc,const tcu::Vec4 & depthCoord,const float zNear,const float zFar,const uint32_t compareFunc)134*35238bceSAndroid Build Coastguard Worker DepthRangeCompareCase::DepthRangeCompareCase(Context &context, const char *name, const char *desc,
135*35238bceSAndroid Build Coastguard Worker                                              const tcu::Vec4 &depthCoord, const float zNear, const float zFar,
136*35238bceSAndroid Build Coastguard Worker                                              const uint32_t compareFunc)
137*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
138*35238bceSAndroid Build Coastguard Worker     , m_depthCoord(depthCoord)
139*35238bceSAndroid Build Coastguard Worker     , m_zNear(zNear)
140*35238bceSAndroid Build Coastguard Worker     , m_zFar(zFar)
141*35238bceSAndroid Build Coastguard Worker     , m_compareFunc(compareFunc)
142*35238bceSAndroid Build Coastguard Worker {
143*35238bceSAndroid Build Coastguard Worker }
144*35238bceSAndroid Build Coastguard Worker 
~DepthRangeCompareCase(void)145*35238bceSAndroid Build Coastguard Worker DepthRangeCompareCase::~DepthRangeCompareCase(void)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker }
148*35238bceSAndroid Build Coastguard Worker 
iterate(void)149*35238bceSAndroid Build Coastguard Worker DepthRangeCompareCase::IterateResult DepthRangeCompareCase::iterate(void)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
152*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()));
153*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
154*35238bceSAndroid Build Coastguard Worker     const int viewportW                   = de::min(128, renderTarget.getWidth());
155*35238bceSAndroid Build Coastguard Worker     const int viewportH                   = de::min(128, renderTarget.getHeight());
156*35238bceSAndroid Build Coastguard Worker     const int viewportX                   = rnd.getInt(0, renderTarget.getWidth() - viewportW);
157*35238bceSAndroid Build Coastguard Worker     const int viewportY                   = rnd.getInt(0, renderTarget.getHeight() - viewportH);
158*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedFrame(viewportW, viewportH);
159*35238bceSAndroid Build Coastguard Worker     tcu::Surface referenceFrame(viewportW, viewportH);
160*35238bceSAndroid Build Coastguard Worker     const float constDepth = 0.1f;
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker     if (renderTarget.getDepthBits() == 0)
163*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(),
166*35238bceSAndroid Build Coastguard Worker                                      glu::makeVtxFragSources(s_vertexShaderSrc, s_fragmentShaderSrc));
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker     if (!program.isOk())
169*35238bceSAndroid Build Coastguard Worker     {
170*35238bceSAndroid Build Coastguard Worker         log << program;
171*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
172*35238bceSAndroid Build Coastguard Worker     }
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker     const int colorLoc = glGetUniformLocation(program.getProgram(), "u_color");
175*35238bceSAndroid Build Coastguard Worker     const int posLoc   = glGetAttribLocation(program.getProgram(), "a_position");
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::Message << "glDepthRangef(" << m_zNear << ", " << m_zFar << ")"
178*35238bceSAndroid Build Coastguard Worker                        << TestLog::EndMessage;
179*35238bceSAndroid Build Coastguard Worker 
180*35238bceSAndroid Build Coastguard Worker     glViewport(viewportX, viewportY, viewportW, viewportH);
181*35238bceSAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
182*35238bceSAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
183*35238bceSAndroid Build Coastguard Worker     glUseProgram(program.getProgram());
184*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(posLoc);
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker     static const uint16_t quadIndices[] = {0, 1, 2, 2, 1, 3};
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker     // Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
189*35238bceSAndroid Build Coastguard Worker     {
190*35238bceSAndroid Build Coastguard Worker         static const float constDepthCoord[]   = {-1.0f, -1.0f, constDepth, 1.0f, -1.0f, +1.0f, constDepth, 1.0f,
191*35238bceSAndroid Build Coastguard Worker                                                   0.0f,  -1.0f, constDepth, 1.0f, 0.0f,  +1.0f, constDepth, 1.0f};
192*35238bceSAndroid Build Coastguard Worker         static const float varyingDepthCoord[] = {0.0f,  -1.0f, +1.0f, 1.0f, 0.0f,  +1.0f, 0.0f,  1.0f,
193*35238bceSAndroid Build Coastguard Worker                                                   +1.0f, -1.0f, 0.0f,  1.0f, +1.0f, +1.0f, -1.0f, 1.0f};
194*35238bceSAndroid Build Coastguard Worker 
195*35238bceSAndroid Build Coastguard Worker         glUniform4f(colorLoc, 0.0f, 0.0f, 1.0f, 1.0f);
196*35238bceSAndroid Build Coastguard Worker         glDepthFunc(GL_ALWAYS);
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &constDepthCoord);
199*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]);
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &varyingDepthCoord);
202*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]);
203*35238bceSAndroid Build Coastguard Worker 
204*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
205*35238bceSAndroid Build Coastguard Worker     }
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker     // Render with depth test.
208*35238bceSAndroid Build Coastguard Worker     {
209*35238bceSAndroid Build Coastguard Worker         const float position[] = {-1.0f, -1.0f, m_depthCoord[0], 1.0f, -1.0f, +1.0f, m_depthCoord[1], 1.0f,
210*35238bceSAndroid Build Coastguard Worker                                   +1.0f, -1.0f, m_depthCoord[2], 1.0f, +1.0f, +1.0f, m_depthCoord[3], 1.0f};
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker         glDepthRangef(m_zNear, m_zFar);
213*35238bceSAndroid Build Coastguard Worker         glDepthFunc(m_compareFunc);
214*35238bceSAndroid Build Coastguard Worker         glUniform4f(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
217*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]);
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
220*35238bceSAndroid Build Coastguard Worker     }
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker     // Render reference.
225*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < referenceFrame.getHeight(); y++)
226*35238bceSAndroid Build Coastguard Worker     {
227*35238bceSAndroid Build Coastguard Worker         float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
228*35238bceSAndroid Build Coastguard Worker         int half = de::clamp((int)((float)referenceFrame.getWidth() * 0.5f + 0.5f), 0, referenceFrame.getWidth());
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker         // Fill left half - comparison to constant 0.5
231*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < half; x++)
232*35238bceSAndroid Build Coastguard Worker         {
233*35238bceSAndroid Build Coastguard Worker             float xf   = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
234*35238bceSAndroid Build Coastguard Worker             float d    = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar);
235*35238bceSAndroid Build Coastguard Worker             bool dpass = compare(m_compareFunc, d, constDepth * 0.5f + 0.5f);
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker             referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
238*35238bceSAndroid Build Coastguard Worker         }
239*35238bceSAndroid Build Coastguard Worker 
240*35238bceSAndroid Build Coastguard Worker         // Fill right half - comparison to interpolated depth
241*35238bceSAndroid Build Coastguard Worker         for (int x = half; x < referenceFrame.getWidth(); x++)
242*35238bceSAndroid Build Coastguard Worker         {
243*35238bceSAndroid Build Coastguard Worker             float xf   = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
244*35238bceSAndroid Build Coastguard Worker             float xh   = ((float)(x - half) + 0.5f) / (float)(referenceFrame.getWidth() - half);
245*35238bceSAndroid Build Coastguard Worker             float rd   = 1.0f - (xh + yf) * 0.5f;
246*35238bceSAndroid Build Coastguard Worker             float d    = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar);
247*35238bceSAndroid Build Coastguard Worker             bool dpass = compare(m_compareFunc, d, rd);
248*35238bceSAndroid Build Coastguard Worker 
249*35238bceSAndroid Build Coastguard Worker             referenceFrame.setPixel(x, y, dpass ? tcu::RGBA::green() : tcu::RGBA::blue());
250*35238bceSAndroid Build Coastguard Worker         }
251*35238bceSAndroid Build Coastguard Worker     }
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f,
254*35238bceSAndroid Build Coastguard Worker                                   tcu::COMPARE_LOG_RESULT);
255*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
256*35238bceSAndroid Build Coastguard Worker     return STOP;
257*35238bceSAndroid Build Coastguard Worker }
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker class DepthRangeWriteCase : public TestCase
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker public:
262*35238bceSAndroid Build Coastguard Worker     DepthRangeWriteCase(Context &context, const char *name, const char *desc, const tcu::Vec4 &depthCoord,
263*35238bceSAndroid Build Coastguard Worker                         const float zNear, const float zFar);
264*35238bceSAndroid Build Coastguard Worker     ~DepthRangeWriteCase(void);
265*35238bceSAndroid Build Coastguard Worker 
266*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
267*35238bceSAndroid Build Coastguard Worker 
268*35238bceSAndroid Build Coastguard Worker private:
269*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 &m_depthCoord;
270*35238bceSAndroid Build Coastguard Worker     const float m_zNear;
271*35238bceSAndroid Build Coastguard Worker     const float m_zFar;
272*35238bceSAndroid Build Coastguard Worker };
273*35238bceSAndroid Build Coastguard Worker 
DepthRangeWriteCase(Context & context,const char * name,const char * desc,const tcu::Vec4 & depthCoord,const float zNear,const float zFar)274*35238bceSAndroid Build Coastguard Worker DepthRangeWriteCase::DepthRangeWriteCase(Context &context, const char *name, const char *desc,
275*35238bceSAndroid Build Coastguard Worker                                          const tcu::Vec4 &depthCoord, const float zNear, const float zFar)
276*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
277*35238bceSAndroid Build Coastguard Worker     , m_depthCoord(depthCoord)
278*35238bceSAndroid Build Coastguard Worker     , m_zNear(zNear)
279*35238bceSAndroid Build Coastguard Worker     , m_zFar(zFar)
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker }
282*35238bceSAndroid Build Coastguard Worker 
~DepthRangeWriteCase(void)283*35238bceSAndroid Build Coastguard Worker DepthRangeWriteCase::~DepthRangeWriteCase(void)
284*35238bceSAndroid Build Coastguard Worker {
285*35238bceSAndroid Build Coastguard Worker }
286*35238bceSAndroid Build Coastguard Worker 
iterate(void)287*35238bceSAndroid Build Coastguard Worker DepthRangeWriteCase::IterateResult DepthRangeWriteCase::iterate(void)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
290*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()));
291*35238bceSAndroid Build Coastguard Worker     const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();
292*35238bceSAndroid Build Coastguard Worker     const int viewportW                   = de::min(128, renderTarget.getWidth());
293*35238bceSAndroid Build Coastguard Worker     const int viewportH                   = de::min(128, renderTarget.getHeight());
294*35238bceSAndroid Build Coastguard Worker     const int viewportX                   = rnd.getInt(0, renderTarget.getWidth() - viewportW);
295*35238bceSAndroid Build Coastguard Worker     const int viewportY                   = rnd.getInt(0, renderTarget.getHeight() - viewportH);
296*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedFrame(viewportW, viewportH);
297*35238bceSAndroid Build Coastguard Worker     tcu::Surface referenceFrame(viewportW, viewportH);
298*35238bceSAndroid Build Coastguard Worker     const int numDepthSteps = VISUALIZE_DEPTH_STEPS;
299*35238bceSAndroid Build Coastguard Worker     const float depthStep   = 1.0f / (float)(numDepthSteps - 1);
300*35238bceSAndroid Build Coastguard Worker 
301*35238bceSAndroid Build Coastguard Worker     if (renderTarget.getDepthBits() == 0)
302*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("Depth buffer is required", "", __FILE__, __LINE__);
303*35238bceSAndroid Build Coastguard Worker 
304*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram program(m_context.getRenderContext(),
305*35238bceSAndroid Build Coastguard Worker                                      glu::makeVtxFragSources(s_vertexShaderSrc, s_fragmentShaderSrc));
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker     if (!program.isOk())
308*35238bceSAndroid Build Coastguard Worker     {
309*35238bceSAndroid Build Coastguard Worker         log << program;
310*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Compile failed");
311*35238bceSAndroid Build Coastguard Worker     }
312*35238bceSAndroid Build Coastguard Worker 
313*35238bceSAndroid Build Coastguard Worker     const int colorLoc = glGetUniformLocation(program.getProgram(), "u_color");
314*35238bceSAndroid Build Coastguard Worker     const int posLoc   = glGetAttribLocation(program.getProgram(), "a_position");
315*35238bceSAndroid Build Coastguard Worker 
316*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << TestLog::Message << "glDepthRangef(" << m_zNear << ", " << m_zFar << ")"
317*35238bceSAndroid Build Coastguard Worker                        << TestLog::EndMessage;
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker     glViewport(viewportX, viewportY, viewportW, viewportH);
320*35238bceSAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
321*35238bceSAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
322*35238bceSAndroid Build Coastguard Worker     glUseProgram(program.getProgram());
323*35238bceSAndroid Build Coastguard Worker     glEnableVertexAttribArray(posLoc);
324*35238bceSAndroid Build Coastguard Worker 
325*35238bceSAndroid Build Coastguard Worker     static const uint16_t quadIndices[] = {0, 1, 2, 2, 1, 3};
326*35238bceSAndroid Build Coastguard Worker 
327*35238bceSAndroid Build Coastguard Worker     // Render with depth range.
328*35238bceSAndroid Build Coastguard Worker     {
329*35238bceSAndroid Build Coastguard Worker         const float position[] = {-1.0f, -1.0f, m_depthCoord[0], 1.0f, -1.0f, +1.0f, m_depthCoord[1], 1.0f,
330*35238bceSAndroid Build Coastguard Worker                                   +1.0f, -1.0f, m_depthCoord[2], 1.0f, +1.0f, +1.0f, m_depthCoord[3], 1.0f};
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker         glDepthFunc(GL_ALWAYS);
333*35238bceSAndroid Build Coastguard Worker         glDepthRangef(m_zNear, m_zFar);
334*35238bceSAndroid Build Coastguard Worker         glUniform4f(colorLoc, 0.0f, 1.0f, 0.0f, 1.0f);
335*35238bceSAndroid Build Coastguard Worker         glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
336*35238bceSAndroid Build Coastguard Worker         glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]);
337*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
338*35238bceSAndroid Build Coastguard Worker     }
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker     // Visualize by rendering full-screen quads with increasing depth and color.
341*35238bceSAndroid Build Coastguard Worker     {
342*35238bceSAndroid Build Coastguard Worker         glDepthFunc(GL_LEQUAL);
343*35238bceSAndroid Build Coastguard Worker         glDepthMask(GL_FALSE);
344*35238bceSAndroid Build Coastguard Worker         glDepthRangef(0.0f, 1.0f);
345*35238bceSAndroid Build Coastguard Worker 
346*35238bceSAndroid Build Coastguard Worker         for (int stepNdx = 0; stepNdx < numDepthSteps; stepNdx++)
347*35238bceSAndroid Build Coastguard Worker         {
348*35238bceSAndroid Build Coastguard Worker             float f     = (float)stepNdx * depthStep;
349*35238bceSAndroid Build Coastguard Worker             float depth = f * 2.0f - 1.0f;
350*35238bceSAndroid Build Coastguard Worker             Vec4 color  = Vec4(f, f, f, 1.0f);
351*35238bceSAndroid Build Coastguard Worker 
352*35238bceSAndroid Build Coastguard Worker             float position[] = {-1.0f, -1.0f, depth, 1.0f, -1.0f, +1.0f, depth, 1.0f,
353*35238bceSAndroid Build Coastguard Worker                                 +1.0f, -1.0f, depth, 1.0f, +1.0f, +1.0f, depth, 1.0f};
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker             glUniform4fv(colorLoc, 1, color.getPtr());
356*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, &position[0]);
357*35238bceSAndroid Build Coastguard Worker             glDrawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, &quadIndices[0]);
358*35238bceSAndroid Build Coastguard Worker         }
359*35238bceSAndroid Build Coastguard Worker 
360*35238bceSAndroid Build Coastguard Worker         GLU_CHECK();
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedFrame.getAccess());
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker     // Render reference.
366*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < referenceFrame.getHeight(); y++)
367*35238bceSAndroid Build Coastguard Worker     {
368*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < referenceFrame.getWidth(); x++)
369*35238bceSAndroid Build Coastguard Worker         {
370*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)referenceFrame.getWidth();
371*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)referenceFrame.getHeight();
372*35238bceSAndroid Build Coastguard Worker             float d  = depthRangeTransform(triQuadInterpolate(xf, yf, m_depthCoord), m_zNear, m_zFar);
373*35238bceSAndroid Build Coastguard Worker             int step = (int)deFloatFloor(d / depthStep);
374*35238bceSAndroid Build Coastguard Worker             int col  = de::clamp(deRoundFloatToInt32((float)step * depthStep * 255.0f), 0, 255);
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker             referenceFrame.setPixel(x, y, tcu::RGBA(col, col, col, 0xff));
377*35238bceSAndroid Build Coastguard Worker         }
378*35238bceSAndroid Build Coastguard Worker     }
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker     bool isOk = tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame, renderedFrame, 0.05f,
381*35238bceSAndroid Build Coastguard Worker                                   tcu::COMPARE_LOG_RESULT);
382*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, isOk ? "Pass" : "Fail");
383*35238bceSAndroid Build Coastguard Worker     return STOP;
384*35238bceSAndroid Build Coastguard Worker }
385*35238bceSAndroid Build Coastguard Worker 
DepthRangeTests(Context & context)386*35238bceSAndroid Build Coastguard Worker DepthRangeTests::DepthRangeTests(Context &context) : TestCaseGroup(context, "depth_range", "glDepthRangef() tests")
387*35238bceSAndroid Build Coastguard Worker {
388*35238bceSAndroid Build Coastguard Worker }
389*35238bceSAndroid Build Coastguard Worker 
~DepthRangeTests(void)390*35238bceSAndroid Build Coastguard Worker DepthRangeTests::~DepthRangeTests(void)
391*35238bceSAndroid Build Coastguard Worker {
392*35238bceSAndroid Build Coastguard Worker }
393*35238bceSAndroid Build Coastguard Worker 
init(void)394*35238bceSAndroid Build Coastguard Worker void DepthRangeTests::init(void)
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker     static const struct
397*35238bceSAndroid Build Coastguard Worker     {
398*35238bceSAndroid Build Coastguard Worker         const char *name;
399*35238bceSAndroid Build Coastguard Worker         const char *desc;
400*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 depthCoord;
401*35238bceSAndroid Build Coastguard Worker         const float zNear;
402*35238bceSAndroid Build Coastguard Worker         const float zFar;
403*35238bceSAndroid Build Coastguard Worker     } cases[] = {{"default", "Default depth range", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 1.0f},
404*35238bceSAndroid Build Coastguard Worker                  {"reverse", "Reversed default range", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 0.0f},
405*35238bceSAndroid Build Coastguard Worker                  {"zero_to_half", "From 0 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 0.5f},
406*35238bceSAndroid Build Coastguard Worker                  {"half_to_one", "From 0.5 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 1.0f},
407*35238bceSAndroid Build Coastguard Worker                  {"half_to_zero", "From 0.5 to 0", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 0.0f},
408*35238bceSAndroid Build Coastguard Worker                  {"one_to_half", "From 1 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 0.5f},
409*35238bceSAndroid Build Coastguard Worker                  {"third_to_0_8", "From 1/3 to 0.8", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f / 3.0f, 0.8f},
410*35238bceSAndroid Build Coastguard Worker                  {"0_8_to_third", "From 0.8 to 1/3", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.8f, 1.0f / 3.0f},
411*35238bceSAndroid Build Coastguard Worker                  {"zero_to_zero", "From 0 to 0", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 0.0f},
412*35238bceSAndroid Build Coastguard Worker                  {"half_to_half", "From 0.5 to 0.5", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.5f, 0.5f},
413*35238bceSAndroid Build Coastguard Worker                  {"one_to_one", "From 1 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 1.0f, 1.0f},
414*35238bceSAndroid Build Coastguard Worker                  {"clamp_near", "From -1 to 1", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), -1.0f, 1.0f},
415*35238bceSAndroid Build Coastguard Worker                  {"clamp_far", "From 0 to 2", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), 0.0f, 2.0},
416*35238bceSAndroid Build Coastguard Worker                  {"clamp_both", "From -1 to 2", tcu::Vec4(-1.0f, 0.2f, -0.3f, 1.0f), -1.0, 2.0}};
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker     // .write
419*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *writeGroup = new tcu::TestCaseGroup(m_testCtx, "write", "gl_FragDepth write tests");
420*35238bceSAndroid Build Coastguard Worker     addChild(writeGroup);
421*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
422*35238bceSAndroid Build Coastguard Worker         writeGroup->addChild(new DepthRangeWriteCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].depthCoord,
423*35238bceSAndroid Build Coastguard Worker                                                      cases[ndx].zNear, cases[ndx].zFar));
424*35238bceSAndroid Build Coastguard Worker 
425*35238bceSAndroid Build Coastguard Worker     // .compare
426*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *compareGroup =
427*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "compare", "gl_FragDepth used with depth comparison");
428*35238bceSAndroid Build Coastguard Worker     addChild(compareGroup);
429*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
430*35238bceSAndroid Build Coastguard Worker         compareGroup->addChild(new DepthRangeCompareCase(m_context, cases[ndx].name, cases[ndx].desc,
431*35238bceSAndroid Build Coastguard Worker                                                          cases[ndx].depthCoord, cases[ndx].zNear, cases[ndx].zFar,
432*35238bceSAndroid Build Coastguard Worker                                                          GL_LESS));
433*35238bceSAndroid Build Coastguard Worker }
434*35238bceSAndroid Build Coastguard Worker 
435*35238bceSAndroid Build Coastguard Worker } // namespace Functional
436*35238bceSAndroid Build Coastguard Worker } // namespace gles2
437*35238bceSAndroid Build Coastguard Worker } // namespace deqp
438